From b0a444eafc7d0c9361ae97cdec6aab01ce69ccdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20=C5=81ugowski?= Date: Mon, 16 Nov 2015 21:07:53 +0100 Subject: [PATCH] Add count parameter to rules history endpoint. --- docs/content/design/coordinator.md | 4 + .../io/druid/server/http/RulesResource.java | 55 ++++++---- .../druid/server/http/RulesResourceTest.java | 103 ++++++++++++++++++ 3 files changed, 142 insertions(+), 20 deletions(-) diff --git a/docs/content/design/coordinator.md b/docs/content/design/coordinator.md index c9b70573680..7301dd82a09 100644 --- a/docs/content/design/coordinator.md +++ b/docs/content/design/coordinator.md @@ -189,6 +189,10 @@ Returns all rules for a specified datasource and includes default datasource. Returns audit history of rules for all datasources. default value of interval can be specified by setting `druid.audit.manager.auditHistoryMillis` (1 week if not configured) in coordinator runtime.properties +* `/druid/coordinator/v1/rules/history?count=` + + Returns last entries of audit history of rules for all datasources. + * `/druid/coordinator/v1/rules/{dataSourceName}/history?interval=` Returns audit history of rules for a specified datasource. default value of interval can be specified by setting `druid.audit.manager.auditHistoryMillis` (1 week if not configured) in coordinator runtime.properties diff --git a/server/src/main/java/io/druid/server/http/RulesResource.java b/server/src/main/java/io/druid/server/http/RulesResource.java index 71e350a9265..bbc10af8c63 100644 --- a/server/src/main/java/io/druid/server/http/RulesResource.java +++ b/server/src/main/java/io/druid/server/http/RulesResource.java @@ -20,6 +20,7 @@ package io.druid.server.http; import com.google.common.collect.ImmutableMap; import com.google.inject.Inject; +import io.druid.audit.AuditEntry; import io.druid.audit.AuditInfo; import io.druid.audit.AuditManager; import io.druid.metadata.MetadataRuleManager; @@ -40,7 +41,6 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; import java.util.List; @@ -116,37 +116,52 @@ public class RulesResource @QueryParam("count") final Integer count ) { - Interval theInterval = interval == null ? null : new Interval(interval); - if (theInterval == null && count != null) { - try { - return Response.ok(auditManager.fetchAuditHistory(dataSourceName, "rules", count)) - .build(); - } - catch (IllegalArgumentException e) { - return Response.status(Response.Status.BAD_REQUEST) - .entity(ImmutableMap.of("error", e.getMessage())) - .build(); - } + try { + return Response.ok(getRuleHistory(dataSourceName, interval, count)) + .build(); + } catch (IllegalArgumentException e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(ImmutableMap.of("error", e.getMessage())) + .build(); } - return Response.ok(auditManager.fetchAuditHistory(dataSourceName, "rules", theInterval)) - .build(); } @GET @Path("/history") @Produces(MediaType.APPLICATION_JSON) public Response getDatasourceRuleHistory( - @QueryParam("interval") final String interval + @QueryParam("interval") final String interval, + @QueryParam("count") final Integer count ) { try { - Interval theInterval = interval == null ? null : new Interval(interval); - return Response.ok(auditManager.fetchAuditHistory("rules", theInterval)) + return Response.ok(getRuleHistory(null, interval, count)) + .build(); + } catch (IllegalArgumentException e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(ImmutableMap.of("error", e.getMessage())) .build(); - } - catch (IllegalArgumentException e) { - return Response.serverError().entity(ImmutableMap.of("error", e.getMessage())).build(); } } + private List getRuleHistory( + final String dataSourceName, + final String interval, + final Integer count + ) throws IllegalArgumentException + { + if (interval == null && count != null) { + if (dataSourceName != null) { + return auditManager.fetchAuditHistory(dataSourceName, "rules", count); + } + return auditManager.fetchAuditHistory("rules", count); + } + + Interval theInterval = interval == null ? null : new Interval(interval); + if (dataSourceName != null) { + return auditManager.fetchAuditHistory(dataSourceName, "rules", theInterval); + } + return auditManager.fetchAuditHistory("rules", theInterval); + } + } diff --git a/server/src/test/java/io/druid/server/http/RulesResourceTest.java b/server/src/test/java/io/druid/server/http/RulesResourceTest.java index 374c15317ea..283026f82cf 100644 --- a/server/src/test/java/io/druid/server/http/RulesResourceTest.java +++ b/server/src/test/java/io/druid/server/http/RulesResourceTest.java @@ -152,4 +152,107 @@ public class RulesResourceTest EasyMock.verify(auditManager); } + + @Test + public void testGetAllDatasourcesRuleHistoryWithCount() + { + AuditEntry entry1 = new AuditEntry( + "testKey", + "testType", + new AuditInfo( + "testAuthor", + "testComment", + "127.0.0.1" + ), + "testPayload", + new DateTime("2013-01-02T00:00:00Z") + ); + AuditEntry entry2 = new AuditEntry( + "testKey", + "testType", + new AuditInfo( + "testAuthor", + "testComment", + "127.0.0.1" + ), + "testPayload", + new DateTime("2013-01-01T00:00:00Z") + ); + EasyMock.expect(auditManager.fetchAuditHistory(EasyMock.eq("rules"), EasyMock.eq(2))) + .andReturn(ImmutableList.of(entry1, entry2)) + .once(); + EasyMock.replay(auditManager); + + RulesResource rulesResource = new RulesResource(databaseRuleManager, auditManager); + + Response response = rulesResource.getDatasourceRuleHistory(null, 2); + List rulesHistory = (List) response.getEntity(); + Assert.assertEquals(2, rulesHistory.size()); + Assert.assertEquals(entry1, rulesHistory.get(0)); + Assert.assertEquals(entry2, rulesHistory.get(1)); + + EasyMock.verify(auditManager); + } + + @Test + public void testGetAllDatasourcesRuleHistoryWithInterval() + { + String interval = "P2D/2013-01-02T00:00:00Z"; + Interval theInterval = new Interval(interval); + AuditEntry entry1 = new AuditEntry( + "testKey", + "testType", + new AuditInfo( + "testAuthor", + "testComment", + "127.0.0.1" + ), + "testPayload", + new DateTime("2013-01-02T00:00:00Z") + ); + AuditEntry entry2 = new AuditEntry( + "testKey", + "testType", + new AuditInfo( + "testAuthor", + "testComment", + "127.0.0.1" + ), + "testPayload", + new DateTime("2013-01-01T00:00:00Z") + ); + EasyMock.expect(auditManager.fetchAuditHistory(EasyMock.eq("rules"), EasyMock.eq(theInterval))) + .andReturn(ImmutableList.of(entry1, entry2)) + .once(); + EasyMock.replay(auditManager); + + RulesResource rulesResource = new RulesResource(databaseRuleManager, auditManager); + + Response response = rulesResource.getDatasourceRuleHistory(interval, null); + List rulesHistory = (List) response.getEntity(); + Assert.assertEquals(2, rulesHistory.size()); + Assert.assertEquals(entry1, rulesHistory.get(0)); + Assert.assertEquals(entry2, rulesHistory.get(1)); + + EasyMock.verify(auditManager); + } + + @Test + public void testGetAllDatasourcesRuleHistoryWithWrongCount() + { + EasyMock.expect(auditManager.fetchAuditHistory(EasyMock.eq("rules"), EasyMock.eq(-1))) + .andThrow(new IllegalArgumentException("Limit must be greater than zero!")) + .once(); + EasyMock.replay(auditManager); + + RulesResource rulesResource = new RulesResource(databaseRuleManager, auditManager); + + Response response = rulesResource.getDatasourceRuleHistory(null, -1); + Map rulesHistory = (Map) response.getEntity(); + Assert.assertEquals(400, response.getStatus()); + Assert.assertTrue(rulesHistory.containsKey("error")); + Assert.assertEquals("Limit must be greater than zero!", rulesHistory.get("error")); + + EasyMock.verify(auditManager); + } }