diff --git a/docs/content/querying/lookups.md b/docs/content/querying/lookups.md index fb47619e754b..7e315103fb7a 100644 --- a/docs/content/querying/lookups.md +++ b/docs/content/querying/lookups.md @@ -301,3 +301,9 @@ It is possible to save the configuration across restarts such that a node will n |Property|Description|Default| |--------|-----------|-------| |`druid.lookup.snapshotWorkingDir`| Working path used to store snapshot of current lookup configuration, leaving this property null will disable snapshot/bootstrap utility|null| + +## Introspect a Lookup + +Lookup implementations can provide some introspection capabilities by implementing `LookupIntrospectHandler`. User will send request to `/druid/lookups/v1/introspect/{lookupId}` to enable introspection on a given lookup. + +For instance you can list all the keys/values of a map based lookup by issuing a `GET` request to `/druid/lookups/v1/introspect/{lookupId}/keys"` or `/druid/lookups/v1/introspect/{lookupId}/values"` diff --git a/processing/src/main/java/io/druid/query/lookup/LookupExtractorFactory.java b/processing/src/main/java/io/druid/query/lookup/LookupExtractorFactory.java index 2afdc44aef33..a18fed85db53 100644 --- a/processing/src/main/java/io/druid/query/lookup/LookupExtractorFactory.java +++ b/processing/src/main/java/io/druid/query/lookup/LookupExtractorFactory.java @@ -19,10 +19,8 @@ package io.druid.query.lookup; -import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.google.common.base.Supplier; -import io.druid.query.extraction.MapLookupExtractorFactory; import javax.annotation.Nullable; @@ -32,9 +30,6 @@ * If a LookupExtractorFactory wishes to support idempotent updates, it needs to implement the `replaces` method */ @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") -@JsonSubTypes(value = { - @JsonSubTypes.Type(name = "map", value = MapLookupExtractorFactory.class) -}) public interface LookupExtractorFactory extends Supplier { /** @@ -55,7 +50,6 @@ public interface LookupExtractorFactory extends Supplier * @return true if successfully closed the {@link LookupExtractor} */ public boolean close(); - /** * Determine if this LookupExtractorFactory should replace some other LookupExtractorFactory. * This is used to implement no-down-time @@ -63,4 +57,11 @@ public interface LookupExtractorFactory extends Supplier * @return `true` if the other should be replaced by this one. `false` if this one should not replace the other factory */ boolean replaces(@Nullable LookupExtractorFactory other); + + /** + * @return Returns the actual introspection request handler, can return {@code null} if it is not supported. + * This will be called once per HTTP request to introspect the actual lookup. + */ + @Nullable + public LookupIntrospectHandler getIntrospectHandler(); } diff --git a/processing/src/main/java/io/druid/query/lookup/LookupIntrospectHandler.java b/processing/src/main/java/io/druid/query/lookup/LookupIntrospectHandler.java new file mode 100644 index 000000000000..3d702f0e9afc --- /dev/null +++ b/processing/src/main/java/io/druid/query/lookup/LookupIntrospectHandler.java @@ -0,0 +1,30 @@ +/* + * Licensed to Metamarkets Group Inc. (Metamarkets) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. Metamarkets licenses this file + * to you 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 io.druid.query.lookup; + + +/** + * This interface is empty because it only exists to signal intent. The actual http endpoints are provided + * through JAX-RS annotations on the {@link LookupIntrospectHandler} objects. + * Note that, if you decide to implement {@link LookupExtractorFactory#getIntrospectHandler()} as request scoped, therefore {@link LookupIntrospectHandler} should have as light of a footprint as possible. + */ +public interface LookupIntrospectHandler +{ +} diff --git a/processing/src/test/java/io/druid/query/lookup/RegisteredLookupExtractionFnTest.java b/processing/src/test/java/io/druid/query/lookup/RegisteredLookupExtractionFnTest.java index 6d6e5d529af7..f9f7e1c041a8 100644 --- a/processing/src/test/java/io/druid/query/lookup/RegisteredLookupExtractionFnTest.java +++ b/processing/src/test/java/io/druid/query/lookup/RegisteredLookupExtractionFnTest.java @@ -246,6 +246,13 @@ public boolean replaces(@Nullable LookupExtractorFactory other) return false; } + @Nullable + @Override + public LookupIntrospectHandler getIntrospectHandler() + { + return null; + } + @Override public LookupExtractor get() { diff --git a/server/pom.xml b/server/pom.xml index 514598afc5d1..42f2dbda6469 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -207,6 +207,24 @@ caliper test + + com.sun.jersey.jersey-test-framework + jersey-test-framework-core + 1.19 + test + + + com.sun.jersey.jersey-test-framework + jersey-test-framework-grizzly2 + 1.19 + test + + + pl.pragmatists + JUnitParams + 1.0.4 + test + diff --git a/server/src/main/java/io/druid/query/lookup/LookupIntrospectionResource.java b/server/src/main/java/io/druid/query/lookup/LookupIntrospectionResource.java new file mode 100644 index 000000000000..c02cf223f2ca --- /dev/null +++ b/server/src/main/java/io/druid/query/lookup/LookupIntrospectionResource.java @@ -0,0 +1,63 @@ +/* + * Licensed to Metamarkets Group Inc. (Metamarkets) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. Metamarkets licenses this file + * to you 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 io.druid.query.lookup; + +import com.google.inject.Inject; +import com.metamx.common.logger.Logger; + +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; + +@Path("/druid/v1/lookups/introspect") +public class LookupIntrospectionResource +{ + private static final Logger LOGGER = new Logger(LookupIntrospectionResource.class); + + private final LookupReferencesManager lookupReferencesManager; + + @Inject + public LookupIntrospectionResource(@Context LookupReferencesManager lookupReferencesManager) + { + this.lookupReferencesManager = lookupReferencesManager; + } + + @Path("/{lookupId}") + public Object introspectLookup(@PathParam("lookupId") final String lookupId) + { + final LookupExtractorFactory lookupExtractorFactory = lookupReferencesManager.get(lookupId); + if (lookupExtractorFactory == null) { + LOGGER.error("trying to introspect non existing lookup [%s]", lookupId); + return Response.status(Response.Status.NOT_FOUND).build(); + } + LookupIntrospectHandler introspectHandler = lookupExtractorFactory.getIntrospectHandler(); + if (introspectHandler != null) { + return introspectHandler; + } else { + LOGGER.warn( + "Trying to introspect lookup [%s] of type [%s] but implementation doesn't provide resource", + lookupId, + lookupExtractorFactory.get().getClass() + ); + return Response.status(Response.Status.NOT_FOUND).build(); + } + } +} diff --git a/server/src/main/java/io/druid/query/lookup/LookupModule.java b/server/src/main/java/io/druid/query/lookup/LookupModule.java index 1ad6d192a64c..6754c17a9f1a 100644 --- a/server/src/main/java/io/druid/query/lookup/LookupModule.java +++ b/server/src/main/java/io/druid/query/lookup/LookupModule.java @@ -25,6 +25,8 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.Module; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.net.HostAndPort; import com.google.inject.Binder; @@ -50,7 +52,6 @@ import org.apache.curator.utils.ZKPaths; import javax.ws.rs.Path; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -68,7 +69,9 @@ public static String getTierListenerPath(String tier) @Override public List getJacksonModules() { - return Collections.emptyList(); + return ImmutableList.of( + new SimpleModule("DruidLookupModule").registerSubtypes(MapLookupExtractorFactory.class) + ); } @Override @@ -78,6 +81,7 @@ public void configure(Binder binder) LifecycleModule.register(binder, LookupReferencesManager.class); JsonConfigProvider.bind(binder, PROPERTY_BASE, LookupListeningAnnouncerConfig.class); Jerseys.addResource(binder, LookupListeningResource.class); + Jerseys.addResource(binder, LookupIntrospectionResource.class); LifecycleModule.register(binder, LookupResourceListenerAnnouncer.class); } } diff --git a/processing/src/main/java/io/druid/query/extraction/MapLookupExtractorFactory.java b/server/src/main/java/io/druid/query/lookup/MapLookupExtractorFactory.java similarity index 60% rename from processing/src/main/java/io/druid/query/extraction/MapLookupExtractorFactory.java rename to server/src/main/java/io/druid/query/lookup/MapLookupExtractorFactory.java index 0f9a7b793d99..5ac15478ca38 100644 --- a/processing/src/main/java/io/druid/query/extraction/MapLookupExtractorFactory.java +++ b/server/src/main/java/io/druid/query/lookup/MapLookupExtractorFactory.java @@ -1,33 +1,39 @@ /* * Licensed to Metamarkets Group Inc. (Metamarkets) under one - * or more contributor license agreements. See the NOTICE file + * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information - * regarding copyright ownership. Metamarkets licenses this file + * regarding copyright ownership. Metamarkets licenses this file * to you 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 + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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 + * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ -package io.druid.query.extraction; +package io.druid.query.lookup; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeName; import com.google.common.base.Preconditions; -import io.druid.query.lookup.LookupExtractor; -import io.druid.query.lookup.LookupExtractorFactory; +import io.druid.query.extraction.MapLookupExtractor; import javax.annotation.Nullable; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import java.util.Map; +@JsonTypeName("map") public class MapLookupExtractorFactory implements LookupExtractorFactory { @JsonProperty @@ -35,6 +41,7 @@ public class MapLookupExtractorFactory implements LookupExtractorFactory @JsonProperty private final boolean isOneToOne; private final MapLookupExtractor lookupExtractor; + private final LookupIntrospectHandler lookupIntrospectHandler; @JsonCreator public MapLookupExtractorFactory( @@ -45,6 +52,7 @@ public MapLookupExtractorFactory( this.map = Preconditions.checkNotNull(map, "map cannot be null"); this.isOneToOne = isOneToOne; this.lookupExtractor = new MapLookupExtractor(map, isOneToOne); + this.lookupIntrospectHandler = new MapLookupIntrospectionHandler(this.map); } @Override @@ -63,6 +71,7 @@ public boolean close() * For MapLookups, the replaces consideration is very easy, it simply considers if the other is the same as this one * * @param other Some other LookupExtractorFactory which might need replaced + * * @return true - should replace, false - should not replace */ @Override @@ -71,6 +80,13 @@ public boolean replaces(@Nullable LookupExtractorFactory other) return !equals(other); } + @Nullable + @Override + public LookupIntrospectHandler getIntrospectHandler() + { + return lookupIntrospectHandler; + } + @Override public LookupExtractor get() { @@ -103,4 +119,34 @@ public int hashCode() result = 31 * result + (isOneToOne ? 1 : 0); return result; } + + public static class MapLookupIntrospectionHandler implements LookupIntrospectHandler + { + final private Map map; + public MapLookupIntrospectionHandler(Map map) + { + this.map = map; + } + + @GET + @Path("/keys") + @Produces(MediaType.APPLICATION_JSON) + public Response getKeys() + { + return Response.ok(map.keySet().toString()).build(); + } + + @GET + @Path("/values") + @Produces(MediaType.APPLICATION_JSON) + public Response getValues() + { + return Response.ok(map.values().toString()).build(); + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response getMap() + {return Response.ok(map).build();} + } } diff --git a/processing/src/test/java/io/druid/query/dimension/LookupDimensionSpecTest.java b/server/src/test/java/io/druid/query/dimension/LookupDimensionSpecTest.java similarity index 99% rename from processing/src/test/java/io/druid/query/dimension/LookupDimensionSpecTest.java rename to server/src/test/java/io/druid/query/dimension/LookupDimensionSpecTest.java index c609521f7a66..061bbefbd2e3 100644 --- a/processing/src/test/java/io/druid/query/dimension/LookupDimensionSpecTest.java +++ b/server/src/test/java/io/druid/query/dimension/LookupDimensionSpecTest.java @@ -26,9 +26,9 @@ import io.druid.jackson.DefaultObjectMapper; import io.druid.query.extraction.ExtractionFn; import io.druid.query.extraction.MapLookupExtractor; -import io.druid.query.extraction.MapLookupExtractorFactory; import io.druid.query.lookup.LookupExtractor; import io.druid.query.lookup.LookupReferencesManager; +import io.druid.query.lookup.MapLookupExtractorFactory; import junitparams.JUnitParamsRunner; import junitparams.Parameters; import org.easymock.EasyMock; diff --git a/server/src/test/java/io/druid/query/lookup/LookupIntrospectionResourceImplTest.java b/server/src/test/java/io/druid/query/lookup/LookupIntrospectionResourceImplTest.java new file mode 100644 index 000000000000..2aaafd4ac6d7 --- /dev/null +++ b/server/src/test/java/io/druid/query/lookup/LookupIntrospectionResourceImplTest.java @@ -0,0 +1,119 @@ +/* + * Licensed to Metamarkets Group Inc. (Metamarkets) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. Metamarkets licenses this file + * to you 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 io.druid.query.lookup; + +import com.google.common.collect.ImmutableMap; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.core.ClassNamesResourceConfig; +import com.sun.jersey.spi.container.servlet.WebComponent; +import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider; +import com.sun.jersey.test.framework.JerseyTest; +import com.sun.jersey.test.framework.WebAppDescriptor; +import com.sun.jersey.test.framework.spi.container.TestContainerFactory; +import com.sun.jersey.test.framework.spi.container.grizzly2.GrizzlyTestContainerFactory; +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import javax.ws.rs.core.Context; +import javax.ws.rs.ext.Provider; + +public class LookupIntrospectionResourceImplTest extends JerseyTest +{ + + static LookupReferencesManager lookupReferencesManager = EasyMock.createMock(LookupReferencesManager.class); + + + @Before + public void setUp() throws Exception + { + super.setUp(); + EasyMock.reset(lookupReferencesManager); + LookupExtractorFactory lookupExtractorFactory1 = new MapLookupExtractorFactory(ImmutableMap.of( + "key", + "value", + "key2", + "value2" + ), false); + EasyMock.expect(lookupReferencesManager.get("lookupId1")).andReturn(lookupExtractorFactory1).anyTimes(); + EasyMock.replay(lookupReferencesManager); + } + + @Provider + public static class MockTodoServiceProvider extends + SingletonTypeInjectableProvider + { + public MockTodoServiceProvider() + { + super(LookupReferencesManager.class, lookupReferencesManager); + } + } + + + public LookupIntrospectionResourceImplTest() + { + super(new WebAppDescriptor.Builder().initParam( + WebComponent.RESOURCE_CONFIG_CLASS, + ClassNamesResourceConfig.class.getName() + ) + .initParam( + ClassNamesResourceConfig.PROPERTY_CLASSNAMES, + LookupIntrospectionResource.class.getName() + + ';' + + MockTodoServiceProvider.class.getName() + + ';' + + LookupIntrospectHandler.class.getName() + ) + .build()); + } + + @Override + protected TestContainerFactory getTestContainerFactory() + { + return new GrizzlyTestContainerFactory(); + } + + + @Test + public void testGetKey() + { + + WebResource r = resource().path("/druid/v1/lookups/introspect/lookupId1/keys"); + String s = r.get(String.class); + Assert.assertEquals("[key, key2]", s); + } + + @Test + public void testGetValue() + { + WebResource r = resource().path("/druid/v1/lookups/introspect/lookupId1/values"); + String s = r.get(String.class); + Assert.assertEquals("[value, value2]", s); + } + + @Test + public void testGetMap() + { + WebResource r = resource().path("/druid/v1/lookups/introspect/lookupId1/"); + String s = r.get(String.class); + Assert.assertEquals("{\"key\":\"value\",\"key2\":\"value2\"}", s); + } +} diff --git a/server/src/test/java/io/druid/query/lookup/LookupIntrospectionResourceTest.java b/server/src/test/java/io/druid/query/lookup/LookupIntrospectionResourceTest.java new file mode 100644 index 000000000000..7974318b1506 --- /dev/null +++ b/server/src/test/java/io/druid/query/lookup/LookupIntrospectionResourceTest.java @@ -0,0 +1,128 @@ +/* + * Licensed to Metamarkets Group Inc. (Metamarkets) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. Metamarkets licenses this file + * to you 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 io.druid.query.lookup; + +import com.google.common.collect.ImmutableMap; +import io.druid.query.extraction.MapLookupExtractor; +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import javax.annotation.Nullable; +import javax.ws.rs.POST; +import javax.ws.rs.core.Response; +import java.io.InputStream; + +public class LookupIntrospectionResourceTest +{ + + LookupReferencesManager lookupReferencesManager = EasyMock.createMock(LookupReferencesManager.class); + LookupExtractorFactory lookupExtractorFactory = EasyMock.createMock(LookupExtractorFactory.class); + LookupIntrospectHandler lookupIntrospectHandler = EasyMock.createMock(LookupIntrospectHandler.class); + + LookupIntrospectionResource lookupIntrospectionResource = new LookupIntrospectionResource(lookupReferencesManager); + + @Before + public void setUp() + { + EasyMock.expect(lookupReferencesManager.get("lookupId")).andReturn(lookupExtractorFactory).anyTimes(); + EasyMock.expect(lookupReferencesManager.get(EasyMock.anyString())).andReturn(null).anyTimes(); + EasyMock.replay(lookupReferencesManager); + } + @Test + public void testNotImplementedIntrospectLookup() + { + EasyMock.expect(lookupExtractorFactory.getIntrospectHandler()).andReturn(null); + EasyMock.expect(lookupExtractorFactory.get()).andReturn(new MapLookupExtractor(ImmutableMap.of(), false)).anyTimes(); + EasyMock.replay(lookupExtractorFactory); + Assert.assertEquals(Response.status(Response.Status.NOT_FOUND).build().getStatus(), ((Response) lookupIntrospectionResource.introspectLookup("lookupId")).getStatus()); + } + + + @Test + public void testNotExistingLookup() + { + Assert.assertEquals(Response.status(Response.Status.NOT_FOUND).build().getStatus(), ((Response) lookupIntrospectionResource.introspectLookup("not there")).getStatus()); + } + + @Test public void testExistingLookup() + { + EasyMock.expect(lookupExtractorFactory.getIntrospectHandler()).andReturn(lookupIntrospectHandler); + EasyMock.expect(lookupExtractorFactory.get()).andReturn(new MapLookupExtractor(ImmutableMap.of(), false)).anyTimes(); + EasyMock.replay(lookupExtractorFactory); + Assert.assertEquals(lookupIntrospectHandler, lookupIntrospectionResource.introspectLookup("lookupId")); + } + @Test + @Ignore + public void testIntrospection() + { + + LookupIntrospectHandler lookupIntrospectHandler = new LookupIntrospectHandler() + { + @POST + public Response postMock(InputStream inputStream){ + return Response.ok().build(); + } + }; + + LookupExtractorFactory lookupExtractorFactory1 = new LookupExtractorFactory() + { + final LookupExtractor mapLookup = new MapLookupExtractor(ImmutableMap.of("key", "value"), true); + + @Override + public boolean start() + { + return true; + } + + @Override + public boolean close() + { + return true; + } + + @Override + public boolean replaces(@Nullable LookupExtractorFactory other) + { + return true; + } + + @Nullable + @Override + public LookupIntrospectHandler getIntrospectHandler() + { + return null; + } + + @Override + public LookupExtractor get() + { + return mapLookup; + } + }; + + LookupIntrospectionResource lookupIntrospectionResource = new LookupIntrospectionResource(lookupReferencesManager); + EasyMock.expect(lookupReferencesManager.get("lookupId1")).andReturn(lookupExtractorFactory1).anyTimes(); + EasyMock.replay(lookupReferencesManager); + + } +} diff --git a/processing/src/test/java/io/druid/query/lookup/LookupReferencesManagerTest.java b/server/src/test/java/io/druid/query/lookup/LookupReferencesManagerTest.java similarity index 99% rename from processing/src/test/java/io/druid/query/lookup/LookupReferencesManagerTest.java rename to server/src/test/java/io/druid/query/lookup/LookupReferencesManagerTest.java index 1308a6284eca..9ee103c1ee58 100644 --- a/processing/src/test/java/io/druid/query/lookup/LookupReferencesManagerTest.java +++ b/server/src/test/java/io/druid/query/lookup/LookupReferencesManagerTest.java @@ -24,7 +24,6 @@ import com.google.common.io.Files; import com.metamx.common.ISE; import io.druid.jackson.DefaultObjectMapper; -import io.druid.query.extraction.MapLookupExtractorFactory; import org.easymock.EasyMock; import org.junit.After; import org.junit.Assert; @@ -45,6 +44,7 @@ public class LookupReferencesManagerTest @Before public void setUp() throws IOException { + mapper.registerSubtypes(MapLookupExtractorFactory.class); lookupReferencesManager = new LookupReferencesManager(new LookupConfig(Files.createTempDir().getAbsolutePath()), mapper); Assert.assertTrue("must be closed before start call", lookupReferencesManager.isClosed()); lookupReferencesManager.start(); @@ -260,5 +260,4 @@ public void testBootstrapFromFile() throws IOException Assert.assertEquals(lookupExtractorFactory, lookupReferencesManager.get("testMockForBootstrap")); } - } diff --git a/processing/src/test/java/io/druid/query/lookup/LookupSnapshotTakerTest.java b/server/src/test/java/io/druid/query/lookup/LookupSnapshotTakerTest.java similarity index 98% rename from processing/src/test/java/io/druid/query/lookup/LookupSnapshotTakerTest.java rename to server/src/test/java/io/druid/query/lookup/LookupSnapshotTakerTest.java index 08e7d9d6d610..2f68ee30a355 100644 --- a/processing/src/test/java/io/druid/query/lookup/LookupSnapshotTakerTest.java +++ b/server/src/test/java/io/druid/query/lookup/LookupSnapshotTakerTest.java @@ -25,7 +25,6 @@ import com.google.common.io.Files; import com.metamx.common.ISE; import com.metamx.common.StringUtils; -import io.druid.query.extraction.MapLookupExtractorFactory; import io.druid.segment.TestHelper; import org.junit.Assert; import org.junit.Before; @@ -52,6 +51,7 @@ public class LookupSnapshotTakerTest @Before public void setUp() throws IOException { + mapper.registerSubtypes(MapLookupExtractorFactory.class); basePersistDirectory = temporaryFolder.newFolder().getAbsolutePath(); lookupSnapshotTaker = new LookupSnapshotTaker(mapper, basePersistDirectory); } diff --git a/processing/src/test/java/io/druid/query/extraction/MapLookupExtractorFactoryTest.java b/server/src/test/java/io/druid/query/lookup/MapLookupExtractorFactoryTest.java similarity index 84% rename from processing/src/test/java/io/druid/query/extraction/MapLookupExtractorFactoryTest.java rename to server/src/test/java/io/druid/query/lookup/MapLookupExtractorFactoryTest.java index 8074fcc85c08..c8fefe6e6704 100644 --- a/processing/src/test/java/io/druid/query/extraction/MapLookupExtractorFactoryTest.java +++ b/server/src/test/java/io/druid/query/lookup/MapLookupExtractorFactoryTest.java @@ -1,28 +1,27 @@ /* * Licensed to Metamarkets Group Inc. (Metamarkets) under one - * or more contributor license agreements. See the NOTICE file + * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information - * regarding copyright ownership. Metamarkets licenses this file + * regarding copyright ownership. Metamarkets licenses this file * to you 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 + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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 + * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ -package io.druid.query.extraction; +package io.druid.query.lookup; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableMap; import io.druid.jackson.DefaultObjectMapper; -import io.druid.query.lookup.LookupExtractorFactory; import org.junit.Assert; import org.junit.Test; @@ -56,6 +55,7 @@ public void testReplaces() public void testSerDeserMapLookupExtractorFactory() throws IOException { ObjectMapper mapper = new DefaultObjectMapper(); + mapper.registerSubtypes(MapLookupExtractorFactory.class); LookupExtractorFactory lookupExtractorFactory = new MapLookupExtractorFactory(ImmutableMap.of("key", "value"), true); Assert.assertEquals(lookupExtractorFactory, mapper.reader(LookupExtractorFactory.class).readValue(mapper.writeValueAsString(lookupExtractorFactory))); }