Skip to content

Commit f364393

Browse files
talevynknize
authored andcommitted
Introduce Spatial Plugin (elastic#44389)
This commit introduces a skeleton Spatial plugin that will be filled-in with some new licensed features coming to Geo/Spatial land!
1 parent b19de55 commit f364393

File tree

10 files changed

+282
-1
lines changed

10 files changed

+282
-1
lines changed

docs/reference/rest-api/info.asciidoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ Example response:
111111
"available" : true,
112112
"enabled" : false
113113
},
114+
"spatial" : {
115+
"available" : true,
116+
"enabled" : true
117+
},
114118
"sql" : {
115119
"available" : true,
116120
"enabled" : true

x-pack/plugin/core/src/main/java/org/elasticsearch/license/XPackLicenseState.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,22 @@ public synchronized boolean isOdbcAllowed() {
728728
return licensed && localStatus.active;
729729
}
730730

731+
/**
732+
* Determine if Spatial features should be enabled.
733+
* <p>
734+
* Spatial features are available in for all license types except
735+
* {@link OperationMode#MISSING}
736+
*
737+
* @return {@code true} as long as the license is valid. Otherwise
738+
* {@code false}.
739+
*/
740+
public boolean isSpatialAllowed() {
741+
// status is volatile
742+
Status localStatus = status;
743+
// Should work on all active licenses
744+
return localStatus.active;
745+
}
746+
731747
public synchronized boolean isTrialLicense() {
732748
return status.mode == OperationMode.TRIAL;
733749
}

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@
207207
import org.elasticsearch.xpack.core.slm.action.ExecuteSnapshotLifecycleAction;
208208
import org.elasticsearch.xpack.core.slm.action.GetSnapshotLifecycleAction;
209209
import org.elasticsearch.xpack.core.slm.action.PutSnapshotLifecycleAction;
210+
import org.elasticsearch.xpack.core.spatial.SpatialFeatureSetUsage;
210211
import org.elasticsearch.xpack.core.sql.SqlFeatureSetUsage;
211212
import org.elasticsearch.xpack.core.ssl.SSLService;
212213
import org.elasticsearch.xpack.core.ssl.action.GetCertificateInfoAction;
@@ -537,7 +538,9 @@ public List<NamedWriteableRegistry.Entry> getNamedWriteables() {
537538
// Voting Only Node
538539
new NamedWriteableRegistry.Entry(XPackFeatureSet.Usage.class, XPackField.VOTING_ONLY, VotingOnlyNodeFeatureSetUsage::new),
539540
// Frozen indices
540-
new NamedWriteableRegistry.Entry(XPackFeatureSet.Usage.class, XPackField.FROZEN_INDICES, FrozenIndicesFeatureSetUsage::new)
541+
new NamedWriteableRegistry.Entry(XPackFeatureSet.Usage.class, XPackField.FROZEN_INDICES, FrozenIndicesFeatureSetUsage::new),
542+
// Spatial
543+
new NamedWriteableRegistry.Entry(XPackFeatureSet.Usage.class, XPackField.SPATIAL, SpatialFeatureSetUsage::new)
541544
);
542545
}
543546

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackField.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ public final class XPackField {
4545
public static final String VOTING_ONLY = "voting_only";
4646
/** Name constant for the frozen index feature. */
4747
public static final String FROZEN_INDICES = "frozen_indices";
48+
/** Name constant for spatial features. */
49+
public static final String SPATIAL = "spatial";
4850

4951
private XPackField() {}
5052

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
package org.elasticsearch.xpack.core.spatial;
8+
9+
import org.elasticsearch.common.io.stream.StreamInput;
10+
import org.elasticsearch.common.io.stream.StreamOutput;
11+
import org.elasticsearch.xpack.core.XPackFeatureSet;
12+
import org.elasticsearch.xpack.core.XPackField;
13+
14+
import java.io.IOException;
15+
import java.util.Objects;
16+
17+
public class SpatialFeatureSetUsage extends XPackFeatureSet.Usage {
18+
19+
public SpatialFeatureSetUsage(boolean available, boolean enabled) {
20+
super(XPackField.SPATIAL, available, enabled);
21+
}
22+
23+
public SpatialFeatureSetUsage(StreamInput input) throws IOException {
24+
super(input);
25+
}
26+
27+
@Override
28+
public void writeTo(StreamOutput out) throws IOException {
29+
super.writeTo(out);
30+
}
31+
32+
@Override
33+
public int hashCode() {
34+
return Objects.hash(available, enabled);
35+
}
36+
37+
@Override
38+
public boolean equals(Object obj) {
39+
if (obj == null) {
40+
return false;
41+
}
42+
if (getClass() != obj.getClass()) {
43+
return false;
44+
}
45+
SpatialFeatureSetUsage other = (SpatialFeatureSetUsage) obj;
46+
return Objects.equals(available, other.available) &&
47+
Objects.equals(enabled, other.enabled);
48+
}
49+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
package org.elasticsearch.xpack.core.spatial;
7+
8+
import org.elasticsearch.common.io.stream.Writeable;
9+
import org.elasticsearch.test.AbstractWireSerializingTestCase;
10+
11+
import java.io.IOException;
12+
13+
public class SpatialFeatureSetUsageTests extends AbstractWireSerializingTestCase<SpatialFeatureSetUsage> {
14+
15+
@Override
16+
protected SpatialFeatureSetUsage createTestInstance() {
17+
boolean available = randomBoolean();
18+
boolean enabled = randomBoolean();
19+
return new SpatialFeatureSetUsage(available, enabled);
20+
}
21+
22+
@Override
23+
protected SpatialFeatureSetUsage mutateInstance(SpatialFeatureSetUsage instance) throws IOException {
24+
boolean available = instance.available();
25+
boolean enabled = instance.enabled();
26+
switch (between(0, 1)) {
27+
case 0:
28+
available = available == false;
29+
break;
30+
case 1:
31+
enabled = enabled == false;
32+
break;
33+
default:
34+
throw new AssertionError("Illegal randomisation branch");
35+
}
36+
return new SpatialFeatureSetUsage(available, enabled);
37+
}
38+
39+
@Override
40+
protected Writeable.Reader<SpatialFeatureSetUsage> instanceReader() {
41+
return SpatialFeatureSetUsage::new;
42+
}
43+
44+
}

x-pack/plugin/spatial/build.gradle

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
evaluationDependsOn(xpackModule('core'))
2+
3+
apply plugin: 'elasticsearch.esplugin'
4+
5+
esplugin {
6+
name 'spatial'
7+
description 'A plugin for Basic Spatial features'
8+
classname 'org.elasticsearch.xpack.spatial.SpatialPlugin'
9+
extendedPlugins = ['x-pack-core']
10+
}
11+
12+
dependencies {
13+
compileOnly project(path: xpackModule('core'), configuration: 'default')
14+
testCompile project(path: xpackModule('core'), configuration: 'testArtifacts')
15+
if (isEclipse) {
16+
testCompile project(path: xpackModule('core-tests'), configuration: 'testArtifacts')
17+
}
18+
}
19+
20+
// xpack modules are installed in real clusters as the meta plugin, so
21+
// installing them as individual plugins for integ tests doesn't make sense,
22+
// so we disable integ tests
23+
integTest.enabled = false
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
package org.elasticsearch.xpack.spatial;
7+
8+
import org.elasticsearch.action.ActionListener;
9+
import org.elasticsearch.common.Nullable;
10+
import org.elasticsearch.common.inject.Inject;
11+
import org.elasticsearch.common.settings.Settings;
12+
import org.elasticsearch.license.XPackLicenseState;
13+
import org.elasticsearch.xpack.core.XPackFeatureSet;
14+
import org.elasticsearch.xpack.core.XPackField;
15+
import org.elasticsearch.xpack.core.spatial.SpatialFeatureSetUsage;
16+
17+
import java.util.Map;
18+
19+
public class SpatialFeatureSet implements XPackFeatureSet {
20+
private final XPackLicenseState licenseState;
21+
22+
@Inject
23+
public SpatialFeatureSet(Settings settings, @Nullable XPackLicenseState licenseState) {
24+
this.licenseState = licenseState;
25+
}
26+
27+
@Override
28+
public String name() {
29+
return XPackField.GRAPH;
30+
}
31+
32+
@Override
33+
public boolean available() {
34+
return licenseState != null && licenseState.isGraphAllowed();
35+
}
36+
37+
@Override
38+
public boolean enabled() {
39+
return true;
40+
}
41+
42+
@Override
43+
public Map<String, Object> nativeCodeInfo() {
44+
return null;
45+
}
46+
47+
@Override
48+
public void usage(ActionListener<XPackFeatureSet.Usage> listener) {
49+
listener.onResponse(new SpatialFeatureSetUsage(available(), enabled()));
50+
}
51+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
package org.elasticsearch.xpack.spatial;
7+
8+
import org.elasticsearch.common.inject.Module;
9+
import org.elasticsearch.common.settings.Settings;
10+
import org.elasticsearch.plugins.Plugin;
11+
import org.elasticsearch.xpack.core.XPackPlugin;
12+
13+
import java.util.Collection;
14+
import java.util.Collections;
15+
16+
public class SpatialPlugin extends Plugin {
17+
18+
public SpatialPlugin(Settings settings) {
19+
}
20+
21+
public Collection<Module> createGuiceModules() {
22+
return Collections.singletonList(b -> {
23+
XPackPlugin.bindFeatureSet(b, SpatialFeatureSet.class);
24+
});
25+
}
26+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
package org.elasticsearch.xpack.spatial;
7+
8+
import org.elasticsearch.action.support.PlainActionFuture;
9+
import org.elasticsearch.common.io.stream.BytesStreamOutput;
10+
import org.elasticsearch.common.settings.Settings;
11+
import org.elasticsearch.license.XPackLicenseState;
12+
import org.elasticsearch.test.ESTestCase;
13+
import org.elasticsearch.xpack.core.XPackFeatureSet;
14+
import org.elasticsearch.xpack.core.spatial.SpatialFeatureSetUsage;
15+
import org.junit.Before;
16+
17+
import static org.hamcrest.core.Is.is;
18+
import static org.mockito.Mockito.mock;
19+
import static org.mockito.Mockito.when;
20+
21+
public class SpatialFeatureSetTests extends ESTestCase {
22+
private XPackLicenseState licenseState;
23+
24+
@Before
25+
public void init() throws Exception {
26+
licenseState = mock(XPackLicenseState.class);
27+
}
28+
29+
public void testAvailable() throws Exception {
30+
SpatialFeatureSet featureSet = new SpatialFeatureSet(Settings.EMPTY, licenseState);
31+
boolean available = randomBoolean();
32+
when(licenseState.isGraphAllowed()).thenReturn(available);
33+
assertThat(featureSet.available(), is(available));
34+
PlainActionFuture<XPackFeatureSet.Usage> future = new PlainActionFuture<>();
35+
featureSet.usage(future);
36+
XPackFeatureSet.Usage usage = future.get();
37+
assertThat(usage.available(), is(available));
38+
39+
BytesStreamOutput out = new BytesStreamOutput();
40+
usage.writeTo(out);
41+
XPackFeatureSet.Usage serializedUsage = new SpatialFeatureSetUsage(out.bytes().streamInput());
42+
assertThat(serializedUsage.available(), is(available));
43+
}
44+
45+
public void testEnabled() throws Exception {
46+
boolean enabled = true;
47+
Settings.Builder settings = Settings.builder();
48+
if (randomBoolean()) {
49+
settings.put("xpack.spatial.enabled", enabled);
50+
}
51+
SpatialFeatureSet featureSet = new SpatialFeatureSet(settings.build(), licenseState);
52+
assertThat(featureSet.enabled(), is(enabled));
53+
PlainActionFuture<XPackFeatureSet.Usage> future = new PlainActionFuture<>();
54+
featureSet.usage(future);
55+
XPackFeatureSet.Usage usage = future.get();
56+
assertThat(usage.enabled(), is(enabled));
57+
58+
BytesStreamOutput out = new BytesStreamOutput();
59+
usage.writeTo(out);
60+
XPackFeatureSet.Usage serializedUsage = new SpatialFeatureSetUsage(out.bytes().streamInput());
61+
assertThat(serializedUsage.enabled(), is(enabled));
62+
}
63+
}

0 commit comments

Comments
 (0)