This is an automated email from the ASF dual-hosted git repository. himanshug pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-druid.git
The following commit(s) were added to refs/heads/master by this push: new b3328b2 endpoint to delete lookup tier and remove tier on last lookup deletion (#7852) b3328b2 is described below commit b3328b2785884a4677338d97a116ef1fdb54459f Author: Himanshu <g.himan...@gmail.com> AuthorDate: Sat Jun 15 17:55:50 2019 -0700 endpoint to delete lookup tier and remove tier on last lookup deletion (#7852) --- docs/content/querying/lookups.md | 5 +- .../server/http/LookupCoordinatorResource.java | 29 ++++++++ .../lookup/cache/LookupCoordinatorManager.java | 28 ++++++- .../server/http/LookupCoordinatorResourceTest.java | 42 +++++++++++ .../lookup/cache/LookupCoordinatorManagerTest.java | 87 ++++++++++++++++++++++ 5 files changed, 189 insertions(+), 2 deletions(-) diff --git a/docs/content/querying/lookups.md b/docs/content/querying/lookups.md index b54f769..7af2bcd 100644 --- a/docs/content/querying/lookups.md +++ b/docs/content/querying/lookups.md @@ -292,7 +292,10 @@ Using the prior example, a `GET` to `/druid/coordinator/v1/lookups/config/realti ``` ## Delete Lookup -A `DELETE` to `/druid/coordinator/v1/lookups/config/{tier}/{id}` will remove that lookup from the cluster. +A `DELETE` to `/druid/coordinator/v1/lookups/config/{tier}/{id}` will remove that lookup from the cluster. If it was last lookup in the tier, then tier is deleted as well. + +## Delete Tier +A `DELETE` to `/druid/coordinator/v1/lookups/config/{tier}` will remove that tier from the cluster. ## List tier names A `GET` to `/druid/coordinator/v1/lookups/config` will return a list of known tier names in the dynamic configuration. diff --git a/server/src/main/java/org/apache/druid/server/http/LookupCoordinatorResource.java b/server/src/main/java/org/apache/druid/server/http/LookupCoordinatorResource.java index 7affefe..f575211 100644 --- a/server/src/main/java/org/apache/druid/server/http/LookupCoordinatorResource.java +++ b/server/src/main/java/org/apache/druid/server/http/LookupCoordinatorResource.java @@ -178,6 +178,35 @@ public class LookupCoordinatorResource @DELETE @Produces({MediaType.APPLICATION_JSON, SmileMediaTypes.APPLICATION_JACKSON_SMILE}) + @Path("/config/{tier}") + public Response deleteTier( + @PathParam("tier") String tier, + @HeaderParam(AuditManager.X_DRUID_AUTHOR) @DefaultValue("") final String author, + @HeaderParam(AuditManager.X_DRUID_COMMENT) @DefaultValue("") final String comment, + @Context HttpServletRequest req + ) + { + try { + if (Strings.isNullOrEmpty(tier)) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(ServletResourceUtils.sanitizeException(new NullPointerException("`tier` required"))) + .build(); + } + + if (lookupCoordinatorManager.deleteTier(tier, new AuditInfo(author, comment, req.getRemoteAddr()))) { + return Response.status(Response.Status.ACCEPTED).build(); + } else { + return Response.status(Response.Status.NOT_FOUND).build(); + } + } + catch (Exception e) { + LOG.error(e, "Error deleting tier [%s]", tier); + return Response.serverError().entity(ServletResourceUtils.sanitizeException(e)).build(); + } + } + + @DELETE + @Produces({MediaType.APPLICATION_JSON, SmileMediaTypes.APPLICATION_JACKSON_SMILE}) @Path("/config/{tier}/{lookup}") public Response deleteLookup( @PathParam("tier") String tier, diff --git a/server/src/main/java/org/apache/druid/server/lookup/cache/LookupCoordinatorManager.java b/server/src/main/java/org/apache/druid/server/lookup/cache/LookupCoordinatorManager.java index 86acfa3..b6589aa 100644 --- a/server/src/main/java/org/apache/druid/server/lookup/cache/LookupCoordinatorManager.java +++ b/server/src/main/java/org/apache/druid/server/lookup/cache/LookupCoordinatorManager.java @@ -255,6 +255,27 @@ public class LookupCoordinatorManager return lookupMapConfigRef.get(); } + public boolean deleteTier(final String tier, AuditInfo auditInfo) + { + Preconditions.checkState(lifecycleLock.awaitStarted(5, TimeUnit.SECONDS), "not started"); + + synchronized (this) { + final Map<String, Map<String, LookupExtractorFactoryMapContainer>> priorSpec = getKnownLookups(); + if (priorSpec == null) { + LOG.warn("Requested delete tier [%s]. But no lookups exist!", tier); + return false; + } + final Map<String, Map<String, LookupExtractorFactoryMapContainer>> updateSpec = new HashMap<>(priorSpec); + + if (updateSpec.remove(tier) == null) { + LOG.warn("Requested delete of tier [%s] that does not exist!", tier); + return false; + } + + return configManager.set(LOOKUP_CONFIG_KEY, updateSpec, auditInfo).isOk(); + } + } + public boolean deleteLookup(final String tier, final String lookup, AuditInfo auditInfo) { Preconditions.checkState(lifecycleLock.awaitStarted(5, TimeUnit.SECONDS), "not started"); @@ -279,7 +300,12 @@ public class LookupCoordinatorManager final Map<String, LookupExtractorFactoryMapContainer> updateTierSpec = new HashMap<>(priorTierSpec); updateTierSpec.remove(lookup); - updateSpec.put(tier, updateTierSpec); + + if (updateTierSpec.isEmpty()) { + updateSpec.remove(tier); + } else { + updateSpec.put(tier, updateTierSpec); + } return configManager.set(LOOKUP_CONFIG_KEY, updateSpec, auditInfo).isOk(); } } diff --git a/server/src/test/java/org/apache/druid/server/http/LookupCoordinatorResourceTest.java b/server/src/test/java/org/apache/druid/server/http/LookupCoordinatorResourceTest.java index fb6e22d..d1e673d 100644 --- a/server/src/test/java/org/apache/druid/server/http/LookupCoordinatorResourceTest.java +++ b/server/src/test/java/org/apache/druid/server/http/LookupCoordinatorResourceTest.java @@ -287,6 +287,48 @@ public class LookupCoordinatorResourceTest } @Test + public void testSimpleDeleteTier() + { + final String author = "some author"; + final String comment = "some comment"; + final String ip = "127.0.0.1"; + + final HttpServletRequest request = EasyMock.createStrictMock(HttpServletRequest.class); + EasyMock.expect(request.getRemoteAddr()).andReturn(ip).once(); + + final Capture<AuditInfo> auditInfoCapture = Capture.newInstance(); + final LookupCoordinatorManager lookupCoordinatorManager = EasyMock.createStrictMock( + LookupCoordinatorManager.class); + EasyMock.expect(lookupCoordinatorManager.deleteTier( + EasyMock.eq(LOOKUP_TIER), + EasyMock.capture(auditInfoCapture) + )).andReturn(true).once(); + + EasyMock.replay(lookupCoordinatorManager, request); + + final LookupCoordinatorResource lookupCoordinatorResource = new LookupCoordinatorResource( + lookupCoordinatorManager, + mapper, + mapper + ); + final Response response = lookupCoordinatorResource.deleteTier( + LOOKUP_TIER, + author, + comment, + request + ); + + Assert.assertEquals(202, response.getStatus()); + Assert.assertTrue(auditInfoCapture.hasCaptured()); + final AuditInfo auditInfo = auditInfoCapture.getValue(); + Assert.assertEquals(author, auditInfo.getAuthor()); + Assert.assertEquals(comment, auditInfo.getComment()); + Assert.assertEquals(ip, auditInfo.getIp()); + + EasyMock.verify(lookupCoordinatorManager, request); + } + + @Test public void testSimpleDelete() { final String author = "some author"; diff --git a/server/src/test/java/org/apache/druid/server/lookup/cache/LookupCoordinatorManagerTest.java b/server/src/test/java/org/apache/druid/server/lookup/cache/LookupCoordinatorManagerTest.java index aa32b81..772b185 100644 --- a/server/src/test/java/org/apache/druid/server/lookup/cache/LookupCoordinatorManagerTest.java +++ b/server/src/test/java/org/apache/druid/server/lookup/cache/LookupCoordinatorManagerTest.java @@ -847,6 +847,52 @@ public class LookupCoordinatorManagerTest } @Test + public void testDeleteTier() + { + final LookupExtractorFactoryMapContainer foo1 = new LookupExtractorFactoryMapContainer( + "v0", + ImmutableMap.of("lookup", "foo1") + ); + + final LookupExtractorFactoryMapContainer foo2 = new LookupExtractorFactoryMapContainer( + "v0", + ImmutableMap.of("lookup", "foo2") + ); + final LookupCoordinatorManager manager = new LookupCoordinatorManager( + client, + druidNodeDiscoveryProvider, + mapper, + configManager, + lookupCoordinatorManagerConfig + ) + { + @Override + public Map<String, Map<String, LookupExtractorFactoryMapContainer>> getKnownLookups() + { + return ImmutableMap.of(LOOKUP_TIER, ImmutableMap.of( + "foo1", foo1, + "foo2", foo2 + )); + } + }; + manager.start(); + final AuditInfo auditInfo = new AuditInfo("author", "comment", "localhost"); + EasyMock.reset(configManager); + EasyMock.expect( + configManager.set( + EasyMock.eq(LookupCoordinatorManager.LOOKUP_CONFIG_KEY), + EasyMock.eq( + ImmutableMap.<String, Map<String, LookupExtractorFactoryMapContainer>>of() + ), + EasyMock.eq(auditInfo) + ) + ).andReturn(SetResult.ok()).once(); + EasyMock.replay(configManager); + Assert.assertTrue(manager.deleteTier(LOOKUP_TIER, auditInfo)); + EasyMock.verify(configManager); + } + + @Test public void testDeleteLookup() { final LookupExtractorFactoryMapContainer ignore = new LookupExtractorFactoryMapContainer( @@ -896,6 +942,47 @@ public class LookupCoordinatorManagerTest EasyMock.verify(configManager); } + + @Test + public void testDeleteLastLookup() + { + final LookupExtractorFactoryMapContainer lookup = new LookupExtractorFactoryMapContainer( + "v0", + ImmutableMap.of("lookup", "foo") + ); + final LookupCoordinatorManager manager = new LookupCoordinatorManager( + client, + druidNodeDiscoveryProvider, + mapper, + configManager, + lookupCoordinatorManagerConfig + ) + { + @Override + public Map<String, Map<String, LookupExtractorFactoryMapContainer>> getKnownLookups() + { + return ImmutableMap.of(LOOKUP_TIER, ImmutableMap.of( + "foo", lookup + )); + } + }; + manager.start(); + final AuditInfo auditInfo = new AuditInfo("author", "comment", "localhost"); + EasyMock.reset(configManager); + EasyMock.expect( + configManager.set( + EasyMock.eq(LookupCoordinatorManager.LOOKUP_CONFIG_KEY), + EasyMock.eq( + ImmutableMap.<String, Map<String, LookupExtractorFactoryMapContainer>>of() + ), + EasyMock.eq(auditInfo) + ) + ).andReturn(SetResult.ok()).once(); + EasyMock.replay(configManager); + Assert.assertTrue(manager.deleteLookup(LOOKUP_TIER, "foo", auditInfo)); + EasyMock.verify(configManager); + } + @Test public void testDeleteLookupIgnoresMissing() { --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@druid.apache.org For additional commands, e-mail: commits-h...@druid.apache.org