Remove support for Jersey
Spring Boot 4 requires Jakarta EE 11. Jersey 4 will support EE 11 but its release schedule is uncertain. Furthermore, Jersey does not yet support Jackson 3 and there's no clear timeline for when Jackson 3 will be supported. In light of the above, this commit removes support for Jersey. Reinstating support can be considered once there's a Jersey GA that supports Jakarta EE 11 or its clear that one will be available in time for Boot's GA in November. Ideally, support for Jackson 3 would also be available before reinstating Jersey support. Closes gh-47017
This commit is contained in:
parent
b52c55d633
commit
8bfb170ebc
|
@ -86,7 +86,6 @@ def dependenciesOf(String version) {
|
|||
"spring-boot-integration",
|
||||
"spring-boot-jackson",
|
||||
"spring-boot-jdbc",
|
||||
"spring-boot-jersey",
|
||||
"spring-boot-jetty",
|
||||
"spring-boot-jms",
|
||||
"spring-boot-jooq",
|
||||
|
@ -133,19 +132,24 @@ def dependenciesOf(String version) {
|
|||
"spring-boot-webservices",
|
||||
"spring-boot-zipkin"
|
||||
]
|
||||
if (version.equals("4.0.0-M1")) {
|
||||
if (version.equals("4.0.0-M1") || version.equals("4.0.0-M2")) {
|
||||
modules += [
|
||||
"spring-boot-metrics",
|
||||
"spring-boot-observation",
|
||||
"spring-boot-tracing"
|
||||
]
|
||||
}
|
||||
else {
|
||||
modules += [
|
||||
"spring-boot-micrometer-metrics",
|
||||
"spring-boot-micrometer-observation",
|
||||
"spring-boot-micrometer-tracing"
|
||||
"spring-boot-jersey"
|
||||
]
|
||||
if (version.equals("4.0.0-M1")) {
|
||||
modules += [
|
||||
"spring-boot-metrics",
|
||||
"spring-boot-observation",
|
||||
"spring-boot-tracing"
|
||||
]
|
||||
}
|
||||
else {
|
||||
modules += [
|
||||
"spring-boot-micrometer-metrics",
|
||||
"spring-boot-micrometer-observation",
|
||||
"spring-boot-micrometer-tracing"
|
||||
]
|
||||
}
|
||||
}
|
||||
return modules
|
||||
}
|
||||
|
|
|
@ -138,8 +138,6 @@ dependencies {
|
|||
implementation("org.assertj:assertj-core")
|
||||
implementation("org.cache2k:cache2k-spring")
|
||||
implementation("org.apache.groovy:groovy")
|
||||
implementation("org.glassfish.jersey.containers:jersey-container-servlet-core")
|
||||
implementation("org.glassfish.jersey.core:jersey-server")
|
||||
implementation("org.hibernate.orm:hibernate-jcache") {
|
||||
exclude group: "javax.activation", module: "javax.activation-api"
|
||||
exclude group: "javax.persistence", module: "javax.persistence-api"
|
||||
|
|
|
@ -63,7 +63,7 @@ xref:reference:features/index.adoc[The following content is for you]:
|
|||
|
||||
If you develop Spring Boot web applications, take a look at the following content:
|
||||
|
||||
* *Servlet Web Applications:* xref:reference:web/servlet.adoc[Spring MVC, Jersey, Embedded Servlet Containers]
|
||||
* *Servlet Web Applications:* xref:reference:web/servlet.adoc[Spring MVC, Embedded Servlet Containers]
|
||||
* *Reactive Web Applications:* xref:reference:web/reactive.adoc[Spring Webflux, Embedded Servlet Containers]
|
||||
* *Graceful Shutdown:* xref:reference:web/graceful-shutdown.adoc[Graceful Shutdown]
|
||||
* *Spring Security:* xref:reference:web/spring-security.adoc[Default Security Configuration, Auto-configuration for OAuth2, SAML]
|
||||
|
|
|
@ -566,12 +566,6 @@
|
|||
* xref:how-to:index.adoc#howto[#howto]
|
||||
* xref:how-to:index.adoc[#howto]
|
||||
* xref:how-to:index.adoc[howto]
|
||||
* xref:how-to:jersey.adoc#howto.jersey.alongside-another-web-framework[#howto-jersey-alongside-another-web-framework]
|
||||
* xref:how-to:jersey.adoc#howto.jersey.alongside-another-web-framework[#howto.jersey.alongside-another-web-framework]
|
||||
* xref:how-to:jersey.adoc#howto.jersey.spring-security[#howto-jersey-spring-security]
|
||||
* xref:how-to:jersey.adoc#howto.jersey.spring-security[#howto.jersey.spring-security]
|
||||
* xref:how-to:jersey.adoc#howto.jersey[#howto-jersey]
|
||||
* xref:how-to:jersey.adoc#howto.jersey[#howto.jersey]
|
||||
* xref:how-to:logging.adoc#howto.logging.log4j.composite-configuration[#howto.logging.log4j.composite-configuration]
|
||||
* xref:how-to:logging.adoc#howto.logging.log4j.yaml-or-json-config[#howto-configure-log4j-for-logging-yaml-or-json-config]
|
||||
* xref:how-to:logging.adoc#howto.logging.log4j.yaml-or-json-config[#howto.logging.log4j.yaml-or-json-config]
|
||||
|
@ -1152,8 +1146,6 @@
|
|||
* xref:reference:actuator/metrics.adoc#actuator.metrics.supported.http-clients[#production-ready-metrics-http-clients]
|
||||
* xref:reference:actuator/metrics.adoc#actuator.metrics.supported.jdbc[#actuator.metrics.supported.jdbc]
|
||||
* xref:reference:actuator/metrics.adoc#actuator.metrics.supported.jdbc[#production-ready-metrics-jdbc]
|
||||
* xref:reference:actuator/metrics.adoc#actuator.metrics.supported.jersey[#actuator.metrics.supported.jersey]
|
||||
* xref:reference:actuator/metrics.adoc#actuator.metrics.supported.jersey[#production-ready-metrics-jersey-server]
|
||||
* xref:reference:actuator/metrics.adoc#actuator.metrics.supported.jetty[#actuator.metrics.supported.jetty]
|
||||
* xref:reference:actuator/metrics.adoc#actuator.metrics.supported.jms[#actuator.metrics.supported.jms]
|
||||
* xref:reference:actuator/metrics.adoc#actuator.metrics.supported.jvm[#actuator.metrics.supported.jvm]
|
||||
|
@ -2130,9 +2122,6 @@
|
|||
* xref:reference:web/servlet.adoc#web.servlet.embedded-container[#boot-features-embedded-container]
|
||||
* xref:reference:web/servlet.adoc#web.servlet.embedded-container[#features.developing-web-applications.embedded-container]
|
||||
* xref:reference:web/servlet.adoc#web.servlet.embedded-container[#web.servlet.embedded-container]
|
||||
* xref:reference:web/servlet.adoc#web.servlet.jersey[#boot-features-jersey]
|
||||
* xref:reference:web/servlet.adoc#web.servlet.jersey[#features.developing-web-applications.jersey]
|
||||
* xref:reference:web/servlet.adoc#web.servlet.jersey[#web.servlet.jersey]
|
||||
* xref:reference:web/servlet.adoc#web.servlet.spring-mvc.auto-configuration[#boot-features-spring-mvc-auto-configuration]
|
||||
* xref:reference:web/servlet.adoc#web.servlet.spring-mvc.auto-configuration[#features.developing-web-applications.spring-mvc.auto-configuration]
|
||||
* xref:reference:web/servlet.adoc#web.servlet.spring-mvc.auto-configuration[#web.servlet.spring-mvc.auto-configuration]
|
||||
|
|
|
@ -1,26 +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 javadoc:org.glassfish.jersey.server.ResourceConfig[] bean, as shown in the following example:
|
||||
|
||||
include-code::JerseySetStatusOverSendErrorConfig[]
|
||||
|
||||
|
||||
|
||||
[[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 javadoc:org.glassfish.jersey.server.ResourceConfig[] to forward requests that would have resulted in a 404, as shown in the following example.
|
||||
|
||||
include-code::JerseyConfig[]
|
|
@ -4,7 +4,6 @@
|
|||
** xref:how-to:properties-and-configuration.adoc[]
|
||||
** xref:how-to:webserver.adoc[]
|
||||
** xref:how-to:spring-mvc.adoc[]
|
||||
** xref:how-to:jersey.adoc[]
|
||||
** xref:how-to:http-clients.adoc[]
|
||||
** xref:how-to:logging.adoc[]
|
||||
** xref:how-to:data-access.adoc[]
|
||||
|
|
|
@ -95,7 +95,7 @@ Subject to xref:actuator/endpoints.adoc#actuator.endpoints.sanitization[sanitiza
|
|||
| 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"]
|
||||
|===
|
||||
|
@ -388,8 +388,7 @@ TIP: See javadoc:org.springframework.boot.actuate.autoconfigure.endpoint.web.Cor
|
|||
== Implementing Custom Endpoints
|
||||
|
||||
If you add a javadoc:org.springframework.context.annotation.Bean[format=annotation] annotated with javadoc:org.springframework.boot.actuate.endpoint.annotation.Endpoint[format=annotation], any methods annotated with javadoc:org.springframework.boot.actuate.endpoint.annotation.ReadOperation[format=annotation], javadoc:org.springframework.boot.actuate.endpoint.annotation.WriteOperation[format=annotation], or javadoc:org.springframework.boot.actuate.endpoint.annotation.DeleteOperation[format=annotation] 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:
|
||||
|
||||
|
@ -451,8 +450,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 javadoc:org.springframework.boot.actuate.endpoint.annotation.Endpoint[format=annotation], javadoc:org.springframework.boot.actuate.endpoint.web.annotation.WebEndpoint[format=annotation], or javadoc:org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension[format=annotation] 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 javadoc:org.springframework.boot.actuate.endpoint.annotation.Endpoint[format=annotation], javadoc:org.springframework.boot.actuate.endpoint.web.annotation.WebEndpoint[format=annotation], or javadoc:org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension[format=annotation] are automatically exposed over HTTP using Spring MVC or Spring WebFlux.
|
||||
|
||||
|
||||
|
||||
|
@ -540,8 +538,6 @@ If an operation is invoked without a required parameter or with a parameter that
|
|||
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 javadoc:org.springframework.core.io.Resource[] automatically support range requests.
|
||||
|
||||
NOTE: Range requests are not supported when using Jersey.
|
||||
|
||||
|
||||
|
||||
[[actuator.endpoints.implementing-custom.web.security]]
|
||||
|
|
|
@ -765,39 +765,6 @@ Applications can opt in and record exceptions by xref:web/reactive.adoc#web.reac
|
|||
|
||||
|
||||
|
||||
[[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.observations.http.server.requests.name[] property.
|
||||
|
||||
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 javadoc:org.springframework.context.annotation.Bean[format=annotation] that implements javadoc:io.micrometer.core.instrument.binder.jersey.server.JerseyObservationConvention[].
|
||||
|
||||
|
||||
|
||||
[[actuator.metrics.supported.ssl]]
|
||||
=== SSL Bundle Metrics
|
||||
|
||||
|
|
|
@ -5,8 +5,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 xref:api:rest/actuator/index.adoc[API documentation].
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[[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.
|
||||
|
||||
|
||||
|
||||
|
@ -497,43 +497,6 @@ See xref:io/rest-client.adoc#io.rest-client.apiversioning[] for details.
|
|||
|
||||
|
||||
|
||||
[[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 javadoc:jakarta.servlet.Servlet[] or javadoc:jakarta.servlet.Filter[] as a javadoc:org.springframework.context.annotation.Bean[format=annotation] 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 javadoc:org.springframework.context.annotation.Bean[format=annotation] of type javadoc:org.glassfish.jersey.server.ResourceConfig[] in which you register all the endpoints, as shown in the following example:
|
||||
|
||||
include-code::MyJerseyConfig[]
|
||||
|
||||
WARNING: Jersey's support for scanning executable archives is rather limited.
|
||||
For example, it cannot scan for endpoints in a package found in a xref:how-to:deployment/installing.adoc[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 javadoc:org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer[].
|
||||
|
||||
All the registered endpoints should be a javadoc:org.springframework.stereotype.Component[format=annotation] with HTTP resource annotations (`@GET` and others), as shown in the following example:
|
||||
|
||||
include-code::MyEndpoint[]
|
||||
|
||||
Since the javadoc:org.springframework.boot.actuate.endpoint.annotation.Endpoint[format=annotation] is a Spring javadoc:org.springframework.stereotype.Component[format=annotation], its lifecycle is managed by Spring and you can use the javadoc:org.springframework.beans.factory.annotation.Autowired[format=annotation] annotation to inject dependencies and use the javadoc:org.springframework.beans.factory.annotation.Value[format=annotation] annotation to inject external configuration.
|
||||
By default, the Jersey servlet is registered and mapped to `/*`.
|
||||
You can change the mapping by adding javadoc:jakarta.ws.rs.ApplicationPath[format=annotation] to your javadoc:org.glassfish.jersey.server.ResourceConfig[].
|
||||
|
||||
By default, Jersey is set up as a servlet in a javadoc:org.springframework.context.annotation.Bean[format=annotation] of type javadoc:org.springframework.boot.web.servlet.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 javadoc:org.springframework.context.annotation.Bean[format=annotation] to replace or override is `jerseyFilterRegistration`).
|
||||
The filter has an javadoc:org.springframework.core.annotation.Order[format=annotation], 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
|
||||
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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-present 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-present 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-present 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-present 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 jakarta.ws.rs.GET;
|
||||
import jakarta.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-present 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);
|
||||
}
|
||||
|
||||
}
|
|
@ -28,7 +28,6 @@ dependencies {
|
|||
testImplementation(project(":module:spring-boot-health"))
|
||||
testImplementation(project(":module:spring-boot-http-converter"))
|
||||
testImplementation(project(":module:spring-boot-jackson"))
|
||||
testImplementation(project(":module:spring-boot-jersey"))
|
||||
testImplementation(project(":module:spring-boot-micrometer-metrics"))
|
||||
testImplementation(project(":module:spring-boot-reactor-netty"))
|
||||
testImplementation(project(":core:spring-boot-test"))
|
||||
|
@ -37,7 +36,6 @@ dependencies {
|
|||
testImplementation(project(":module:spring-boot-web-server"))
|
||||
testImplementation(project(":module:spring-boot-webflux"))
|
||||
testImplementation(project(":module:spring-boot-webmvc"))
|
||||
testImplementation(testFixtures(project(":module:spring-boot-jersey")))
|
||||
testImplementation(testFixtures(project(":module:spring-boot-webflux")))
|
||||
testImplementation(testFixtures(project(":module:spring-boot-webmvc")))
|
||||
testImplementation("io.micrometer:micrometer-registry-prometheus")
|
||||
|
|
|
@ -1,172 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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 com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.servlet.Filter;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.ws.rs.ext.ContextResolver;
|
||||
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.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
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.jersey.actuate.endpoint.web.JerseyEndpointResourceFactory;
|
||||
import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
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
|
||||
*/
|
||||
class JerseyWebEndpointIntegrationTests
|
||||
extends AbstractWebEndpointIntegrationTests<AnnotationConfigServletWebServerApplicationContext> {
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
@Disabled("Jersey does not distinguish between /example and /example/")
|
||||
protected void operationWithTrailingSlashShouldNotMatch() {
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -46,15 +46,10 @@ public @interface WebEndpointTest {
|
|||
* The infrastructure against which the test should run.
|
||||
* @return the infrastructure to run the tests against
|
||||
*/
|
||||
Infrastructure[] infrastructure() default { Infrastructure.JERSEY, Infrastructure.MVC, Infrastructure.WEBFLUX };
|
||||
Infrastructure[] infrastructure() default { Infrastructure.MVC, Infrastructure.WEBFLUX };
|
||||
|
||||
enum Infrastructure {
|
||||
|
||||
/**
|
||||
* Actuator running on the Jersey-based infrastructure.
|
||||
*/
|
||||
JERSEY("Jersey"),
|
||||
|
||||
/**
|
||||
* Actuator running on the WebMVC-based infrastructure.
|
||||
*/
|
||||
|
|
|
@ -77,8 +77,8 @@ class WebEndpointTestInvocationContextProvider implements TestTemplateInvocation
|
|||
.findFirst()
|
||||
.ifPresent((provider) -> this.infrastructures.put(infrastructure,
|
||||
provider.getInfrastructureConfiguration(infrastructure))));
|
||||
this.contextFactories = Map.of(Infrastructure.JERSEY, this::createJerseyContext, Infrastructure.MVC,
|
||||
this::createWebMvcContext, Infrastructure.WEBFLUX, this::createWebFluxContext);
|
||||
this.contextFactories = Map.of(Infrastructure.MVC, this::createWebMvcContext, Infrastructure.WEBFLUX,
|
||||
this::createWebFluxContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -100,14 +100,6 @@ class WebEndpointTestInvocationContextProvider implements TestTemplateInvocation
|
|||
return infrastructure.createInvocationContext(this.contextFactories.get(infrastructure));
|
||||
}
|
||||
|
||||
private ConfigurableApplicationContext createJerseyContext(List<Class<?>> classes) {
|
||||
AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext();
|
||||
classes.addAll(getEndpointInfrastructureConfiguration(Infrastructure.JERSEY));
|
||||
context.register(ClassUtils.toClassArray(classes));
|
||||
context.refresh();
|
||||
return context;
|
||||
}
|
||||
|
||||
private ConfigurableApplicationContext createWebMvcContext(List<Class<?>> classes) {
|
||||
AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext();
|
||||
classes.addAll(getEndpointInfrastructureConfiguration(Infrastructure.MVC));
|
||||
|
|
|
@ -136,9 +136,6 @@ dependencies {
|
|||
api(project(":module:spring-boot-jdbc")) {
|
||||
transitive = false
|
||||
}
|
||||
api(project(":module:spring-boot-jersey")) {
|
||||
transitive = false
|
||||
}
|
||||
api(project(":module:spring-boot-jetty")) {
|
||||
transitive = false
|
||||
}
|
||||
|
|
|
@ -63,7 +63,6 @@ dependencies {
|
|||
testImplementation(project(":core:spring-boot-test"))
|
||||
testImplementation(project(":test-support:spring-boot-test-support"))
|
||||
testImplementation(testFixtures(project(":core:spring-boot-autoconfigure")))
|
||||
testImplementation(testFixtures(project(":module:spring-boot-jersey")))
|
||||
testImplementation(testFixtures(project(":module:spring-boot-webmvc")))
|
||||
testImplementation(testFixtures(project(":module:spring-boot-webflux")))
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@ dependencies {
|
|||
testImplementation(project(":module:spring-boot-flyway"))
|
||||
testImplementation(project(":module:spring-boot-rsocket"))
|
||||
testImplementation(project(":test-support:spring-boot-test-support"))
|
||||
testImplementation(testFixtures(project(":module:spring-boot-jersey")))
|
||||
testImplementation(testFixtures(project(":module:spring-boot-webflux")))
|
||||
testImplementation(testFixtures(project(":module:spring-boot-webmvc")))
|
||||
testImplementation("org.springframework:spring-web")
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id "java-library"
|
||||
id "java-test-fixtures"
|
||||
id "org.springframework.boot.auto-configuration"
|
||||
id "org.springframework.boot.configuration-properties"
|
||||
id "org.springframework.boot.deployed"
|
||||
id "org.springframework.boot.optional-dependencies"
|
||||
}
|
||||
|
||||
description = "Spring Boot Jersey"
|
||||
|
||||
dependencies {
|
||||
api(project(":module:spring-boot-servlet"))
|
||||
api("org.glassfish.jersey.containers:jersey-container-servlet-core")
|
||||
api("org.glassfish.jersey.containers:jersey-container-servlet")
|
||||
api("org.glassfish.jersey.core:jersey-server")
|
||||
api("org.glassfish.jersey.ext:jersey-spring6")
|
||||
api("org.glassfish.jersey.media:jersey-media-json-jackson")
|
||||
|
||||
compileOnly("jakarta.servlet:jakarta.servlet-api")
|
||||
compileOnly("com.google.code.findbugs:jsr305")
|
||||
|
||||
implementation("org.springframework:spring-web")
|
||||
|
||||
optional(project(":core:spring-boot-autoconfigure"))
|
||||
optional(project(":module:spring-boot-actuator-autoconfigure"))
|
||||
optional(project(":module:spring-boot-health"))
|
||||
optional(project(":module:spring-boot-jackson"))
|
||||
optional(project(":module:spring-boot-micrometer-metrics"))
|
||||
optional(project(":module:spring-boot-micrometer-observation"))
|
||||
optional("io.projectreactor:reactor-core")
|
||||
optional("org.glassfish.jersey.ext:jersey-micrometer")
|
||||
|
||||
testFixturesApi(testFixtures(project(":module:spring-boot-actuator")))
|
||||
testFixturesImplementation(project(":module:spring-boot-tomcat"))
|
||||
|
||||
testImplementation(project(":core:spring-boot-test"))
|
||||
testImplementation(project(":module:spring-boot-restclient"))
|
||||
testImplementation(project(":module:spring-boot-tomcat"))
|
||||
testImplementation(project(":test-support:spring-boot-test-support"))
|
||||
testImplementation(project(":module:spring-boot-web-server-test"))
|
||||
testImplementation(testFixtures(project(":module:spring-boot-actuator-autoconfigure")))
|
||||
testImplementation("jakarta.servlet:jakarta.servlet-api")
|
||||
testImplementation("org.springframework:spring-webflux")
|
||||
|
||||
testRuntimeOnly("ch.qos.logback:logback-classic")
|
||||
}
|
|
@ -1,362 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.actuate.endpoint.web;
|
||||
|
||||
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 jakarta.ws.rs.HttpMethod;
|
||||
import jakarta.ws.rs.container.ContainerRequestContext;
|
||||
import jakarta.ws.rs.core.MultivaluedMap;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.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 org.jspecify.annotations.Nullable;
|
||||
import reactor.core.publisher.Flux;
|
||||
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.OperationResponseBody;
|
||||
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.core.ParameterizedTypeReference;
|
||||
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 4.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, @Nullable WebServerNamespace serverNamespace,
|
||||
@Nullable 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<@Nullable Object, @Nullable Object>> BODY_CONVERTERS;
|
||||
|
||||
static {
|
||||
List<Function<@Nullable Object, @Nullable Object>> converters = new ArrayList<>();
|
||||
converters.add(new ResourceBodyConverter());
|
||||
if (ClassUtils.isPresent("reactor.core.publisher.Mono", OperationInflector.class.getClassLoader())) {
|
||||
converters.add(new FluxBodyConverter());
|
||||
converters.add(new MonoBodyConverter());
|
||||
}
|
||||
BODY_CONVERTERS = Collections.unmodifiableList(converters);
|
||||
}
|
||||
|
||||
private final WebOperation operation;
|
||||
|
||||
private final boolean readBody;
|
||||
|
||||
private final @Nullable WebServerNamespace serverNamespace;
|
||||
|
||||
private final @Nullable JerseyRemainingPathSegmentProvider remainingPathSegmentProvider;
|
||||
|
||||
private OperationInflector(WebOperation operation, boolean readBody,
|
||||
@Nullable WebServerNamespace serverNamespace,
|
||||
@Nullable 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, String> extractBodyArguments(ContainerRequestContext data) {
|
||||
Map<String, String> entity = ((ContainerRequest) data).readEntity(Map.class,
|
||||
new ParameterizedTypeReference<Map<String, String>>() {
|
||||
}.getType());
|
||||
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 @Nullable 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(@Nullable 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(@Nullable 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();
|
||||
}
|
||||
if (!(response instanceof WebEndpointResponse<?> webEndpointResponse)) {
|
||||
return Response.status(Status.OK).entity(convertIfNecessary(response)).build();
|
||||
}
|
||||
return Response.status(webEndpointResponse.getStatus())
|
||||
.header("Content-Type", webEndpointResponse.getContentType())
|
||||
.entity(convertIfNecessary(webEndpointResponse.getBody()))
|
||||
.build();
|
||||
}
|
||||
|
||||
private @Nullable Object convertIfNecessary(@Nullable Object body) {
|
||||
for (Function<@Nullable Object, @Nullable 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<@Nullable Object, @Nullable Object> {
|
||||
|
||||
@Override
|
||||
public @Nullable Object apply(@Nullable Object body) {
|
||||
if (body instanceof Mono) {
|
||||
return ((Mono<?>) body).block();
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Body converter from {@link Flux} to {@link Flux#collectList Mono<List>}.
|
||||
*/
|
||||
private static final class FluxBodyConverter implements Function<@Nullable Object, @Nullable Object> {
|
||||
|
||||
@Override
|
||||
public @Nullable Object apply(@Nullable Object body) {
|
||||
if (body instanceof Flux) {
|
||||
return ((Flux<?>) body).collectList();
|
||||
}
|
||||
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());
|
||||
Map<String, Map<String, Link>> entity = OperationResponseBody.of(Collections.singletonMap("_links", links));
|
||||
return Response.ok(entity).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class JerseySecurityContext implements SecurityContext {
|
||||
|
||||
private final jakarta.ws.rs.core.SecurityContext securityContext;
|
||||
|
||||
private JerseySecurityContext(jakarta.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,83 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.actuate.endpoint.web;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.glassfish.jersey.server.model.Resource;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
|
||||
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 final class JerseyHealthEndpointAdditionalPathResourceFactory {
|
||||
|
||||
private final JerseyEndpointResourceFactory delegate = new JerseyEndpointResourceFactory();
|
||||
|
||||
private final Set<HealthEndpointGroup> groups;
|
||||
|
||||
private final WebServerNamespace serverNamespace;
|
||||
|
||||
public JerseyHealthEndpointAdditionalPathResourceFactory(WebServerNamespace serverNamespace,
|
||||
HealthEndpointGroups groups) {
|
||||
this.serverNamespace = serverNamespace;
|
||||
this.groups = groups.getAllWithAdditionalPath(serverNamespace);
|
||||
}
|
||||
|
||||
public Collection<Resource> createEndpointResources(EndpointMapping endpointMapping,
|
||||
Collection<ExposableWebEndpoint> endpoints) {
|
||||
return endpoints.stream()
|
||||
.flatMap((endpoint) -> endpoint.getOperations().stream())
|
||||
.flatMap((operation) -> createResources(endpointMapping, operation))
|
||||
.toList();
|
||||
}
|
||||
|
||||
private Stream<Resource> createResources(EndpointMapping endpointMapping, WebOperation operation) {
|
||||
WebOperationRequestPredicate requestPredicate = operation.getRequestPredicate();
|
||||
String matchAllRemainingPathSegmentsVariable = requestPredicate.getMatchAllRemainingPathSegmentsVariable();
|
||||
if (matchAllRemainingPathSegmentsVariable != null) {
|
||||
List<Resource> resources = new ArrayList<>();
|
||||
for (HealthEndpointGroup group : this.groups) {
|
||||
AdditionalHealthEndpointPath additionalPath = group.getAdditionalPath();
|
||||
if (additionalPath != null) {
|
||||
resources.add(this.delegate.getResource(endpointMapping, operation, requestPredicate,
|
||||
additionalPath.getValue(), this.serverNamespace,
|
||||
(data, pathSegmentsVariable) -> data.getUriInfo().getPath()));
|
||||
}
|
||||
}
|
||||
return resources.stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.actuate.endpoint.web;
|
||||
|
||||
import jakarta.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,23 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.boot.jersey.actuate.endpoint.web;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
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 4.0.0
|
||||
*/
|
||||
public class DefaultJerseyApplicationPath implements JerseyApplicationPath {
|
||||
|
||||
private final @Nullable String applicationPath;
|
||||
|
||||
private final ResourceConfig config;
|
||||
|
||||
public DefaultJerseyApplicationPath(@Nullable 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-present 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.jersey.autoconfigure;
|
||||
|
||||
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 4.0.0
|
||||
*/
|
||||
@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 + "/*";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,232 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import com.fasterxml.jackson.databind.AnnotationIntrospector;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.cfg.MapperConfig;
|
||||
import com.fasterxml.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationIntrospector;
|
||||
import jakarta.servlet.DispatcherType;
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.ServletRegistration;
|
||||
import jakarta.ws.rs.ext.ContextResolver;
|
||||
import jakarta.xml.bind.annotation.XmlElement;
|
||||
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.AutoConfiguration;
|
||||
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.ConditionalOnMissingFilterBean;
|
||||
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.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 4.0.0
|
||||
*/
|
||||
@AutoConfiguration(afterName = "org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration")
|
||||
@ConditionalOnClass({ SpringComponentProvider.class, ServletRegistration.class })
|
||||
@ConditionalOnBean(type = "org.glassfish.jersey.server.ResourceConfig")
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
|
||||
@EnableConfigurationProperties(JerseyProperties.class)
|
||||
public final class JerseyAutoConfiguration implements ServletContextAware {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(JerseyAutoConfiguration.class);
|
||||
|
||||
private final JerseyProperties jersey;
|
||||
|
||||
private final ResourceConfig config;
|
||||
|
||||
JerseyAutoConfiguration(JerseyProperties jersey, ResourceConfig config,
|
||||
ObjectProvider<ResourceConfigCustomizer> customizers) {
|
||||
this.jersey = jersey;
|
||||
this.config = config;
|
||||
customizers.orderedStream().forEach((customizer) -> customizer.customize(this.config));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingFilterBean
|
||||
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
|
||||
JerseyApplicationPath jerseyApplicationPath() {
|
||||
return new DefaultJerseyApplicationPath(this.jersey.getApplicationPath(), this.config);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "jerseyFilterRegistration")
|
||||
@ConditionalOnProperty(name = "spring.jersey.type", havingValue = "filter")
|
||||
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(name = "spring.jersey.type", havingValue = "servlet", matchIfMissing = true)
|
||||
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());
|
||||
registration.setIgnoreRegistrationFailure(true);
|
||||
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 {
|
||||
if (ClassUtils.isPresent("org.glassfish.jersey.server.spring.SpringWebApplicationInitializer",
|
||||
getClass().getClassLoader())) {
|
||||
// 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 jacksonResourceConfigCustomizer(ObjectMapper objectMapper) {
|
||||
return (ResourceConfig config) -> {
|
||||
config.register(JacksonFeature.class);
|
||||
config.register(new ObjectMapperContextResolver(objectMapper), ContextResolver.class);
|
||||
};
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ JakartaXmlBindAnnotationIntrospector.class, XmlElement.class })
|
||||
static class JaxbObjectMapperCustomizer {
|
||||
|
||||
@Autowired
|
||||
void addJaxbAnnotationIntrospector(ObjectMapper objectMapper) {
|
||||
JakartaXmlBindAnnotationIntrospector jaxbAnnotationIntrospector = new JakartaXmlBindAnnotationIntrospector(
|
||||
objectMapper.getTypeFactory());
|
||||
objectMapper.setAnnotationIntrospectors(
|
||||
createPair(objectMapper.getSerializationConfig(), jaxbAnnotationIntrospector),
|
||||
createPair(objectMapper.getDeserializationConfig(), jaxbAnnotationIntrospector));
|
||||
}
|
||||
|
||||
private AnnotationIntrospector createPair(MapperConfig<?> config,
|
||||
JakartaXmlBindAnnotationIntrospector 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,129 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* {@link ConfigurationProperties @ConfigurationProperties} for Jersey.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Eddú Meléndez
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@ConfigurationProperties("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 @Nullable 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 @Nullable String getApplicationPath() {
|
||||
return this.applicationPath;
|
||||
}
|
||||
|
||||
public void setApplicationPath(@Nullable 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-present 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.jersey.autoconfigure;
|
||||
|
||||
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 4.0.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ResourceConfigCustomizer {
|
||||
|
||||
/**
|
||||
* Customize the resource config.
|
||||
* @param config the {@link ResourceConfig} to customize
|
||||
*/
|
||||
void customize(ResourceConfig config);
|
||||
|
||||
}
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.actuate.endpoint.web;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.server.model.Resource;
|
||||
import org.glassfish.jersey.servlet.ServletContainer;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
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.autoconfigure.health.HealthEndpointAutoConfiguration;
|
||||
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.health.HealthEndpoint;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroups;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
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.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.jersey.actuate.endpoint.web.JerseyHealthEndpointAdditionalPathResourceFactory;
|
||||
import org.springframework.boot.jersey.autoconfigure.DefaultJerseyApplicationPath;
|
||||
import org.springframework.boot.jersey.autoconfigure.JerseyApplicationPath;
|
||||
import org.springframework.boot.jersey.autoconfigure.JerseyProperties;
|
||||
import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Auto-Configuration for {@link HealthEndpoint} Jersey extension.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Madhura Bhave
|
||||
* @since 4.0.0
|
||||
* @see HealthEndpointAutoConfiguration
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
@ConditionalOnBean(HealthEndpoint.class)
|
||||
@ConditionalOnAvailableEndpoint(endpoint = HealthEndpoint.class, exposure = EndpointExposure.WEB)
|
||||
@ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet")
|
||||
public final class HealthEndpointJerseyExtensionAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
JerseyAdditionalHealthEndpointPathsResourcesRegistrar jerseyAdditionalHealthEndpointPathsResourcesRegistrar(
|
||||
WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups healthEndpointGroups) {
|
||||
ExposableWebEndpoint health = getHealthEndpoint(webEndpointsSupplier);
|
||||
return new JerseyAdditionalHealthEndpointPathsResourcesRegistrar(health, healthEndpointGroups);
|
||||
}
|
||||
|
||||
private static @Nullable ExposableWebEndpoint getHealthEndpoint(WebEndpointsSupplier webEndpointsSupplier) {
|
||||
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
|
||||
return webEndpoints.stream()
|
||||
.filter((endpoint) -> endpoint.getEndpointId().equals(HealthEndpoint.ID))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnMissingBean(ResourceConfig.class)
|
||||
@EnableConfigurationProperties(JerseyProperties.class)
|
||||
static class JerseyInfrastructureConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
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 @Nullable ExposableWebEndpoint endpoint;
|
||||
|
||||
private final HealthEndpointGroups groups;
|
||||
|
||||
JerseyAdditionalHealthEndpointPathsResourcesRegistrar(@Nullable 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,
|
||||
(this.endpoint != null) ? Collections.singletonList(this.endpoint) : Collections.emptyList())
|
||||
.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
register(endpointResources, config);
|
||||
}
|
||||
|
||||
private void register(Collection<Resource> resources, ResourceConfig config) {
|
||||
config.registerResources(new HashSet<>(resources));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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 web endpoint support.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.boot.jersey.autoconfigure.actuate.endpoint.web;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.actuate.web;
|
||||
|
||||
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.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.jersey.autoconfigure.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 4.0.0
|
||||
*/
|
||||
@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false)
|
||||
@Import(JerseyManagementContextConfiguration.class)
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
@ConditionalOnClass({ JerseyApplicationPath.class, 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,53 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.actuate.web;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.EndpointAccessResolver;
|
||||
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.jersey.autoconfigure.JerseyApplicationPath;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
/**
|
||||
* {@link ManagementContextConfiguration @ManagementContextConfiguration} for Jetty
|
||||
* endpoints.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @author Madhura Bhave
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@ManagementContextConfiguration(proxyBeanMethods = false)
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
@ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet")
|
||||
public class JerseyEndpointManagementContextConfiguration {
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("removal")
|
||||
public org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar servletEndpointRegistrar(
|
||||
WebEndpointProperties properties,
|
||||
org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier servletEndpointsSupplier,
|
||||
JerseyApplicationPath jerseyApplicationPath, EndpointAccessResolver endpointAccessResolver) {
|
||||
return new org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar(
|
||||
jerseyApplicationPath.getRelativePath(properties.getBasePath()),
|
||||
servletEndpointsSupplier.getEndpoints(), endpointAccessResolver);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.actuate.web;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.servlet.ServletContainer;
|
||||
|
||||
import org.springframework.boot.jersey.autoconfigure.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,78 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.actuate.web;
|
||||
|
||||
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.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.jersey.autoconfigure.DefaultJerseyApplicationPath;
|
||||
import org.springframework.boot.jersey.autoconfigure.JerseyApplicationPath;
|
||||
import org.springframework.boot.jersey.autoconfigure.JerseyProperties;
|
||||
import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer;
|
||||
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 4.0.0
|
||||
*/
|
||||
@ManagementContextConfiguration(value = ManagementContextType.SAME, proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(JerseyProperties.class)
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
@ConditionalOnClass({ JerseyApplicationPath.class, 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 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,243 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.actuate.web;
|
||||
|
||||
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 com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.annotation.Priority;
|
||||
import jakarta.ws.rs.Priorities;
|
||||
import jakarta.ws.rs.ext.ContextResolver;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.server.model.Resource;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
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.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.OperationResponseBody;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.jackson.EndpointObjectMapper;
|
||||
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.WebEndpointsSupplier;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebServerNamespace;
|
||||
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.boot.jersey.actuate.endpoint.web.JerseyEndpointResourceFactory;
|
||||
import org.springframework.boot.jersey.actuate.endpoint.web.JerseyHealthEndpointAdditionalPathResourceFactory;
|
||||
import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer;
|
||||
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
|
||||
@SuppressWarnings("removal")
|
||||
JerseyWebEndpointsResourcesRegistrar jerseyWebEndpointsResourcesRegistrar(Environment environment,
|
||||
WebEndpointsSupplier webEndpointsSupplier,
|
||||
org.springframework.boot.actuate.endpoint.web.annotation.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 healthEndpoint = webEndpoints.stream()
|
||||
.filter((endpoint) -> endpoint.getEndpointId().equals(HEALTH_ENDPOINT_ID))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
return new JerseyAdditionalHealthEndpointPathsManagementResourcesRegistrar(healthEndpoint,
|
||||
healthEndpointGroups);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(EndpointObjectMapper.class)
|
||||
ResourceConfigCustomizer endpointObjectMapperResourceConfigCustomizer(EndpointObjectMapper endpointObjectMapper) {
|
||||
return (config) -> config.register(new EndpointObjectMapperContextResolver(endpointObjectMapper),
|
||||
ContextResolver.class);
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
static class JerseyWebEndpointsResourcesRegistrar implements ManagementContextResourceConfigCustomizer {
|
||||
|
||||
private final WebEndpointsSupplier webEndpointsSupplier;
|
||||
|
||||
private final org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier servletEndpointsSupplier;
|
||||
|
||||
private final EndpointMediaTypes mediaTypes;
|
||||
|
||||
private final String basePath;
|
||||
|
||||
private final boolean shouldRegisterLinks;
|
||||
|
||||
JerseyWebEndpointsResourcesRegistrar(WebEndpointsSupplier webEndpointsSupplier,
|
||||
org.springframework.boot.actuate.endpoint.web.annotation.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<org.springframework.boot.actuate.endpoint.web.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<org.springframework.boot.actuate.endpoint.web.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 @Nullable ExposableWebEndpoint healthEndpoint;
|
||||
|
||||
private final HealthEndpointGroups groups;
|
||||
|
||||
JerseyAdditionalHealthEndpointPathsManagementResourcesRegistrar(@Nullable ExposableWebEndpoint healthEndpoint,
|
||||
HealthEndpointGroups groups) {
|
||||
this.healthEndpoint = healthEndpoint;
|
||||
this.groups = groups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(ResourceConfig config) {
|
||||
if (this.healthEndpoint != null) {
|
||||
register(config, this.healthEndpoint);
|
||||
}
|
||||
}
|
||||
|
||||
private void register(ResourceConfig config, ExposableWebEndpoint healthEndpoint) {
|
||||
EndpointMapping mapping = new EndpointMapping("");
|
||||
JerseyHealthEndpointAdditionalPathResourceFactory resourceFactory = new JerseyHealthEndpointAdditionalPathResourceFactory(
|
||||
WebServerNamespace.MANAGEMENT, this.groups);
|
||||
Collection<Resource> endpointResources = resourceFactory
|
||||
.createEndpointResources(mapping, Collections.singletonList(healthEndpoint))
|
||||
.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
register(endpointResources, config);
|
||||
}
|
||||
|
||||
private void register(Collection<Resource> resources, ResourceConfig config) {
|
||||
config.registerResources(new HashSet<>(resources));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ContextResolver} used to obtain the {@link ObjectMapper} that should be used
|
||||
* for {@link OperationResponseBody} instances.
|
||||
*/
|
||||
@Priority(Priorities.USER - 100)
|
||||
private static final class EndpointObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
|
||||
|
||||
private final EndpointObjectMapper endpointObjectMapper;
|
||||
|
||||
private EndpointObjectMapperContextResolver(EndpointObjectMapper endpointObjectMapper) {
|
||||
this.endpointObjectMapper = endpointObjectMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ObjectMapper getContext(Class<?> type) {
|
||||
for (Class<?> supportedType : this.endpointObjectMapper.getSupportedTypes()) {
|
||||
if (supportedType.isAssignableFrom(type)) {
|
||||
return this.endpointObjectMapper.get();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.actuate.web;
|
||||
|
||||
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 4.0.0
|
||||
*/
|
||||
public interface ManagementContextResourceConfigCustomizer {
|
||||
|
||||
/**
|
||||
* Customize the resource config.
|
||||
* @param config the {@link ResourceConfig} to customize
|
||||
*/
|
||||
void customize(ResourceConfig config);
|
||||
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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 web concerns.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.boot.jersey.autoconfigure.actuate.web;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.metrics;
|
||||
|
||||
import io.micrometer.core.instrument.config.MeterFilter;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import org.glassfish.jersey.micrometer.server.JerseyObservationConvention;
|
||||
import org.glassfish.jersey.micrometer.server.ObservationApplicationEventListener;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
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.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer;
|
||||
import org.springframework.boot.micrometer.metrics.OnlyOnceLoggingDenyMeterFilter;
|
||||
import org.springframework.boot.micrometer.metrics.autoconfigure.MetricsProperties;
|
||||
import org.springframework.boot.micrometer.observation.autoconfigure.ObservationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Jersey server instrumentation.
|
||||
*
|
||||
* @author Michael Weirauch
|
||||
* @author Michael Simons
|
||||
* @author Andy Wilkinson
|
||||
* @author Moritz Halbritter
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@AutoConfiguration(
|
||||
afterName = "org.springframework.boot.micrometer.observation.autoconfigure.ObservationAutoConfiguration")
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
@ConditionalOnClass({ ResourceConfig.class, ObservationApplicationEventListener.class })
|
||||
@ConditionalOnBean({ ResourceConfig.class, ObservationRegistry.class })
|
||||
@EnableConfigurationProperties({ MetricsProperties.class, ObservationProperties.class })
|
||||
public final class JerseyServerMetricsAutoConfiguration {
|
||||
|
||||
private final ObservationProperties observationProperties;
|
||||
|
||||
JerseyServerMetricsAutoConfiguration(ObservationProperties observationProperties) {
|
||||
this.observationProperties = observationProperties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
ResourceConfigCustomizer jerseyServerObservationResourceConfigCustomizer(ObservationRegistry observationRegistry,
|
||||
ObjectProvider<JerseyObservationConvention> jerseyObservationConvention) {
|
||||
String metricName = this.observationProperties.getHttp().getServer().getRequests().getName();
|
||||
return (config) -> config.register(new ObservationApplicationEventListener(observationRegistry, metricName,
|
||||
jerseyObservationConvention.getIfAvailable()));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Order(0)
|
||||
MeterFilter jerseyMetricsUriTagFilter(MetricsProperties metricsProperties) {
|
||||
String metricName = this.observationProperties.getHttp().getServer().getRequests().getName();
|
||||
MeterFilter filter = new OnlyOnceLoggingDenyMeterFilter(
|
||||
() -> String.format("Reached the maximum number of URI tags for '%s'.", metricName));
|
||||
return MeterFilter.maximumAllowableTags(metricName, "uri",
|
||||
metricsProperties.getWeb().getServer().getMaxUriTags(), filter);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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 metrics.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.boot.jersey.autoconfigure.metrics;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.boot.jersey.autoconfigure;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
|
@ -1,4 +0,0 @@
|
|||
org.springframework.boot.jersey.autoconfigure.actuate.web.JerseyChildManagementContextConfiguration
|
||||
org.springframework.boot.jersey.autoconfigure.actuate.web.JerseyEndpointManagementContextConfiguration
|
||||
org.springframework.boot.jersey.autoconfigure.actuate.web.JerseySameManagementContextConfiguration
|
||||
org.springframework.boot.jersey.autoconfigure.actuate.web.JerseyWebEndpointManagementContextConfiguration
|
|
@ -1,3 +0,0 @@
|
|||
org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration
|
||||
org.springframework.boot.jersey.autoconfigure.actuate.endpoint.web.HealthEndpointJerseyExtensionAutoConfiguration
|
||||
org.springframework.boot.jersey.autoconfigure.metrics.JerseyServerMetricsAutoConfiguration
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure;
|
||||
|
||||
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/*");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.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.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.web.server.test.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({ TomcatServletWebServerAutoConfiguration.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,100 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.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.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.web.server.test.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({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.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.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.web.server.test.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({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.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.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
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({ JerseyAutoConfiguration.class, TomcatServletWebServerAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.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.jackson.autoconfigure.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.web.server.test.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(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
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({ TomcatServletWebServerAutoConfiguration.class, JacksonAutoConfiguration.class,
|
||||
JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.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.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.web.server.test.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({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.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.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.web.server.test.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({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.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.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.web.server.test.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({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.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.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.web.server.test.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({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.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.jackson.autoconfigure.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.web.server.test.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(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
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({ TomcatServletWebServerAutoConfiguration.class, JacksonAutoConfiguration.class,
|
||||
JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.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.jersey.autoconfigure.JerseyAutoConfigurationServletContainerTests.Application;
|
||||
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.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.tomcat.servlet.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({ TomcatServletWebServerAutoConfiguration.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,163 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationIntrospector;
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.ServletException;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration.JerseyWebApplicationInitializer;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
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(JakartaXmlBindAnnotationIntrospector.class::isInstance)).hasSize(1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenJaxbIsNotAvailableTheObjectMapperCustomizationBacksOff() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class))
|
||||
.withClassLoader(new FilteredClassLoader("jakarta.xml.bind.annotation"))
|
||||
.run((context) -> {
|
||||
ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
|
||||
assertThat(objectMapper.getSerializationConfig()
|
||||
.getAnnotationIntrospector()
|
||||
.allIntrospectors()
|
||||
.stream()
|
||||
.filter(JakartaXmlBindAnnotationIntrospector.class::isInstance)).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenJacksonJaxbModuleIsNotAvailableTheObjectMapperCustomizationBacksOff() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class))
|
||||
.withClassLoader(new FilteredClassLoader(JakartaXmlBindAnnotationIntrospector.class))
|
||||
.run((context) -> {
|
||||
ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
|
||||
assertThat(objectMapper.getSerializationConfig()
|
||||
.getAnnotationIntrospector()
|
||||
.allIntrospectors()
|
||||
.stream()
|
||||
.filter(JakartaXmlBindAnnotationIntrospector.class::isInstance)).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void webApplicationInitializerDisablesJerseyWebApplicationInitializer() throws ServletException {
|
||||
ServletContext context = new MockServletContext();
|
||||
new JerseyWebApplicationInitializer().onStartup(context);
|
||||
assertThat(context.getInitParameter("contextConfigLocation")).isEqualTo("<NONE>");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ClassPathExclusions("jersey-spring6-*.jar")
|
||||
void webApplicationInitializerHasNoEffectWhenJerseyIsAbsent() throws ServletException {
|
||||
ServletContext context = new MockServletContext();
|
||||
new JerseyWebApplicationInitializer().onStartup(context);
|
||||
assertThat(Collections.list(context.getInitParameterNames())).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,96 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.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.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.web.server.test.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({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.actuate.endpoint.web;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.WithTestEndpointOutcomeExposureContributor;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier;
|
||||
import org.springframework.boot.actuate.health.HealthEndpoint;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointWebExtension;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.health.autoconfigure.contributor.HealthContributorAutoConfiguration;
|
||||
import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration;
|
||||
import org.springframework.boot.health.contributor.Health;
|
||||
import org.springframework.boot.health.contributor.HealthIndicator;
|
||||
import org.springframework.boot.health.contributor.ReactiveHealthIndicator;
|
||||
import org.springframework.boot.jersey.autoconfigure.actuate.endpoint.web.HealthEndpointJerseyExtensionAutoConfiguration.JerseyAdditionalHealthEndpointPathsResourcesRegistrar;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link HealthEndpointJerseyExtensionAutoConfiguration}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class HealthEndpointJerseyExtensionAutoConfigurationTests {
|
||||
|
||||
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
|
||||
.withUserConfiguration(HealthIndicatorsConfiguration.class)
|
||||
.withConfiguration(AutoConfigurations.of(HealthContributorAutoConfiguration.class,
|
||||
HealthContributorRegistryAutoConfiguration.class, HealthEndpointAutoConfiguration.class,
|
||||
HealthEndpointJerseyExtensionAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
@WithTestEndpointOutcomeExposureContributor
|
||||
void additionalJerseyHealthEndpointsPathsTolerateHealthEndpointThatIsNotWebExposed() {
|
||||
this.contextRunner
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class))
|
||||
.withPropertyValues("management.endpoints.web.exposure.exclude=*",
|
||||
"management.endpoints.test.exposure.include=*")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasNotFailed();
|
||||
assertThat(context).hasSingleBean(HealthEndpoint.class);
|
||||
assertThat(context).hasSingleBean(HealthEndpointWebExtension.class);
|
||||
assertThat(context.getBean(WebEndpointsSupplier.class).getEndpoints()).isEmpty();
|
||||
assertThat(context).hasSingleBean(JerseyAdditionalHealthEndpointPathsResourcesRegistrar.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class HealthIndicatorsConfiguration {
|
||||
|
||||
@Bean
|
||||
HealthIndicator simpleHealthIndicator() {
|
||||
return () -> Health.up().withDetail("counter", 42).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
HealthIndicator additionalHealthIndicator() {
|
||||
return () -> Health.up().build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
ReactiveHealthIndicator reactiveHealthIndicator() {
|
||||
return () -> Mono.just(Health.up().build());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,191 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.actuate.endpoint.web;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
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.web.server.ManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration;
|
||||
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.test.web.reactive.server.EntityExchangeResult;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.web.reactive.function.client.ExchangeStrategies;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for controlling access to endpoints exposed by Jersey.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class JerseyEndpointAccessIntegrationTests {
|
||||
|
||||
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner(
|
||||
AnnotationConfigServletWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
EndpointAutoConfiguration.class, TomcatServletWebServerAutoConfiguration.class,
|
||||
WebEndpointAutoConfiguration.class, ManagementContextAutoConfiguration.class,
|
||||
BeansEndpointAutoConfiguration.class))
|
||||
.withUserConfiguration(CustomServletEndpoint.class)
|
||||
.withPropertyValues("server.port:0");
|
||||
|
||||
@Test
|
||||
void accessIsUnrestrictedByDefault() {
|
||||
this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=*").run((context) -> {
|
||||
WebTestClient client = createClient(context);
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "beans")).isTrue();
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isTrue();
|
||||
assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void accessCanBeReadOnlyByDefault() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("management.endpoints.web.exposure.include=*",
|
||||
"management.endpoints.access.default=READ_ONLY")
|
||||
.run((context) -> {
|
||||
WebTestClient client = createClient(context);
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "beans")).isTrue();
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isTrue();
|
||||
assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void accessCanBeNoneByDefault() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("management.endpoints.web.exposure.include=*",
|
||||
"management.endpoints.access.default=NONE")
|
||||
.run((context) -> {
|
||||
WebTestClient client = createClient(context);
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "beans")).isFalse();
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isFalse();
|
||||
assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void accessForOneEndpointCanOverrideTheDefaultAccess() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("management.endpoints.web.exposure.include=*",
|
||||
"management.endpoints.access.default=NONE", "management.endpoint.customservlet.access=READ_ONLY")
|
||||
.run((context) -> {
|
||||
WebTestClient client = createClient(context);
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "beans")).isFalse();
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isTrue();
|
||||
assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void accessCanBeCappedAtReadOnly() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("management.endpoints.web.exposure.include=*",
|
||||
"management.endpoints.access.default=UNRESTRICTED",
|
||||
"management.endpoints.access.max-permitted=READ_ONLY")
|
||||
.run((context) -> {
|
||||
WebTestClient client = createClient(context);
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "beans")).isTrue();
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isTrue();
|
||||
assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void accessCanBeCappedAtNone() {
|
||||
this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=*",
|
||||
"management.endpoints.access.default=UNRESTRICTED", "management.endpoints.access.max-permitted=NONE")
|
||||
.run((context) -> {
|
||||
WebTestClient client = createClient(context);
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "beans")).isFalse();
|
||||
assertThat(isAccessible(client, HttpMethod.GET, "customservlet")).isFalse();
|
||||
assertThat(isAccessible(client, HttpMethod.POST, "customservlet")).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
private WebTestClient createClient(AssertableWebApplicationContext context) {
|
||||
int port = context.getSourceApplicationContext(ServletWebServerApplicationContext.class)
|
||||
.getWebServer()
|
||||
.getPort();
|
||||
ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder()
|
||||
.codecs((configurer) -> configurer.defaultCodecs().maxInMemorySize(-1))
|
||||
.build();
|
||||
return WebTestClient.bindToServer()
|
||||
.baseUrl("http://localhost:" + port)
|
||||
.exchangeStrategies(exchangeStrategies)
|
||||
.responseTimeout(Duration.ofMinutes(5))
|
||||
.build();
|
||||
}
|
||||
|
||||
private boolean isAccessible(WebTestClient client, HttpMethod method, String path) {
|
||||
path = "/actuator/" + path;
|
||||
EntityExchangeResult<byte[]> result = client.method(method).uri(path).exchange().expectBody().returnResult();
|
||||
if (result.getStatus() == HttpStatus.OK) {
|
||||
return true;
|
||||
}
|
||||
if (result.getStatus() == HttpStatus.NOT_FOUND || result.getStatus() == HttpStatus.METHOD_NOT_ALLOWED) {
|
||||
return false;
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
String.format("Unexpected %s HTTP status for endpoint %s", result.getStatus(), path));
|
||||
}
|
||||
|
||||
@org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpoint(id = "customservlet")
|
||||
@SuppressWarnings({ "deprecation", "removal" })
|
||||
static class CustomServletEndpoint
|
||||
implements Supplier<org.springframework.boot.actuate.endpoint.web.EndpointServlet> {
|
||||
|
||||
@Override
|
||||
public org.springframework.boot.actuate.endpoint.web.EndpointServlet get() {
|
||||
return new org.springframework.boot.actuate.endpoint.web.EndpointServlet(new HttpServlet() {
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,228 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.actuate.endpoint.web;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
|
||||
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.web.server.ManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.jackson.EndpointObjectMapper;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* 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 endpointObjectMapperCanBeApplied() {
|
||||
WebApplicationContextRunner contextRunner = getContextRunner(new Class<?>[] { EndpointsConfiguration.class,
|
||||
ResourceConfigConfiguration.class, EndpointObjectMapperConfiguration.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/beans").exchange().expectStatus().isOk().expectBody().consumeWith((result) -> {
|
||||
String json = new String(result.getResponseBody(), StandardCharsets.UTF_8);
|
||||
assertThat(json).contains("\"scope\":\"notelgnis\"");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
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) {
|
||||
return new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new)
|
||||
.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,
|
||||
TomcatServletWebServerAutoConfiguration.class, WebEndpointAutoConfiguration.class,
|
||||
ManagementContextAutoConfiguration.class, BeansEndpointAutoConfiguration.class));
|
||||
autoconfigurations.addAll(Arrays.asList(additional));
|
||||
return autoconfigurations.toArray(new Class<?>[0]);
|
||||
}
|
||||
|
||||
@org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint(id = "controller")
|
||||
@SuppressWarnings("removal")
|
||||
static class TestControllerEndpoint {
|
||||
|
||||
}
|
||||
|
||||
@org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint(id = "restcontroller")
|
||||
@SuppressWarnings("removal")
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@SuppressWarnings({ "deprecation", "removal" })
|
||||
static class EndpointObjectMapperConfiguration {
|
||||
|
||||
@Bean
|
||||
EndpointObjectMapper endpointObjectMapper() {
|
||||
SimpleModule module = new SimpleModule();
|
||||
module.addSerializer(String.class, new ReverseStringSerializer());
|
||||
ObjectMapper objectMapper = org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.json()
|
||||
.modules(module)
|
||||
.build();
|
||||
return () -> objectMapper;
|
||||
}
|
||||
|
||||
static class ReverseStringSerializer extends StdScalarSerializer<Object> {
|
||||
|
||||
ReverseStringSerializer() {
|
||||
super(String.class, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty(SerializerProvider prov, Object value) {
|
||||
return ((String) value).isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||
serialize(value, gen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void serializeWithType(Object value, JsonGenerator gen, SerializerProvider provider,
|
||||
TypeSerializer typeSer) throws IOException {
|
||||
serialize(value, gen);
|
||||
}
|
||||
|
||||
private void serialize(Object value, JsonGenerator gen) throws IOException {
|
||||
StringBuilder builder = new StringBuilder((String) value);
|
||||
gen.writeString(builder.reverse().toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.actuate.web;
|
||||
|
||||
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.jersey.autoconfigure.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.BDDMockito.then;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
then(customizer).should().customize(config);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
ManagementContextResourceConfigCustomizer resourceConfigCustomizer() {
|
||||
return mock(ManagementContextResourceConfigCustomizer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.actuate.web;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
|
||||
import org.springframework.boot.actuate.endpoint.Access;
|
||||
import org.springframework.boot.actuate.endpoint.EndpointAccessResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.jersey.autoconfigure.JerseyApplicationPath;
|
||||
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 static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyEndpointManagementContextConfiguration}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
class JerseyEndpointManagementContextConfigurationTests {
|
||||
|
||||
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
|
||||
.withUserConfiguration(TestConfig.class);
|
||||
|
||||
@Test
|
||||
void contextShouldContainServletEndpointRegistrar() {
|
||||
this.contextRunner.run((context) -> {
|
||||
assertThat(context).hasSingleBean(ServletEndpointRegistrar.class);
|
||||
ServletEndpointRegistrar bean = context.getBean(ServletEndpointRegistrar.class);
|
||||
assertThat(bean).hasFieldOrPropertyWithValue("basePath", "/test/actuator");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void contextWhenNotServletBasedShouldNotContainServletEndpointRegistrar() {
|
||||
new ApplicationContextRunner().withUserConfiguration(TestConfig.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(ServletEndpointRegistrar.class));
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import(JerseyEndpointManagementContextConfiguration.class)
|
||||
@EnableConfigurationProperties(WebEndpointProperties.class)
|
||||
static class TestConfig {
|
||||
|
||||
@Bean
|
||||
ServletEndpointsSupplier servletEndpointsSupplier() {
|
||||
return Collections::emptyList;
|
||||
}
|
||||
|
||||
@Bean
|
||||
JerseyApplicationPath jerseyApplicationPath() {
|
||||
return () -> "/test";
|
||||
}
|
||||
|
||||
@Bean
|
||||
EndpointAccessResolver endpointAccessResolver() {
|
||||
return (endpointId, defaultAccess) -> Access.UNRESTRICTED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.actuate.web;
|
||||
|
||||
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.integrationtest.AbstractHealthEndpointAdditionalPathIntegrationTests;
|
||||
import org.springframework.boot.actuate.autoconfigure.system.DiskSpaceHealthContributorAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration;
|
||||
import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration;
|
||||
import org.springframework.boot.jersey.autoconfigure.actuate.endpoint.web.HealthEndpointJerseyExtensionAutoConfiguration;
|
||||
import org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.tomcat.autoconfigure.actuate.web.server.TomcatServletManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.web.server.context.ServerPortInfoApplicationContextInitializer;
|
||||
import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.web.context.ConfigurableWebApplicationContext;
|
||||
|
||||
/**
|
||||
* 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, TomcatServletWebServerAutoConfiguration.class,
|
||||
TomcatServletManagementContextAutoConfiguration.class, WebEndpointAutoConfiguration.class,
|
||||
JerseyAutoConfiguration.class, ManagementContextAutoConfiguration.class,
|
||||
ServletManagementContextAutoConfiguration.class, HealthEndpointAutoConfiguration.class,
|
||||
HealthContributorRegistryAutoConfiguration.class,
|
||||
HealthEndpointJerseyExtensionAutoConfiguration.class,
|
||||
DiskSpaceHealthContributorAutoConfiguration.class))
|
||||
.withInitializer(new ServerPortInfoApplicationContextInitializer())
|
||||
.withPropertyValues("server.port=0"));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.actuate.web;
|
||||
|
||||
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.jersey.autoconfigure.DefaultJerseyApplicationPath;
|
||||
import org.springframework.boot.jersey.autoconfigure.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.BDDMockito.then;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
then(customizer).should().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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.actuate.web;
|
||||
|
||||
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.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
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,
|
||||
TomcatServletWebServerAutoConfiguration.class, EndpointAutoConfiguration.class,
|
||||
WebEndpointAutoConfiguration.class, JerseyWebEndpointManagementContextConfiguration.class))
|
||||
.withUserConfiguration(ResourceConfigConfiguration.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,69 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.actuate.web;
|
||||
|
||||
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.endpoint.Access;
|
||||
import org.springframework.boot.actuate.endpoint.EndpointAccessResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.jersey.autoconfigure.actuate.web.JerseyWebEndpointManagementContextConfiguration.JerseyWebEndpointsResourcesRegistrar;
|
||||
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)
|
||||
.withBean(EndpointAccessResolver.class, () -> (endpointId, defaultAccess) -> Access.UNRESTRICTED);
|
||||
|
||||
@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,143 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.autoconfigure.metrics;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.Timer;
|
||||
import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler;
|
||||
import io.micrometer.core.instrument.observation.MeterObservationHandler;
|
||||
import io.micrometer.observation.Observation.Context;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import org.glassfish.jersey.micrometer.server.ObservationApplicationEventListener;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration;
|
||||
import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer;
|
||||
import org.springframework.boot.micrometer.metrics.autoconfigure.MetricsAutoConfiguration;
|
||||
import org.springframework.boot.micrometer.metrics.autoconfigure.export.simple.SimpleMetricsExportAutoConfiguration;
|
||||
import org.springframework.boot.micrometer.observation.autoconfigure.ObservationAutoConfiguration;
|
||||
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.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.web.server.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
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class JerseyServerMetricsAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(JerseyServerMetricsAutoConfiguration.class));
|
||||
|
||||
private final WebApplicationContextRunner webContextRunner = new WebApplicationContextRunner(
|
||||
AnnotationConfigServletWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(JerseyAutoConfiguration.class,
|
||||
JerseyServerMetricsAutoConfiguration.class, TomcatServletWebServerAutoConfiguration.class,
|
||||
TomcatServletWebServerAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class,
|
||||
ObservationAutoConfiguration.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).hasBean("jerseyMetricsUriTagFilter")
|
||||
.hasSingleBean(ResourceConfigCustomizer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void httpRequestsAreTimed() {
|
||||
this.webContextRunner.withUserConfiguration(MetricsConfiguration.class).run((context) -> {
|
||||
doRequest(context);
|
||||
Thread.sleep(500);
|
||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||
Timer timer = registry.get("http.server.requests").tag("uri", "/users/{id}").timer();
|
||||
assertThat(timer.count()).isOne();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void noHttpRequestsTimedWhenJerseyInstrumentationMissingFromClasspath() {
|
||||
this.webContextRunner.withClassLoader(new FilteredClassLoader(ObservationApplicationEventListener.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 static class TestResource {
|
||||
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
public String getUser(@PathParam("id") String id) {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class MetricsConfiguration {
|
||||
|
||||
@Bean
|
||||
MeterObservationHandler<Context> meterObservationHandler(MeterRegistry registry) {
|
||||
return new DefaultMeterObservationHandler(registry);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.actuate.endpoint.web.test;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.server.model.Resource;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper;
|
||||
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.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.jersey.actuate.endpoint.web.JerseyEndpointResourceFactory;
|
||||
import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration;
|
||||
import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer;
|
||||
import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Endpoint configuration for Jersey.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ImportAutoConfiguration({ JacksonAutoConfiguration.class, JerseyAutoConfiguration.class })
|
||||
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(), 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));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.jersey.actuate.endpoint.web.test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.web.test.WebEndpointInfrastructureProvider;
|
||||
import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest.Infrastructure;
|
||||
|
||||
/**
|
||||
* {@link WebEndpointInfrastructureProvider} for Jersey.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class JerseyWebEndpointInfrastructureProvider implements WebEndpointInfrastructureProvider {
|
||||
|
||||
@Override
|
||||
public boolean supports(Infrastructure infrastructure) {
|
||||
return infrastructure == Infrastructure.JERSEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Class<?>> getInfrastructureConfiguration(Infrastructure infrastructure) {
|
||||
return List.of(JerseyEndpointConfiguration.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
org.springframework.boot.actuate.endpoint.web.test.WebEndpointInfrastructureProvider=\
|
||||
org.springframework.boot.jersey.actuate.endpoint.web.test.JerseyWebEndpointInfrastructureProvider
|
|
@ -38,7 +38,6 @@ dependencies {
|
|||
testImplementation(project(":module:spring-boot-flyway"))
|
||||
testImplementation(project(":module:spring-boot-liquibase"))
|
||||
testImplementation(project(":test-support:spring-boot-test-support"))
|
||||
testImplementation(testFixtures(project(":module:spring-boot-jersey")))
|
||||
testImplementation(testFixtures(project(":module:spring-boot-webflux")))
|
||||
testImplementation(testFixtures(project(":module:spring-boot-webmvc")))
|
||||
testImplementation("net.minidev:json-smart")
|
||||
|
|
|
@ -32,7 +32,6 @@ dependencies {
|
|||
optional(project(":core:spring-boot-autoconfigure"))
|
||||
optional(project(":module:spring-boot-actuator-autoconfigure"))
|
||||
optional(project(":module:spring-boot-h2console"))
|
||||
optional(project(":module:spring-boot-jersey"))
|
||||
optional(project(":module:spring-boot-reactor"))
|
||||
optional(project(":module:spring-boot-rsocket"))
|
||||
optional(project(":module:spring-boot-webmvc"))
|
||||
|
|
|
@ -16,16 +16,12 @@
|
|||
|
||||
package org.springframework.boot.security.autoconfigure.actuate.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.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.jersey.autoconfigure.JerseyApplicationPath;
|
||||
import org.springframework.boot.webmvc.autoconfigure.DispatcherServletPath;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
@ -58,17 +54,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 PathPatternRequestMatcherProvider(applicationPath::getRelativePath);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,156 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.security.autoconfigure.actuate.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.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpStatus;
|
||||
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()
|
||||
.isEqualTo(expectedStatusWithTrailingSlash());
|
||||
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 HttpStatus expectedStatusWithTrailingSlash() {
|
||||
return HttpStatus.OK;
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -19,7 +19,6 @@ package org.springframework.boot.security.autoconfigure.actuate.servlet;
|
|||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.jersey.autoconfigure.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,19 +66,6 @@ class SecurityRequestMatchersManagementContextConfigurationTests {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void registersRequestMatcherForJerseyProviderIfJerseyPresentAndMvcAbsent() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("org.springframework.web.servlet.DispatcherServlet"))
|
||||
.withUserConfiguration(TestJerseyConfiguration.class)
|
||||
.run((context) -> {
|
||||
PathPatternRequestMatcherProvider matcherProvider = context
|
||||
.getBean(PathPatternRequestMatcherProvider.class);
|
||||
RequestMatcher requestMatcher = matcherProvider.getRequestMatcher("/example", null);
|
||||
assertThat(requestMatcher).extracting("pattern")
|
||||
.isEqualTo(PathPatternParser.defaultInstance.parse("/admin/example"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void mvcRequestMatcherProviderConditionalOnDispatcherServletClass() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("org.springframework.web.servlet.DispatcherServlet"))
|
||||
|
@ -117,14 +103,4 @@ class SecurityRequestMatchersManagementContextConfigurationTests {
|
|||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TestJerseyConfiguration {
|
||||
|
||||
@Bean
|
||||
JerseyApplicationPath jerseyApplicationPath() {
|
||||
return () -> "/admin";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -48,7 +48,6 @@ dependencies {
|
|||
testImplementation(project(":module:spring-boot-tomcat"))
|
||||
testImplementation(project(":test-support:spring-boot-test-support"))
|
||||
testImplementation(project(":module:spring-boot-webflux"))
|
||||
testImplementation(testFixtures(project(":module:spring-boot-jersey")))
|
||||
testImplementation(testFixtures(project(":module:spring-boot-webflux")))
|
||||
testImplementation(testFixtures(project(":module:spring-boot-webmvc")))
|
||||
testImplementation(testFixtures(project(":module:spring-boot-web-server")))
|
||||
|
|
|
@ -33,8 +33,7 @@ import static org.mockito.BDDMockito.given;
|
|||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link SessionsEndpoint} exposed by Jersey, Spring MVC, and
|
||||
* WebFlux.
|
||||
* Integration tests for {@link SessionsEndpoint} exposed by Spring MVC and WebFlux.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
|
@ -46,7 +45,7 @@ class SessionsEndpointWebIntegrationTests {
|
|||
private static final FindByIndexNameSessionRepository<Session> repository = mock(
|
||||
FindByIndexNameSessionRepository.class);
|
||||
|
||||
@WebEndpointTest(infrastructure = { Infrastructure.JERSEY, Infrastructure.MVC })
|
||||
@WebEndpointTest(infrastructure = Infrastructure.MVC)
|
||||
void sessionsForUsernameWithoutUsernameParam(WebTestClient client) {
|
||||
client.get()
|
||||
.uri((builder) -> builder.path("/actuator/sessions").build())
|
||||
|
@ -55,7 +54,7 @@ class SessionsEndpointWebIntegrationTests {
|
|||
.isBadRequest();
|
||||
}
|
||||
|
||||
@WebEndpointTest(infrastructure = { Infrastructure.JERSEY, Infrastructure.MVC })
|
||||
@WebEndpointTest(infrastructure = Infrastructure.MVC)
|
||||
void sessionsForUsernameNoResults(WebTestClient client) {
|
||||
given(repository.findByPrincipalName("user")).willReturn(Collections.emptyMap());
|
||||
client.get()
|
||||
|
@ -68,7 +67,7 @@ class SessionsEndpointWebIntegrationTests {
|
|||
.isEmpty();
|
||||
}
|
||||
|
||||
@WebEndpointTest(infrastructure = { Infrastructure.JERSEY, Infrastructure.MVC })
|
||||
@WebEndpointTest(infrastructure = Infrastructure.MVC)
|
||||
void sessionsForUsernameFound(WebTestClient client) {
|
||||
given(repository.findByPrincipalName("user")).willReturn(Collections.singletonMap(session.getId(), session));
|
||||
client.get()
|
||||
|
@ -81,7 +80,7 @@ class SessionsEndpointWebIntegrationTests {
|
|||
.isEqualTo(new JSONArray().appendElement(session.getId()));
|
||||
}
|
||||
|
||||
@WebEndpointTest(infrastructure = { Infrastructure.JERSEY, Infrastructure.MVC })
|
||||
@WebEndpointTest(infrastructure = Infrastructure.MVC)
|
||||
void sessionForIdNotFound(WebTestClient client) {
|
||||
client.get()
|
||||
.uri((builder) -> builder.path("/actuator/sessions/session-id-not-found").build())
|
||||
|
@ -90,7 +89,7 @@ class SessionsEndpointWebIntegrationTests {
|
|||
.isNotFound();
|
||||
}
|
||||
|
||||
@WebEndpointTest(infrastructure = { Infrastructure.JERSEY, Infrastructure.MVC })
|
||||
@WebEndpointTest(infrastructure = Infrastructure.MVC)
|
||||
void deleteSession(WebTestClient client) {
|
||||
client.delete()
|
||||
.uri((builder) -> builder.path("/actuator/sessions/{id}").build(session.getId()))
|
||||
|
|
|
@ -48,6 +48,7 @@ dependencies {
|
|||
testFixturesApi(testFixtures(project(":module:spring-boot-actuator")))
|
||||
testFixturesImplementation(project(":module:spring-boot-http-converter"))
|
||||
testFixturesImplementation(project(":module:spring-boot-jackson"))
|
||||
testFixturesImplementation(project(":module:spring-boot-tomcat"))
|
||||
|
||||
testImplementation(project(":core:spring-boot-test"))
|
||||
testImplementation(project(":module:spring-boot-freemarker"))
|
||||
|
|
|
@ -988,16 +988,6 @@ bom {
|
|||
releaseNotes("https://github.com/redis/jedis/releases/tag/v{version}")
|
||||
}
|
||||
}
|
||||
library("Jersey", "4.0.0-M2") {
|
||||
group("org.glassfish.jersey") {
|
||||
bom("jersey-bom")
|
||||
}
|
||||
links {
|
||||
site("https://github.com/eclipse-ee4j/jersey")
|
||||
javadoc("https://javadoc.io/doc/org.glassfish.jersey.core/jersey-server/{version}", "org.glassfish.jersey.server")
|
||||
releaseNotes("https://github.com/eclipse-ee4j/jersey/releases/tag/{version}")
|
||||
}
|
||||
}
|
||||
library("Jetty Reactive HTTPClient", "4.0.11") {
|
||||
group("org.eclipse.jetty") {
|
||||
modules = [
|
||||
|
@ -2031,7 +2021,6 @@ bom {
|
|||
"spring-boot-jackson",
|
||||
"spring-boot-jarmode-tools",
|
||||
"spring-boot-jdbc",
|
||||
"spring-boot-jersey",
|
||||
"spring-boot-jetty",
|
||||
"spring-boot-jms",
|
||||
"spring-boot-jooq",
|
||||
|
@ -2112,7 +2101,6 @@ bom {
|
|||
"spring-boot-starter-integration",
|
||||
"spring-boot-starter-jackson",
|
||||
"spring-boot-starter-jdbc",
|
||||
"spring-boot-starter-jersey",
|
||||
"spring-boot-starter-jetty",
|
||||
"spring-boot-starter-jms",
|
||||
"spring-boot-starter-jooq",
|
||||
|
|
|
@ -117,7 +117,6 @@ include "module:spring-boot-http-converter"
|
|||
include "module:spring-boot-integration"
|
||||
include "module:spring-boot-jackson"
|
||||
include "module:spring-boot-jdbc"
|
||||
include "module:spring-boot-jersey"
|
||||
include "module:spring-boot-jetty"
|
||||
include "module:spring-boot-jms"
|
||||
include "module:spring-boot-jooq"
|
||||
|
@ -208,7 +207,6 @@ include "starter:spring-boot-starter-hazelcast"
|
|||
include "starter:spring-boot-starter-integration"
|
||||
include "starter:spring-boot-starter-jackson"
|
||||
include "starter:spring-boot-starter-jdbc"
|
||||
include "starter:spring-boot-starter-jersey"
|
||||
include "starter:spring-boot-starter-jetty"
|
||||
include "starter:spring-boot-starter-jms"
|
||||
include "starter:spring-boot-starter-jooq"
|
||||
|
@ -312,7 +310,6 @@ include ":smoke-test:spring-boot-smoke-test-graphql"
|
|||
include ":smoke-test:spring-boot-smoke-test-hateoas"
|
||||
include ":smoke-test:spring-boot-smoke-test-hibernate"
|
||||
include ":smoke-test:spring-boot-smoke-test-integration"
|
||||
include ":smoke-test:spring-boot-smoke-test-jersey"
|
||||
include ":smoke-test:spring-boot-smoke-test-jetty"
|
||||
include ":smoke-test:spring-boot-smoke-test-jetty-jsp"
|
||||
include ":smoke-test:spring-boot-smoke-test-jetty-ssl"
|
||||
|
@ -333,7 +330,6 @@ include ":smoke-test:spring-boot-smoke-test-reactive-oauth2-resource-server"
|
|||
include ":smoke-test:spring-boot-smoke-test-rsocket"
|
||||
include ":smoke-test:spring-boot-smoke-test-saml2-service-provider"
|
||||
include ":smoke-test:spring-boot-smoke-test-secure"
|
||||
include ":smoke-test:spring-boot-smoke-test-secure-jersey"
|
||||
include ":smoke-test:spring-boot-smoke-test-secure-webflux"
|
||||
include ":smoke-test:spring-boot-smoke-test-servlet"
|
||||
include ":smoke-test:spring-boot-smoke-test-session-hazelcast"
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id "java"
|
||||
}
|
||||
|
||||
description = "Spring Boot Jersey smoke test"
|
||||
|
||||
dependencies {
|
||||
implementation(project(":starter:spring-boot-starter-actuator"))
|
||||
implementation(project(":starter:spring-boot-starter-jersey"))
|
||||
implementation(project(":starter:spring-boot-starter-tomcat"))
|
||||
|
||||
runtimeOnly("jakarta.xml.bind:jakarta.xml.bind-api")
|
||||
|
||||
testImplementation(project(":starter:spring-boot-starter-restclient"))
|
||||
testImplementation(project(":starter:spring-boot-starter-test"))
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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 jakarta.ws.rs.GET;
|
||||
import jakarta.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-present 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-present 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 jakarta.validation.constraints.NotNull;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.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,34 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.context.metrics.buffering.BufferingApplicationStartup;
|
||||
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)
|
||||
.applicationStartup(new BufferingApplicationStartup(2048)))
|
||||
.run(args);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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}")
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private String msg;
|
||||
|
||||
public String message() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.
|
||||
*/
|
||||
|
||||
@NullMarked
|
||||
package smoketest.jersey;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
|
@ -1,3 +0,0 @@
|
|||
management.endpoints.web.exposure.include=*
|
||||
management.endpoints.jackson.isolated-object-mapper=true
|
||||
spring.jackson.visibility.field=any
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.web.server.test.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,106 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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 jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import smoketest.jersey.AbstractJerseyManagementPortTests.ResourceConfigConfiguration;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.boot.web.server.test.LocalManagementPort;
|
||||
import org.springframework.boot.web.server.test.LocalServerPort;
|
||||
import org.springframework.boot.web.server.test.client.TestRestTemplate;
|
||||
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 (config) -> config.register(TestEndpoint.class);
|
||||
}
|
||||
|
||||
@Path("/test")
|
||||
public static class TestEndpoint {
|
||||
|
||||
@GET
|
||||
public String test() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.SpringApplication;
|
||||
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader;
|
||||
|
||||
class ApplicationStartupSpringBootContextLoader extends SpringBootContextLoader {
|
||||
|
||||
@Override
|
||||
protected SpringApplication getSpringApplication() {
|
||||
SpringApplication application = new SpringApplication();
|
||||
application.setApplicationStartup(new BufferingApplicationStartup(1024));
|
||||
return application;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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 com.fasterxml.jackson.databind.ObjectMapper;
|
||||
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.web.server.test.LocalManagementPort;
|
||||
import org.springframework.boot.web.server.test.LocalServerPort;
|
||||
import org.springframework.boot.web.server.test.client.TestRestTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration test for Jersey actuator when not using an isolated {@link ObjectMapper}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
properties = "management.endpoints.jackson.isolated-object-mapper=false")
|
||||
@ContextConfiguration(loader = ApplicationStartupSpringBootContextLoader.class)
|
||||
class JerseyActuatorIsolatedObjectMapperFalseTests {
|
||||
|
||||
@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 + "/actuator/startup", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
assertThat(entity.getBody())
|
||||
.contains("Java 8 date/time type `java.time.Clock$SystemClock` not supported by default");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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 com.fasterxml.jackson.databind.ObjectMapper;
|
||||
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.web.server.test.LocalManagementPort;
|
||||
import org.springframework.boot.web.server.test.LocalServerPort;
|
||||
import org.springframework.boot.web.server.test.client.TestRestTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration test for Jersey actuator when using an isolated {@link ObjectMapper}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
properties = "management.endpoints.jackson.isolated-object-mapper=true")
|
||||
@ContextConfiguration(loader = ApplicationStartupSpringBootContextLoader.class)
|
||||
class JerseyActuatorIsolatedObjectMapperTrueTests {
|
||||
|
||||
@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 + "/actuator/startup", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("\"timeline\":");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.web.server.test.LocalManagementPort;
|
||||
import org.springframework.boot.web.server.test.LocalServerPort;
|
||||
import org.springframework.boot.web.server.test.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 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-present 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.test.context.SpringBootTest;
|
||||
import org.springframework.boot.web.server.test.LocalManagementPort;
|
||||
import org.springframework.boot.web.server.test.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-present 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 {
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue