Browse Source

Added HLRC support for enrich put policy API. (#45183)

This PR also adds HLRC docs.

Relates to #32789
Martijn van Groningen 6 years ago
parent
commit
43b23aa505

+ 86 - 0
client/rest-high-level/src/main/java/org/elasticsearch/client/EnrichClient.java

@@ -0,0 +1,86 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.client;
+
+import org.elasticsearch.action.ActionListener;
+import org.elasticsearch.client.core.AcknowledgedResponse;
+import org.elasticsearch.client.enrich.PutPolicyRequest;
+
+import java.io.IOException;
+import java.util.Collections;
+
+/**
+ * A wrapper for the {@link RestHighLevelClient} that provides methods for
+ * accessing the Elastic enrich related methods
+ * <p>
+ * See the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/enrich-processor.html#enrich-policy-apis">
+ * X-Pack Enrich Policy APIs on elastic.co</a> for more information.
+ */
+public final class EnrichClient {
+
+    private final RestHighLevelClient restHighLevelClient;
+
+    EnrichClient(RestHighLevelClient restHighLevelClient) {
+        this.restHighLevelClient = restHighLevelClient;
+    }
+
+    /**
+     * Executes the put policy api, which stores an enrich policy.
+     *
+     * See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/enrich-processor.html#put-policy-api">
+     * the docs</a> for more.
+     *
+     * @param request the {@link PutPolicyRequest}
+     * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
+     * @return the response
+     * @throws IOException in case there is a problem sending the request or parsing back the response
+     */
+    public AcknowledgedResponse putPolicy(PutPolicyRequest request, RequestOptions options) throws IOException {
+        return restHighLevelClient.performRequestAndParseEntity(
+            request,
+            EnrichRequestConverters::putPolicy,
+            options,
+            AcknowledgedResponse::fromXContent,
+            Collections.emptySet()
+        );
+    }
+
+    /**
+     * Asynchronously executes the put policy api, which stores an enrich policy.
+     *
+     * See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/enrich-processor.html#put-policy-api">
+     * the docs</a> for more.
+     *
+     * @param request the {@link PutPolicyRequest}
+     * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
+     * @param listener the listener to be notified upon request completion
+     */
+    public void putPolicyAsync(PutPolicyRequest request,
+                               RequestOptions options,
+                               ActionListener<AcknowledgedResponse> listener) {
+        restHighLevelClient.performRequestAsyncAndParseEntity(
+            request,
+            EnrichRequestConverters::putPolicy,
+            options,
+            AcknowledgedResponse::fromXContent,
+            listener,
+            Collections.emptySet()
+        );
+    }
+}

+ 41 - 0
client/rest-high-level/src/main/java/org/elasticsearch/client/EnrichRequestConverters.java

@@ -0,0 +1,41 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.client;
+
+import org.apache.http.client.methods.HttpPut;
+import org.elasticsearch.client.enrich.PutPolicyRequest;
+
+import java.io.IOException;
+
+import static org.elasticsearch.client.RequestConverters.REQUEST_BODY_CONTENT_TYPE;
+import static org.elasticsearch.client.RequestConverters.createEntity;
+
+final class EnrichRequestConverters {
+
+    static Request putPolicy(PutPolicyRequest putPolicyRequest) throws IOException {
+        String endpoint = new RequestConverters.EndpointBuilder()
+            .addPathPartAsIs("_enrich", "policy")
+            .addPathPart(putPolicyRequest.getName())
+            .build();
+        Request request = new Request(HttpPut.METHOD_NAME, endpoint);
+        request.setEntity(createEntity(putPolicyRequest, REQUEST_BODY_CONTENT_TYPE));
+        return request;
+    }
+
+}

+ 5 - 0
client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java

@@ -257,6 +257,7 @@ public class RestHighLevelClient implements Closeable {
     private final RollupClient rollupClient = new RollupClient(this);
     private final RollupClient rollupClient = new RollupClient(this);
     private final CcrClient ccrClient = new CcrClient(this);
     private final CcrClient ccrClient = new CcrClient(this);
     private final DataFrameClient dataFrameClient = new DataFrameClient(this);
     private final DataFrameClient dataFrameClient = new DataFrameClient(this);
+    private final EnrichClient enrichClient = new EnrichClient(this);
 
 
     /**
     /**
      * Creates a {@link RestHighLevelClient} given the low level {@link RestClientBuilder} that allows to build the
      * Creates a {@link RestHighLevelClient} given the low level {@link RestClientBuilder} that allows to build the
@@ -481,6 +482,10 @@ public class RestHighLevelClient implements Closeable {
         return dataFrameClient;
         return dataFrameClient;
     }
     }
 
 
+    public EnrichClient enrich() {
+        return enrichClient;
+    }
+
     /**
     /**
      * Executes a bulk request using the Bulk API.
      * Executes a bulk request using the Bulk API.
      * See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html">Bulk API on elastic.co</a>
      * See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html">Bulk API on elastic.co</a>

+ 150 - 0
client/rest-high-level/src/main/java/org/elasticsearch/client/enrich/PutPolicyRequest.java

@@ -0,0 +1,150 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.client.enrich;
+
+import org.elasticsearch.client.Validatable;
+import org.elasticsearch.common.ParseField;
+import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.bytes.BytesReference;
+import org.elasticsearch.common.xcontent.ToXContentObject;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentHelper;
+import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.common.xcontent.json.JsonXContent;
+import org.elasticsearch.index.query.QueryBuilder;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+public class PutPolicyRequest implements Validatable, ToXContentObject {
+
+    static final ParseField TYPE_FIELD = new ParseField("type");
+    static final ParseField QUERY_FIELD = new ParseField("query");
+    static final ParseField INDICES_FIELD = new ParseField("indices");
+    static final ParseField ENRICH_KEY_FIELD = new ParseField("enrich_key");
+    static final ParseField ENRICH_VALUES_FIELD = new ParseField("enrich_values");
+
+    private final String name;
+    private final String type;
+    private BytesReference query;
+    private final List<String> indices;
+    private final String enrichKey;
+    private final List<String> enrichValues;
+
+    public PutPolicyRequest(String name, String type, List<String> indices, String enrichKey, List<String> enrichValues) {
+        if (Strings.hasLength(name) == false) {
+            throw new IllegalArgumentException("name must be a non-null and non-empty string");
+        }
+        if (Strings.hasLength(type) == false) {
+            throw new IllegalArgumentException("type must be a non-null and non-empty string");
+        }
+        if (indices == null || indices.isEmpty()) {
+            throw new IllegalArgumentException("indices must be specified");
+        }
+        if (Strings.hasLength(enrichKey) == false) {
+            throw new IllegalArgumentException("enrichKey must be a non-null and non-empty string");
+        }
+        if (enrichValues == null || enrichValues.isEmpty()) {
+            throw new IllegalArgumentException("enrichValues must be specified");
+        }
+
+        this.name = name;
+        this.type = type;
+        this.indices = indices;
+        this.enrichKey = enrichKey;
+        this.enrichValues = enrichValues;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public BytesReference getQuery() {
+        return query;
+    }
+
+    public void setQuery(BytesReference query) {
+        this.query = query;
+    }
+
+    public void setQuery(QueryBuilder query) throws IOException {
+        setQuery(xContentToBytes(query));
+    }
+
+    public List<String> getIndices() {
+        return indices;
+    }
+
+    public String getEnrichKey() {
+        return enrichKey;
+    }
+
+    public List<String> getEnrichValues() {
+        return enrichValues;
+    }
+
+    @Override
+    public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+        builder.startObject();
+        builder.field(TYPE_FIELD.getPreferredName(), type);
+        builder.field(INDICES_FIELD.getPreferredName(), indices);
+        if (query != null) {
+            builder.field(QUERY_FIELD.getPreferredName(), asMap(query, builder.contentType()));
+        }
+        builder.field(ENRICH_KEY_FIELD.getPreferredName(), enrichKey);
+        builder.field(ENRICH_VALUES_FIELD.getPreferredName(), enrichValues);
+        builder.endObject();
+        return builder;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        PutPolicyRequest that = (PutPolicyRequest) o;
+        return Objects.equals(name, that.name) &&
+            Objects.equals(type, that.type) &&
+            Objects.equals(query, that.query) &&
+            Objects.equals(indices, that.indices) &&
+            Objects.equals(enrichKey, that.enrichKey) &&
+            Objects.equals(enrichValues, that.enrichValues);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(name, type, query, indices, enrichKey, enrichValues);
+    }
+
+    private static BytesReference xContentToBytes(ToXContentObject object) throws IOException {
+        try (XContentBuilder builder = JsonXContent.contentBuilder()) {
+            object.toXContent(builder, ToXContentObject.EMPTY_PARAMS);
+            return BytesReference.bytes(builder);
+        }
+    }
+
+    static Map<String, Object> asMap(BytesReference bytesReference, XContentType xContentType) {
+        return bytesReference == null ? null : XContentHelper.convertToMap(bytesReference, true, xContentType).v2();
+    }
+}

+ 58 - 0
client/rest-high-level/src/test/java/org/elasticsearch/client/EnrichIT.java

@@ -0,0 +1,58 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.client;
+
+import org.apache.http.util.EntityUtils;
+import org.elasticsearch.client.core.AcknowledgedResponse;
+import org.elasticsearch.client.enrich.PutPolicyRequest;
+import org.elasticsearch.common.xcontent.XContentHelper;
+import org.elasticsearch.common.xcontent.json.JsonXContent;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+
+public class EnrichIT extends ESRestHighLevelClientTestCase {
+
+    public void testCRUD() throws Exception {
+        final EnrichClient enrichClient = highLevelClient().enrich();
+        PutPolicyRequest putPolicyRequest =
+            new PutPolicyRequest("my-policy", "exact_match", List.of("my-index"), "enrich_key", List.of("enrich_value"));
+        AcknowledgedResponse putPolicyResponse = execute(putPolicyRequest, enrichClient::putPolicy, enrichClient::putPolicyAsync);
+        assertThat(putPolicyResponse.isAcknowledged(), is(true));
+
+        // TODO: Replace with get policy hlrc code:
+        Request getPolicyRequest = new Request("get", "/_enrich/policy/my-policy");
+        Response getPolicyResponse = highLevelClient().getLowLevelClient().performRequest(getPolicyRequest);
+        assertThat(getPolicyResponse.getHttpResponse().getStatusLine().getStatusCode(), equalTo(200));
+        Map<String, Object> responseBody = toMap(getPolicyResponse);
+        assertThat(responseBody.get("type"), equalTo(putPolicyRequest.getType()));
+        assertThat(responseBody.get("indices"), equalTo(putPolicyRequest.getIndices()));
+        assertThat(responseBody.get("enrich_key"), equalTo(putPolicyRequest.getEnrichKey()));
+        assertThat(responseBody.get("enrich_values"), equalTo(putPolicyRequest.getEnrichValues()));
+    }
+
+    private static Map<String, Object> toMap(Response response) throws IOException {
+        return XContentHelper.convertToMap(JsonXContent.jsonXContent, EntityUtils.toString(response.getEntity()), false);
+    }
+
+}

+ 39 - 0
client/rest-high-level/src/test/java/org/elasticsearch/client/EnrichRequestConvertersTests.java

@@ -0,0 +1,39 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.client;
+
+import org.apache.http.client.methods.HttpPut;
+import org.elasticsearch.client.enrich.PutPolicyRequest;
+import org.elasticsearch.client.enrich.PutPolicyRequestTests;
+import org.elasticsearch.test.ESTestCase;
+
+import static org.hamcrest.Matchers.equalTo;
+
+public class EnrichRequestConvertersTests extends ESTestCase {
+
+    public void testPutPolicy() throws Exception {
+        PutPolicyRequest request = PutPolicyRequestTests.createTestInstance();
+        Request result = EnrichRequestConverters.putPolicy(request);
+
+        assertThat(result.getMethod(), equalTo(HttpPut.METHOD_NAME));
+        assertThat(result.getEndpoint(), equalTo("/_enrich/policy/" + request.getName()));
+        RequestConvertersTests.assertToXContentBody(request, result.getEntity());
+    }
+
+}

+ 1 - 0
client/rest-high-level/src/test/java/org/elasticsearch/client/RestHighLevelClientTests.java

@@ -837,6 +837,7 @@ public class RestHighLevelClientTests extends ESTestCase {
                                 apiName.startsWith("security.") == false &&
                                 apiName.startsWith("security.") == false &&
                                 apiName.startsWith("index_lifecycle.") == false &&
                                 apiName.startsWith("index_lifecycle.") == false &&
                                 apiName.startsWith("ccr.") == false &&
                                 apiName.startsWith("ccr.") == false &&
+                                apiName.startsWith("enrich.") == false &&
                                 apiName.startsWith("data_frame") == false &&
                                 apiName.startsWith("data_frame") == false &&
                                 apiName.endsWith("freeze") == false &&
                                 apiName.endsWith("freeze") == false &&
                                 apiName.endsWith("reload_analyzers") == false &&
                                 apiName.endsWith("reload_analyzers") == false &&

+ 80 - 0
client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/EnrichDocumentationIT.java

@@ -0,0 +1,80 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.client.documentation;
+
+import org.elasticsearch.action.ActionListener;
+import org.elasticsearch.action.LatchedActionListener;
+import org.elasticsearch.client.ESRestHighLevelClientTestCase;
+import org.elasticsearch.client.RequestOptions;
+import org.elasticsearch.client.RestHighLevelClient;
+import org.elasticsearch.client.core.AcknowledgedResponse;
+import org.elasticsearch.client.enrich.PutPolicyRequest;
+
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class EnrichDocumentationIT extends ESRestHighLevelClientTestCase {
+
+    public void testPutPolicy() throws Exception {
+        RestHighLevelClient client = highLevelClient();
+        // tag::enrich-put-policy-request
+        PutPolicyRequest putPolicyRequest = new PutPolicyRequest(
+            "users-policy", "exact_match", List.of("users"),
+            "email", List.of("address", "zip", "city", "state"));
+        // end::enrich-put-policy-request
+
+        // tag::enrich-put-policy-execute
+        AcknowledgedResponse putPolicyResponse =
+            client.enrich().putPolicy(putPolicyRequest, RequestOptions.DEFAULT);
+        // end::enrich-put-policy-execute
+
+        // tag::enrich-put-policy-response
+        boolean isAcknowledged =
+            putPolicyResponse.isAcknowledged(); // <1>
+        // end::enrich-put-policy-response
+
+        // tag::enrich-put-policy-execute-listener
+        ActionListener<AcknowledgedResponse> listener = new ActionListener<>() {
+                @Override
+                public void onResponse(AcknowledgedResponse response) { // <1>
+                    boolean isAcknowledged =
+                        putPolicyResponse.isAcknowledged();
+                }
+
+                @Override
+                public void onFailure(Exception e) {
+                    // <2>
+                }
+            };
+        // end::enrich-put-policy-execute-listener
+
+        // Replace the empty listener by a blocking listener in test
+        final CountDownLatch latch = new CountDownLatch(1);
+        listener = new LatchedActionListener<>(listener, latch);
+
+        // tag::enrich-put-policy-execute-async
+        client.enrich().putPolicyAsync(putPolicyRequest,
+            RequestOptions.DEFAULT, listener); // <1>
+        // end::enrich-put-policy-execute-async
+
+        assertTrue(latch.await(30L, TimeUnit.SECONDS));
+    }
+
+}

+ 105 - 0
client/rest-high-level/src/test/java/org/elasticsearch/client/enrich/PutPolicyRequestTests.java

@@ -0,0 +1,105 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.client.enrich;
+
+import org.elasticsearch.client.AbstractRequestTestCase;
+import org.elasticsearch.common.xcontent.XContentParser;
+import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.index.query.MatchAllQueryBuilder;
+import org.elasticsearch.test.EqualsHashCodeTestUtils;
+import org.elasticsearch.xpack.core.enrich.action.PutEnrichPolicyAction;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.Arrays;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.nullValue;
+
+public class PutPolicyRequestTests extends AbstractRequestTestCase<PutPolicyRequest, PutEnrichPolicyAction.Request> {
+
+    public void testValidate() {
+        PutPolicyRequest request = createClientTestInstance();
+        assertThat(request.validate().isPresent(), is(false));
+
+        Exception e = expectThrows(IllegalArgumentException.class,
+            () -> new PutPolicyRequest(request.getName(), request.getType(), request.getIndices(), null, request.getEnrichValues()));
+        assertThat(e.getMessage(), containsString("enrichKey must be a non-null and non-empty string"));
+    }
+
+    public void testEqualsAndHashcode() {
+        PutPolicyRequest testInstance = createTestInstance();
+        EqualsHashCodeTestUtils.checkEqualsAndHashCode(testInstance, (original) -> {
+            PutPolicyRequest copy = new PutPolicyRequest(original.getName(), original.getType(), original.getIndices(),
+                original.getEnrichKey(), original.getEnrichValues());
+            copy.setQuery(original.getQuery());
+            return copy;
+        });
+    }
+
+    @Override
+    protected PutPolicyRequest createClientTestInstance() {
+        return createTestInstance("name");
+    }
+
+    public static PutPolicyRequest createTestInstance() {
+        return createTestInstance(randomAlphaOfLength(4));
+    }
+
+    public static PutPolicyRequest createTestInstance(String name) {
+        PutPolicyRequest testInstance = new PutPolicyRequest(
+            name,
+            randomAlphaOfLength(4),
+            Arrays.asList(generateRandomStringArray(4, 4, false, false)),
+            randomAlphaOfLength(4),
+            Arrays.asList(generateRandomStringArray(4, 4, false, false))
+        );
+        if (randomBoolean()) {
+            try {
+                testInstance.setQuery(new MatchAllQueryBuilder());
+            } catch (IOException e) {
+                throw new UncheckedIOException(e);
+            }
+        }
+        return testInstance;
+    }
+
+    @Override
+    protected PutEnrichPolicyAction.Request doParseToServerInstance(XContentParser parser) throws IOException {
+        return PutEnrichPolicyAction.fromXContent(parser, "name");
+    }
+
+    @Override
+    protected void assertInstances(PutEnrichPolicyAction.Request serverInstance, PutPolicyRequest clientTestInstance) {
+        assertThat(clientTestInstance.getName(), equalTo(serverInstance.getName()));
+        assertThat(clientTestInstance.getType(), equalTo(serverInstance.getPolicy().getType()));
+        assertThat(clientTestInstance.getIndices(), equalTo(serverInstance.getPolicy().getIndices()));
+        if (clientTestInstance.getQuery() != null) {
+            XContentType type = serverInstance.getPolicy().getQuery().getContentType();
+            assertThat(PutPolicyRequest.asMap(clientTestInstance.getQuery(), type),
+                equalTo(PutPolicyRequest.asMap(serverInstance.getPolicy().getQuery().getQuery(), type)));
+        } else {
+            assertThat(serverInstance.getPolicy().getQuery(), nullValue());
+        }
+        assertThat(clientTestInstance.getEnrichKey(), equalTo(serverInstance.getPolicy().getEnrichKey()));
+        assertThat(clientTestInstance.getEnrichValues(), equalTo(serverInstance.getPolicy().getEnrichValues()));
+    }
+}

+ 31 - 0
docs/java-rest/high-level/enrich/put_policy.asciidoc

@@ -0,0 +1,31 @@
+--
+:api: enrich-put-policy
+:request: PutPolicyRequest
+:response: AcknowledgedResponse
+--
+
+[id="{upid}-{api}"]
+=== Put Policy API
+
+[id="{upid}-{api}-request"]
+==== Request
+
+The Put Policy API stores an enrich policy in Elasticsearch.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request]
+--------------------------------------------------
+
+[id="{upid}-{api}-response"]
+==== Response
+
+The returned +{response}+ indicates if the put policy request was acknowledged.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-response]
+--------------------------------------------------
+<1> Whether put policy request was acknowledged.
+
+include::../execution.asciidoc[]

+ 11 - 0
docs/java-rest/high-level/supported-apis.asciidoc

@@ -592,3 +592,14 @@ include::dataframe/delete_data_frame.asciidoc[]
 include::dataframe/preview_data_frame.asciidoc[]
 include::dataframe/preview_data_frame.asciidoc[]
 include::dataframe/start_data_frame.asciidoc[]
 include::dataframe/start_data_frame.asciidoc[]
 include::dataframe/stop_data_frame.asciidoc[]
 include::dataframe/stop_data_frame.asciidoc[]
+
+== Enrich APIs
+
+:upid: {mainid}-enrich
+:doc-tests-file: {doc-tests}/EnrichDocumentationIT.java
+
+The Java High Level REST Client supports the following Enrich APIs:
+
+* <<{upid}-enrich-put-policy>>
+
+include::enrich/put_policy.asciidoc[]