From 849baa4c02db43cc8bbcd00b8aed37d359e84bb3 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 18 Jan 2018 10:16:56 +0000 Subject: [PATCH] Do not require after in audit events endpoint Closes gh-11605 --- .../main/asciidoc/endpoints/auditevents.adoc | 7 +-- .../AuditEventsEndpointAutoConfiguration.java | 22 +------ ...tEventsEndpointAutoConfigurationTests.java | 22 +------ ...AuditEventsEndpointDocumentationTests.java | 13 +--- .../actuate/audit/AuditEventsEndpoint.java | 5 +- .../AuditEventsEndpointWebExtension.java | 49 --------------- .../AuditEventsJmxEndpointExtension.java | 52 --------------- ...uditEventsEndpointWebIntegrationTests.java | 24 +++---- .../AuditEventsJmxEndpointExtensionTests.java | 63 ------------------- 9 files changed, 21 insertions(+), 236 deletions(-) delete mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/audit/AuditEventsEndpointWebExtension.java delete mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/audit/AuditEventsJmxEndpointExtension.java delete mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/audit/AuditEventsJmxEndpointExtensionTests.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/asciidoc/endpoints/auditevents.adoc b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/asciidoc/endpoints/auditevents.adoc index 3dea1c724f..e37333c289 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/asciidoc/endpoints/auditevents.adoc +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/asciidoc/endpoints/auditevents.adoc @@ -25,14 +25,11 @@ include::{snippets}auditevents/filtered/http-response.adoc[] === Query Parameters The endpoint uses query parameters to limit the events that it returns. The following - table shows the supported query parameters: +table shows the supported query parameters: [cols="2,4"] include::{snippets}auditevents/filtered/request-parameters.adoc[] -The `after` parameter is required. You can also use one or both of the `principal` and -`type` parameters to further limit the results. - [[audit-events-retrieving-response-structure]] @@ -42,4 +39,4 @@ The response contains details of all of the audit events that matched the query. following table describes the structure of the response: [cols="2,1,3"] -include::{snippets}auditevents/after/response-fields.adoc[] +include::{snippets}auditevents/all/response-fields.adoc[] diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/audit/AuditEventsEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/audit/AuditEventsEndpointAutoConfiguration.java index 756de19036..6801dba405 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/audit/AuditEventsEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/audit/AuditEventsEndpointAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,8 +18,6 @@ package org.springframework.boot.actuate.autoconfigure.audit; import org.springframework.boot.actuate.audit.AuditEventRepository; import org.springframework.boot.actuate.audit.AuditEventsEndpoint; -import org.springframework.boot.actuate.audit.AuditEventsEndpointWebExtension; -import org.springframework.boot.actuate.audit.AuditEventsJmxEndpointExtension; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint; import org.springframework.boot.actuate.logging.LoggersEndpoint; import org.springframework.boot.autoconfigure.AutoConfigureAfter; @@ -50,22 +48,4 @@ public class AuditEventsEndpointAutoConfiguration { return new AuditEventsEndpoint(auditEventRepository); } - @Bean - @ConditionalOnMissingBean - @ConditionalOnEnabledEndpoint - @ConditionalOnBean(AuditEventsEndpoint.class) - public AuditEventsJmxEndpointExtension auditEventsJmxEndpointExtension( - AuditEventsEndpoint auditEventsEndpoint) { - return new AuditEventsJmxEndpointExtension(auditEventsEndpoint); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnEnabledEndpoint - @ConditionalOnBean(AuditEventsEndpoint.class) - public AuditEventsEndpointWebExtension auditEventsWebEndpointExtension( - AuditEventsEndpoint auditEventsEndpoint) { - return new AuditEventsEndpointWebExtension(auditEventsEndpoint); - } - } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/audit/AuditEventsEndpointAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/audit/AuditEventsEndpointAutoConfigurationTests.java index c345e348a0..cc601acb07 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/audit/AuditEventsEndpointAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/audit/AuditEventsEndpointAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -19,8 +19,6 @@ package org.springframework.boot.actuate.autoconfigure.audit; import org.junit.Test; import org.springframework.boot.actuate.audit.AuditEventsEndpoint; -import org.springframework.boot.actuate.audit.AuditEventsEndpointWebExtension; -import org.springframework.boot.actuate.audit.AuditEventsJmxEndpointExtension; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -46,25 +44,11 @@ public class AuditEventsEndpointAutoConfigurationTests { } @Test - public void runShouldHaveJmxExtensionBean() { - this.contextRunner.run((context) -> assertThat(context) - .hasSingleBean(AuditEventsJmxEndpointExtension.class)); - } - - @Test - public void runShouldHaveWebExtensionBean() { - this.contextRunner.run((context) -> assertThat(context) - .hasSingleBean(AuditEventsEndpointWebExtension.class)); - } - - @Test - public void runWhenEnabledPropertyIsFalseShouldNotHaveEndpointOrExtensionBean() { + public void runWhenEnabledPropertyIsFalseShouldNotHaveEndpoint() { this.contextRunner .withPropertyValues("management.endpoint.auditevents.enabled:false") .run((context) -> assertThat(context) - .doesNotHaveBean(AuditEventsEndpoint.class) - .doesNotHaveBean(AuditEventsJmxEndpointExtension.class) - .doesNotHaveBean(AuditEventsEndpointWebExtension.class)); + .doesNotHaveBean(AuditEventsEndpoint.class)); } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/AuditEventsEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/AuditEventsEndpointDocumentationTests.java index bfe6c6f080..518c863365 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/AuditEventsEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/AuditEventsEndpointDocumentationTests.java @@ -26,7 +26,6 @@ import org.junit.Test; import org.springframework.boot.actuate.audit.AuditEvent; import org.springframework.boot.actuate.audit.AuditEventRepository; import org.springframework.boot.actuate.audit.AuditEventsEndpoint; -import org.springframework.boot.actuate.audit.AuditEventsEndpointWebExtension; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -55,13 +54,13 @@ public class AuditEventsEndpointDocumentationTests private AuditEventRepository repository; @Test - public void allAuditEventsAfter() throws Exception { + public void allAuditEvents() throws Exception { String queryTimestamp = "2017-11-07T09:37Z"; given(this.repository.find(any(), any(), any())).willReturn( Arrays.asList(new AuditEvent("alice", "logout", Collections.emptyMap()))); this.mockMvc.perform(get("/actuator/auditevents").param("after", queryTimestamp)) .andExpect(status().isOk()) - .andDo(document("auditevents/after", responseFields( + .andDo(document("auditevents/all", responseFields( fieldWithPath("events").description("An array of audit events."), fieldWithPath("events.[].timestamp") .description("The timestamp of when the event occurred."), @@ -85,7 +84,7 @@ public class AuditEventsEndpointDocumentationTests requestParameters( parameterWithName("after").description( "Restricts the events to those that occurred " - + "after the given time. Required."), + + "after the given time. Optional."), parameterWithName("principal").description( "Restricts the events to those with the given " + "principal. Optional."), @@ -104,12 +103,6 @@ public class AuditEventsEndpointDocumentationTests return new AuditEventsEndpoint(repository); } - @Bean - public AuditEventsEndpointWebExtension adAuditEventsWebEndpointExtension( - AuditEventsEndpoint delegate) { - return new AuditEventsEndpointWebExtension(delegate); - } - } } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/audit/AuditEventsEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/audit/AuditEventsEndpoint.java index 930a528728..ae56fb46ef 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/audit/AuditEventsEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/audit/AuditEventsEndpoint.java @@ -21,6 +21,7 @@ import java.util.List; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -40,8 +41,8 @@ public class AuditEventsEndpoint { } @ReadOperation - public AuditEventsDescriptor events(String principal, OffsetDateTime after, - String type) { + public AuditEventsDescriptor events(@Nullable String principal, + @Nullable OffsetDateTime after, @Nullable String type) { return new AuditEventsDescriptor(this.auditEventRepository.find(principal, after == null ? null : after.toInstant(), type)); } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/audit/AuditEventsEndpointWebExtension.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/audit/AuditEventsEndpointWebExtension.java deleted file mode 100644 index c9b7b63bd6..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/audit/AuditEventsEndpointWebExtension.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2012-2018 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.audit; - -import java.time.OffsetDateTime; - -import org.springframework.boot.actuate.audit.AuditEventsEndpoint.AuditEventsDescriptor; -import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; -import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; -import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension; -import org.springframework.lang.Nullable; - -/** - * {@link EndpointWebExtension} for the {@link AuditEventsEndpoint}. - * - * @author Vedran Pavic - * @since 2.0.0 - */ -@EndpointWebExtension(endpoint = AuditEventsEndpoint.class) -public class AuditEventsEndpointWebExtension { - - private final AuditEventsEndpoint delegate; - - public AuditEventsEndpointWebExtension(AuditEventsEndpoint delegate) { - this.delegate = delegate; - } - - @ReadOperation - public WebEndpointResponse events(@Nullable String principal, - OffsetDateTime after, @Nullable String type) { - AuditEventsDescriptor auditEvents = this.delegate.events(principal, after, type); - return new WebEndpointResponse<>(auditEvents); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/audit/AuditEventsJmxEndpointExtension.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/audit/AuditEventsJmxEndpointExtension.java deleted file mode 100644 index 69f53068ea..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/audit/AuditEventsJmxEndpointExtension.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2012-2018 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.audit; - -import java.time.OffsetDateTime; - -import org.springframework.boot.actuate.audit.AuditEventsEndpoint.AuditEventsDescriptor; -import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; -import org.springframework.boot.actuate.endpoint.jmx.annotation.EndpointJmxExtension; - -/** - * JMX-specific extension of the {@link AuditEventsEndpoint}. - * - * @author Vedran Pavic - * @author Andy Wilkinson - * @since 2.0.0 - */ -@EndpointJmxExtension(endpoint = AuditEventsEndpoint.class) -public class AuditEventsJmxEndpointExtension { - - private final AuditEventsEndpoint delegate; - - public AuditEventsJmxEndpointExtension(AuditEventsEndpoint delegate) { - this.delegate = delegate; - } - - @ReadOperation - public AuditEventsDescriptor eventsAfter(OffsetDateTime after) { - return this.delegate.events(null, after, null); - } - - @ReadOperation - public AuditEventsDescriptor eventsWithPrincipalAndAfter(String principal, - OffsetDateTime after) { - return this.delegate.events(principal, after, null); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/audit/AuditEventsEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/audit/AuditEventsEndpointWebIntegrationTests.java index 9cc1233d56..1fd55ad0c0 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/audit/AuditEventsEndpointWebIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/audit/AuditEventsEndpointWebIntegrationTests.java @@ -41,13 +41,16 @@ public class AuditEventsEndpointWebIntegrationTests { private static WebTestClient client; @Test - public void eventsWithoutParams() { + public void allEvents() { client.get().uri((builder) -> builder.path("/actuator/auditevents").build()) - .exchange().expectStatus().isBadRequest(); + .exchange().expectStatus().isOk().expectBody() + .jsonPath("events.[*].principal") + .isEqualTo(new JSONArray().appendElement("admin").appendElement("admin") + .appendElement("user")); } @Test - public void eventsWithDateAfter() { + public void eventsAfter() { client.get() .uri((builder) -> builder.path("/actuator/auditevents") .queryParam("after", "2016-11-01T13:00:00%2B00:00").build()) @@ -56,10 +59,9 @@ public class AuditEventsEndpointWebIntegrationTests { } @Test - public void eventsWithPrincipalAndDateAfter() { + public void eventsWithPrincipal() { client.get() .uri((builder) -> builder.path("/actuator/auditevents") - .queryParam("after", "2016-11-01T10:00:00%2B00:00") .queryParam("principal", "user").build()) .exchange().expectStatus().isOk().expectBody() .jsonPath("events.[*].principal") @@ -67,12 +69,10 @@ public class AuditEventsEndpointWebIntegrationTests { } @Test - public void eventsWithPrincipalDateAfterAndType() { + public void eventsWithType() { client.get() .uri((builder) -> builder.path("/actuator/auditevents") - .queryParam("after", "2016-11-01T10:00:00%2B00:00") - .queryParam("principal", "admin").queryParam("type", "logout") - .build()) + .queryParam("type", "logout").build()) .exchange().expectStatus().isOk().expectBody() .jsonPath("events.[*].principal") .isEqualTo(new JSONArray().appendElement("admin")) @@ -97,12 +97,6 @@ public class AuditEventsEndpointWebIntegrationTests { return new AuditEventsEndpoint(auditEventsRepository()); } - @Bean - public AuditEventsEndpointWebExtension auditEventsEndpointWebExtension( - AuditEventsEndpoint auditEventsEndpoint) { - return new AuditEventsEndpointWebExtension(auditEventsEndpoint); - } - private AuditEvent createEvent(String instant, String principal, String type) { return new AuditEvent(Instant.parse(instant), principal, type, Collections.emptyMap()); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/audit/AuditEventsJmxEndpointExtensionTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/audit/AuditEventsJmxEndpointExtensionTests.java deleted file mode 100644 index 1a5bbd46fc..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/audit/AuditEventsJmxEndpointExtensionTests.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2012-2018 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.audit; - -import java.time.OffsetDateTime; -import java.util.Collections; -import java.util.List; - -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link AuditEventsJmxEndpointExtension}. - * - * @author Andy Wilkinson - */ -public class AuditEventsJmxEndpointExtensionTests { - - private final AuditEventRepository repository = mock(AuditEventRepository.class); - - private final AuditEventsJmxEndpointExtension extension = new AuditEventsJmxEndpointExtension( - new AuditEventsEndpoint(this.repository)); - - private final AuditEvent event = new AuditEvent("principal", "type", - Collections.singletonMap("a", "alpha")); - - @Test - public void eventsCreatedAfter() { - OffsetDateTime now = OffsetDateTime.now(); - given(this.repository.find(null, now.toInstant(), null)) - .willReturn(Collections.singletonList(this.event)); - List result = this.extension.eventsAfter(now).getEvents(); - assertThat(result).isEqualTo(Collections.singletonList(this.event)); - } - - @Test - public void eventsWithPrincipalAndDateAfter() { - OffsetDateTime now = OffsetDateTime.now(); - given(this.repository.find("Joan", now.toInstant(), null)) - .willReturn(Collections.singletonList(this.event)); - List result = this.extension.eventsWithPrincipalAndAfter("Joan", now) - .getEvents(); - assertThat(result).isEqualTo(Collections.singletonList(this.event)); - } - -}