blob: 557dca72effcae6f3de4ac873f527c36b1922056 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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 org.apache.druid.benchmark;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.wnameless.json.flattener.JsonFlattener;
import org.apache.druid.data.input.impl.DimensionsSpec;
import org.apache.druid.data.input.impl.JSONParseSpec;
import org.apache.druid.data.input.impl.TimestampSpec;
import org.apache.druid.jackson.DefaultObjectMapper;
import org.apache.druid.java.util.common.parsers.JSONPathFieldSpec;
import org.apache.druid.java.util.common.parsers.JSONPathSpec;
import org.apache.druid.java.util.common.parsers.Parser;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class FlattenJSONBenchmarkUtil
{
private static final String DEFAULT_TIMESTAMP = "2015-09-12T12:10:53.155Z";
private final Random rng = new Random(9999);
private final ObjectMapper mapper = new DefaultObjectMapper();
public FlattenJSONBenchmarkUtil()
{
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.PUBLIC_ONLY);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
public Parser getFlatParser()
{
JSONParseSpec spec = new JSONParseSpec(
new TimestampSpec("ts", "iso", null),
new DimensionsSpec(null, null, null),
null,
null,
null
);
return spec.makeParser();
}
public Parser getFieldDiscoveryParser()
{
List<JSONPathFieldSpec> fields = new ArrayList<>();
JSONPathSpec flattenSpec = new JSONPathSpec(true, fields);
JSONParseSpec spec = new JSONParseSpec(
new TimestampSpec("ts", "iso", null),
new DimensionsSpec(null, null, null),
flattenSpec,
null,
null
);
return spec.makeParser();
}
public Parser getNestedParser()
{
List<JSONPathFieldSpec> fields = new ArrayList<>();
fields.add(JSONPathFieldSpec.createRootField("ts"));
fields.add(JSONPathFieldSpec.createRootField("d1"));
//fields.add(JSONPathFieldSpec.createRootField("d2"));
fields.add(JSONPathFieldSpec.createNestedField("e1.d1", "$.e1.d1"));
fields.add(JSONPathFieldSpec.createNestedField("e1.d2", "$.e1.d2"));
fields.add(JSONPathFieldSpec.createNestedField("e2.d3", "$.e2.d3"));
fields.add(JSONPathFieldSpec.createNestedField("e2.d4", "$.e2.d4"));
fields.add(JSONPathFieldSpec.createNestedField("e2.d5", "$.e2.d5"));
fields.add(JSONPathFieldSpec.createNestedField("e2.d6", "$.e2.d6"));
fields.add(JSONPathFieldSpec.createNestedField("e2.ad1[0]", "$.e2.ad1[0]"));
fields.add(JSONPathFieldSpec.createNestedField("e2.ad1[1]", "$.e2.ad1[1]"));
fields.add(JSONPathFieldSpec.createNestedField("e2.ad1[2]", "$.e2.ad1[2]"));
fields.add(JSONPathFieldSpec.createNestedField("ae1[0].d1", "$.ae1[0].d1"));
fields.add(JSONPathFieldSpec.createNestedField("ae1[1].d1", "$.ae1[1].d1"));
fields.add(JSONPathFieldSpec.createNestedField("ae1[2].e1.d2", "$.ae1[2].e1.d2"));
fields.add(JSONPathFieldSpec.createRootField("m3"));
//fields.add(JSONPathFieldSpec.createRootField("m4"));
fields.add(JSONPathFieldSpec.createNestedField("e3.m1", "$.e3.m1"));
fields.add(JSONPathFieldSpec.createNestedField("e3.m2", "$.e3.m2"));
fields.add(JSONPathFieldSpec.createNestedField("e3.m3", "$.e3.m3"));
fields.add(JSONPathFieldSpec.createNestedField("e3.m4", "$.e3.m4"));
fields.add(JSONPathFieldSpec.createNestedField("e3.am1[0]", "$.e3.am1[0]"));
fields.add(JSONPathFieldSpec.createNestedField("e3.am1[1]", "$.e3.am1[1]"));
fields.add(JSONPathFieldSpec.createNestedField("e3.am1[2]", "$.e3.am1[2]"));
fields.add(JSONPathFieldSpec.createNestedField("e3.am1[3]", "$.e3.am1[3]"));
fields.add(JSONPathFieldSpec.createNestedField("e4.e4.m4", "$.e4.e4.m4"));
JSONPathSpec flattenSpec = new JSONPathSpec(true, fields);
JSONParseSpec spec = new JSONParseSpec(
new TimestampSpec("ts", "iso", null),
new DimensionsSpec(null, null, null),
flattenSpec,
null,
null
);
return spec.makeParser();
}
public Parser getForcedPathParser()
{
List<JSONPathFieldSpec> fields = new ArrayList<>();
fields.add(JSONPathFieldSpec.createNestedField("ts", "$['ts']"));
fields.add(JSONPathFieldSpec.createNestedField("d1", "$['d1']"));
fields.add(JSONPathFieldSpec.createNestedField("d2", "$['d2']"));
fields.add(JSONPathFieldSpec.createNestedField("e1.d1", "$['e1.d1']"));
fields.add(JSONPathFieldSpec.createNestedField("e1.d2", "$['e1.d2']"));
fields.add(JSONPathFieldSpec.createNestedField("e2.d3", "$['e2.d3']"));
fields.add(JSONPathFieldSpec.createNestedField("e2.d4", "$['e2.d4']"));
fields.add(JSONPathFieldSpec.createNestedField("e2.d5", "$['e2.d5']"));
fields.add(JSONPathFieldSpec.createNestedField("e2.d6", "$['e2.d6']"));
fields.add(JSONPathFieldSpec.createNestedField("e2.ad1[0]", "$['e2.ad1[0]']"));
fields.add(JSONPathFieldSpec.createNestedField("e2.ad1[1]", "$['e2.ad1[1]']"));
fields.add(JSONPathFieldSpec.createNestedField("e2.ad1[2]", "$['e2.ad1[2]']"));
fields.add(JSONPathFieldSpec.createNestedField("ae1[0].d1", "$['ae1[0].d1']"));
fields.add(JSONPathFieldSpec.createNestedField("ae1[1].d1", "$['ae1[1].d1']"));
fields.add(JSONPathFieldSpec.createNestedField("ae1[2].e1.d2", "$['ae1[2].e1.d2']"));
fields.add(JSONPathFieldSpec.createNestedField("m3", "$['m3']"));
fields.add(JSONPathFieldSpec.createNestedField("m4", "$['m4']"));
fields.add(JSONPathFieldSpec.createNestedField("e3.m1", "$['e3.m1']"));
fields.add(JSONPathFieldSpec.createNestedField("e3.m2", "$['e3.m2']"));
fields.add(JSONPathFieldSpec.createNestedField("e3.m3", "$['e3.m3']"));
fields.add(JSONPathFieldSpec.createNestedField("e3.m4", "$['e3.m4']"));
fields.add(JSONPathFieldSpec.createNestedField("e3.am1[0]", "$['e3.am1[0]']"));
fields.add(JSONPathFieldSpec.createNestedField("e3.am1[1]", "$['e3.am1[1]']"));
fields.add(JSONPathFieldSpec.createNestedField("e3.am1[2]", "$['e3.am1[2]']"));
fields.add(JSONPathFieldSpec.createNestedField("e3.am1[3]", "$['e3.am1[3]']"));
fields.add(JSONPathFieldSpec.createNestedField("e4.e4.m4", "$['e4.e4.m4']"));
JSONPathSpec flattenSpec = new JSONPathSpec(false, fields);
JSONParseSpec spec = new JSONParseSpec(
new TimestampSpec("ts", "iso", null),
new DimensionsSpec(null, null, null),
flattenSpec,
null,
null
);
return spec.makeParser();
}
public Parser getJqParser()
{
List<JSONPathFieldSpec> fields = new ArrayList<>();
fields.add(JSONPathFieldSpec.createRootField("ts"));
fields.add(JSONPathFieldSpec.createRootField("d1"));
fields.add(JSONPathFieldSpec.createJqField("e1.d1", ".e1.d1"));
fields.add(JSONPathFieldSpec.createJqField("e1.d2", ".e1.d2"));
fields.add(JSONPathFieldSpec.createJqField("e2.d3", ".e2.d3"));
fields.add(JSONPathFieldSpec.createJqField("e2.d4", ".e2.d4"));
fields.add(JSONPathFieldSpec.createJqField("e2.d5", ".e2.d5"));
fields.add(JSONPathFieldSpec.createJqField("e2.d6", ".e2.d6"));
fields.add(JSONPathFieldSpec.createJqField("e2.ad1[0]", ".e2.ad1[0]"));
fields.add(JSONPathFieldSpec.createJqField("e2.ad1[1]", ".e2.ad1[1]"));
fields.add(JSONPathFieldSpec.createJqField("e2.ad1[2]", ".e2.ad1[2]"));
fields.add(JSONPathFieldSpec.createJqField("ae1[0].d1", ".ae1[0].d1"));
fields.add(JSONPathFieldSpec.createJqField("ae1[1].d1", ".ae1[1].d1"));
fields.add(JSONPathFieldSpec.createJqField("ae1[2].e1.d2", ".ae1[2].e1.d2"));
fields.add(JSONPathFieldSpec.createRootField("m3"));
fields.add(JSONPathFieldSpec.createJqField("e3.m1", ".e3.m1"));
fields.add(JSONPathFieldSpec.createJqField("e3.m2", ".e3.m2"));
fields.add(JSONPathFieldSpec.createJqField("e3.m3", ".e3.m3"));
fields.add(JSONPathFieldSpec.createJqField("e3.m4", ".e3.m4"));
fields.add(JSONPathFieldSpec.createJqField("e3.am1[0]", ".e3.am1[0]"));
fields.add(JSONPathFieldSpec.createJqField("e3.am1[1]", ".e3.am1[1]"));
fields.add(JSONPathFieldSpec.createJqField("e3.am1[2]", ".e3.am1[2]"));
fields.add(JSONPathFieldSpec.createJqField("e3.am1[3]", ".e3.am1[3]"));
fields.add(JSONPathFieldSpec.createJqField("e4.e4.m4", ".e4.e4.m4"));
JSONPathSpec flattenSpec = new JSONPathSpec(true, fields);
JSONParseSpec spec = new JSONParseSpec(
new TimestampSpec("ts", "iso", null),
new DimensionsSpec(null, null, null),
flattenSpec,
null,
null
);
return spec.makeParser();
}
public String generateFlatEvent() throws Exception
{
String nestedEvent = generateNestedEvent();
String flatEvent = JsonFlattener.flatten(nestedEvent);
return flatEvent;
}
/*
e.g.,
{
"d1":"-889954295",
"d2":"-1724267856",
"m3":0.1429096312550323,
"m4":-7491190942271782800,
"e1":{"d1":"2044704643",
"d2":"743384585"},
"e2":{"d3":"1879234327",
"d4":"1248394579",
"d5":"-639742676",
"d6":"1334864967",
"ad1":["-684042233","-1368392605","1826364033"]},
"e3":{"m1":1026394465228315487,
"m2":0.27737174619459004,
"m3":0.011921350960908628,
"m4":-7507319256575520484,
"am1":[-2383262648875933574,-3980663171371801209,-8225906222712163481,6074309311406287835]},
"e4":{"e4":{"m4":32836881083689842}},
"ae1":[{"d1":"-1797792200"},{"d1":"142582995"},{"e1":{"d2":"-1341994709"}}],
"ts":"2015-09-12T12:10:53.155Z"
}
*/
public String generateNestedEvent() throws Exception
{
BenchmarkEvent nestedDims1 = new BenchmarkEvent(
null,
String.valueOf(rng.nextInt()), String.valueOf(rng.nextInt()), null, null, null, null,
null, null, null, null,
null, null, null, null,
null, null, null
);
String[] dimsArray1 = {String.valueOf(rng.nextInt()), String.valueOf(rng.nextInt()), String.valueOf(rng.nextInt())};
BenchmarkEvent nestedDims2 = new BenchmarkEvent(
null,
null, null, String.valueOf(rng.nextInt()), String.valueOf(rng.nextInt()), String.valueOf(rng.nextInt()), String.valueOf(rng.nextInt()),
null, null, null, null,
null, null, null, null,
dimsArray1, null, null
);
Long[] metricsArray1 = {rng.nextLong(), rng.nextLong(), rng.nextLong(), rng.nextLong()};
BenchmarkEvent nestedMetrics1 = new BenchmarkEvent(
null,
null, null, null, null, null, null,
rng.nextLong(), rng.nextDouble(), rng.nextDouble(), rng.nextLong(),
null, null, null, null,
null, metricsArray1, null
);
BenchmarkEvent nestedMetrics2 = new BenchmarkEvent(
null,
null, null, null, null, null, null,
null, null, null, rng.nextLong(),
null, null, null, null,
null, null, null
);
BenchmarkEvent metricsWrapper = new BenchmarkEvent(
null,
null, null, null, null, null, null,
null, null, null, null,
null, null, null, nestedMetrics2,
null, null, null
);
//nest some dimensions in an array!
BenchmarkEvent arrayNestedDim1 = new BenchmarkEvent(
null,
String.valueOf(rng.nextInt()), null, null, null, null, null,
null, null, null, null,
null, null, null, null,
null, null, null
);
BenchmarkEvent arrayNestedDim2 = new BenchmarkEvent(
null,
String.valueOf(rng.nextInt()), null, null, null, null, null,
null, null, null, null,
null, null, null, null,
null, null, null
);
BenchmarkEvent arrayNestedDim3 = new BenchmarkEvent(
null,
null, String.valueOf(rng.nextInt()), null, null, null, null,
null, null, null, null,
null, null, null, null,
null, null, null
);
BenchmarkEvent arrayNestedWrapper = new BenchmarkEvent(
null,
null, null, null, null, null, null,
null, null, null, null,
arrayNestedDim3, null, null, null,
null, null, null
);
BenchmarkEvent[] eventArray = {arrayNestedDim1, arrayNestedDim2, arrayNestedWrapper};
Long[] ignoredMetrics = {Long.valueOf(10), Long.valueOf(20), Long.valueOf(30)};
BenchmarkEvent wrapper = new BenchmarkEvent(
DEFAULT_TIMESTAMP,
String.valueOf(rng.nextInt()), String.valueOf(rng.nextInt()), null, null, null, null,
null, null, rng.nextDouble(), rng.nextLong(),
nestedDims1, nestedDims2, nestedMetrics1, metricsWrapper,
null, ignoredMetrics, eventArray
);
return mapper.writeValueAsString(wrapper);
}
public static class BenchmarkEvent
{
public String ts;
@JsonProperty
public String getTs()
{
return ts;
}
@JsonProperty
public String getD1()
{
return d1;
}
@JsonProperty
public String getD2()
{
return d2;
}
@JsonProperty
public String getD3()
{
return d3;
}
@JsonProperty
public String getD4()
{
return d4;
}
@JsonProperty
public String getD5()
{
return d5;
}
@JsonProperty
public String getD6()
{
return d6;
}
@JsonProperty
public Long getM1()
{
return m1;
}
@JsonProperty
public Double getM2()
{
return m2;
}
@JsonProperty
public Double getM3()
{
return m3;
}
@JsonProperty
public Long getM4()
{
return m4;
}
@JsonProperty
public BenchmarkEvent getE1()
{
return e1;
}
@JsonProperty
public BenchmarkEvent getE2()
{
return e2;
}
@JsonProperty
public BenchmarkEvent getE3()
{
return e3;
}
@JsonProperty
public BenchmarkEvent getE4()
{
return e4;
}
@JsonProperty
public String[] getAd1()
{
return ad1;
}
@JsonProperty
public Long[] getAm1()
{
return am1;
}
@JsonProperty
public BenchmarkEvent[] getAe1()
{
return ae1;
}
public String d1;
public String d2;
public String d3;
public String d4;
public String d5;
public String d6;
public Long m1;
public Double m2;
public Double m3;
public Long m4;
public BenchmarkEvent e1;
public BenchmarkEvent e2;
public BenchmarkEvent e3;
public BenchmarkEvent e4;
public String[] ad1;
public Long[] am1;
public BenchmarkEvent[] ae1;
@JsonCreator
public BenchmarkEvent(
@JsonProperty("ts") String ts,
@JsonProperty("d1") String d1,
@JsonProperty("d2") String d2,
@JsonProperty("d3") String d3,
@JsonProperty("d4") String d4,
@JsonProperty("d5") String d5,
@JsonProperty("d6") String d6,
@JsonProperty("m1") Long m1,
@JsonProperty("m2") Double m2,
@JsonProperty("m3") Double m3,
@JsonProperty("m4") Long m4,
@JsonProperty("e1") BenchmarkEvent e1,
@JsonProperty("e2") BenchmarkEvent e2,
@JsonProperty("e3") BenchmarkEvent e3,
@JsonProperty("e4") BenchmarkEvent e4,
@JsonProperty("ad1") String[] ad1,
@JsonProperty("am1") Long[] am1,
@JsonProperty("ae1") BenchmarkEvent[] ae1
)
{
this.ts = ts;
this.d1 = d1;
this.d2 = d2;
this.d3 = d3;
this.d4 = d4;
this.d5 = d5;
this.d6 = d6;
this.m1 = m1;
this.m2 = m2;
this.m3 = m3;
this.m4 = m4;
this.e1 = e1;
this.e2 = e2;
this.e3 = e3;
this.e4 = e4;
this.ad1 = ad1;
this.am1 = am1;
this.ae1 = ae1;
}
}
}