Drop support for self-hosted Actuator docs
Closes gh-9899
This commit is contained in:
parent
e64090838c
commit
fb3d79c750
1
pom.xml
1
pom.xml
|
|
@ -86,7 +86,6 @@
|
|||
<module>spring-boot-devtools</module>
|
||||
<module>spring-boot-docs</module>
|
||||
<module>spring-boot-starters</module>
|
||||
<module>spring-boot-actuator-docs</module>
|
||||
<module>spring-boot-cli</module>
|
||||
</modules>
|
||||
</profile>
|
||||
|
|
|
|||
|
|
@ -1,252 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-parent</artifactId>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../spring-boot-parent</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-boot-actuator-docs</artifactId>
|
||||
<name>Spring Boot Actuator Docs</name>
|
||||
<description>Spring Boot Actuator Docs</description>
|
||||
<organization>
|
||||
<name>Pivotal Software, Inc.</name>
|
||||
<url>http://www.spring.io</url>
|
||||
</organization>
|
||||
<properties>
|
||||
<main.basedir>${basedir}/..</main.basedir>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<!-- Compile -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.hateoas</groupId>
|
||||
<artifactId>spring-hateoas</artifactId>
|
||||
</dependency>
|
||||
<!-- Provided -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-actuator</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-test</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-test-autoconfigure</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jayway.jsonpath</groupId>
|
||||
<artifactId>json-path</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-templates</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.liquibase</groupId>
|
||||
<artifactId>liquibase-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.plugin</groupId>
|
||||
<artifactId>spring-plugin-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.restdocs</groupId>
|
||||
<artifactId>spring-restdocs-mockmvc</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add-restdoc-source</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>${basedir}/src/restdoc/java</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>add-restdoc-resource</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>add-resource</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${basedir}/src/restdoc/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<testClassesDirectory>${project.build.outputDirectory}</testClassesDirectory>
|
||||
<includes>
|
||||
<include>**/*Documentation.java</include>
|
||||
</includes>
|
||||
<skipTests>false</skipTests>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-rest-documentation</id>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.asciidoctor</groupId>
|
||||
<artifactId>asciidoctor-maven-plugin</artifactId>
|
||||
<version>1.5.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-docs</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>process-asciidoc</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<backend>html</backend>
|
||||
<doctype>book</doctype>
|
||||
<sourceDocumentName>index.adoc</sourceDocumentName>
|
||||
<attributes>
|
||||
<generated>${project.build.directory}/generated-snippets</generated>
|
||||
<docs>${project.build.directory}/../src/main/asciidoc</docs>
|
||||
</attributes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-resources</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.outputDirectory}/META-INF/resources/spring-boot-actuator/docs</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${project.build.directory}/generated-docs</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*.html</include>
|
||||
<include>**/*.png</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<!--This plugin's configuration is used to store Eclipse m2e settings
|
||||
only. It has no influence on the Maven build itself. -->
|
||||
<plugin>
|
||||
<groupId>org.eclipse.m2e</groupId>
|
||||
<artifactId>lifecycle-mapping</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<configuration>
|
||||
<lifecycleMappingMetadata>
|
||||
<pluginExecutions>
|
||||
<pluginExecution>
|
||||
<pluginExecutionFilter>
|
||||
<groupId>
|
||||
org.apache.maven.plugins
|
||||
</groupId>
|
||||
<artifactId>
|
||||
maven-surefire-plugin
|
||||
</artifactId>
|
||||
<versionRange>
|
||||
[2.18.1,)
|
||||
</versionRange>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
</pluginExecutionFilter>
|
||||
<action>
|
||||
<ignore />
|
||||
</action>
|
||||
</pluginExecution>
|
||||
</pluginExecutions>
|
||||
</lifecycleMappingMetadata>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
=== /autoconfig
|
||||
This endpoint is a report on the Spring Boot auto-configuration process that happened when
|
||||
your application started up. It lists all the `@Conditional` annotations that were
|
||||
evaluated as the context started and in each case it gives an indication of if (and why)
|
||||
the condition matched. A positive match results in a bean being included in the context,
|
||||
and a negative result means the opposite (the bean's class may not even be loaded).
|
||||
|
||||
The report is split into 2 parts, positive matches first, and then negative. If the
|
||||
context is a hierarchy, there is also a separate report on the parent context with the
|
||||
same format (and recursively up to the top of the hierarchy).
|
||||
|
||||
NOTE: The report is actually about `@Conditional` evaluation not auto-configuration
|
||||
per se, but most auto-configuration features use `@Conditional` heavily, so there is a lot
|
||||
of overlap.
|
||||
|
||||
Example curl request:
|
||||
include::{generated}/autoconfig/curl-request.adoc[]
|
||||
|
||||
Example HTTP request: [small]##link:../autoconfig[icon:external-link[role="silver"]]##
|
||||
include::{generated}/autoconfig/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/autoconfig/http-response.adoc[]
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
=== /beans
|
||||
This endpoint is a report on the Spring Boot `ApplicationContext`. It lists the beans in
|
||||
the context and their dependencies, detailing the names and concrete classes of each bean.
|
||||
|
||||
NOTE: Some beans are pure configuration (any class that is annotated `@Configuration`).
|
||||
|
||||
Example curl request:
|
||||
include::{generated}/beans/curl-request.adoc[]
|
||||
|
||||
Example HTTP request: [small]##link:../beans[icon:external-link[role="silver"]]##
|
||||
include::{generated}/beans/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/beans/http-response.adoc[]
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
=== /configprops
|
||||
This endpoint is a report on the Spring Boot `@ConfigurationProperties` beans. Beans with
|
||||
this annotation are bound to the `Environment` on startup, so they reflect the
|
||||
externalised configuration of the application. Beans are listed by name. A bean that is
|
||||
added using `@EnableConfigurationProperties` will have a conventional name:
|
||||
`<prefix>-<fqn>`, where `<prefix>` is the environment key prefix specified in the
|
||||
`@ConfigurationProperties` annotation and <fqn> the fully qualified name of the bean.
|
||||
|
||||
Example curl request:
|
||||
include::{generated}/configprops/curl-request.adoc[]
|
||||
|
||||
Example HTTP request: [small]##link:../configprops[icon:external-link[role="silver"]]##
|
||||
include::{generated}/configprops/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/configprops/http-response.adoc[]
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
=== /dump
|
||||
This endpoint is a thread dump: the result is a list of threads each with their name,
|
||||
monitor state and stack. It is the same information as you would get from `kill -3` of a
|
||||
running Java process. It can be very useful for detecting issues at runtime, especially
|
||||
sluggish behaviour caused by threads blocked by slow or unavailable I/O (e.g. if a
|
||||
connection pool is exhausted).
|
||||
|
||||
NOTE: Some `SecurityManager` implementations might prevent this endpoint from working.
|
||||
|
||||
Example curl request:
|
||||
include::{generated}/dump/curl-request.adoc[]
|
||||
|
||||
Example HTTP request: [small]##link:../dump[icon:external-link[role="silver"]]##
|
||||
include::{generated}/dump/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/dump/http-response.adoc[]
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
=== /env
|
||||
This endpoint is a dump of the Spring `Environment`. It lists the active profiles and all
|
||||
the `PropertySources` in the `Environment` (the ones that are listed first take precedence
|
||||
when binding to `@ConfigurationProperties` or `@Value`). Normally you will see the Java
|
||||
`System` properties and the OS environment variables in their own `PropertySources` plus
|
||||
any `.properties` or `.yml` files used to configure the application on start up.
|
||||
|
||||
Example curl request:
|
||||
include::{generated}/env/curl-request.adoc[]
|
||||
|
||||
Example HTTP request: [small]##link:../env[icon:external-link[role="silver"]]##
|
||||
include::{generated}/env/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/env/http-response.adoc[]
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
=== /flyway
|
||||
This endpoint provides information about database migrations that have been performed
|
||||
by Flyway.
|
||||
|
||||
Example curl request:
|
||||
include::{generated}/flyway/curl-request.adoc[]
|
||||
|
||||
Example HTTP request:
|
||||
include::{generated}/flyway/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/flyway/http-response.adoc[]
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
=== /health
|
||||
This endpoint is an indication of the health of the application. It has an overall status
|
||||
("UP", "DOWN" etc.), which is the only thing you see unless either you are authenticated
|
||||
or the endpoint is marked as `sensitive=false` (`endpoints.health.sensitive=false`).
|
||||
|
||||
The HTTP code in the response reflects the status (e.g. "`UP`"=200,
|
||||
"`OUT_OF_SERVICE`"=503, "`DOWN`"=503). The mappings can be changed by configuring
|
||||
`endpoints.health.mapping.<STATUS>=XXX`.
|
||||
|
||||
Example curl request:
|
||||
include::{generated}/health/curl-request.adoc[]
|
||||
|
||||
Example HTTP request: [small]##link:../health[icon:external-link[role="silver"]]##
|
||||
include::{generated}/health/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/health/http-response.adoc[]
|
||||
|
||||
Example HTTP response with `endpoints.health.sensitive=false`:
|
||||
include::{generated}/health/insensitive/http-response.adoc[]
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 432 KiB |
|
|
@ -1,203 +0,0 @@
|
|||
= Spring Boot Actuator Endpoints
|
||||
:toc: left
|
||||
:idprefix: spring_boot_actuator_
|
||||
:sectanchors:
|
||||
:icons: font
|
||||
:last-update-label!:
|
||||
|
||||
Actuator endpoints allow you to monitor and interact with your application. Spring Boot
|
||||
includes a number of built-in endpoints and you can also add your own. For example the
|
||||
`health` endpoint provides basic application health information.
|
||||
|
||||
The way that endpoints are exposed will depend on the type of technology that you choose.
|
||||
Most applications choose HTTP monitoring, where the ID of the endpoint is mapped
|
||||
to a URL. For example, by default, the `health` endpoint will be mapped to `/health`.
|
||||
|
||||
|
||||
|
||||
== List of Endpoints
|
||||
include::{generated}/endpoints.adoc[]
|
||||
|
||||
|
||||
|
||||
=== /auditevents
|
||||
This endpoint provides information about audit events registered by the application.
|
||||
Audit events can be filtered using the `after`, `principal` and `type` parameters as
|
||||
defined by `AuditEventRepository`.
|
||||
|
||||
Example cURL request with `after` parameter:
|
||||
include::{generated}/auditevents/curl-request.adoc[]
|
||||
|
||||
Example HTTP request with `after` parameter:
|
||||
include::{generated}/auditevents/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/auditevents/http-response.adoc[]
|
||||
|
||||
Example cURL request with `principal` and `after` parameters:
|
||||
include::{generated}/auditevents/filter-by-principal/curl-request.adoc[]
|
||||
|
||||
Example HTTP request with `principal` and `after` parameters:
|
||||
include::{generated}/auditevents/filter-by-principal/http-request.adoc[]
|
||||
|
||||
Example cURL request with `principal`, `after` and `type` parameters:
|
||||
include::{generated}/auditevents/filter-by-principal-and-type/curl-request.adoc[]
|
||||
|
||||
Example HTTP request with `principal`, `after` and `type` parameters:
|
||||
include::{generated}/auditevents/filter-by-principal-and-type/http-request.adoc[]
|
||||
|
||||
|
||||
|
||||
=== /logfile
|
||||
This endpoint (if available) contains the plain text logfile configured by the user
|
||||
using `logging.file` or `logging.path` (by default logs are only emitted on stdout
|
||||
so one of these properties has to be set for this endpoint to be active).
|
||||
|
||||
Example curl request:
|
||||
include::{generated}/logfile/curl-request.adoc[]
|
||||
|
||||
Example HTTP request: [small]##link:../logfile[icon:external-link[role="silver"]]##
|
||||
include::{generated}/logfile/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/logfile/http-response.adoc[]
|
||||
|
||||
==== Partial content
|
||||
|
||||
You can use the `Range` header to retrieve part of the log file's content.
|
||||
|
||||
Example curl request:
|
||||
include::{generated}/partial-logfile/curl-request.adoc[]
|
||||
|
||||
Example HTTP request:
|
||||
include::{generated}/partial-logfile/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/partial-logfile/http-response.adoc[]
|
||||
|
||||
|
||||
|
||||
=== /docs
|
||||
This endpoint (if available) contains HTML documentation for the other endpoints. Its path
|
||||
can be "/docs" (if there is an existing home page) or "/" (otherwise, including if the
|
||||
HAL browser is not active).
|
||||
|
||||
|
||||
|
||||
== Hypermedia Support
|
||||
If `endpoints.hypermedia.enabled` is set to `true` and
|
||||
https://projects.spring.io/spring-hateoas[Spring HATEOAS] is on the classpath (e.g.
|
||||
through the `spring-boot-starter-hateoas` or if you are using
|
||||
http://projects.spring.io/spring-data-rest[Spring Data REST]) then the Actuator endpoint
|
||||
responses are enhanced with hypermedia in the form of "links". The default media type for
|
||||
responses is http://stateless.co/hal_specification.html[HAL], resulting in each resource
|
||||
having an extra property called "_links". You can change the media type to another one
|
||||
supported by Spring HATEOAS by providing your own `@EnableHypermedia` annotation and
|
||||
custom providers as necessary.
|
||||
|
||||
Example enhanced "/metrics" endpoint with additional "_links":
|
||||
|
||||
include::{generated}/metrics/hypermedia/http-response.adoc[]
|
||||
|
||||
WARNING: Beware of Actuator endpoint paths clashing with application endpoints.
|
||||
The easiest way to avoid that is to use a `management.context-path`, e.g. "/admin".
|
||||
|
||||
TIP: You can disable the hypermedia support in Actuator endpoints by setting
|
||||
`endpoints.actuator.enabled=false`.
|
||||
|
||||
|
||||
|
||||
=== Main entry point
|
||||
When the hypermedia support is enabled, the Actuator provides a main entry point that
|
||||
provides links to all of its endpoints. If `management.context-path` is empty, this entry
|
||||
point is available at `/actuator`. If a management context path has been configured then
|
||||
the entry point is available at the root of that context. For example, if
|
||||
`management.context-path` has been set to `/admin` then the main entry point will be
|
||||
available at `/admin`.
|
||||
|
||||
TIP: The endpoint path can always, as with all MVC endpoints, be overridden using
|
||||
`endpoints.actuator.path=/yourpath` (note the leading slash).
|
||||
|
||||
include::{generated}/admin/http-response.adoc[]
|
||||
|
||||
|
||||
|
||||
=== Endpoints with format changes
|
||||
Some endpoints in their "`raw`" form consist of an array (e.g. the `/beans` and the
|
||||
`/trace` endpoints). These need to be converted to objects (maps) before they can be
|
||||
enhanced with links, so their contents are inserted as a field named "`content`".
|
||||
Example enhanced `/beans` endpoint with additional `_links`:
|
||||
|
||||
include::{generated}/beans/hypermedia/http-response.adoc[]
|
||||
|
||||
|
||||
|
||||
== HAL Browser
|
||||
If Hypermedia is enabled and the HAL format is in use (which is the default), then you
|
||||
can provide a browser for the resources by including a dependency on the
|
||||
https://github.com/mikekelly/hal-browser[HAL browser] webjar.
|
||||
|
||||
For example in Maven:
|
||||
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>hal-browser</artifactId>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
|
||||
or in Gradle:
|
||||
|
||||
[source,groovy,indent=0]
|
||||
----
|
||||
dependencies {
|
||||
...
|
||||
compile('org.webjars:hal-browser')
|
||||
...
|
||||
}
|
||||
----
|
||||
|
||||
NOTE: If you are using Spring Data REST, then a dependency on the
|
||||
`spring-data-rest-hal-browser` will have an equivalent effect.
|
||||
|
||||
If you do that then the main entry point will server a static HTML page to browser clients
|
||||
with some JavaScript that lets you browse the available resources.
|
||||
|
||||
Example:
|
||||
|
||||
image::hal-browser.png[HAL Browser]
|
||||
|
||||
|
||||
|
||||
== Actuator Documentation Browser
|
||||
You can also provide a browser for the standard generated documentation for the Actuator
|
||||
endpoints by including a dependency on the documentation jar.
|
||||
|
||||
For example in Maven:
|
||||
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-actuator-docs</artifactId>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
or in Gradle:
|
||||
|
||||
[source,groovy,indent=0]
|
||||
----
|
||||
dependencies {
|
||||
...
|
||||
compile('org.springframework.boot:spring-boot-actuator-docs')
|
||||
...
|
||||
}
|
||||
----
|
||||
|
||||
If you do that then a new endpoint at `/` or `/docs` (relative to the
|
||||
`management.context-path`) will serve up a static HTML page with this documentation in it.
|
||||
The default endpoint path depends on whether or not there is already a static home page
|
||||
("index.html" or a HAL browser) - if there is not and the `management.context-path` is
|
||||
empty, then the docs browser shows up on the home page.
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
=== /info
|
||||
This endpoint is empty and marked as `sensitive=false` by default (so it is
|
||||
unauthenticated by default if Spring Security is in use). It reflects the content of the
|
||||
`info.*` properties in the `Environment`, as well as the properties in `git.properties`
|
||||
if such a file exists in the root of the classpath.
|
||||
|
||||
Example curl request:
|
||||
include::{generated}/info/curl-request.adoc[]
|
||||
|
||||
Example HTTP request: [small]##link:../info[icon:external-link[role="silver"]]##
|
||||
include::{generated}/info/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/info/http-response.adoc[]
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
=== /liquibase
|
||||
This endpoint provides information about database migrations that have been performed
|
||||
by Liquibase.
|
||||
|
||||
Example curl request:
|
||||
include::{generated}/liquibase/curl-request.adoc[]
|
||||
|
||||
Example HTTP request:
|
||||
include::{generated}/liquibase/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/liquibase/http-response.adoc[]
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
=== /loggers
|
||||
This endpoint allows you to view and modify the log levels for the loggers in your
|
||||
application. It builds on top of the `LoggingSystem` abstraction and supports the same
|
||||
logging frameworks. The logging levels are defined by the `LogLevel` enumeration and
|
||||
consist of the following values (although not all logging systems support the full set):
|
||||
|
||||
* `TRACE`
|
||||
* `DEBUG`
|
||||
* `INFO`
|
||||
* `WARN`
|
||||
* `ERROR`
|
||||
* `FATAL`
|
||||
* `OFF`
|
||||
* `null`
|
||||
|
||||
The `configuredLevel` property reflects an explicitly configured logger level, while the
|
||||
`effectiveLevel` property reflects the logger level inherited from parent loggers. The
|
||||
`effectiveLevel` is managed by each logging framework and reflects the propagation rules
|
||||
inherent to and configured in that framework. `null` indicates that there is no explicit
|
||||
configuration defined.
|
||||
|
||||
|
||||
|
||||
==== Listing All Loggers
|
||||
Example curl request:
|
||||
include::{generated}/loggers/curl-request.adoc[]
|
||||
|
||||
Example HTTP request: [small]##link:../loggers[icon:external-link[role="silver"]]##
|
||||
include::{generated}/loggers/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/loggers/http-response.adoc[]
|
||||
|
||||
|
||||
|
||||
==== Getting a Single Logger
|
||||
Example curl request:
|
||||
include::{generated}/single-logger/curl-request.adoc[]
|
||||
|
||||
Example HTTP request: [small]##link:../loggers[icon:external-link[role="silver"]]##
|
||||
include::{generated}/single-logger/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/single-logger/http-response.adoc[]
|
||||
|
||||
|
||||
|
||||
==== Configuring a Logger
|
||||
Setting the `configuredLevel` of a logger requires `POSTing` a partial payload to the
|
||||
resource. The `configuredLevel` property must contain a string representation of the
|
||||
enumeration described above. `null` indicates that the log level should be unset,
|
||||
allowing it to inherit configuration from its parent.
|
||||
|
||||
Example curl request:
|
||||
include::{generated}/set-logger/curl-request.adoc[]
|
||||
|
||||
Example HTTP request: [small]##link:../loggers[icon:external-link[role="silver"]]##
|
||||
include::{generated}/set-logger/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/set-logger/http-response.adoc[]
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
=== /mappings
|
||||
This endpoint lists the Spring MVC request mappings, so users can see the handlers
|
||||
registered for requests by path, method, media type, etc.
|
||||
|
||||
Example curl request:
|
||||
include::{generated}/mappings/curl-request.adoc[]
|
||||
|
||||
Example HTTP request: [small]##link:../mappings[icon:external-link[role="silver"]]##
|
||||
include::{generated}/mappings/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/mappings/http-response.adoc[]
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
=== /metrics
|
||||
This endpoint lists the public metrics exposed by the application. By default this
|
||||
includes all the counters in the `CounterService` and all the gauges in the
|
||||
`GaugeService`, plus a few JVM metrics about memory and uptime. Users can register
|
||||
additional sources by creating beans of type `PublicMetrics` and/or by registering
|
||||
counters and gauges.
|
||||
|
||||
Example curl request:
|
||||
include::{generated}/metrics/curl-request.adoc[]
|
||||
|
||||
Example HTTP request: [small]##link:../metrics[icon:external-link[role="silver"]]##
|
||||
include::{generated}/metrics/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/metrics/http-response.adoc[]
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
=== /trace
|
||||
This endpoint lists contents of the `TraceRepository` (which users can override by
|
||||
providing a bean of that type, or by injecting that bean and adding stuff to it). By
|
||||
default it stores the last 100 HTTP requests, including all headers in the request and
|
||||
response, and the path and HTTP status.
|
||||
|
||||
Example curl request:
|
||||
include::{generated}/trace/curl-request.adoc[]
|
||||
|
||||
Example HTTP request: [small]##link:../trace[icon:external-link[role="silver"]]##
|
||||
include::{generated}/trace/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}/trace/http-response.adoc[]
|
||||
|
|
@ -1,235 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.hypermedia;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import groovy.text.Template;
|
||||
import groovy.text.TemplateEngine;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.ActuatorMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoints;
|
||||
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrint;
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration(classes = SpringBootHypermediaApplication.class, loader = SpringBootContextLoader.class)
|
||||
@WebAppConfiguration
|
||||
@TestPropertySource(properties = { "spring.jackson.serialization.indent_output=true",
|
||||
"endpoints.health.sensitive=true", "endpoints.actuator.enabled=false",
|
||||
"management.security.enabled=false" })
|
||||
@DirtiesContext
|
||||
@AutoConfigureRestDocs(EndpointDocumentation.RESTDOCS_OUTPUT_DIR)
|
||||
@AutoConfigureMockMvc(print = MockMvcPrint.NONE)
|
||||
public class EndpointDocumentation {
|
||||
|
||||
static final String RESTDOCS_OUTPUT_DIR = "target/generated-snippets";
|
||||
|
||||
static final File LOG_FILE = new File("target/logs/spring.log");
|
||||
|
||||
private static final Set<String> SKIPPED = Collections
|
||||
.<String>unmodifiableSet(new HashSet<>(
|
||||
Arrays.asList("/docs", "/logfile", "/heapdump", "/auditevents")));
|
||||
|
||||
@Autowired
|
||||
private MvcEndpoints mvcEndpoints;
|
||||
|
||||
@Autowired
|
||||
private TemplateEngine templates;
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@BeforeClass
|
||||
public static void clearLog() {
|
||||
LOG_FILE.delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logfile() throws Exception {
|
||||
this.mockMvc.perform(get("/application/logfile").accept(MediaType.TEXT_PLAIN))
|
||||
.andExpect(status().isOk()).andDo(document("logfile"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void partialLogfile() throws Exception {
|
||||
FileCopyUtils.copy(getClass().getResourceAsStream("log.txt"),
|
||||
new FileOutputStream(LOG_FILE));
|
||||
this.mockMvc
|
||||
.perform(get("/application/logfile").accept(MediaType.TEXT_PLAIN)
|
||||
.header(HttpHeaders.RANGE, "bytes=0-1024"))
|
||||
.andExpect(status().isPartialContent())
|
||||
.andDo(document("partial-logfile"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleLogger() throws Exception {
|
||||
this.mockMvc
|
||||
.perform(get("/application/loggers/org.springframework.boot")
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk()).andDo(document("single-logger"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setLogger() throws Exception {
|
||||
this.mockMvc
|
||||
.perform(post("/application/loggers/org.springframework.boot")
|
||||
.contentType(ActuatorMediaTypes.APPLICATION_ACTUATOR_V2_JSON)
|
||||
.content("{\"configuredLevel\": \"DEBUG\"}"))
|
||||
.andExpect(status().isNoContent()).andDo(document("set-logger"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void auditEvents() throws Exception {
|
||||
this.mockMvc
|
||||
.perform(get("/application/auditevents")
|
||||
.param("after", "2016-11-01T10:00:00+0000")
|
||||
.accept(ActuatorMediaTypes.APPLICATION_ACTUATOR_V2_JSON))
|
||||
.andExpect(status().isOk()).andDo(document("auditevents"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void auditEventsByPrincipal() throws Exception {
|
||||
this.mockMvc
|
||||
.perform(get("/application/auditevents").param("principal", "admin")
|
||||
.param("after", "2016-11-01T10:00:00+0000")
|
||||
.accept(ActuatorMediaTypes.APPLICATION_ACTUATOR_V2_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andDo(document("auditevents/filter-by-principal"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void auditEventsByPrincipalAndType() throws Exception {
|
||||
this.mockMvc
|
||||
.perform(get("/application/auditevents").param("principal", "admin")
|
||||
.param("after", "2016-11-01T10:00:00+0000")
|
||||
.param("type", "AUTHENTICATION_SUCCESS")
|
||||
.accept(ActuatorMediaTypes.APPLICATION_ACTUATOR_V2_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andDo(document("auditevents/filter-by-principal-and-type"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void endpoints() throws Exception {
|
||||
File docs = new File("src/main/asciidoc");
|
||||
Map<String, Object> model = new LinkedHashMap<>();
|
||||
model.put("endpoints", getEndpointDocs(docs));
|
||||
File file = new File(RESTDOCS_OUTPUT_DIR + "/endpoints.adoc");
|
||||
file.getParentFile().mkdirs();
|
||||
try (PrintWriter writer = new PrintWriter(file, "UTF-8")) {
|
||||
Template template = this.templates.createTemplate(
|
||||
new File("src/restdoc/resources/templates/endpoints.adoc.tpl"));
|
||||
template.make(model).writeTo(writer);
|
||||
}
|
||||
}
|
||||
|
||||
private List<EndpointDoc> getEndpointDocs(File docs) throws Exception {
|
||||
final List<EndpointDoc> endpoints = new ArrayList<>();
|
||||
for (MvcEndpoint endpoint : getEndpoints()) {
|
||||
String path = endpoint.getPath();
|
||||
path = (StringUtils.hasText(path) ? path : "/");
|
||||
if (!SKIPPED.contains(path)) {
|
||||
documentEndpoint(path);
|
||||
endpoints.add(new EndpointDoc(docs, path));
|
||||
}
|
||||
}
|
||||
return endpoints;
|
||||
}
|
||||
|
||||
private Collection<? extends MvcEndpoint> getEndpoints() {
|
||||
List<? extends MvcEndpoint> endpoints = new ArrayList<>(
|
||||
this.mvcEndpoints.getEndpoints());
|
||||
endpoints.sort(Comparator.comparing(MvcEndpoint::getPath));
|
||||
return endpoints;
|
||||
}
|
||||
|
||||
private String documentEndpoint(final String endpointPath) throws Exception {
|
||||
String output = endpointPath.substring(1);
|
||||
output = (output.length() > 0 ? output : "./");
|
||||
this.mockMvc
|
||||
.perform(get("/application" + endpointPath)
|
||||
.accept(ActuatorMediaTypes.APPLICATION_ACTUATOR_V2_JSON))
|
||||
.andExpect(status().isOk()).andDo(document(output));
|
||||
return output;
|
||||
}
|
||||
|
||||
public static class EndpointDoc {
|
||||
|
||||
private String path;
|
||||
|
||||
private String custom;
|
||||
|
||||
private String title;
|
||||
|
||||
public EndpointDoc(File rootDir, String path) {
|
||||
this.title = path;
|
||||
this.path = path.equals("/") ? "" : path;
|
||||
String custom = path.substring(1) + ".adoc";
|
||||
if (new File(rootDir, custom).exists()) {
|
||||
this.custom = custom;
|
||||
}
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return this.title;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
public String getCustom() {
|
||||
return this.custom;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.hypermedia;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.ActuatorMediaTypes;
|
||||
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration(classes = SpringBootHypermediaApplication.class, loader = SpringBootContextLoader.class)
|
||||
@WebAppConfiguration
|
||||
@TestPropertySource(properties = { "spring.jackson.serialization.indent_output=true",
|
||||
"endpoints.health.sensitive=false", "management.security.enabled=false" })
|
||||
@DirtiesContext
|
||||
@AutoConfigureMockMvc
|
||||
@AutoConfigureRestDocs("target/generated-snippets")
|
||||
public class HealthEndpointDocumentation {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Test
|
||||
public void health() throws Exception {
|
||||
this.mockMvc
|
||||
.perform(get("/application/health")
|
||||
.accept(ActuatorMediaTypes.APPLICATION_ACTUATOR_V2_JSON))
|
||||
.andExpect(status().isOk()).andDo(document("health/insensitive"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.hypermedia;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.ActuatorMediaTypes;
|
||||
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration(classes = SpringBootHypermediaApplication.class, loader = SpringBootContextLoader.class)
|
||||
@WebAppConfiguration
|
||||
@TestPropertySource(properties = { "spring.jackson.serialization.indent_output=true",
|
||||
"endpoints.hypermedia.enabled=true", "management.security.enabled=false" })
|
||||
@DirtiesContext
|
||||
@AutoConfigureMockMvc
|
||||
@AutoConfigureRestDocs("target/generated-snippets")
|
||||
public class HypermediaEndpointDocumentation {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Test
|
||||
public void beans() throws Exception {
|
||||
this.mockMvc
|
||||
.perform(get("/application/beans")
|
||||
.accept(ActuatorMediaTypes.APPLICATION_ACTUATOR_V2_JSON))
|
||||
.andExpect(status().isOk()).andDo(document("beans/hypermedia"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metrics() throws Exception {
|
||||
this.mockMvc
|
||||
.perform(get("/application/metrics")
|
||||
.accept(ActuatorMediaTypes.APPLICATION_ACTUATOR_V2_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._links.self.href")
|
||||
.value("http://localhost:8080/application/metrics"))
|
||||
.andDo(document("metrics/hypermedia"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void home() throws Exception {
|
||||
this.mockMvc
|
||||
.perform(get("/application")
|
||||
.accept(ActuatorMediaTypes.APPLICATION_ACTUATOR_V2_JSON))
|
||||
.andExpect(status().isOk()).andDo(document("admin"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.hypermedia;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
/**
|
||||
* {@link EnvironmentEndpoint} with reduced output to look better in the documentation.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class LimitedEnvironmentEndpoint extends EnvironmentEndpoint {
|
||||
|
||||
private static final MultiValueMap<String, String> INCLUDES;
|
||||
|
||||
static {
|
||||
Map<String, List<String>> includes = new LinkedHashMap<>();
|
||||
List<String> systemProperties = new ArrayList<>();
|
||||
systemProperties.add("java.runtime.name");
|
||||
systemProperties.add("sun.boot.library.path");
|
||||
systemProperties.add("java.vendor.url");
|
||||
systemProperties.add("path.separator");
|
||||
systemProperties.add("sun.java.launcher");
|
||||
systemProperties.add("java.runtime.version");
|
||||
systemProperties.add("os.arch");
|
||||
systemProperties.add("line.separator");
|
||||
systemProperties.add("os.name");
|
||||
systemProperties.add("user.timezone");
|
||||
systemProperties.add("file.encoding");
|
||||
systemProperties.add("java.vm.specification.version");
|
||||
systemProperties.add("sun.java.command");
|
||||
systemProperties.add("sun.arch.data.model");
|
||||
systemProperties.add("user.language");
|
||||
systemProperties.add("awt.toolkit");
|
||||
systemProperties.add("java.awt.headless");
|
||||
systemProperties.add("java.vendor");
|
||||
systemProperties.add("file.separator");
|
||||
includes.put("systemProperties", systemProperties);
|
||||
List<String> systemEnvironment = new ArrayList<>();
|
||||
systemEnvironment.add("SHELL");
|
||||
systemEnvironment.add("TMPDIR");
|
||||
systemEnvironment.add("DISPLAY");
|
||||
systemEnvironment.add("LOGNAME");
|
||||
includes.put("systemEnvironment", systemEnvironment);
|
||||
INCLUDES = new LinkedMultiValueMap<>(Collections.unmodifiableMap(includes));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object sanitize(String name, Object object) {
|
||||
if (name.equals("gopherProxySet")) {
|
||||
return object;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Object> postProcessSourceProperties(String sourceName,
|
||||
Map<String, Object> properties) {
|
||||
List<String> sourceIncludes = INCLUDES.get(sourceName);
|
||||
if (sourceIncludes != null) {
|
||||
Set<Entry<String, Object>> entries = properties.entrySet();
|
||||
Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
if (!sourceIncludes.contains(iterator.next().getKey())) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.hypermedia;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
|
||||
import groovy.text.GStringTemplateEngine;
|
||||
import groovy.text.TemplateEngine;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.actuate.audit.AuditEvent;
|
||||
import org.springframework.boot.actuate.audit.AuditEventRepository;
|
||||
import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
// Flyway must go first
|
||||
@SpringBootApplication
|
||||
@Import({ FlywayAutoConfiguration.class, LiquibaseAutoConfiguration.class })
|
||||
public class SpringBootHypermediaApplication implements CommandLineRunner {
|
||||
|
||||
@Autowired
|
||||
private AuditEventRepository auditEventRepository;
|
||||
|
||||
@Bean
|
||||
public TemplateEngine groovyTemplateEngine() {
|
||||
return new GStringTemplateEngine();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EnvironmentEndpoint environmentEndpoint() {
|
||||
return new LimitedEnvironmentEndpoint();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringBootHypermediaApplication.class, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
this.auditEventRepository.add(
|
||||
createEvent("2016-11-01T11:00:00Z", "user", "AUTHENTICATION_FAILURE"));
|
||||
this.auditEventRepository.add(
|
||||
createEvent("2016-11-01T12:00:00Z", "admin", "AUTHENTICATION_SUCCESS"));
|
||||
}
|
||||
|
||||
private AuditEvent createEvent(String instant, String principal, String type) {
|
||||
return new AuditEvent(Date.from(Instant.parse(instant)), principal, type,
|
||||
Collections.<String, Object>emptyMap());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
# management.context-path=/admin
|
||||
logging.path: target/logs
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
databaseChangeLog:
|
||||
- changeSet:
|
||||
id: 1
|
||||
author: awilkinson
|
||||
changes:
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
2016-05-10 10:55:45.405 INFO 40532 --- [ main] sanity.SanityCheckApplication : Starting SanityCheckApplication on pwmbp with PID 40532 (/Users/pwebb/projects/spring-boot/samples/spring-boot-sanity-check/target/classes started by pwebb in /Users/pwebb/projects/spring-boot/samples/spring-boot-sanity-check)
|
||||
2016-05-10 10:55:45.408 INFO 40532 --- [ main] sanity.SanityCheckApplication : No active profile set, falling back to default profiles: default
|
||||
2016-05-10 10:55:45.473 INFO 40532 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@59e5ddf: startup date [Tue May 10 10:55:45 PDT 2016]; root of context hierarchy
|
||||
2016-05-10 10:55:47.076 INFO 40532 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
|
||||
2016-05-10 10:55:47.088 INFO 40532 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
|
||||
2016-05-10 10:55:47.090 INFO 40532 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.0.33
|
||||
2016-05-10 10:55:47.173 INFO 40532 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
|
||||
2016-05-10 10:55:47.173 INFO 40532 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1705 ms
|
||||
2016-05-10 10:55:47.486 INFO 40532 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
|
||||
2016-05-10 10:55:47.489 INFO 40532 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
|
||||
2016-05-10 10:55:47.490 INFO 40532 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
|
||||
2016-05-10 10:55:47.490 INFO 40532 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
|
||||
2016-05-10 10:55:47.490 INFO 40532 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
|
||||
2016-05-10 10:55:47.763 INFO 40532 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@59e5ddf: startup date [Tue May 10 10:55:45 PDT 2016]; root of context hierarchy
|
||||
2016-05-10 10:55:47.826 INFO 40532 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto public org.springframework.http.ResponseEntity<java.lang.String> sanity.MyController.hello()
|
||||
2016-05-10 10:55:47.829 INFO 40532 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
|
||||
2016-05-10 10:55:47.830 INFO 40532 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
|
||||
2016-05-10 10:55:47.864 INFO 40532 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
|
||||
2016-05-10 10:55:47.864 INFO 40532 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
|
||||
2016-05-10 10:55:47.908 INFO 40532 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
|
||||
2016-05-10 10:55:48.208 WARN 40532 --- [ main] arterDepricationWarningAutoConfiguration : spring-boot-starter-redis is deprecated as of Spring Boot 1.4, please migrate to spring-boot-starter-data-redis
|
||||
2016-05-10 10:55:48.268 INFO 40532 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
|
||||
2016-05-10 10:55:48.320 ERROR 40532 --- [ main] o.a.coyote.http11.Http11NioProtocol : Failed to start end point associated with ProtocolHandler ["http-nio-8080"]
|
||||
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
[source,http,options="nowrap"]
|
||||
----
|
||||
HTTP/1.1 {{statusCode}} {{statusReason}}
|
||||
{{#headers}}
|
||||
{{name}}: {{value}}
|
||||
{{/headers}}
|
||||
{{responseBody}}
|
||||
----
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<% endpoints.each { endpoint ->
|
||||
if (endpoint.custom) { %>
|
||||
include::{docs}/${endpoint.custom}[]
|
||||
<% } else { %>
|
||||
=== Link: ${endpoint.title}
|
||||
|
||||
Example curl request:
|
||||
include::{generated}${endpoint.path}/curl-request.adoc[]
|
||||
|
||||
Example HTTP request:
|
||||
include::{generated}${endpoint.path}/http-request.adoc[]
|
||||
|
||||
Example HTTP response:
|
||||
include::{generated}${endpoint.path}/http-response.adoc[]
|
||||
<% }
|
||||
} %>
|
||||
|
|
@ -33,38 +33,28 @@ import com.fasterxml.jackson.annotation.JsonUnwrapped;
|
|||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcHypermediaManagementContextConfiguration.EndpointHypermediaEnabledCondition;
|
||||
import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.ActuatorMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.DocsMvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.HalBrowserMvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.HalJsonMvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.HypermediaDisabled;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.ManagementServletContext;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoints;
|
||||
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnResource;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
|
||||
import org.springframework.boot.autoconfigure.web.ResourceProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.Resource;
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
import org.springframework.hateoas.UriTemplate;
|
||||
import org.springframework.hateoas.hal.CurieProvider;
|
||||
import org.springframework.hateoas.hal.DefaultCurieProvider;
|
||||
import org.springframework.hateoas.mvc.TypeConstrainedMappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.AbstractHttpMessageConverter;
|
||||
|
|
@ -93,7 +83,7 @@ import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
|
|||
@ConditionalOnClass(Link.class)
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||
@ConditionalOnBean(HttpMessageConverters.class)
|
||||
@Conditional(EndpointHypermediaEnabledCondition.class)
|
||||
@ConditionalOnEnabledEndpoint("actuator")
|
||||
@EnableConfigurationProperties({ ResourceProperties.class,
|
||||
ManagementServerProperties.class })
|
||||
public class EndpointWebMvcHypermediaManagementContextConfiguration {
|
||||
|
|
@ -104,7 +94,6 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
|
|||
return properties::getContextPath;
|
||||
}
|
||||
|
||||
@ConditionalOnEnabledEndpoint("actuator")
|
||||
@Bean
|
||||
public HalJsonMvcEndpoint halJsonMvcEndpoint(
|
||||
ManagementServletContext managementServletContext,
|
||||
|
|
@ -115,30 +104,6 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
|
|||
return new HalJsonMvcEndpoint(managementServletContext);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(DocsMvcEndpoint.class)
|
||||
@ConditionalOnMissingBean(CurieProvider.class)
|
||||
@ConditionalOnProperty(prefix = "endpoints.docs.curies", name = "enabled", matchIfMissing = false)
|
||||
public DefaultCurieProvider curieProvider(ManagementServerProperties management,
|
||||
DocsMvcEndpoint endpoint) {
|
||||
String path = management.getContextPath() + endpoint.getPath()
|
||||
+ "/#spring_boot_actuator__{rel}";
|
||||
return new DefaultCurieProvider("boot", new UriTemplate(path));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class DocsMvcEndpointConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnEnabledEndpoint("docs")
|
||||
@ConditionalOnResource(resources = "classpath:/META-INF/resources/spring-boot-actuator/docs/index.html")
|
||||
public DocsMvcEndpoint docsMvcEndpoint(
|
||||
ManagementServletContext managementServletContext) {
|
||||
return new DocsMvcEndpoint(managementServletContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Controller advice that adds links to the actuator endpoint's path.
|
||||
*/
|
||||
|
|
@ -363,22 +328,4 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
|
|||
|
||||
}
|
||||
|
||||
static class EndpointHypermediaEnabledCondition extends AnyNestedCondition {
|
||||
|
||||
EndpointHypermediaEnabledCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
|
||||
@ConditionalOnEnabledEndpoint("actuator")
|
||||
static class ActuatorEndpointEnabled {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnEnabledEndpoint("docs")
|
||||
static class DocsEndpointEnabled {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.endpoint.mvc;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
|
||||
/**
|
||||
* {@link MvcEndpoint} to expose actuator documentation.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "endpoints.docs")
|
||||
public class DocsMvcEndpoint extends AbstractNamedMvcEndpoint {
|
||||
|
||||
private static final String DOCS_LOCATION = "classpath:/META-INF/resources/spring-boot-actuator/docs/";
|
||||
|
||||
private final ManagementServletContext managementServletContext;
|
||||
|
||||
private Curies curies = new Curies();
|
||||
|
||||
public Curies getCuries() {
|
||||
return this.curies;
|
||||
}
|
||||
|
||||
public DocsMvcEndpoint(ManagementServletContext managementServletContext) {
|
||||
super("docs", "/docs", false);
|
||||
this.managementServletContext = managementServletContext;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/", produces = MediaType.TEXT_HTML_VALUE)
|
||||
public String browse() {
|
||||
return "forward:" + this.managementServletContext.getContextPath() + getPath()
|
||||
+ "/index.html";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "", produces = MediaType.TEXT_HTML_VALUE)
|
||||
public String redirect() {
|
||||
return "redirect:" + this.managementServletContext.getContextPath() + getPath()
|
||||
+ "/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler(
|
||||
this.managementServletContext.getContextPath() + getPath() + "/**")
|
||||
.addResourceLocations(DOCS_LOCATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Properties of the default CurieProvider (used for adding docs links). If enabled,
|
||||
* all unqualified rels will pick up a prefix and a curie template pointing to the
|
||||
* docs endpoint.
|
||||
*/
|
||||
public static class Curies {
|
||||
|
||||
/**
|
||||
* Enable the curie generation.
|
||||
*/
|
||||
private boolean enabled = false;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,151 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
import net.minidev.json.JSONArray;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for the href of the actuator's curies link
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class BootCuriesHrefIntegrationTests {
|
||||
|
||||
private AnnotationConfigServletWebServerApplicationContext context;
|
||||
|
||||
@After
|
||||
public void closeContext() {
|
||||
this.context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basicCuriesHref() {
|
||||
int port = load("endpoints.docs.curies.enabled:true", "server.port:0");
|
||||
assertThat(getCurieHref("http://localhost:" + port + "/application"))
|
||||
.isEqualTo("http://localhost:" + port
|
||||
+ "/application/docs/#spring_boot_actuator__{rel}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void curiesHrefWithCustomContextPath() {
|
||||
int port = load("endpoints.docs.curies.enabled:true", "server.port:0",
|
||||
"server.servlet.context-path:/context");
|
||||
assertThat(getCurieHref("http://localhost:" + port + "/context/application"))
|
||||
.isEqualTo("http://localhost:" + port
|
||||
+ "/context/application/docs/#spring_boot_actuator__{rel}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void curiesHrefWithCustomServletPath() {
|
||||
int port = load("endpoints.docs.curies.enabled:true", "server.port:0",
|
||||
"server.servlet.path:/servlet");
|
||||
assertThat(getCurieHref("http://localhost:" + port + "/servlet/application"))
|
||||
.isEqualTo("http://localhost:" + port
|
||||
+ "/servlet/application/docs/#spring_boot_actuator__{rel}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void curiesHrefWithCustomServletAndContextPaths() {
|
||||
int port = load("endpoints.docs.curies.enabled:true", "server.port:0",
|
||||
"server.servlet.context-path:/context", "server.servlet.path:/servlet");
|
||||
assertThat(getCurieHref("http://localhost:" + port
|
||||
+ "/context/servlet/application")).isEqualTo("http://localhost:" + port
|
||||
+ "/context/servlet/application/docs/#spring_boot_actuator__{rel}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void curiesHrefWithCustomServletContextAndManagementContextPaths() {
|
||||
int port = load("endpoints.docs.curies.enabled:true", "server.port:0",
|
||||
"server.servlet.context-path:/context", "server.servlet.path:/servlet",
|
||||
"management.context-path:/management");
|
||||
assertThat(getCurieHref("http://localhost:" + port
|
||||
+ "/context/servlet/management/")).isEqualTo("http://localhost:" + port
|
||||
+ "/context/servlet/management/docs/#spring_boot_actuator__{rel}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serverPathsAreIgnoredWithSeparateManagementPort() {
|
||||
int port = load("endpoints.docs.curies.enabled:true", "server.port:0",
|
||||
"server.servlet.context-path:/context", "server.servlet.path:/servlet",
|
||||
"management.port:0");
|
||||
assertThat(getCurieHref("http://localhost:" + port + "/application/"))
|
||||
.isEqualTo("http://localhost:" + port
|
||||
+ "/application/docs/#spring_boot_actuator__{rel}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void managementContextPathWithSeparateManagementPort() {
|
||||
int port = load("endpoints.docs.curies.enabled:true",
|
||||
"management.context-path:/management", "server.port:0",
|
||||
"management.port:0");
|
||||
assertThat(getCurieHref("http://localhost:" + port + "/management/"))
|
||||
.isEqualTo("http://localhost:" + port
|
||||
+ "/management/docs/#spring_boot_actuator__{rel}");
|
||||
}
|
||||
|
||||
private int load(String... properties) {
|
||||
this.context = new AnnotationConfigServletWebServerApplicationContext();
|
||||
this.context.setClassLoader(new ClassLoader(getClass().getClassLoader()) {
|
||||
|
||||
@Override
|
||||
public URL getResource(String name) {
|
||||
if ("META-INF/resources/spring-boot-actuator/docs/index.html"
|
||||
.equals(name)) {
|
||||
return super.getResource("actuator-docs-index.html");
|
||||
}
|
||||
return super.getResource(name);
|
||||
}
|
||||
|
||||
});
|
||||
TestPropertyValues.of(properties).applyTo(this.context);
|
||||
this.context.register(TestConfiguration.class);
|
||||
new ServerPortInfoApplicationContextInitializer().initialize(this.context);
|
||||
this.context.refresh();
|
||||
return Integer.parseInt(
|
||||
this.context.getEnvironment().getProperty("local.management.port"));
|
||||
}
|
||||
|
||||
private String getCurieHref(String uri) {
|
||||
ResponseEntity<String> response = new TestRestTemplate().getForEntity(uri,
|
||||
String.class);
|
||||
JSONArray bootCuriesHrefs = JsonPath.parse(response.getBody())
|
||||
.read("_links.curies[?(@.name == 'boot')].href");
|
||||
assertThat(bootCuriesHrefs).hasSize(1);
|
||||
return (String) bootCuriesHrefs.get(0);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@MinimalActuatorHypermediaApplication
|
||||
static class TestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -16,13 +16,10 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.mvc.DocsMvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.HalJsonMvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.ManagementServletContext;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoints;
|
||||
|
|
@ -32,7 +29,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
|||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.hal.DefaultCurieProvider;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
|
|
@ -72,60 +68,11 @@ public class EndpointWebMvcHypermediaManagementContextConfigurationTests {
|
|||
assertThat(this.context.getBeansOfType(ManagementServletContext.class))
|
||||
.hasSize(1);
|
||||
assertThat(this.context.getBeansOfType(HalJsonMvcEndpoint.class)).hasSize(1);
|
||||
assertThat(this.context.getBeansOfType(DocsMvcEndpoint.class)).hasSize(1);
|
||||
assertThat(this.context.getBeansOfType(DefaultCurieProvider.class)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void curiesEnabledWithDefaultPorts() {
|
||||
load("endpoints.docs.curies.enabled:true");
|
||||
assertThat(getCurieHref()).isEqualTo(
|
||||
"http://localhost/application/docs/#spring_boot_actuator__{rel}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void curiesEnabledWithRandomPorts() {
|
||||
load("endpoints.docs.curies.enabled:true", "server.port:0", "management.port:0");
|
||||
assertThat(getCurieHref()).isEqualTo(
|
||||
"http://localhost/application/docs/#spring_boot_actuator__{rel}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void curiesEnabledWithSpecificServerPort() {
|
||||
load("endpoints.docs.curies.enabled:true", "server.port:8080");
|
||||
assertThat(getCurieHref()).isEqualTo(
|
||||
"http://localhost/application/docs/#spring_boot_actuator__{rel}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void curiesEnabledWithSpecificManagementPort() {
|
||||
load("endpoints.docs.curies.enabled:true", "management.port:8081");
|
||||
assertThat(getCurieHref()).isEqualTo(
|
||||
"http://localhost/application/docs/#spring_boot_actuator__{rel}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void curiesEnabledWithSpecificManagementAndServerPorts() {
|
||||
load("endpoints.docs.curies.enabled:true", "server.port:8080",
|
||||
"management.port:8081");
|
||||
assertThat(getCurieHref()).isEqualTo(
|
||||
"http://localhost/application/docs/#spring_boot_actuator__{rel}");
|
||||
}
|
||||
|
||||
private void load(String... properties) {
|
||||
this.context = new AnnotationConfigWebApplicationContext();
|
||||
this.context.setClassLoader(new ClassLoader(getClass().getClassLoader()) {
|
||||
|
||||
@Override
|
||||
public URL getResource(String name) {
|
||||
if ("META-INF/resources/spring-boot-actuator/docs/index.html"
|
||||
.equals(name)) {
|
||||
return super.getResource("actuator-docs-index.html");
|
||||
}
|
||||
return super.getResource(name);
|
||||
}
|
||||
|
||||
});
|
||||
TestPropertyValues.of(properties).applyTo(this.context);
|
||||
this.context.register(TestConfiguration.class,
|
||||
HttpMessageConvertersAutoConfiguration.class,
|
||||
|
|
@ -133,13 +80,6 @@ public class EndpointWebMvcHypermediaManagementContextConfigurationTests {
|
|||
this.context.refresh();
|
||||
}
|
||||
|
||||
private String getCurieHref() {
|
||||
DefaultCurieProvider curieProvider = this.context
|
||||
.getBean(DefaultCurieProvider.class);
|
||||
Link link = (Link) curieProvider.getCurieInformation(null).iterator().next();
|
||||
return link.getHref();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties({ ManagementServerProperties.class,
|
||||
ServerProperties.class })
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ import org.springframework.boot.actuate.endpoint.RequestMappingEndpoint;
|
|||
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.TraceEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.AuditEventsMvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.DocsMvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.HalJsonMvcEndpoint;
|
||||
|
|
@ -44,7 +43,6 @@ import org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint;
|
|||
import org.springframework.boot.actuate.endpoint.mvc.JolokiaMvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.LogFileMvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.LoggersMvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.ManagementServletContext;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoints;
|
||||
|
|
@ -90,7 +88,6 @@ public class MvcEndpointPathConfigurationTests {
|
|||
new Object[] { "beans", BeansEndpoint.class },
|
||||
new Object[] { "configprops",
|
||||
ConfigurationPropertiesReportEndpoint.class },
|
||||
new Object[] { "docs", DocsMvcEndpoint.class },
|
||||
new Object[] { "dump", DumpEndpoint.class },
|
||||
new Object[] { "env", EnvironmentMvcEndpoint.class },
|
||||
new Object[] { "flyway", FlywayEndpoint.class },
|
||||
|
|
@ -169,11 +166,6 @@ public class MvcEndpointPathConfigurationTests {
|
|||
return new LiquibaseEndpoint(new SpringLiquibase());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DocsMvcEndpoint docs(ManagementServletContext managementServletContext) {
|
||||
return new DocsMvcEndpoint(managementServletContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -240,11 +240,6 @@
|
|||
<artifactId>spring-boot-actuator</artifactId>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-actuator-docs</artifactId>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
|
|
|
|||
|
|
@ -144,11 +144,6 @@ If you are using Spring MVC, the following additional endpoints can also be used
|
|||
|===
|
||||
| ID | Description | Sensitive Default
|
||||
|
||||
|`docs`
|
||||
|Displays documentation, including example requests and responses, for the Actuator's
|
||||
endpoints. Requires `spring-boot-actuator-docs` to be on the classpath.
|
||||
|false
|
||||
|
||||
|`heapdump`
|
||||
|Returns a GZip compressed `hprof` heap dump file.
|
||||
|true
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@
|
|||
<module>../spring-boot-autoconfigure</module>
|
||||
<module>../spring-boot-test-autoconfigure</module>
|
||||
<module>../spring-boot-actuator</module>
|
||||
<module>../spring-boot-actuator-docs</module>
|
||||
<module>../spring-boot-devtools</module>
|
||||
<module>../spring-boot-starters</module>
|
||||
<module>../spring-boot-cli</module>
|
||||
|
|
|
|||
|
|
@ -27,10 +27,6 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-hateoas</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-actuator-docs</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-rest</artifactId>
|
||||
|
|
|
|||
|
|
@ -59,14 +59,6 @@ public class SampleHypermediaJpaApplicationIntegrationTests {
|
|||
.andExpect(status().isOk()).andExpect(jsonPath("$._links").exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void docs() throws Exception {
|
||||
MvcResult response = this.mockMvc
|
||||
.perform(get("/admin/docs/").accept(MediaType.TEXT_HTML))
|
||||
.andExpect(status().isOk()).andReturn();
|
||||
System.err.println(response.getResponse().getContentAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void browser() throws Exception {
|
||||
MvcResult response = this.mockMvc.perform(get("/").accept(MediaType.TEXT_HTML))
|
||||
|
|
|
|||
|
|
@ -31,10 +31,6 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-hateoas</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-actuator-docs</artifactId>
|
||||
</dependency>
|
||||
<!-- Test -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
|
|
|||
|
|
@ -27,10 +27,6 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-hateoas</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-actuator-docs</artifactId>
|
||||
</dependency>
|
||||
<!-- Test -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
|
|
|||
|
|
@ -28,10 +28,6 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-hateoas</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-actuator-docs</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>hal-browser</artifactId>
|
||||
|
|
|
|||
Loading…
Reference in New Issue