From a0a28de5516a54c77de826097050ed413b442118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20L=C3=A9aut=C3=A9?= Date: Wed, 22 Apr 2015 10:47:12 -0700 Subject: [PATCH] fix serde issue when pulling timestamps from cache --- .../search/SearchQueryQueryToolChest.java | 4 +- .../TimeBoundaryQueryQueryToolChest.java | 2 +- .../query/topn/TopNQueryQueryToolChest.java | 2 +- .../search/SearchQueryQueryToolChestTest.java | 87 +++++++++++++++++ .../TimeBoundaryQueryQueryToolChestTest.java | 54 ++++++++++- .../TimeseriesQueryQueryToolChestTest.java | 84 ++++++++++++++++ .../topn/TopNQueryQueryToolChestTest.java | 96 +++++++++++++++++++ 7 files changed, 324 insertions(+), 5 deletions(-) create mode 100644 processing/src/test/java/io/druid/query/search/SearchQueryQueryToolChestTest.java create mode 100644 processing/src/test/java/io/druid/query/timeseries/TimeseriesQueryQueryToolChestTest.java create mode 100644 processing/src/test/java/io/druid/query/topn/TopNQueryQueryToolChestTest.java diff --git a/processing/src/main/java/io/druid/query/search/SearchQueryQueryToolChest.java b/processing/src/main/java/io/druid/query/search/SearchQueryQueryToolChest.java index 33dcdb47a04..d0a25d31368 100644 --- a/processing/src/main/java/io/druid/query/search/SearchQueryQueryToolChest.java +++ b/processing/src/main/java/io/druid/query/search/SearchQueryQueryToolChest.java @@ -214,8 +214,8 @@ public class SearchQueryQueryToolChest extends QueryToolChest result = (List) input; - return new Result( - new DateTime(result.get(0)), + return new Result<>( + new DateTime(((Number)result.get(0)).longValue()), new SearchResultValue( Lists.transform( (List) result.get(1), diff --git a/processing/src/main/java/io/druid/query/timeboundary/TimeBoundaryQueryQueryToolChest.java b/processing/src/main/java/io/druid/query/timeboundary/TimeBoundaryQueryQueryToolChest.java index 4239e9058c3..62167cd1e42 100644 --- a/processing/src/main/java/io/druid/query/timeboundary/TimeBoundaryQueryQueryToolChest.java +++ b/processing/src/main/java/io/druid/query/timeboundary/TimeBoundaryQueryQueryToolChest.java @@ -187,7 +187,7 @@ public class TimeBoundaryQueryQueryToolChest List result = (List) input; return new Result<>( - new DateTime(result.get(0)), + new DateTime(((Number)result.get(0)).longValue()), new TimeBoundaryResultValue(result.get(1)) ); } diff --git a/processing/src/main/java/io/druid/query/topn/TopNQueryQueryToolChest.java b/processing/src/main/java/io/druid/query/topn/TopNQueryQueryToolChest.java index a6569b52e39..b9d52e02b34 100644 --- a/processing/src/main/java/io/druid/query/topn/TopNQueryQueryToolChest.java +++ b/processing/src/main/java/io/druid/query/topn/TopNQueryQueryToolChest.java @@ -380,7 +380,7 @@ public class TopNQueryQueryToolChest extends QueryToolChest> retVal = Lists.newArrayListWithCapacity(results.size()); Iterator inputIter = results.iterator(); - DateTime timestamp = granularity.toDateTime(new DateTime(inputIter.next()).getMillis()); + DateTime timestamp = granularity.toDateTime(((Number) inputIter.next()).longValue()); while (inputIter.hasNext()) { List result = (List) inputIter.next(); diff --git a/processing/src/test/java/io/druid/query/search/SearchQueryQueryToolChestTest.java b/processing/src/test/java/io/druid/query/search/SearchQueryQueryToolChestTest.java new file mode 100644 index 00000000000..c493b9e8b3f --- /dev/null +++ b/processing/src/test/java/io/druid/query/search/SearchQueryQueryToolChestTest.java @@ -0,0 +1,87 @@ +/* + * 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.search; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableList; +import io.druid.granularity.QueryGranularity; +import io.druid.jackson.DefaultObjectMapper; +import io.druid.query.CacheStrategy; +import io.druid.query.Result; +import io.druid.query.TableDataSource; +import io.druid.query.search.search.FragmentSearchQuerySpec; +import io.druid.query.search.search.SearchHit; +import io.druid.query.search.search.SearchQuery; +import io.druid.query.spec.MultipleIntervalSegmentSpec; +import org.joda.time.DateTime; +import org.joda.time.Interval; +import org.junit.Assert; +import org.junit.Test; + +public class SearchQueryQueryToolChestTest +{ + + @Test + public void testCacheStrategy() throws Exception + { + CacheStrategy, Object, SearchQuery> strategy = + new SearchQueryQueryToolChest(null, null).getCacheStrategy( + new SearchQuery( + new TableDataSource("dummy"), + null, + QueryGranularity.ALL, + 1, + new MultipleIntervalSegmentSpec( + ImmutableList.of( + new Interval( + "2015-01-01/2015-01-02" + ) + ) + ), + ImmutableList.of("dim1"), + new FragmentSearchQuerySpec(ImmutableList.of("a", "b")), + null, + null + ) + ); + + final Result result = new Result<>( + new DateTime(123L), new SearchResultValue( + ImmutableList.of( + new SearchHit("dim1", "a") + ) + ) + ); + + Object preparedValue = strategy.prepareForCache().apply( + result + ); + + ObjectMapper objectMapper = new DefaultObjectMapper(); + Object fromCacheValue = objectMapper.readValue( + objectMapper.writeValueAsBytes(preparedValue), + strategy.getCacheObjectClazz() + ); + + Result fromCacheResult = strategy.pullFromCache().apply(fromCacheValue); + + Assert.assertEquals(result, fromCacheResult); + } +} diff --git a/processing/src/test/java/io/druid/query/timeboundary/TimeBoundaryQueryQueryToolChestTest.java b/processing/src/test/java/io/druid/query/timeboundary/TimeBoundaryQueryQueryToolChestTest.java index 6612e4253c0..2f902d828fe 100644 --- a/processing/src/test/java/io/druid/query/timeboundary/TimeBoundaryQueryQueryToolChestTest.java +++ b/processing/src/test/java/io/druid/query/timeboundary/TimeBoundaryQueryQueryToolChestTest.java @@ -17,9 +17,18 @@ package io.druid.query.timeboundary; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import io.druid.jackson.DefaultObjectMapper; +import io.druid.query.CacheStrategy; +import io.druid.query.Result; +import io.druid.query.TableDataSource; +import io.druid.query.spec.MultipleIntervalSegmentSpec; import io.druid.timeline.LogicalSegment; -import junit.framework.Assert; +import org.joda.time.DateTime; import org.joda.time.Interval; +import org.junit.Assert; import org.junit.Test; import java.util.Arrays; @@ -95,4 +104,47 @@ public class TimeBoundaryQueryQueryToolChestTest Assert.assertEquals(segments.get(i).getInterval(), expected.get(i).getInterval()); } } + + @Test + public void testCacheStrategy() throws Exception + { + CacheStrategy, Object, TimeBoundaryQuery> strategy = + new TimeBoundaryQueryQueryToolChest().getCacheStrategy( + new TimeBoundaryQuery( + new TableDataSource("dummy"), + new MultipleIntervalSegmentSpec( + ImmutableList.of( + new Interval( + "2015-01-01/2015-01-02" + ) + ) + ), + null, + null + ) + ); + + final Result result = new Result<>( + new DateTime(123L), new TimeBoundaryResultValue( + ImmutableMap.of( + TimeBoundaryQuery.MIN_TIME, new DateTime(0L).toString(), + TimeBoundaryQuery.MAX_TIME, new DateTime("2015-01-01").toString() + ) + ) + ); + + Object preparedValue = strategy.prepareForCache().apply( + result + ); + + ObjectMapper objectMapper = new DefaultObjectMapper(); + Object fromCacheValue = objectMapper.readValue( + objectMapper.writeValueAsBytes(preparedValue), + strategy.getCacheObjectClazz() + ); + + Result fromCacheResult = strategy.pullFromCache().apply(fromCacheValue); + + Assert.assertEquals(result, fromCacheResult); + } } diff --git a/processing/src/test/java/io/druid/query/timeseries/TimeseriesQueryQueryToolChestTest.java b/processing/src/test/java/io/druid/query/timeseries/TimeseriesQueryQueryToolChestTest.java new file mode 100644 index 00000000000..7523f9b459d --- /dev/null +++ b/processing/src/test/java/io/druid/query/timeseries/TimeseriesQueryQueryToolChestTest.java @@ -0,0 +1,84 @@ +/* + * 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.timeseries; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import io.druid.granularity.QueryGranularity; +import io.druid.jackson.DefaultObjectMapper; +import io.druid.query.CacheStrategy; +import io.druid.query.Result; +import io.druid.query.TableDataSource; +import io.druid.query.aggregation.AggregatorFactory; +import io.druid.query.aggregation.CountAggregatorFactory; +import io.druid.query.spec.MultipleIntervalSegmentSpec; +import org.joda.time.DateTime; +import org.joda.time.Interval; +import org.junit.Assert; +import org.junit.Test; + +public class TimeseriesQueryQueryToolChestTest +{ + + @Test + public void testCacheStrategy() throws Exception + { + + CacheStrategy, Object, TimeseriesQuery> strategy = + new TimeseriesQueryQueryToolChest(null).getCacheStrategy( + new TimeseriesQuery( + new TableDataSource("dummy"), + new MultipleIntervalSegmentSpec( + ImmutableList.of( + new Interval( + "2015-01-01/2015-01-02" + ) + ) + ), + null, + QueryGranularity.ALL, + ImmutableList.of(new CountAggregatorFactory("metric1")), + null, + null + ) + ); + + final Result result = new Result<>( + // test timestamps that result in integer size millis + new DateTime(123L), + new TimeseriesResultValue( + ImmutableMap.of("metric1", 2) + ) + ); + + Object preparedValue = strategy.prepareForCache().apply(result); + + ObjectMapper objectMapper = new DefaultObjectMapper(); + Object fromCacheValue = objectMapper.readValue( + objectMapper.writeValueAsBytes(preparedValue), + strategy.getCacheObjectClazz() + ); + + Result fromCacheResult = strategy.pullFromCache().apply(fromCacheValue); + + Assert.assertEquals(result, fromCacheResult); + } +} diff --git a/processing/src/test/java/io/druid/query/topn/TopNQueryQueryToolChestTest.java b/processing/src/test/java/io/druid/query/topn/TopNQueryQueryToolChestTest.java new file mode 100644 index 00000000000..111f8d4520d --- /dev/null +++ b/processing/src/test/java/io/druid/query/topn/TopNQueryQueryToolChestTest.java @@ -0,0 +1,96 @@ +/* + * 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.topn; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import io.druid.granularity.QueryGranularity; +import io.druid.jackson.DefaultObjectMapper; +import io.druid.query.CacheStrategy; +import io.druid.query.Result; +import io.druid.query.TableDataSource; +import io.druid.query.aggregation.AggregatorFactory; +import io.druid.query.aggregation.CountAggregatorFactory; +import io.druid.query.dimension.DefaultDimensionSpec; +import io.druid.query.spec.MultipleIntervalSegmentSpec; +import org.joda.time.DateTime; +import org.joda.time.Interval; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; + +public class TopNQueryQueryToolChestTest +{ + + @Test + public void testCacheStrategy() throws Exception + { + CacheStrategy, Object, TopNQuery> strategy = + new TopNQueryQueryToolChest(null, null).getCacheStrategy( + new TopNQuery( + new TableDataSource("dummy"), + new DefaultDimensionSpec("test", "test"), + new NumericTopNMetricSpec("metric1"), + 3, + new MultipleIntervalSegmentSpec( + ImmutableList.of( + new Interval( + "2015-01-01/2015-01-02" + ) + ) + ), + null, + QueryGranularity.ALL, + ImmutableList.of(new CountAggregatorFactory("metric1")), + null, + null + ) + ); + + final Result result = new Result<>( + // test timestamps that result in integer size millis + new DateTime(123L), + new TopNResultValue( + Arrays.asList( + ImmutableMap.of( + "test", "val1", + "metric1", 2 + ) + ) + ) + ); + + Object preparedValue = strategy.prepareForCache().apply( + result + ); + + ObjectMapper objectMapper = new DefaultObjectMapper(); + Object fromCacheValue = objectMapper.readValue( + objectMapper.writeValueAsBytes(preparedValue), + strategy.getCacheObjectClazz() + ); + + Result fromCacheResult = strategy.pullFromCache().apply(fromCacheValue); + + Assert.assertEquals(result, fromCacheResult); + } +}