Skip to content

Commit fa81e2e

Browse files
authored
[Feature/extensions] Get namedXContentRegistry from ExtensionsRunner (#725)
* Extend BaseExtension to simplify boilerplate Signed-off-by: Daniel Widdis <[email protected]> * Pass ExtensionsRunner and Extension to Rest Action Signed-off-by: Daniel Widdis <[email protected]> * Use XContentRegistry in Rest Action Signed-off-by: Daniel Widdis <[email protected]> * AD YAML config is handled in another PR Signed-off-by: Daniel Widdis <[email protected]> * Extension settings are now private with a getter Signed-off-by: Daniel Widdis <[email protected]> Signed-off-by: Daniel Widdis <[email protected]>
1 parent bcd5a3e commit fa81e2e

File tree

2 files changed

+50
-101
lines changed

2 files changed

+50
-101
lines changed

src/main/java/org/opensearch/ad/AnomalyDetectorExtension.java

+26-30
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,49 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* The OpenSearch Contributors require contributions made to
6+
* this file be licensed under the Apache-2.0 license or a
7+
* compatible open source license.
8+
*/
9+
110
package org.opensearch.ad;
211

312
import static java.util.Collections.unmodifiableList;
413

514
import java.io.IOException;
6-
import java.util.Collection;
715
import java.util.List;
816
import java.util.stream.Collectors;
917
import java.util.stream.Stream;
1018

19+
import org.opensearch.ad.model.AnomalyDetector;
20+
import org.opensearch.ad.model.AnomalyResult;
21+
import org.opensearch.ad.model.DetectorInternalState;
1122
import org.opensearch.ad.rest.RestCreateDetectorAction;
1223
import org.opensearch.ad.rest.RestGetDetectorAction;
1324
import org.opensearch.ad.settings.AnomalyDetectorSettings;
1425
import org.opensearch.ad.settings.EnabledSetting;
1526
import org.opensearch.client.opensearch.OpenSearchClient;
16-
import org.opensearch.cluster.service.ClusterService;
1727
import org.opensearch.common.settings.Setting;
18-
import org.opensearch.sdk.Extension;
28+
import org.opensearch.common.xcontent.NamedXContentRegistry;
29+
import org.opensearch.sdk.BaseExtension;
1930
import org.opensearch.sdk.ExtensionRestHandler;
20-
import org.opensearch.sdk.ExtensionSettings;
2131
import org.opensearch.sdk.ExtensionsRunner;
2232
import org.opensearch.sdk.SDKClient;
23-
import org.opensearch.threadpool.ThreadPool;
2433

2534
import com.google.common.collect.ImmutableList;
2635

27-
public class AnomalyDetectorExtension implements Extension {
36+
public class AnomalyDetectorExtension extends BaseExtension {
2837

2938
private static final String EXTENSION_SETTINGS_PATH = "/ad-extension.yml";
3039

31-
private ExtensionSettings settings;
32-
3340
public AnomalyDetectorExtension() {
34-
try {
35-
this.settings = initializeSettings();
36-
} catch (IOException e) {
37-
throw new ExceptionInInitializerError(e);
38-
}
39-
}
40-
41-
@Override
42-
public ExtensionSettings getExtensionSettings() {
43-
return this.settings;
41+
super(EXTENSION_SETTINGS_PATH);
4442
}
4543

4644
@Override
4745
public List<ExtensionRestHandler> getExtensionRestHandlers() {
48-
return List.of(new RestCreateDetectorAction(), new RestGetDetectorAction());
46+
return List.of(new RestCreateDetectorAction(extensionsRunner, this), new RestGetDetectorAction());
4947
}
5048

5149
@Override
@@ -90,22 +88,20 @@ public List<Setting<?>> getSettings() {
9088
}
9189

9290
@Override
93-
public Collection<Object> createComponents(SDKClient sdkClient, ClusterService clusterService, ThreadPool threadPool) {
94-
return null;
95-
}
96-
97-
private static ExtensionSettings initializeSettings() throws IOException {
98-
ExtensionSettings settings = Extension.readSettingsFromYaml(EXTENSION_SETTINGS_PATH);
99-
if (settings == null || settings.getHostAddress() == null || settings.getHostPort() == null) {
100-
throw new IOException("Failed to initialize Extension settings. No port bound.");
101-
}
102-
return settings;
91+
public List<NamedXContentRegistry.Entry> getNamedXContent() {
92+
// Copied from AnomalyDetectorPlugin getNamedXContent
93+
return ImmutableList.of(AnomalyDetector.XCONTENT_REGISTRY, AnomalyResult.XCONTENT_REGISTRY, DetectorInternalState.XCONTENT_REGISTRY
94+
// Pending Job Scheduler Integration
95+
// AnomalyDetectorJob.XCONTENT_REGISTRY
96+
);
10397
}
10498

99+
// TODO: replace or override client object on BaseExtension
100+
// https://github.com/opensearch-project/opensearch-sdk-java/issues/160
105101
public OpenSearchClient getClient() {
106102
SDKClient sdkClient = new SDKClient();
107103
OpenSearchClient client = sdkClient
108-
.initializeClient(settings.getOpensearchAddress(), Integer.parseInt(settings.getOpensearchPort()));
104+
.initializeClient(getExtensionSettings().getOpensearchAddress(), Integer.parseInt(getExtensionSettings().getOpensearchPort()));
109105
return client;
110106
}
111107

src/main/java/org/opensearch/ad/rest/RestCreateDetectorAction.java

+24-71
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* The OpenSearch Contributors require contributions made to
6+
* this file be licensed under the Apache-2.0 license or a
7+
* compatible open source license.
8+
*/
9+
110
package org.opensearch.ad.rest;
211

312
import static org.opensearch.ad.model.AnomalyDetector.ANOMALY_DETECTORS_INDEX;
413
import static org.opensearch.ad.settings.AnomalyDetectorSettings.ANOMALY_DETECTORS_INDEX_MAPPING_FILE;
514
import static org.opensearch.common.xcontent.XContentParserUtils.ensureExpectedToken;
615
import static org.opensearch.rest.RestRequest.Method.POST;
716
import static org.opensearch.rest.RestStatus.BAD_REQUEST;
17+
import static org.opensearch.rest.RestStatus.CREATED;
818
import static org.opensearch.rest.RestStatus.NOT_FOUND;
919
import static org.opensearch.rest.RestStatus.OK;
1020

11-
import java.io.*;
21+
import java.io.ByteArrayInputStream;
22+
import java.io.IOException;
1223
import java.net.URL;
1324
import java.nio.charset.StandardCharsets;
1425
import java.time.Instant;
15-
import java.util.ArrayList;
1626
import java.util.List;
1727

1828
import org.apache.logging.log4j.LogManager;
@@ -21,8 +31,6 @@
2131
import org.opensearch.ad.constant.CommonErrorMessages;
2232
import org.opensearch.ad.indices.AnomalyDetectionIndices;
2333
import org.opensearch.ad.model.AnomalyDetector;
24-
import org.opensearch.ad.model.AnomalyResult;
25-
import org.opensearch.ad.model.DetectorInternalState;
2634
import org.opensearch.ad.settings.EnabledSetting;
2735
import org.opensearch.client.json.JsonpMapper;
2836
import org.opensearch.client.opensearch.OpenSearchClient;
@@ -37,29 +45,25 @@
3745
import org.opensearch.common.xcontent.XContentType;
3846
import org.opensearch.extensions.rest.ExtensionRestRequest;
3947
import org.opensearch.extensions.rest.ExtensionRestResponse;
40-
import org.opensearch.index.query.BoolQueryBuilder;
41-
import org.opensearch.index.query.NestedQueryBuilder;
42-
import org.opensearch.index.query.QueryBuilder;
43-
import org.opensearch.index.query.RangeQueryBuilder;
44-
import org.opensearch.plugins.SearchPlugin;
4548
import org.opensearch.rest.RestHandler.Route;
4649
import org.opensearch.rest.RestRequest.Method;
47-
import org.opensearch.rest.RestStatus;
4850
import org.opensearch.sdk.ExtensionRestHandler;
49-
import org.opensearch.search.aggregations.BaseAggregationBuilder;
50-
import org.opensearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
51-
import org.opensearch.search.aggregations.bucket.filter.InternalFilter;
52-
import org.opensearch.search.aggregations.metrics.InternalSum;
53-
import org.opensearch.search.aggregations.metrics.SumAggregationBuilder;
51+
import org.opensearch.sdk.ExtensionsRunner;
5452

5553
import com.google.common.base.Charsets;
5654
import com.google.common.io.Resources;
5755
import jakarta.json.stream.JsonParser;
5856

5957
public class RestCreateDetectorAction implements ExtensionRestHandler {
60-
private final Logger logger = LogManager.getLogger(RestCreateDetectorAction.class);
61-
private AnomalyDetectorExtension anomalyDetectorExtension = new AnomalyDetectorExtension();
62-
private OpenSearchClient sdkClient = anomalyDetectorExtension.getClient();
58+
private static final Logger logger = LogManager.getLogger(RestCreateDetectorAction.class);
59+
60+
private final OpenSearchClient sdkClient;
61+
private final NamedXContentRegistry xContentRegistry;
62+
63+
public RestCreateDetectorAction(ExtensionsRunner runner, AnomalyDetectorExtension extension) {
64+
this.xContentRegistry = runner.getNamedXContentRegistry().getRegistry();
65+
this.sdkClient = extension.getClient();
66+
}
6367

6468
@Override
6569
public List<Route> routes() {
@@ -101,56 +105,6 @@ private IndexResponse indexAnomalyDetector(AnomalyDetector anomalyDetector) thro
101105

102106
}
103107

104-
public List<NamedXContentRegistry.Entry> getNamedXWriteables() {
105-
List<NamedXContentRegistry.Entry> entries = new ArrayList<>();
106-
entries.add(AnomalyDetector.XCONTENT_REGISTRY);
107-
entries.add(AnomalyResult.XCONTENT_REGISTRY);
108-
entries.add(DetectorInternalState.XCONTENT_REGISTRY);
109-
entries
110-
.add(
111-
registerQuery(
112-
new SearchPlugin.QuerySpec<>(NestedQueryBuilder.NAME, NestedQueryBuilder::new, NestedQueryBuilder::fromXContent)
113-
)
114-
);
115-
entries
116-
.add(registerQuery(new SearchPlugin.QuerySpec<>(BoolQueryBuilder.NAME, BoolQueryBuilder::new, BoolQueryBuilder::fromXContent)));
117-
entries
118-
.add(
119-
registerAggregation(
120-
new SearchPlugin.AggregationSpec(SumAggregationBuilder.NAME, SumAggregationBuilder::new, SumAggregationBuilder.PARSER)
121-
.addResultReader(InternalSum::new)
122-
)
123-
);
124-
125-
entries
126-
.add(
127-
registerAggregation(
128-
new SearchPlugin.AggregationSpec(
129-
FilterAggregationBuilder.NAME,
130-
FilterAggregationBuilder::new,
131-
FilterAggregationBuilder::parse
132-
).addResultReader(InternalFilter::new)
133-
)
134-
);
135-
entries
136-
.add(
137-
registerQuery(new SearchPlugin.QuerySpec<>(RangeQueryBuilder.NAME, RangeQueryBuilder::new, RangeQueryBuilder::fromXContent))
138-
);
139-
return entries;
140-
141-
}
142-
143-
private NamedXContentRegistry.Entry registerQuery(SearchPlugin.QuerySpec<?> spec) {
144-
return new NamedXContentRegistry.Entry(QueryBuilder.class, spec.getName(), (p, c) -> spec.getParser().fromXContent(p));
145-
}
146-
147-
private NamedXContentRegistry.Entry registerAggregation(SearchPlugin.AggregationSpec spec) {
148-
return new NamedXContentRegistry.Entry(BaseAggregationBuilder.class, spec.getName(), (p, c) -> {
149-
String name = (String) c;
150-
return spec.getParser().parse(p, name);
151-
});
152-
}
153-
154108
private CreateIndexRequest initAnomalyDetectorIndex() {
155109
JsonpMapper mapper = sdkClient._transport().jsonpMapper();
156110
JsonParser parser = null;
@@ -190,13 +144,12 @@ public ExtensionRestResponse handleRequest(ExtensionRestRequest request) {
190144
);
191145
}
192146

193-
NamedXContentRegistry xContentRegistry = new NamedXContentRegistry(getNamedXWriteables());
194147
XContentParser parser;
195148
AnomalyDetector detector;
196149
XContentBuilder builder = null;
197150
CreateIndexRequest createIndexRequest;
198151
try {
199-
parser = request.contentParser(xContentRegistry);
152+
parser = request.contentParser(this.xContentRegistry);
200153
ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser);
201154
detector = AnomalyDetector.parse(parser);
202155
createIndexRequest = initAnomalyDetectorIndex();
@@ -211,7 +164,7 @@ public ExtensionRestResponse handleRequest(ExtensionRestRequest request) {
211164
builder.field("seqNo", indexResponse.seqNo());
212165
builder.field("primaryTerm", indexResponse.primaryTerm());
213166
builder.field("detector", detector);
214-
builder.field("status", RestStatus.CREATED);
167+
builder.field("status", CREATED);
215168
builder.endObject();
216169
} catch (IOException e) {
217170
e.printStackTrace();

0 commit comments

Comments
 (0)