Merge pull request #6579 from vpavic/audit-endpoint
* pr/6579: Polish audit event endpoint support Improve MBean without backing Endpoint support Add MVC and JMX endpoints to retrieve audit events Add JMX without backing `Endpoint` support
This commit is contained in:
commit
6adab91fd1
|
@ -20,6 +20,34 @@ 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
|
=== /logfile
|
||||||
This endpoint (if available) contains the plain text logfile configured by the user
|
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
|
using `logging.file` or `logging.path` (by default logs are only emitted on stdout
|
||||||
|
|
|
@ -77,7 +77,8 @@ public class EndpointDocumentation {
|
||||||
static final File LOG_FILE = new File("target/logs/spring.log");
|
static final File LOG_FILE = new File("target/logs/spring.log");
|
||||||
|
|
||||||
private static final Set<String> SKIPPED = Collections.<String>unmodifiableSet(
|
private static final Set<String> SKIPPED = Collections.<String>unmodifiableSet(
|
||||||
new HashSet<String>(Arrays.asList("/docs", "/logfile", "/heapdump")));
|
new HashSet<String>(Arrays.asList("/docs", "/logfile", "/heapdump",
|
||||||
|
"/auditevents")));
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private MvcEndpoints mvcEndpoints;
|
private MvcEndpoints mvcEndpoints;
|
||||||
|
@ -127,6 +128,33 @@ public class EndpointDocumentation {
|
||||||
.andExpect(status().isOk()).andDo(document("set-logger"));
|
.andExpect(status().isOk()).andDo(document("set-logger"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void auditEvents() throws Exception {
|
||||||
|
this.mockMvc.perform(get("/auditevents")
|
||||||
|
.param("after", "2016-11-01T10:00:00+0000")
|
||||||
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
.andExpect(status().isOk()).andDo(document("auditevents"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void auditEventsByPrincipal() throws Exception {
|
||||||
|
this.mockMvc.perform(get("/auditevents").param("principal", "admin")
|
||||||
|
.param("after", "2016-11-01T10:00:00+0000")
|
||||||
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andDo(document("auditevents/filter-by-principal"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void auditEventsByPrincipalAndType() throws Exception {
|
||||||
|
this.mockMvc.perform(get("/auditevents").param("principal", "admin")
|
||||||
|
.param("after", "2016-11-01T10:00:00+0000")
|
||||||
|
.param("type", "AUTHENTICATION_SUCCESS")
|
||||||
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andDo(document("auditevents/filter-by-principal-and-type"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void endpoints() throws Exception {
|
public void endpoints() throws Exception {
|
||||||
final File docs = new File("src/main/asciidoc");
|
final File docs = new File("src/main/asciidoc");
|
||||||
|
|
|
@ -16,21 +16,33 @@
|
||||||
|
|
||||||
package org.springframework.boot.actuate.hypermedia;
|
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.GStringTemplateEngine;
|
||||||
import groovy.text.TemplateEngine;
|
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.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.actuate.endpoint.EnvironmentEndpoint;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
|
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
|
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.lang.UsesJava8;
|
||||||
|
|
||||||
// Flyway must go first
|
// Flyway must go first
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@Import({ FlywayAutoConfiguration.class, LiquibaseAutoConfiguration.class })
|
@Import({ FlywayAutoConfiguration.class, LiquibaseAutoConfiguration.class })
|
||||||
public class SpringBootHypermediaApplication {
|
public class SpringBootHypermediaApplication implements CommandLineRunner {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuditEventRepository auditEventRepository;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public TemplateEngine groovyTemplateEngine() {
|
public TemplateEngine groovyTemplateEngine() {
|
||||||
|
@ -46,4 +58,18 @@ public class SpringBootHypermediaApplication {
|
||||||
SpringApplication.run(SpringBootHypermediaApplication.class, 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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@UsesJava8
|
||||||
|
private AuditEvent createEvent(String instant, String principal, String type) {
|
||||||
|
return new AuditEvent(Date.from(Instant.parse(instant)), principal, type,
|
||||||
|
Collections.<String, Object>emptyMap());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,11 @@ import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||||
|
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.context.ApplicationEventPublisherAware;
|
import org.springframework.context.ApplicationEventPublisherAware;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
@ -39,6 +44,7 @@ import org.springframework.util.Assert;
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
* @see AuditEventRepository
|
* @see AuditEventRepository
|
||||||
*/
|
*/
|
||||||
|
@JsonInclude(Include.NON_EMPTY)
|
||||||
public class AuditEvent implements Serializable {
|
public class AuditEvent implements Serializable {
|
||||||
|
|
||||||
private final Date timestamp;
|
private final Date timestamp;
|
||||||
|
@ -106,6 +112,7 @@ public class AuditEvent implements Serializable {
|
||||||
* Returns the date/time that the even was logged.
|
* Returns the date/time that the even was logged.
|
||||||
* @return the time stamp
|
* @return the time stamp
|
||||||
*/
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssZ")
|
||||||
public Date getTimestamp() {
|
public Date getTimestamp() {
|
||||||
return this.timestamp;
|
return this.timestamp;
|
||||||
}
|
}
|
||||||
|
@ -130,6 +137,7 @@ public class AuditEvent implements Serializable {
|
||||||
* Returns the event data.
|
* Returns the event data.
|
||||||
* @return the event data
|
* @return the event data
|
||||||
*/
|
*/
|
||||||
|
@JsonAnyGetter
|
||||||
public Map<String, Object> getData() {
|
public Map<String, Object> getData() {
|
||||||
return this.data;
|
return this.data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,13 +21,17 @@ import javax.management.MBeanServer;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
|
import org.springframework.boot.actuate.audit.AuditEventRepository;
|
||||||
import org.springframework.boot.actuate.autoconfigure.EndpointMBeanExportAutoConfiguration.JmxEnabledCondition;
|
import org.springframework.boot.actuate.autoconfigure.EndpointMBeanExportAutoConfiguration.JmxEnabledCondition;
|
||||||
|
import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||||
|
import org.springframework.boot.actuate.endpoint.jmx.AuditEventsJmxEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter;
|
import org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
|
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
|
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
|
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
|
||||||
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
||||||
|
@ -83,6 +87,14 @@ public class EndpointMBeanExportAutoConfiguration {
|
||||||
return new JmxAutoConfiguration().mbeanServer();
|
return new JmxAutoConfiguration().mbeanServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnBean(AuditEventRepository.class)
|
||||||
|
@ConditionalOnEnabledEndpoint("auditevents")
|
||||||
|
public AuditEventsJmxEndpoint abstractEndpointMBean(
|
||||||
|
AuditEventRepository auditEventRepository) {
|
||||||
|
return new AuditEventsJmxEndpoint(this.objectMapper, auditEventRepository);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Condition to check that spring.jmx and endpoints.jmx are enabled.
|
* Condition to check that spring.jmx and endpoints.jmx are enabled.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
|
import org.springframework.boot.actuate.audit.AuditEventRepository;
|
||||||
import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint;
|
import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint;
|
import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint;
|
||||||
|
@ -28,6 +29,7 @@ import org.springframework.boot.actuate.endpoint.HealthEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.LoggersEndpoint;
|
import org.springframework.boot.actuate.endpoint.LoggersEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.MetricsEndpoint;
|
import org.springframework.boot.actuate.endpoint.MetricsEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
||||||
|
import org.springframework.boot.actuate.endpoint.mvc.AuditEventsMvcEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping;
|
import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping;
|
||||||
import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMappingCustomizer;
|
import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMappingCustomizer;
|
||||||
import org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint;
|
import org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint;
|
||||||
|
@ -62,6 +64,7 @@ import org.springframework.web.cors.CorsConfiguration;
|
||||||
*
|
*
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
* @author Ben Hale
|
* @author Ben Hale
|
||||||
|
* @author Vedran Pavic
|
||||||
* @since 1.3.0
|
* @since 1.3.0
|
||||||
*/
|
*/
|
||||||
@ManagementContextConfiguration
|
@ManagementContextConfiguration
|
||||||
|
@ -195,6 +198,14 @@ public class EndpointWebMvcManagementContextConfiguration {
|
||||||
return new ShutdownMvcEndpoint(delegate);
|
return new ShutdownMvcEndpoint(delegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnBean(AuditEventRepository.class)
|
||||||
|
@ConditionalOnEnabledEndpoint("auditevents")
|
||||||
|
public AuditEventsMvcEndpoint auditEventMvcEndpoint(
|
||||||
|
AuditEventRepository auditEventRepository) {
|
||||||
|
return new AuditEventsMvcEndpoint(auditEventRepository);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isHealthSecure() {
|
private boolean isHealthSecure() {
|
||||||
return isSpringSecurityAvailable()
|
return isSpringSecurityAvailable()
|
||||||
&& this.managementServerProperties.getSecurity().isEnabled();
|
&& this.managementServerProperties.getSecurity().isEnabled();
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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.jmx;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||||
|
import org.springframework.boot.actuate.endpoint.EndpointProperties;
|
||||||
|
import org.springframework.context.EnvironmentAware;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.jmx.export.annotation.ManagedResource;
|
||||||
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract base class for {@link JmxEndpoint} implementations without a backing
|
||||||
|
* {@link Endpoint}.
|
||||||
|
*
|
||||||
|
* @author Vedran Pavic
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
@ManagedResource
|
||||||
|
public abstract class AbstractJmxEndpoint implements JmxEndpoint, EnvironmentAware {
|
||||||
|
|
||||||
|
private final DataConverter dataConverter;
|
||||||
|
|
||||||
|
private Environment environment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable the endpoint.
|
||||||
|
*/
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
public AbstractJmxEndpoint(ObjectMapper objectMapper) {
|
||||||
|
this.dataConverter = new DataConverter(objectMapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEnvironment(Environment environment) {
|
||||||
|
this.environment = environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final Environment getEnvironment() {
|
||||||
|
return this.environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return EndpointProperties.isEnabled(this.environment, this.enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(Boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentity() {
|
||||||
|
return ObjectUtils.getIdentityHexString(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public Class<? extends Endpoint> getEndpointType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the given data into JSON.
|
||||||
|
* @param data the source data
|
||||||
|
* @return the JSON representation
|
||||||
|
*/
|
||||||
|
protected Object convert(Object data) {
|
||||||
|
return this.dataConverter.convert(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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.jmx;
|
||||||
|
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.audit.AuditEvent;
|
||||||
|
import org.springframework.boot.actuate.audit.AuditEventRepository;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.jmx.export.annotation.ManagedOperation;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link JmxEndpoint} for {@link AuditEventRepository}.
|
||||||
|
*
|
||||||
|
* @author Vedran Pavic
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
@ConfigurationProperties(prefix = "endpoints.auditevents")
|
||||||
|
public class AuditEventsJmxEndpoint extends AbstractJmxEndpoint {
|
||||||
|
|
||||||
|
private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssZ";
|
||||||
|
|
||||||
|
private final AuditEventRepository auditEventRepository;
|
||||||
|
|
||||||
|
public AuditEventsJmxEndpoint(ObjectMapper objectMapper,
|
||||||
|
AuditEventRepository auditEventRepository) {
|
||||||
|
super(objectMapper);
|
||||||
|
Assert.notNull(auditEventRepository, "AuditEventRepository must not be null");
|
||||||
|
this.auditEventRepository = auditEventRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManagedOperation(description = "Retrieves a list of audit events meeting the given criteria")
|
||||||
|
public Object getData(String dateAfter) {
|
||||||
|
List<AuditEvent> auditEvents = this.auditEventRepository
|
||||||
|
.find(parseDate(dateAfter));
|
||||||
|
return convert(auditEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManagedOperation(description = "Retrieves a list of audit events meeting the given criteria")
|
||||||
|
public Object getData(String dateAfter, String principal) {
|
||||||
|
List<AuditEvent> auditEvents = this.auditEventRepository.find(principal,
|
||||||
|
parseDate(dateAfter));
|
||||||
|
return convert(auditEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManagedOperation(description = "Retrieves a list of audit events meeting the given criteria")
|
||||||
|
public Object getData(String principal, String dateAfter, String type) {
|
||||||
|
List<AuditEvent> auditEvents = this.auditEventRepository.find(principal,
|
||||||
|
parseDate(dateAfter), type);
|
||||||
|
return convert(auditEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Date parseDate(String date) {
|
||||||
|
try {
|
||||||
|
return new SimpleDateFormat(DATE_FORMAT).parse(date);
|
||||||
|
}
|
||||||
|
catch (ParseException ex) {
|
||||||
|
throw new IllegalArgumentException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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.jmx;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JavaType;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal converter that uses an {@link ObjectMapper} to convert to JSON.
|
||||||
|
*
|
||||||
|
* @author Christian Dupuis
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
class DataConverter {
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
private final JavaType listObject;
|
||||||
|
|
||||||
|
private final JavaType mapStringObject;
|
||||||
|
|
||||||
|
DataConverter(ObjectMapper objectMapper) {
|
||||||
|
this.objectMapper = (objectMapper == null ? new ObjectMapper() : objectMapper);
|
||||||
|
this.listObject = this.objectMapper.getTypeFactory()
|
||||||
|
.constructParametricType(List.class, Object.class);
|
||||||
|
this.mapStringObject = this.objectMapper.getTypeFactory()
|
||||||
|
.constructParametricType(Map.class, String.class, Object.class);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object convert(Object data) {
|
||||||
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (data instanceof String) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
if (data.getClass().isArray() || data instanceof List) {
|
||||||
|
return this.objectMapper.convertValue(data, this.listObject);
|
||||||
|
}
|
||||||
|
return this.objectMapper.convertValue(data, this.mapStringObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,10 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.boot.actuate.endpoint.jmx;
|
package org.springframework.boot.actuate.endpoint.jmx;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JavaType;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||||
|
@ -27,24 +23,25 @@ import org.springframework.jmx.export.annotation.ManagedAttribute;
|
||||||
import org.springframework.jmx.export.annotation.ManagedResource;
|
import org.springframework.jmx.export.annotation.ManagedResource;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple wrapper around {@link Endpoint} implementations to enable JMX export.
|
* Base for adapters that convert {@link Endpoint} implementations to {@link JmxEndpoint}.
|
||||||
*
|
*
|
||||||
* @author Christian Dupuis
|
* @author Christian Dupuis
|
||||||
* @author Andy Wilkinson
|
* @author Andy Wilkinson
|
||||||
|
* @author Vedran Pavic
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @see JmxEndpoint
|
||||||
|
* @see DataEndpointMBean
|
||||||
*/
|
*/
|
||||||
@ManagedResource
|
@ManagedResource
|
||||||
public class EndpointMBean {
|
public abstract class EndpointMBean implements JmxEndpoint {
|
||||||
|
|
||||||
|
private final DataConverter dataConverter;
|
||||||
|
|
||||||
private final Endpoint<?> endpoint;
|
private final Endpoint<?> endpoint;
|
||||||
|
|
||||||
private final ObjectMapper mapper;
|
|
||||||
|
|
||||||
private final JavaType listObject;
|
|
||||||
|
|
||||||
private final JavaType mapStringObject;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link EndpointMBean} instance.
|
* Create a new {@link EndpointMBean} instance.
|
||||||
* @param beanName the bean name
|
* @param beanName the bean name
|
||||||
|
@ -53,20 +50,20 @@ public class EndpointMBean {
|
||||||
*/
|
*/
|
||||||
public EndpointMBean(String beanName, Endpoint<?> endpoint,
|
public EndpointMBean(String beanName, Endpoint<?> endpoint,
|
||||||
ObjectMapper objectMapper) {
|
ObjectMapper objectMapper) {
|
||||||
|
this.dataConverter = new DataConverter(objectMapper);
|
||||||
Assert.notNull(beanName, "BeanName must not be null");
|
Assert.notNull(beanName, "BeanName must not be null");
|
||||||
Assert.notNull(endpoint, "Endpoint must not be null");
|
Assert.notNull(endpoint, "Endpoint must not be null");
|
||||||
Assert.notNull(objectMapper, "ObjectMapper must not be null");
|
|
||||||
this.endpoint = endpoint;
|
this.endpoint = endpoint;
|
||||||
this.mapper = objectMapper;
|
|
||||||
this.listObject = objectMapper.getTypeFactory()
|
|
||||||
.constructParametricType(List.class, Object.class);
|
|
||||||
this.mapStringObject = objectMapper.getTypeFactory()
|
|
||||||
.constructParametricType(Map.class, String.class, Object.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ManagedAttribute(description = "Returns the class of the underlying endpoint")
|
@ManagedAttribute(description = "Returns the class of the underlying endpoint")
|
||||||
public String getEndpointClass() {
|
public String getEndpointClass() {
|
||||||
return ClassUtils.getQualifiedName(this.endpoint.getClass());
|
return ClassUtils.getQualifiedName(getEndpointType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return this.endpoint.isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ManagedAttribute(description = "Indicates whether the underlying endpoint exposes sensitive information")
|
@ManagedAttribute(description = "Indicates whether the underlying endpoint exposes sensitive information")
|
||||||
|
@ -74,21 +71,28 @@ public class EndpointMBean {
|
||||||
return this.endpoint.isSensitive();
|
return this.endpoint.isSensitive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentity() {
|
||||||
|
return ObjectUtils.getIdentityHexString(getEndpoint());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public Class<? extends Endpoint> getEndpointType() {
|
||||||
|
return getEndpoint().getClass();
|
||||||
|
}
|
||||||
|
|
||||||
public Endpoint<?> getEndpoint() {
|
public Endpoint<?> getEndpoint() {
|
||||||
return this.endpoint;
|
return this.endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Object convert(Object result) {
|
/**
|
||||||
if (result == null) {
|
* Convert the given data into JSON.
|
||||||
return null;
|
* @param data the source data
|
||||||
}
|
* @return the JSON representation
|
||||||
if (result instanceof String) {
|
*/
|
||||||
return result;
|
protected Object convert(Object data) {
|
||||||
}
|
return this.dataConverter.convert(data);
|
||||||
if (result.getClass().isArray() || result instanceof List) {
|
|
||||||
return this.mapper.convertValue(result, this.listObject);
|
|
||||||
}
|
|
||||||
return this.mapper.convertValue(result, this.mapStringObject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ import org.springframework.boot.actuate.endpoint.LoggersEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.ApplicationContextAware;
|
import org.springframework.context.ApplicationContextAware;
|
||||||
import org.springframework.context.ApplicationListener;
|
|
||||||
import org.springframework.context.SmartLifecycle;
|
import org.springframework.context.SmartLifecycle;
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.jmx.export.MBeanExportException;
|
import org.springframework.jmx.export.MBeanExportException;
|
||||||
|
@ -53,7 +52,7 @@ import org.springframework.jmx.support.ObjectNameManager;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ApplicationListener} that registers all known {@link Endpoint}s with an
|
* {@link SmartLifecycle} bean that registers all known {@link Endpoint}s with an
|
||||||
* {@link MBeanServer} using the {@link MBeanExporter} located from the application
|
* {@link MBeanServer} using the {@link MBeanExporter} located from the application
|
||||||
* context.
|
* context.
|
||||||
*
|
*
|
||||||
|
@ -79,7 +78,7 @@ public class EndpointMBeanExporter extends MBeanExporter
|
||||||
private final MetadataNamingStrategy defaultNamingStrategy = new MetadataNamingStrategy(
|
private final MetadataNamingStrategy defaultNamingStrategy = new MetadataNamingStrategy(
|
||||||
this.attributeSource);
|
this.attributeSource);
|
||||||
|
|
||||||
private final Set<Endpoint<?>> registeredEndpoints = new HashSet<Endpoint<?>>();
|
private final Set<Class<?>> registeredEndpoints = new HashSet<Class<?>>();
|
||||||
|
|
||||||
private volatile boolean autoStartup = true;
|
private volatile boolean autoStartup = true;
|
||||||
|
|
||||||
|
@ -156,39 +155,88 @@ public class EndpointMBeanExporter extends MBeanExporter
|
||||||
locateAndRegisterEndpoints();
|
locateAndRegisterEndpoints();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "rawtypes" })
|
|
||||||
protected void locateAndRegisterEndpoints() {
|
protected void locateAndRegisterEndpoints() {
|
||||||
Map<String, Endpoint> endpoints = this.beanFactory.getBeansOfType(Endpoint.class);
|
registerJmxEndpoints(this.beanFactory.getBeansOfType(JmxEndpoint.class));
|
||||||
for (Map.Entry<String, Endpoint> endpointEntry : endpoints.entrySet()) {
|
registerEndpoints(this.beanFactory.getBeansOfType(Endpoint.class));
|
||||||
if (!this.registeredEndpoints.contains(endpointEntry.getValue())
|
}
|
||||||
&& endpointEntry.getValue().isEnabled()) {
|
|
||||||
registerEndpoint(endpointEntry.getKey(), endpointEntry.getValue());
|
private void registerJmxEndpoints(Map<String, JmxEndpoint> endpoints) {
|
||||||
this.registeredEndpoints.add(endpointEntry.getValue());
|
for (Map.Entry<String, JmxEndpoint> entry : endpoints.entrySet()) {
|
||||||
|
String name = entry.getKey();
|
||||||
|
JmxEndpoint endpoint = entry.getValue();
|
||||||
|
Class<?> type = (endpoint.getEndpointType() != null
|
||||||
|
? endpoint.getEndpointType() : endpoint.getClass());
|
||||||
|
if (!this.registeredEndpoints.contains(type) && endpoint.isEnabled()) {
|
||||||
|
try {
|
||||||
|
registerBeanNameOrInstance(endpoint, name);
|
||||||
|
}
|
||||||
|
catch (MBeanExportException ex) {
|
||||||
|
logger.error("Could not register JmxEndpoint [" + name + "]", ex);
|
||||||
|
}
|
||||||
|
this.registeredEndpoints.add(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
private void registerEndpoints(Map<String, Endpoint> endpoints) {
|
||||||
|
for (Map.Entry<String, Endpoint> entry : endpoints.entrySet()) {
|
||||||
|
String name = entry.getKey();
|
||||||
|
Endpoint endpoint = entry.getValue();
|
||||||
|
Class<?> type = endpoint.getClass();
|
||||||
|
if (!this.registeredEndpoints.contains(type) && endpoint.isEnabled()) {
|
||||||
|
registerEndpoint(name, endpoint);
|
||||||
|
this.registeredEndpoints.add(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a regular {@link Endpoint} with the {@link MBeanServer}.
|
||||||
|
* @param beanName the bean name
|
||||||
|
* @param endpoint the endpoint to register
|
||||||
|
* @deprecated as of 1.5 in favor of direct {@link JmxEndpoint} registration or
|
||||||
|
* {@link #adaptEndpoint(String, Endpoint)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
protected void registerEndpoint(String beanName, Endpoint<?> endpoint) {
|
protected void registerEndpoint(String beanName, Endpoint<?> endpoint) {
|
||||||
@SuppressWarnings("rawtypes")
|
Class<?> type = endpoint.getClass();
|
||||||
Class<? extends Endpoint> type = endpoint.getClass();
|
if (isAnnotatedWithManagedResource(type) || (type.isMemberClass()
|
||||||
if (AnnotationUtils.findAnnotation(type, ManagedResource.class) != null) {
|
&& isAnnotatedWithManagedResource(type.getEnclosingClass()))) {
|
||||||
// Already managed
|
// Endpoint is directly managed
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (type.isMemberClass()
|
|
||||||
&& AnnotationUtils.findAnnotation(type.getEnclosingClass(),
|
|
||||||
ManagedResource.class) != null) {
|
|
||||||
// Nested class with @ManagedResource in parent
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
JmxEndpoint jmxEndpoint = adaptEndpoint(beanName, endpoint);
|
||||||
try {
|
try {
|
||||||
registerBeanNameOrInstance(getEndpointMBean(beanName, endpoint), beanName);
|
registerBeanNameOrInstance(jmxEndpoint, beanName);
|
||||||
}
|
}
|
||||||
catch (MBeanExportException ex) {
|
catch (MBeanExportException ex) {
|
||||||
logger.error("Could not register MBean for endpoint [" + beanName + "]", ex);
|
logger.error("Could not register MBean for endpoint [" + beanName + "]", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isAnnotatedWithManagedResource(Class<?> type) {
|
||||||
|
return AnnotationUtils.findAnnotation(type, ManagedResource.class) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapt the given {@link Endpoint} to a {@link JmxEndpoint}.
|
||||||
|
* @param beanName the bean name
|
||||||
|
* @param endpoint the endpoint to adapt
|
||||||
|
* @return an adapted endpoint
|
||||||
|
*/
|
||||||
|
protected JmxEndpoint adaptEndpoint(String beanName, Endpoint<?> endpoint) {
|
||||||
|
return getEndpointMBean(beanName, endpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a {@link EndpointMBean} for the specified {@link Endpoint}.
|
||||||
|
* @param beanName the bean name
|
||||||
|
* @param endpoint the endpoint
|
||||||
|
* @return an {@link EndpointMBean}
|
||||||
|
* @deprecated as of 1.5 in favor of {@link #adaptEndpoint(String, Endpoint)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
protected EndpointMBean getEndpointMBean(String beanName, Endpoint<?> endpoint) {
|
protected EndpointMBean getEndpointMBean(String beanName, Endpoint<?> endpoint) {
|
||||||
if (endpoint instanceof ShutdownEndpoint) {
|
if (endpoint instanceof ShutdownEndpoint) {
|
||||||
return new ShutdownEndpointMBean(beanName, endpoint, this.objectMapper);
|
return new ShutdownEndpointMBean(beanName, endpoint, this.objectMapper);
|
||||||
|
@ -205,27 +253,29 @@ public class EndpointMBeanExporter extends MBeanExporter
|
||||||
if (bean instanceof SelfNaming) {
|
if (bean instanceof SelfNaming) {
|
||||||
return ((SelfNaming) bean).getObjectName();
|
return ((SelfNaming) bean).getObjectName();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bean instanceof EndpointMBean) {
|
if (bean instanceof EndpointMBean) {
|
||||||
StringBuilder builder = new StringBuilder();
|
return getObjectName((EndpointMBean) bean, beanKey);
|
||||||
builder.append(this.domain);
|
|
||||||
builder.append(":type=Endpoint");
|
|
||||||
builder.append(",name=" + beanKey);
|
|
||||||
if (parentContextContainsSameBean(this.applicationContext, beanKey)) {
|
|
||||||
builder.append(",context="
|
|
||||||
+ ObjectUtils.getIdentityHexString(this.applicationContext));
|
|
||||||
}
|
|
||||||
if (this.ensureUniqueRuntimeObjectNames) {
|
|
||||||
builder.append(",identity=" + ObjectUtils
|
|
||||||
.getIdentityHexString(((EndpointMBean) bean).getEndpoint()));
|
|
||||||
}
|
|
||||||
builder.append(getStaticNames());
|
|
||||||
return ObjectNameManager.getInstance(builder.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.defaultNamingStrategy.getObjectName(bean, beanKey);
|
return this.defaultNamingStrategy.getObjectName(bean, beanKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ObjectName getObjectName(JmxEndpoint jmxEndpoint, String beanKey)
|
||||||
|
throws MalformedObjectNameException {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append(this.domain);
|
||||||
|
builder.append(":type=Endpoint");
|
||||||
|
builder.append(",name=" + beanKey);
|
||||||
|
if (parentContextContainsSameBean(this.applicationContext, beanKey)) {
|
||||||
|
builder.append(",context="
|
||||||
|
+ ObjectUtils.getIdentityHexString(this.applicationContext));
|
||||||
|
}
|
||||||
|
if (this.ensureUniqueRuntimeObjectNames) {
|
||||||
|
builder.append(",identity=" + jmxEndpoint.getIdentity());
|
||||||
|
}
|
||||||
|
builder.append(getStaticNames());
|
||||||
|
return ObjectNameManager.getInstance(builder.toString());
|
||||||
|
}
|
||||||
|
|
||||||
private boolean parentContextContainsSameBean(ApplicationContext applicationContext,
|
private boolean parentContextContainsSameBean(ApplicationContext applicationContext,
|
||||||
String beanKey) {
|
String beanKey) {
|
||||||
if (applicationContext.getParent() != null) {
|
if (applicationContext.getParent() != null) {
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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.jmx;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A strategy for the JMX layer on top of an {@link Endpoint}. Implementations are allowed
|
||||||
|
* to use {@code @ManagedAttribute} and the full Spring JMX machinery. Implementations may
|
||||||
|
* be backed by an actual {@link Endpoint} or may be specifically designed for JMX only.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @since 1.5.0
|
||||||
|
* @see EndpointMBean
|
||||||
|
* @see AbstractJmxEndpoint
|
||||||
|
*/
|
||||||
|
public interface JmxEndpoint {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return if the JMX endpoint is enabled.
|
||||||
|
* @return if the endpoint is enabled
|
||||||
|
*/
|
||||||
|
boolean isEnabled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the MBean identity for this endpoint.
|
||||||
|
* @return the MBean identity.
|
||||||
|
*/
|
||||||
|
String getIdentity();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the type of {@link Endpoint} exposed, or {@code null} if this
|
||||||
|
* {@link JmxEndpoint} exposes information that cannot be represented as a traditional
|
||||||
|
* {@link Endpoint}.
|
||||||
|
* @return the endpoint type
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
Class<? extends Endpoint> getEndpointType();
|
||||||
|
|
||||||
|
}
|
|
@ -26,7 +26,7 @@ import org.springframework.util.Assert;
|
||||||
* @author Madhura Bhave
|
* @author Madhura Bhave
|
||||||
* @since 1.5.0
|
* @since 1.5.0
|
||||||
*/
|
*/
|
||||||
public class AbstractNamedMvcEndpoint extends AbstractMvcEndpoint
|
public abstract class AbstractNamedMvcEndpoint extends AbstractMvcEndpoint
|
||||||
implements NamedMvcEndpoint {
|
implements NamedMvcEndpoint {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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 java.util.Date;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.audit.AuditEvent;
|
||||||
|
import org.springframework.boot.actuate.audit.AuditEventRepository;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link MvcEndpoint} to expose {@link AuditEvent}s.
|
||||||
|
*
|
||||||
|
* @author Vedran Pavic
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
@ConfigurationProperties(prefix = "endpoints.auditevents")
|
||||||
|
public class AuditEventsMvcEndpoint extends AbstractNamedMvcEndpoint {
|
||||||
|
|
||||||
|
private final AuditEventRepository auditEventRepository;
|
||||||
|
|
||||||
|
public AuditEventsMvcEndpoint(AuditEventRepository auditEventRepository) {
|
||||||
|
super("auditevents", "/auditevents", true);
|
||||||
|
Assert.notNull(auditEventRepository, "AuditEventRepository must not be null");
|
||||||
|
this.auditEventRepository = auditEventRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
@ResponseBody
|
||||||
|
public ResponseEntity<?> findByPrincipalAndAfterAndType(
|
||||||
|
@RequestParam(required = false) String principal,
|
||||||
|
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssZ") Date after,
|
||||||
|
@RequestParam(required = false) String type) {
|
||||||
|
if (!isEnabled()) {
|
||||||
|
return DISABLED_RESPONSE;
|
||||||
|
}
|
||||||
|
Map<Object, Object> result = new LinkedHashMap<Object, Object>();
|
||||||
|
result.put("events", this.auditEventRepository.find(principal, after, type));
|
||||||
|
return ResponseEntity.ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -103,14 +103,13 @@ public class EndpointMvcIntegrationTests {
|
||||||
@MinimalWebConfiguration
|
@MinimalWebConfiguration
|
||||||
@Import({ ManagementServerPropertiesAutoConfiguration.class,
|
@Import({ ManagementServerPropertiesAutoConfiguration.class,
|
||||||
JacksonAutoConfiguration.class, EndpointAutoConfiguration.class,
|
JacksonAutoConfiguration.class, EndpointAutoConfiguration.class,
|
||||||
EndpointWebMvcAutoConfiguration.class })
|
EndpointWebMvcAutoConfiguration.class, AuditAutoConfiguration.class })
|
||||||
@RestController
|
@RestController
|
||||||
protected static class Application {
|
protected static class Application {
|
||||||
|
|
||||||
private final List<HttpMessageConverter<?>> converters;
|
private final List<HttpMessageConverter<?>> converters;
|
||||||
|
|
||||||
public Application(
|
public Application(ObjectProvider<List<HttpMessageConverter<?>>> converters) {
|
||||||
ObjectProvider<List<HttpMessageConverter<?>>> converters) {
|
|
||||||
this.converters = converters.getIfAvailable();
|
this.converters = converters.getIfAvailable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -364,7 +364,7 @@ public class EndpointWebMvcAutoConfigurationTests {
|
||||||
EmbeddedServletContainerAutoConfiguration.class,
|
EmbeddedServletContainerAutoConfiguration.class,
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
HttpMessageConvertersAutoConfiguration.class,
|
||||||
DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||||
EndpointWebMvcAutoConfiguration.class);
|
EndpointWebMvcAutoConfiguration.class, AuditAutoConfiguration.class);
|
||||||
this.applicationContext.refresh();
|
this.applicationContext.refresh();
|
||||||
assertContent("/controller", ports.get().server, "controlleroutput");
|
assertContent("/controller", ports.get().server, "controlleroutput");
|
||||||
assertContent("/test/endpoint", ports.get().server, "endpointoutput");
|
assertContent("/test/endpoint", ports.get().server, "endpointoutput");
|
||||||
|
@ -381,7 +381,7 @@ public class EndpointWebMvcAutoConfigurationTests {
|
||||||
EmbeddedServletContainerAutoConfiguration.class,
|
EmbeddedServletContainerAutoConfiguration.class,
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
HttpMessageConvertersAutoConfiguration.class,
|
||||||
DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||||
EndpointWebMvcAutoConfiguration.class);
|
EndpointWebMvcAutoConfiguration.class, AuditAutoConfiguration.class);
|
||||||
this.applicationContext.refresh();
|
this.applicationContext.refresh();
|
||||||
assertContent("/controller", ports.get().server, "controlleroutput");
|
assertContent("/controller", ports.get().server, "controlleroutput");
|
||||||
ServerProperties serverProperties = this.applicationContext
|
ServerProperties serverProperties = this.applicationContext
|
||||||
|
@ -440,9 +440,9 @@ public class EndpointWebMvcAutoConfigurationTests {
|
||||||
BaseConfiguration.class, ServerPortConfig.class,
|
BaseConfiguration.class, ServerPortConfig.class,
|
||||||
EndpointWebMvcAutoConfiguration.class);
|
EndpointWebMvcAutoConfiguration.class);
|
||||||
this.applicationContext.refresh();
|
this.applicationContext.refresh();
|
||||||
// /health, /metrics, /loggers, /env, /actuator, /heapdump (/shutdown is disabled
|
// /health, /metrics, /loggers, /env, /actuator, /heapdump, /auditevents
|
||||||
// by default)
|
// (/shutdown is disabled by default)
|
||||||
assertThat(this.applicationContext.getBeansOfType(MvcEndpoint.class)).hasSize(6);
|
assertThat(this.applicationContext.getBeansOfType(MvcEndpoint.class)).hasSize(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -734,7 +734,7 @@ public class EndpointWebMvcAutoConfigurationTests {
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
HttpMessageConvertersAutoConfiguration.class,
|
||||||
DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||||
ManagementServerPropertiesAutoConfiguration.class,
|
ManagementServerPropertiesAutoConfiguration.class,
|
||||||
ServerPropertiesAutoConfiguration.class })
|
ServerPropertiesAutoConfiguration.class, AuditAutoConfiguration.class })
|
||||||
protected static class BaseConfiguration {
|
protected static class BaseConfiguration {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ public class HealthMvcEndpointAutoConfigurationTests {
|
||||||
@Configuration
|
@Configuration
|
||||||
@ImportAutoConfiguration({ SecurityAutoConfiguration.class,
|
@ImportAutoConfiguration({ SecurityAutoConfiguration.class,
|
||||||
JacksonAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
JacksonAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
HttpMessageConvertersAutoConfiguration.class, AuditAutoConfiguration.class,
|
||||||
ManagementServerPropertiesAutoConfiguration.class,
|
ManagementServerPropertiesAutoConfiguration.class,
|
||||||
EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class })
|
EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class })
|
||||||
static class TestConfiguration {
|
static class TestConfiguration {
|
||||||
|
|
|
@ -91,7 +91,7 @@ public class ManagementWebSecurityAutoConfigurationTests {
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
HttpMessageConvertersAutoConfiguration.class,
|
||||||
EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class,
|
EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class,
|
||||||
ManagementServerPropertiesAutoConfiguration.class,
|
ManagementServerPropertiesAutoConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class);
|
PropertyPlaceholderAutoConfiguration.class, AuditAutoConfiguration.class);
|
||||||
EnvironmentTestUtils.addEnvironment(this.context, "security.basic.enabled:false");
|
EnvironmentTestUtils.addEnvironment(this.context, "security.basic.enabled:false");
|
||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
assertThat(this.context.getBean(AuthenticationManagerBuilder.class)).isNotNull();
|
assertThat(this.context.getBean(AuthenticationManagerBuilder.class)).isNotNull();
|
||||||
|
@ -202,8 +202,8 @@ public class ManagementWebSecurityAutoConfigurationTests {
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
HttpMessageConvertersAutoConfiguration.class,
|
||||||
EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class,
|
EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class,
|
||||||
ManagementServerPropertiesAutoConfiguration.class,
|
ManagementServerPropertiesAutoConfiguration.class,
|
||||||
WebMvcAutoConfiguration.class,
|
WebMvcAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class);
|
AuditAutoConfiguration.class);
|
||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
|
|
||||||
Filter filter = this.context.getBean("springSecurityFilterChain", Filter.class);
|
Filter filter = this.context.getBean("springSecurityFilterChain", Filter.class);
|
||||||
|
@ -265,7 +265,7 @@ public class ManagementWebSecurityAutoConfigurationTests {
|
||||||
JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class,
|
JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class,
|
||||||
EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class,
|
EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class,
|
||||||
ManagementServerPropertiesAutoConfiguration.class,
|
ManagementServerPropertiesAutoConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
PropertyPlaceholderAutoConfiguration.class, AuditAutoConfiguration.class,
|
||||||
FallbackWebSecurityAutoConfiguration.class })
|
FallbackWebSecurityAutoConfiguration.class })
|
||||||
static class WebConfiguration {
|
static class WebConfiguration {
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ import org.springframework.context.annotation.Configuration;
|
||||||
HttpMessageConvertersAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
HttpMessageConvertersAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||||
HypermediaAutoConfiguration.class, EndpointAutoConfiguration.class,
|
HypermediaAutoConfiguration.class, EndpointAutoConfiguration.class,
|
||||||
EndpointWebMvcAutoConfiguration.class, ErrorMvcAutoConfiguration.class,
|
EndpointWebMvcAutoConfiguration.class, ErrorMvcAutoConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class })
|
PropertyPlaceholderAutoConfiguration.class, AuditAutoConfiguration.class })
|
||||||
public @interface MinimalActuatorHypermediaApplication {
|
public @interface MinimalActuatorHypermediaApplication {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.springframework.boot.actuate.endpoint.LiquibaseEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.RequestMappingEndpoint;
|
import org.springframework.boot.actuate.endpoint.RequestMappingEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.TraceEndpoint;
|
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.DocsMvcEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;
|
import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;
|
||||||
import org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint;
|
import org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint;
|
||||||
|
@ -85,6 +86,7 @@ public class MvcEndpointPathConfigurationTests {
|
||||||
@Parameters(name = "{0}")
|
@Parameters(name = "{0}")
|
||||||
public static Object[] parameters() {
|
public static Object[] parameters() {
|
||||||
return new Object[] { new Object[] { "actuator", HalJsonMvcEndpoint.class },
|
return new Object[] { new Object[] { "actuator", HalJsonMvcEndpoint.class },
|
||||||
|
new Object[] { "auditevents", AuditEventsMvcEndpoint.class },
|
||||||
new Object[] { "autoconfig", AutoConfigurationReportEndpoint.class },
|
new Object[] { "autoconfig", AutoConfigurationReportEndpoint.class },
|
||||||
new Object[] { "beans", BeansEndpoint.class },
|
new Object[] { "beans", BeansEndpoint.class },
|
||||||
new Object[] { "configprops",
|
new Object[] { "configprops",
|
||||||
|
@ -143,9 +145,8 @@ public class MvcEndpointPathConfigurationTests {
|
||||||
@ImportAutoConfiguration({ EndpointAutoConfiguration.class,
|
@ImportAutoConfiguration({ EndpointAutoConfiguration.class,
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
HttpMessageConvertersAutoConfiguration.class,
|
||||||
ManagementServerPropertiesAutoConfiguration.class,
|
ManagementServerPropertiesAutoConfiguration.class,
|
||||||
ServerPropertiesAutoConfiguration.class,
|
ServerPropertiesAutoConfiguration.class, AuditAutoConfiguration.class,
|
||||||
EndpointWebMvcAutoConfiguration.class, JolokiaAutoConfiguration.class,
|
EndpointWebMvcAutoConfiguration.class, JolokiaAutoConfiguration.class })
|
||||||
EndpointAutoConfiguration.class })
|
|
||||||
|
|
||||||
protected static class TestConfiguration {
|
protected static class TestConfiguration {
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ public class EndpointMBeanExporterTests {
|
||||||
this.context.registerBeanDefinition("endpoint1",
|
this.context.registerBeanDefinition("endpoint1",
|
||||||
new RootBeanDefinition(TestEndpoint.class));
|
new RootBeanDefinition(TestEndpoint.class));
|
||||||
this.context.registerBeanDefinition("endpoint2",
|
this.context.registerBeanDefinition("endpoint2",
|
||||||
new RootBeanDefinition(TestEndpoint.class));
|
new RootBeanDefinition(TestEndpoint2.class));
|
||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
MBeanExporter mbeanExporter = this.context.getBean(EndpointMBeanExporter.class);
|
MBeanExporter mbeanExporter = this.context.getBean(EndpointMBeanExporter.class);
|
||||||
assertThat(mbeanExporter.getServer()
|
assertThat(mbeanExporter.getServer()
|
||||||
|
@ -329,6 +329,10 @@ public class EndpointMBeanExporterTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class TestEndpoint2 extends TestEndpoint {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static class JsonMapConversionEndpoint
|
public static class JsonMapConversionEndpoint
|
||||||
extends AbstractEndpoint<Map<String, Object>> {
|
extends AbstractEndpoint<Map<String, Object>> {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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 java.time.Instant;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.actuate.audit.AuditEvent;
|
||||||
|
import org.springframework.boot.actuate.audit.AuditEventRepository;
|
||||||
|
import org.springframework.boot.actuate.audit.InMemoryAuditEventRepository;
|
||||||
|
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
||||||
|
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.test.context.TestPropertySource;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.hamcrest.CoreMatchers.not;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link AuditEventsMvcEndpoint}.
|
||||||
|
*
|
||||||
|
* @author Vedran Pavic
|
||||||
|
*/
|
||||||
|
@SpringBootTest
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@TestPropertySource(properties = "management.security.enabled=false")
|
||||||
|
public class AuditEventsMvcEndpointTests {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WebApplicationContext context;
|
||||||
|
|
||||||
|
private MockMvc mvc;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
this.context.getBean(AuditEventsMvcEndpoint.class).setEnabled(true);
|
||||||
|
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void invokeWhenDisabledShouldReturnNotFoundStatus() throws Exception {
|
||||||
|
this.context.getBean(AuditEventsMvcEndpoint.class).setEnabled(false);
|
||||||
|
this.mvc.perform(get("/auditevents").param("after", "2016-11-01T10:00:00+0000"))
|
||||||
|
.andExpect(status().isNotFound());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void invokeFilterByDateAfter() throws Exception {
|
||||||
|
this.mvc.perform(get("/auditevents").param("after", "2016-11-01T13:00:00+0000"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().string("{\"events\":[]}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void invokeFilterByPrincipalAndDateAfter() throws Exception {
|
||||||
|
this.mvc.perform(get("/auditevents").param("principal", "user").param("after",
|
||||||
|
"2016-11-01T10:00:00+0000"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().string(
|
||||||
|
containsString("\"principal\":\"user\",\"type\":\"login\"")))
|
||||||
|
.andExpect(content().string(not(containsString("admin"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void invokeFilterByPrincipalAndDateAfterAndType() throws Exception {
|
||||||
|
this.mvc.perform(get("/auditevents").param("principal", "admin")
|
||||||
|
.param("after", "2016-11-01T10:00:00+0000").param("type", "logout"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().string(
|
||||||
|
containsString("\"principal\":\"admin\",\"type\":\"logout\"")))
|
||||||
|
.andExpect(content().string(not(containsString("login"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Import({ JacksonAutoConfiguration.class,
|
||||||
|
HttpMessageConvertersAutoConfiguration.class,
|
||||||
|
EndpointWebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||||
|
ManagementServerPropertiesAutoConfiguration.class })
|
||||||
|
@Configuration
|
||||||
|
protected static class TestConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public AuditEventRepository auditEventsRepository() {
|
||||||
|
AuditEventRepository repository = new InMemoryAuditEventRepository(3);
|
||||||
|
repository.add(createEvent("2016-11-01T11:00:00Z", "admin", "login"));
|
||||||
|
repository.add(createEvent("2016-11-01T12:00:00Z", "admin", "logout"));
|
||||||
|
repository.add(createEvent("2016-11-01T12:00:00Z", "user", "login"));
|
||||||
|
return repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AuditEvent createEvent(String instant, String principal, String type) {
|
||||||
|
return new AuditEvent(Date.from(Instant.parse(instant)), principal, type,
|
||||||
|
Collections.<String, Object>emptyMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint;
|
import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint;
|
||||||
|
@ -107,7 +108,7 @@ public class EnvironmentMvcEndpointTests {
|
||||||
@Configuration
|
@Configuration
|
||||||
@Import({ JacksonAutoConfiguration.class,
|
@Import({ JacksonAutoConfiguration.class,
|
||||||
HttpMessageConvertersAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
HttpMessageConvertersAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||||
EndpointWebMvcAutoConfiguration.class,
|
EndpointWebMvcAutoConfiguration.class, AuditAutoConfiguration.class,
|
||||||
ManagementServerPropertiesAutoConfiguration.class })
|
ManagementServerPropertiesAutoConfiguration.class })
|
||||||
public static class TestConfiguration {
|
public static class TestConfiguration {
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.springframework.test.annotation.DirtiesContext;
|
||||||
import org.springframework.test.context.TestPropertySource;
|
import org.springframework.test.context.TestPropertySource;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
||||||
|
@ -86,7 +87,11 @@ public class HalBrowserMvcEndpointDisabledIntegrationTests {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
path = path.length() > 0 ? path : "/";
|
path = path.length() > 0 ? path : "/";
|
||||||
this.mockMvc.perform(get(path).accept(MediaType.APPLICATION_JSON))
|
MockHttpServletRequestBuilder requestBuilder = get(path);
|
||||||
|
if (endpoint instanceof AuditEventsMvcEndpoint) {
|
||||||
|
requestBuilder.param("after", "2016-01-01T12:00:00+00:00");
|
||||||
|
}
|
||||||
|
this.mockMvc.perform(requestBuilder.accept(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$._links").doesNotExist());
|
.andExpect(jsonPath("$._links").doesNotExist());
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,8 +119,8 @@ public class HalBrowserMvcEndpointVanillaIntegrationTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void endpointsEachHaveSelf() throws Exception {
|
public void endpointsEachHaveSelf() throws Exception {
|
||||||
Set<String> collections = new HashSet<String>(
|
Set<String> collections = new HashSet<String>(Arrays.asList("/trace", "/beans",
|
||||||
Arrays.asList("/trace", "/beans", "/dump", "/heapdump", "/loggers"));
|
"/dump", "/heapdump", "/loggers", "/auditevents"));
|
||||||
for (MvcEndpoint endpoint : this.mvcEndpoints.getEndpoints()) {
|
for (MvcEndpoint endpoint : this.mvcEndpoints.getEndpoints()) {
|
||||||
String path = endpoint.getPath();
|
String path = endpoint.getPath();
|
||||||
if (collections.contains(path)) {
|
if (collections.contains(path)) {
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||||
|
@ -114,7 +115,7 @@ public class HeapdumpMvcEndpointTests {
|
||||||
this.mvc.perform(options("/heapdump")).andExpect(status().isOk());
|
this.mvc.perform(options("/heapdump")).andExpect(status().isOk());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Import({ JacksonAutoConfiguration.class,
|
@Import({ JacksonAutoConfiguration.class, AuditAutoConfiguration.class,
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
HttpMessageConvertersAutoConfiguration.class,
|
||||||
EndpointWebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
EndpointWebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||||
ManagementServerPropertiesAutoConfiguration.class })
|
ManagementServerPropertiesAutoConfiguration.class })
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.endpoint.InfoEndpoint;
|
import org.springframework.boot.actuate.endpoint.InfoEndpoint;
|
||||||
|
@ -79,7 +80,7 @@ public class InfoMvcEndpointTests {
|
||||||
"\"beanName2\":{\"key21\":\"value21\",\"key22\":\"value22\"}")));
|
"\"beanName2\":{\"key21\":\"value21\",\"key22\":\"value22\"}")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Import({ JacksonAutoConfiguration.class,
|
@Import({ JacksonAutoConfiguration.class, AuditAutoConfiguration.class,
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
HttpMessageConvertersAutoConfiguration.class,
|
||||||
EndpointWebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
EndpointWebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||||
ManagementServerPropertiesAutoConfiguration.class })
|
ManagementServerPropertiesAutoConfiguration.class })
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.endpoint.InfoEndpoint;
|
import org.springframework.boot.actuate.endpoint.InfoEndpoint;
|
||||||
|
@ -68,7 +69,7 @@ public class InfoMvcEndpointWithNoInfoContributorsTests {
|
||||||
this.mvc.perform(get("/info")).andExpect(status().isOk());
|
this.mvc.perform(get("/info")).andExpect(status().isOk());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Import({ JacksonAutoConfiguration.class,
|
@Import({ JacksonAutoConfiguration.class, AuditAutoConfiguration.class,
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
HttpMessageConvertersAutoConfiguration.class,
|
||||||
EndpointWebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
EndpointWebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||||
ManagementServerPropertiesAutoConfiguration.class })
|
ManagementServerPropertiesAutoConfiguration.class })
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.JolokiaAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.JolokiaAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
||||||
|
@ -85,7 +86,7 @@ public class JolokiaMvcEndpointContextPathTests {
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableConfigurationProperties
|
@EnableConfigurationProperties
|
||||||
@EnableWebMvc
|
@EnableWebMvc
|
||||||
@Import({ JacksonAutoConfiguration.class,
|
@Import({ JacksonAutoConfiguration.class, AuditAutoConfiguration.class,
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
HttpMessageConvertersAutoConfiguration.class,
|
||||||
EndpointWebMvcAutoConfiguration.class, JolokiaAutoConfiguration.class,
|
EndpointWebMvcAutoConfiguration.class, JolokiaAutoConfiguration.class,
|
||||||
ManagementServerPropertiesAutoConfiguration.class })
|
ManagementServerPropertiesAutoConfiguration.class })
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.JolokiaAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.JolokiaAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
||||||
|
@ -100,7 +101,7 @@ public class JolokiaMvcEndpointIntegrationTests {
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableConfigurationProperties
|
@EnableConfigurationProperties
|
||||||
@EnableWebMvc
|
@EnableWebMvc
|
||||||
@Import({ JacksonAutoConfiguration.class,
|
@Import({ JacksonAutoConfiguration.class, AuditAutoConfiguration.class,
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
HttpMessageConvertersAutoConfiguration.class,
|
||||||
EndpointWebMvcAutoConfiguration.class, JolokiaAutoConfiguration.class,
|
EndpointWebMvcAutoConfiguration.class, JolokiaAutoConfiguration.class,
|
||||||
ManagementServerPropertiesAutoConfiguration.class })
|
ManagementServerPropertiesAutoConfiguration.class })
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.endpoint.MetricsEndpoint;
|
import org.springframework.boot.actuate.endpoint.MetricsEndpoint;
|
||||||
|
@ -129,7 +130,7 @@ public class MetricsMvcEndpointTests {
|
||||||
.andExpect(content().string(containsString("1")));
|
.andExpect(content().string(containsString("1")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Import({ JacksonAutoConfiguration.class,
|
@Import({ JacksonAutoConfiguration.class, AuditAutoConfiguration.class,
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
HttpMessageConvertersAutoConfiguration.class,
|
||||||
EndpointWebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
EndpointWebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||||
ManagementServerPropertiesAutoConfiguration.class })
|
ManagementServerPropertiesAutoConfiguration.class })
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.actuate.endpoint.mvc;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.JolokiaAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.JolokiaAutoConfiguration;
|
||||||
|
@ -56,7 +57,7 @@ public class MvcEndpointCorsIntegrationTests {
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
HttpMessageConvertersAutoConfiguration.class,
|
||||||
EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class,
|
EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class,
|
||||||
ManagementServerPropertiesAutoConfiguration.class,
|
ManagementServerPropertiesAutoConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
PropertyPlaceholderAutoConfiguration.class, AuditAutoConfiguration.class,
|
||||||
JolokiaAutoConfiguration.class, WebMvcAutoConfiguration.class);
|
JolokiaAutoConfiguration.class, WebMvcAutoConfiguration.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.actuate.endpoint.mvc;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
||||||
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
||||||
|
@ -229,9 +230,10 @@ public class MvcEndpointIntegrationTests {
|
||||||
|
|
||||||
@ImportAutoConfiguration({ JacksonAutoConfiguration.class,
|
@ImportAutoConfiguration({ JacksonAutoConfiguration.class,
|
||||||
HttpMessageConvertersAutoConfiguration.class, EndpointAutoConfiguration.class,
|
HttpMessageConvertersAutoConfiguration.class, EndpointAutoConfiguration.class,
|
||||||
EndpointWebMvcAutoConfiguration.class,
|
EndpointWebMvcAutoConfiguration.class, AuditAutoConfiguration.class,
|
||||||
ManagementServerPropertiesAutoConfiguration.class,
|
ManagementServerPropertiesAutoConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class, WebMvcAutoConfiguration.class })
|
PropertyPlaceholderAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||||
|
AuditAutoConfiguration.class })
|
||||||
static class DefaultConfiguration {
|
static class DefaultConfiguration {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -961,6 +961,9 @@ content into your application; rather pick only the properties that you need.
|
||||||
endpoints.actuator.enabled=true # Enable the endpoint.
|
endpoints.actuator.enabled=true # Enable the endpoint.
|
||||||
endpoints.actuator.path= # Endpoint URL path.
|
endpoints.actuator.path= # Endpoint URL path.
|
||||||
endpoints.actuator.sensitive=false # Enable security on the endpoint.
|
endpoints.actuator.sensitive=false # Enable security on the endpoint.
|
||||||
|
endpoints.auditevents.enabled= # Enable the endpoint.
|
||||||
|
endpoints.auditevents.id= # Endpoint identifier.
|
||||||
|
endpoints.auditevents.path= # Endpoint path.
|
||||||
endpoints.autoconfig.enabled= # Enable the endpoint.
|
endpoints.autoconfig.enabled= # Enable the endpoint.
|
||||||
endpoints.autoconfig.id= # Endpoint identifier.
|
endpoints.autoconfig.id= # Endpoint identifier.
|
||||||
endpoints.autoconfig.path= # Endpoint path.
|
endpoints.autoconfig.path= # Endpoint path.
|
||||||
|
|
|
@ -73,6 +73,10 @@ The following technology agnostic endpoints are available:
|
||||||
HATEOAS to be on the classpath.
|
HATEOAS to be on the classpath.
|
||||||
|true
|
|true
|
||||||
|
|
||||||
|
|`auditevents`
|
||||||
|
|Exposes audit events information for the current application.
|
||||||
|
|true
|
||||||
|
|
||||||
|`autoconfig`
|
|`autoconfig`
|
||||||
|Displays an auto-configuration report showing all auto-configuration candidates and the
|
|Displays an auto-configuration report showing all auto-configuration candidates and the
|
||||||
reason why they '`were`' or '`were not`' applied.
|
reason why they '`were`' or '`were not`' applied.
|
||||||
|
|
Loading…
Reference in New Issue