Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge feature/vector tiles branch to master #73872

Merged
merged 27 commits into from
Jun 18, 2021
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e0e8d6e
initial skeleton of vector tiles prototype implementation (#69338)
iverase Mar 30, 2021
bf2b209
Vector Tiles: Start refactoring rest layer (#71080)
imotov Mar 31, 2021
e3acfc6
Vector Tiles: continue REST layer refactoring (#71259)
imotov Apr 6, 2021
14826ec
simplify mvt end point (#71548)
iverase Apr 13, 2021
7b6f3da
Vector Tiles: add a more generic way of building meta layer (#71804)
imotov Apr 19, 2021
9a86dde
Merge branch 'master' into feature/vector-tiles
iverase Apr 21, 2021
d6cfec0
Add value ranges for GeoTile aggregation metrics metrics in the meta …
iverase Apr 22, 2021
c4f919d
Vector Tiles: add support for array serialization in meta layer (#72136)
imotov Apr 24, 2021
cf360ce
Merge branch 'master' into feature/vector-tiles
iverase Apr 27, 2021
bfbd991
Merge branch 'master' into feature/vector-tiles
iverase Apr 29, 2021
2fe2ee7
Vector Tiles: Add support for feature flag (#72657)
imotov May 4, 2021
4528e78
Merge branch 'master' into feature/vector-tiles
iverase May 12, 2021
18e30d9
Merge branch 'master' into feature/vector-tiles
iverase May 26, 2021
09056ed
Merge branch 'master' into feature/vector-tiles
iverase May 27, 2021
929ff3c
Merge branch 'master' into feature/vector-tiles
iverase May 31, 2021
2b27561
Move vector tile implementation to its own module (#73562)
iverase Jun 2, 2021
2afb4ac
Merge branch 'master' into feature/vector-tiles
iverase Jun 2, 2021
9cbc5f7
Merge branch 'master' into feature/vector-tiles
iverase Jun 7, 2021
f364883
Fix extra line in build.gradle from spatial module (#73816)
iverase Jun 7, 2021
ad11159
Merge remote-tracking branch 'elastic/master' into feature/vector-tiles
imotov Jun 7, 2021
88a43f9
Update x-pack/plugin/vector-tile/src/main/java/org/elasticsearch/xpac…
imotov Jun 16, 2021
106a965
Update x-pack/plugin/vector-tile/src/main/java/org/elasticsearch/xpac…
imotov Jun 16, 2021
6a8f8f3
Merge remote-tracking branch 'elastic/master' into feature/vector-tiles
imotov Jun 16, 2021
19ade1e
Fix vector tile plugin after master merge
imotov Jun 16, 2021
29f939a
Address review comments
imotov Jun 16, 2021
8ae6cf4
Fix spotless issues
imotov Jun 17, 2021
82ae674
Merge branch 'master' into feature/vector-tiles
elasticmachine Jun 17, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 45 additions & 6 deletions server/src/main/java/org/elasticsearch/common/util/Maps.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand Down Expand Up @@ -62,7 +64,7 @@ public static <K, V> Map<K, V> copyMapWithAddedOrReplacedEntry(final Map<K, V> m
Objects.requireNonNull(value);
assert checkIsImmutableMap(map, key, value);
return Stream.concat(map.entrySet().stream().filter(k -> key.equals(k.getKey()) == false), Stream.of(entry(key, value)))
.collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue));
.collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue));
}

/**
Expand All @@ -85,10 +87,10 @@ public static <K, V> Map<K, V> copyMapWithRemovedEntry(final Map<K, V> map, fina

// map classes that are known to be immutable, used to speed up immutability check in #assertImmutableMap
private static final Set<Class<?>> IMMUTABLE_MAP_CLASSES = Set.of(
Collections.emptyMap().getClass(),
Collections.unmodifiableMap(new HashMap<>()).getClass(),
Map.of().getClass(),
Map.of("a", "b").getClass()
Collections.emptyMap().getClass(),
Collections.unmodifiableMap(new HashMap<>()).getClass(),
Map.of().getClass(),
Map.of("a", "b").getClass()
);

private static <K, V> boolean checkIsImmutableMap(final Map<K, V> map, final K key, final V value) {
Expand Down Expand Up @@ -135,7 +137,44 @@ public static <K, V> boolean deepEquals(Map<K, V> left, Map<K, V> right) {
return false;
}
return left.entrySet().stream()
.allMatch(e -> right.containsKey(e.getKey()) && Objects.deepEquals(e.getValue(), right.get(e.getKey())));
.allMatch(e -> right.containsKey(e.getKey()) && Objects.deepEquals(e.getValue(), right.get(e.getKey())));
}

public static Map<String, Object> flatten(Map<String, Object> map, boolean flattenArrays, boolean ordered) {
return flatten(map, flattenArrays, ordered, null);
}

@SuppressWarnings("unchecked")
private static Map<String, Object> flatten(Map<String, Object> map, boolean flattenArrays, boolean ordered, String parentPath) {
Map<String, Object> flatMap = ordered ? new TreeMap<>() : new HashMap<>();
String prefix = parentPath != null ? parentPath + "." : "";
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getValue() instanceof Map) {
flatMap.putAll(flatten((Map<String, Object>) entry.getValue(), flattenArrays, ordered, prefix + entry.getKey()));
} else if (flattenArrays && entry.getValue() instanceof List) {
flatMap.putAll(flatten((List<Object>) entry.getValue(), ordered, prefix + entry.getKey()));
} else {
flatMap.put(prefix + entry.getKey(), entry.getValue());
}
}
return flatMap;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to care about the case when a field exists under two different paths in the map, so that one doesn't override the other? Let's document the behavior if we think it's acceptable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for our purpose overriding is acceptable. We can fix check for it and throw an exception if needed. I will add javadoc with the explanation of the limitations for now.

}

@SuppressWarnings("unchecked")
private static Map<String, Object> flatten(List<Object> list, boolean ordered, String parentPath) {
Map<String, Object> flatMap = ordered ? new TreeMap<>() : new HashMap<>();
String prefix = parentPath != null ? parentPath + "." : "";
for (int i = 0; i < list.size(); i++) {
Object cur = list.get(i);
if (cur instanceof Map) {
flatMap.putAll(flatten((Map<String, Object>) cur, true, ordered, prefix + i));
}
if (cur instanceof List) {
flatMap.putAll(flatten((List<Object>) cur, ordered, prefix + i));
} else {
flatMap.put(prefix + i, cur);
}
}
return flatMap;
}
}
65 changes: 65 additions & 0 deletions server/src/test/java/org/elasticsearch/common/util/MapsTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -122,6 +123,70 @@ public void testDeepEquals() {
assertFalse(Maps.deepEquals(map, mapModified));
}

public void testFlatten() {
Map<String, Object> map = randomNestedMap(10);
Map<String, Object> flatten = Maps.flatten(map, true, true);
assertThat(flatten.size(), equalTo(deepCount(map.values())));
for (Map.Entry<String, Object> entry : flatten.entrySet()) {
assertThat(entry.getKey(), entry.getValue(), equalTo(deepGet(entry.getKey(), map)));
}
}

@SuppressWarnings("unchecked")
private static Object deepGet(String path, Object obj) {
Object cur = obj;
String[] keys = path.split("\\.");
for (String key : keys) {
if (Character.isDigit(key.charAt(0))) {
List<Object> list = (List<Object>) cur;
cur = list.get(Integer.parseInt(key));
} else {
Map<String, Object> map = (Map<String, Object>) cur;
cur = map.get(key);
}
}
return cur;
}

@SuppressWarnings("unchecked")
private int deepCount(Collection<Object> map) {
int sum = 0;
for (Object val : map) {
if (val instanceof Map) {
sum += deepCount(((Map<String, Object>) val).values());
} else if (val instanceof List) {
sum += deepCount((List<Object>) val);
} else {
sum ++;
}
}
return sum;
}

private Map<String, Object> randomNestedMap(int level) {
final Supplier<String> keyGenerator = () -> randomAlphaOfLengthBetween(1, 5);
final Supplier<Object> arrayValueGenerator = () -> random().ints(randomInt(5))
.boxed()
.map(s -> (Object) s)
.collect(Collectors.toList());

final Supplier<Object> mapSupplier;
if (level > 0) {
mapSupplier = () -> randomNestedMap(level - 1);
} else {
mapSupplier = ESTestCase::randomLong;
}
final Supplier<Supplier<Object>> valueSupplier = () -> randomFrom(
ESTestCase::randomBoolean,
ESTestCase::randomDouble,
ESTestCase::randomLong,
arrayValueGenerator,
mapSupplier
);
final Supplier<Object> valueGenerator = () -> valueSupplier.get().get();
return randomMap(randomInt(5), keyGenerator, valueGenerator);
}

private void assertMapEntries(final Map<String, String> map, final Collection<Map.Entry<String, String>> entries) {
for (var entry : entries) {
assertThat("map [" + map + "] does not contain key [" + entry.getKey() + "]", map.keySet(), hasItem(entry.getKey()));
Expand Down
69 changes: 69 additions & 0 deletions x-pack/plugin/vector-tile/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import org.elasticsearch.gradle.internal.info.BuildParams

apply plugin: 'elasticsearch.internal-es-plugin'
apply plugin: 'elasticsearch.java-rest-test'

esplugin {
name 'vector-tile'
description 'A plugin for mapbox vector tile features'
classname 'org.elasticsearch.xpack.vectortile.VectorTilePlugin'
extendedPlugins = ['x-pack-core']
}

dependencies {
compileOnly project(path: xpackModule('core'))
testImplementation(testArtifact(project(xpackModule('core'))))
api "com.wdtinc:mapbox-vector-tile:3.1.0"
api "com.google.protobuf:protobuf-java:3.14.0"
javaRestTestImplementation("com.wdtinc:mapbox-vector-tile:3.1.0")
javaRestTestImplementation("com.google.protobuf:protobuf-java:3.14.0")
}

testClusters.all {
setting 'xpack.license.self_generated.type', 'trial'
testDistribution = 'DEFAULT'
setting 'xpack.security.enabled', 'false'
if (BuildParams.isSnapshotBuild() == false) {
systemProperty 'es.vector_tile_feature_flag_registered', 'true'
}
}

tasks.named("test").configure {
if (BuildParams.isSnapshotBuild() == false) {
systemProperty 'es.vector_tile_feature_flag_registered', 'true'
}
}

tasks.named("thirdPartyAudit").configure {
ignoreViolations(
// uses internal java api: sun.misc.Unsafe
'com.google.protobuf.UnsafeUtil',
'com.google.protobuf.MessageSchema',
'com.google.protobuf.UnsafeUtil$1',
'com.google.protobuf.UnsafeUtil$Android32MemoryAccessor',
'com.google.protobuf.UnsafeUtil$Android64MemoryAccessor',
'com.google.protobuf.UnsafeUtil$JvmMemoryAccessor',
'com.google.protobuf.UnsafeUtil$MemoryAccessor'
)

ignoreMissingClasses(
'org.slf4j.Logger',
'org.slf4j.LoggerFactory'
)
}

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
06c4432c7885a3938571a57e73cc1444d7a39f12
Loading