-
Notifications
You must be signed in to change notification settings - Fork 25.2k
Add enrich policy PUT API #41383
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
Add enrich policy PUT API #41383
Changes from 11 commits
cc1703a
e4ebea3
b69741a
071681b
86f10cd
c073a80
23c7870
1db9d71
6c31d81
06d8c54
976f53a
c8772b8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
package org.elasticsearch.xpack.core.enrich.action; | ||
|
||
import org.elasticsearch.action.Action; | ||
import org.elasticsearch.action.ActionRequestValidationException; | ||
import org.elasticsearch.action.support.master.AcknowledgedResponse; | ||
import org.elasticsearch.action.support.master.MasterNodeRequest; | ||
import org.elasticsearch.common.io.stream.StreamInput; | ||
import org.elasticsearch.common.io.stream.StreamOutput; | ||
import org.elasticsearch.common.xcontent.XContentParser; | ||
import org.elasticsearch.xpack.core.enrich.EnrichPolicy; | ||
|
||
import java.io.IOException; | ||
import java.util.Objects; | ||
|
||
public class PutEnrichPolicyAction extends Action<AcknowledgedResponse> { | ||
|
||
public static final PutEnrichPolicyAction INSTANCE = new PutEnrichPolicyAction(); | ||
public static final String NAME = "cluster:admin/xpack/enrich/put"; | ||
|
||
protected PutEnrichPolicyAction() { | ||
super(NAME); | ||
} | ||
|
||
public static Request fromXContent(XContentParser parser, String name) throws IOException { | ||
return new Request(name, EnrichPolicy.fromXContent(parser)); | ||
} | ||
|
||
@Override | ||
public AcknowledgedResponse newResponse() { | ||
return new AcknowledgedResponse(); | ||
} | ||
|
||
public static class Request extends MasterNodeRequest<PutEnrichPolicyAction.Request> { | ||
|
||
private final EnrichPolicy policy; | ||
private final String name; | ||
|
||
public Request(String name, EnrichPolicy policy) { | ||
this.name = Objects.requireNonNull(name, "name cannot be null"); | ||
this.policy = policy; | ||
} | ||
|
||
public Request(StreamInput in) throws IOException { | ||
super(in); | ||
name = in.readString(); | ||
policy = new EnrichPolicy(in); | ||
} | ||
|
||
@Override | ||
public void writeTo(StreamOutput out) throws IOException { | ||
super.writeTo(out); | ||
out.writeString(name); | ||
policy.writeTo(out); | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public EnrichPolicy getPolicy() { | ||
return policy; | ||
} | ||
|
||
@Override | ||
public ActionRequestValidationException validate() { | ||
return null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add validation here that the name is required? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. im not sure we need this since the constructor for the request has an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. Maybe instead of using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Never mind. This good as it is now. In production, the constructor can't be invoked with a null |
||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
Request request = (Request) o; | ||
return policy.equals(request.policy) && | ||
name.equals(request.name); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(policy, name); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,7 +20,7 @@ | |
/** | ||
* Helper methods for access and storage of an enrich policy. | ||
*/ | ||
public final class EnrichStore { | ||
public class EnrichStore { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can keep this class final now? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh, yes, now that it holds no state, good catch! |
||
|
||
private EnrichStore() {} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
package org.elasticsearch.xpack.enrich.action; | ||
|
||
import org.elasticsearch.action.ActionListener; | ||
import org.elasticsearch.action.support.ActionFilters; | ||
import org.elasticsearch.action.support.master.AcknowledgedResponse; | ||
import org.elasticsearch.action.support.master.TransportMasterNodeAction; | ||
import org.elasticsearch.cluster.ClusterState; | ||
import org.elasticsearch.cluster.block.ClusterBlockException; | ||
import org.elasticsearch.cluster.block.ClusterBlockLevel; | ||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; | ||
import org.elasticsearch.cluster.service.ClusterService; | ||
import org.elasticsearch.common.inject.Inject; | ||
import org.elasticsearch.threadpool.ThreadPool; | ||
import org.elasticsearch.transport.TransportService; | ||
import org.elasticsearch.xpack.core.enrich.action.PutEnrichPolicyAction; | ||
import org.elasticsearch.xpack.enrich.EnrichStore; | ||
|
||
public class TransportPutEnrichPolicyAction extends TransportMasterNodeAction<PutEnrichPolicyAction.Request, AcknowledgedResponse> { | ||
|
||
@Inject | ||
public TransportPutEnrichPolicyAction(TransportService transportService, | ||
ClusterService clusterService, | ||
ThreadPool threadPool, | ||
ActionFilters actionFilters, | ||
IndexNameExpressionResolver indexNameExpressionResolver) { | ||
super(PutEnrichPolicyAction.NAME, transportService, clusterService, threadPool, actionFilters, | ||
PutEnrichPolicyAction.Request::new, indexNameExpressionResolver); | ||
} | ||
|
||
@Override | ||
protected String executor() { | ||
return ThreadPool.Names.SAME; | ||
} | ||
|
||
@Override | ||
protected AcknowledgedResponse newResponse() { | ||
throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable"); | ||
} | ||
|
||
@Override | ||
protected void masterOperation(PutEnrichPolicyAction.Request request, ClusterState state, | ||
ActionListener<AcknowledgedResponse> listener) { | ||
EnrichStore.putPolicy(request.getName(), request.getPolicy(), clusterService, e -> { | ||
if (e == null) { | ||
listener.onResponse(new AcknowledgedResponse(true)); | ||
} else { | ||
listener.onFailure(e); | ||
} | ||
}); | ||
} | ||
|
||
@Override | ||
protected ClusterBlockException checkBlock(PutEnrichPolicyAction.Request request, ClusterState state) { | ||
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
package org.elasticsearch.xpack.enrich.rest; | ||
|
||
import org.elasticsearch.client.node.NodeClient; | ||
import org.elasticsearch.common.settings.Settings; | ||
import org.elasticsearch.common.xcontent.XContentParser; | ||
import org.elasticsearch.rest.BaseRestHandler; | ||
import org.elasticsearch.rest.RestController; | ||
import org.elasticsearch.rest.RestRequest; | ||
import org.elasticsearch.rest.action.RestToXContentListener; | ||
import org.elasticsearch.xpack.core.enrich.action.PutEnrichPolicyAction; | ||
|
||
import java.io.IOException; | ||
|
||
public class RestPutEnrichPolicyAction extends BaseRestHandler { | ||
|
||
public RestPutEnrichPolicyAction(final Settings settings, final RestController controller) { | ||
super(settings); | ||
controller.registerHandler(RestRequest.Method.PUT, "/_enrich/policy/{name}", this); | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return "put_enrich_policy"; | ||
} | ||
|
||
@Override | ||
protected RestChannelConsumer prepareRequest(final RestRequest restRequest, final NodeClient client) throws IOException { | ||
final PutEnrichPolicyAction.Request request = createRequest(restRequest); | ||
return channel -> client.execute(PutEnrichPolicyAction.INSTANCE, request, new RestToXContentListener<>(channel)); | ||
} | ||
|
||
static PutEnrichPolicyAction.Request createRequest(RestRequest restRequest) throws IOException { | ||
try (XContentParser parser = restRequest.contentOrSourceParamParser()) { | ||
return PutEnrichPolicyAction.fromXContent(parser, restRequest.param("name")); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
package org.elasticsearch.xpack.enrich.action; | ||
|
||
import org.elasticsearch.common.io.stream.Writeable; | ||
import org.elasticsearch.common.xcontent.XContentType; | ||
import org.elasticsearch.test.AbstractWireSerializingTestCase; | ||
import org.elasticsearch.xpack.core.enrich.EnrichPolicy; | ||
import org.elasticsearch.xpack.core.enrich.action.PutEnrichPolicyAction; | ||
|
||
import static org.elasticsearch.xpack.enrich.EnrichPolicyTests.randomEnrichPolicy; | ||
|
||
public class PutEnrichPolicyActionRequestTests extends AbstractWireSerializingTestCase<PutEnrichPolicyAction.Request> { | ||
|
||
@Override | ||
protected PutEnrichPolicyAction.Request createTestInstance() { | ||
final EnrichPolicy policy = randomEnrichPolicy(XContentType.JSON); | ||
return new PutEnrichPolicyAction.Request(randomAlphaOfLength(3), policy); | ||
} | ||
|
||
@Override | ||
protected Writeable.Reader<PutEnrichPolicyAction.Request> instanceReader() { | ||
return PutEnrichPolicyAction.Request::new; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"enrich.put_policy": { | ||
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/enrich-put-policy.html", | ||
"methods": [ "PUT" ], | ||
"url": { | ||
"path": "/_enrich/policy/{name}", | ||
"paths": ["/_enrich/policy/{name}"], | ||
"parts": { | ||
"name": { | ||
"type" : "string", | ||
"description" : "The name of the enrich policy" | ||
} | ||
}, | ||
"params": { | ||
} | ||
}, | ||
"body": { | ||
"description": "The enrich policy to register" | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
--- | ||
"Test enrich crud apis": | ||
|
||
- do: | ||
enrich.put_policy: | ||
name: policy-crud | ||
body: | ||
type: exact_match | ||
index_pattern: "bar*" | ||
enrich_key: baz | ||
enrich_values: ["a", "b"] | ||
schedule: "*/120" | ||
|
||
- is_true: acknowledged | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. iirc all yaml test files are required to end with a newline? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add newline before the first field