Skip to content

Commit f14874c

Browse files
authored
Change how type is stored in an enrich policy. (#45789)
A policy type controls how the enrich index is created and the query executed against the match field. Currently there is a single policy type (`exact_match`). In the near future more policy types will be added and different policy may have different configuration options. For this reason type should be a json object instead of a string field: ``` { "exact_match": { ... } } ``` instead of: ``` { "type": "exact_match", ... } ``` This will make streaming parsing of enrich policies easier as in the new format, the parsing code can know ahead what configuration fields to expect. In the latter format that is not possible if the type field appears not as the first field. Relates to #32789
1 parent b48784f commit f14874c

File tree

8 files changed

+166
-91
lines changed

8 files changed

+166
-91
lines changed

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636

3737
public class PutPolicyRequest implements Validatable, ToXContentObject {
3838

39-
static final ParseField TYPE_FIELD = new ParseField("type");
4039
static final ParseField QUERY_FIELD = new ParseField("query");
4140
static final ParseField INDICES_FIELD = new ParseField("indices");
4241
static final ParseField MATCH_FIELD_FIELD = new ParseField("match_field");
@@ -108,13 +107,18 @@ public List<String> getEnrichFields() {
108107
@Override
109108
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
110109
builder.startObject();
111-
builder.field(TYPE_FIELD.getPreferredName(), type);
112-
builder.field(INDICES_FIELD.getPreferredName(), indices);
113-
if (query != null) {
114-
builder.field(QUERY_FIELD.getPreferredName(), asMap(query, builder.contentType()));
110+
{
111+
builder.startObject(type);
112+
{
113+
builder.field(INDICES_FIELD.getPreferredName(), indices);
114+
if (query != null) {
115+
builder.field(QUERY_FIELD.getPreferredName(), asMap(query, builder.contentType()));
116+
}
117+
builder.field(MATCH_FIELD_FIELD.getPreferredName(), matchField);
118+
builder.field(ENRICH_FIELDS_FIELD.getPreferredName(), enrichFields);
119+
}
120+
builder.endObject();
115121
}
116-
builder.field(MATCH_FIELD_FIELD.getPreferredName(), matchField);
117-
builder.field(ENRICH_FIELDS_FIELD.getPreferredName(), enrichFields);
118122
builder.endObject();
119123
return builder;
120124
}

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.elasticsearch.client.enrich.PutPolicyRequest;
2424
import org.elasticsearch.common.xcontent.XContentHelper;
2525
import org.elasticsearch.common.xcontent.json.JsonXContent;
26+
import org.elasticsearch.common.xcontent.support.XContentMapValues;
2627

2728
import java.io.IOException;
2829
import java.util.List;
@@ -48,10 +49,12 @@ public void testCRUD() throws Exception {
4849
@SuppressWarnings("unchecked")
4950
List<Map<String, Object>> responsePolicies = (List<Map<String, Object>>) responseBody.get("policies");
5051
assertThat(responsePolicies.size(), equalTo(1));
51-
assertThat(responsePolicies.get(0).get("type"), equalTo(putPolicyRequest.getType()));
52-
assertThat(responsePolicies.get(0).get("indices"), equalTo(putPolicyRequest.getIndices()));
53-
assertThat(responsePolicies.get(0).get("match_field"), equalTo(putPolicyRequest.getMatchField()));
54-
assertThat(responsePolicies.get(0).get("enrich_fields"), equalTo(putPolicyRequest.getEnrichFields()));
52+
assertThat(XContentMapValues.extractValue("exact_match.indices", responsePolicies.get(0)),
53+
equalTo(putPolicyRequest.getIndices()));
54+
assertThat(XContentMapValues.extractValue("exact_match.match_field", responsePolicies.get(0)),
55+
equalTo(putPolicyRequest.getMatchField()));
56+
assertThat(XContentMapValues.extractValue("exact_match.enrich_fields", responsePolicies.get(0)),
57+
equalTo(putPolicyRequest.getEnrichFields()));
5558
}
5659

5760
private static Map<String, Object> toMap(Response response) throws IOException {

docs/reference/ingest/ingest-node.asciidoc

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -858,10 +858,11 @@ Create an enrich policy:
858858
--------------------------------------------------
859859
PUT /_enrich/policy/users-policy
860860
{
861-
"type": "exact_match",
862-
"indices": "users",
863-
"match_field": "email",
864-
"enrich_fields": ["first_name", "last_name", "address", "city", "zip", "state"]
861+
"exact_match": {
862+
"indices": "users",
863+
"match_field": "email",
864+
"enrich_fields": ["first_name", "last_name", "address", "city", "zip", "state"]
865+
}
865866
}
866867
--------------------------------------------------
867868
// CONSOLE
@@ -990,10 +991,11 @@ Request:
990991
--------------------------------------------------
991992
PUT /_enrich/policy/my-policy
992993
{
993-
"type": "exact_match",
994-
"indices": "users",
995-
"match_field": "email",
996-
"enrich_fields": ["first_name", "last_name", "address", "city", "zip", "state"]
994+
"exact_match": {
995+
"indices": "users",
996+
"match_field": "email",
997+
"enrich_fields": ["first_name", "last_name", "address", "city", "zip", "state"]
998+
}
997999
}
9981000
--------------------------------------------------
9991001
// CONSOLE
@@ -1029,18 +1031,19 @@ Response:
10291031
{
10301032
"policies": [
10311033
{
1032-
"name" : "my-policy",
1033-
"type" : "exact_match",
1034-
"indices" : ["users"],
1035-
"match_field" : "email",
1036-
"enrich_fields" : [
1037-
"first_name",
1038-
"last_name",
1039-
"address",
1040-
"city",
1041-
"zip",
1042-
"state"
1043-
]
1034+
"exact_match": {
1035+
"name" : "my-policy",
1036+
"indices" : ["users"],
1037+
"match_field" : "email",
1038+
"enrich_fields" : [
1039+
"first_name",
1040+
"last_name",
1041+
"address",
1042+
"city",
1043+
"zip",
1044+
"state"
1045+
]
1046+
}
10441047
}
10451048
]
10461049
}
@@ -1065,18 +1068,19 @@ Response:
10651068
{
10661069
"policies": [
10671070
{
1068-
"name" : "my-policy",
1069-
"type" : "exact_match",
1070-
"indices" : ["users"],
1071-
"match_field" : "email",
1072-
"enrich_fields" : [
1073-
"first_name",
1074-
"last_name",
1075-
"address",
1076-
"city",
1077-
"zip",
1078-
"state"
1079-
]
1071+
"exact_match": {
1072+
"name" : "my-policy",
1073+
"indices" : ["users"],
1074+
"match_field" : "email",
1075+
"enrich_fields" : [
1076+
"first_name",
1077+
"last_name",
1078+
"address",
1079+
"city",
1080+
"zip",
1081+
"state"
1082+
]
1083+
}
10801084
}
10811085
]
10821086
}

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

Lines changed: 72 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package org.elasticsearch.xpack.core.enrich;
77

88
import org.elasticsearch.common.ParseField;
9+
import org.elasticsearch.common.ParsingException;
910
import org.elasticsearch.common.Strings;
1011
import org.elasticsearch.common.bytes.BytesReference;
1112
import org.elasticsearch.common.io.stream.StreamInput;
@@ -17,6 +18,7 @@
1718
import org.elasticsearch.common.xcontent.XContentBuilder;
1819
import org.elasticsearch.common.xcontent.XContentHelper;
1920
import org.elasticsearch.common.xcontent.XContentParser;
21+
import org.elasticsearch.common.xcontent.XContentParser.Token;
2022
import org.elasticsearch.common.xcontent.XContentType;
2123

2224
import java.io.IOException;
@@ -34,20 +36,21 @@ public final class EnrichPolicy implements Writeable, ToXContentFragment {
3436
public static final String EXACT_MATCH_TYPE = "exact_match";
3537
public static final String[] SUPPORTED_POLICY_TYPES = new String[]{EXACT_MATCH_TYPE};
3638

37-
private static final ParseField TYPE = new ParseField("type");
3839
private static final ParseField QUERY = new ParseField("query");
3940
private static final ParseField INDICES = new ParseField("indices");
4041
private static final ParseField MATCH_FIELD = new ParseField("match_field");
4142
private static final ParseField ENRICH_FIELDS = new ParseField("enrich_fields");
4243

4344
@SuppressWarnings("unchecked")
44-
private static final ConstructingObjectParser<EnrichPolicy, Void> PARSER = new ConstructingObjectParser<>("policy",
45-
args -> new EnrichPolicy(
46-
(String) args[0],
47-
(QuerySource) args[1],
48-
(List<String>) args[2],
49-
(String) args[3],
50-
(List<String>) args[4]
45+
private static final ConstructingObjectParser<EnrichPolicy, String> PARSER = new ConstructingObjectParser<>(
46+
"policy",
47+
false,
48+
(args, policyType) -> new EnrichPolicy(
49+
policyType,
50+
(QuerySource) args[0],
51+
(List<String>) args[1],
52+
(String) args[2],
53+
(List<String>) args[3]
5154
)
5255
);
5356

@@ -56,7 +59,6 @@ public final class EnrichPolicy implements Writeable, ToXContentFragment {
5659
}
5760

5861
private static void declareParserOptions(ConstructingObjectParser<?, ?> parser) {
59-
parser.declareString(ConstructingObjectParser.constructorArg(), TYPE);
6062
parser.declareObject(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> {
6163
XContentBuilder contentBuilder = XContentBuilder.builder(p.contentType().xContent());
6264
contentBuilder.generator().copyCurrentStructure(p);
@@ -68,7 +70,24 @@ private static void declareParserOptions(ConstructingObjectParser<?, ?> parser)
6870
}
6971

7072
public static EnrichPolicy fromXContent(XContentParser parser) throws IOException {
71-
return PARSER.parse(parser, null);
73+
Token token = parser.currentToken();
74+
if (token != Token.START_OBJECT) {
75+
token = parser.nextToken();
76+
}
77+
if (token != Token.START_OBJECT) {
78+
throw new ParsingException(parser.getTokenLocation(), "unexpected token");
79+
}
80+
token = parser.nextToken();
81+
if (token != Token.FIELD_NAME) {
82+
throw new ParsingException(parser.getTokenLocation(), "unexpected token");
83+
}
84+
String policyType = parser.currentName();
85+
EnrichPolicy policy = PARSER.parse(parser, policyType);
86+
token = parser.nextToken();
87+
if (token != Token.END_OBJECT) {
88+
throw new ParsingException(parser.getTokenLocation(), "unexpected token");
89+
}
90+
return policy;
7291
}
7392

7493
private final String type;
@@ -134,14 +153,21 @@ public void writeTo(StreamOutput out) throws IOException {
134153

135154
@Override
136155
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
137-
builder.field(TYPE.getPreferredName(), type);
156+
builder.startObject(type);
157+
{
158+
toInnerXContent(builder);
159+
}
160+
builder.endObject();
161+
return builder;
162+
}
163+
164+
private void toInnerXContent(XContentBuilder builder) throws IOException {
138165
if (query != null) {
139166
builder.field(QUERY.getPreferredName(), query.getQueryAsMap());
140167
}
141168
builder.array(INDICES.getPreferredName(), indices.toArray(new String[0]));
142169
builder.field(MATCH_FIELD.getPreferredName(), matchField);
143170
builder.array(ENRICH_FIELDS.getPreferredName(), enrichFields.toArray(new String[0]));
144-
return builder;
145171
}
146172

147173
@Override
@@ -222,14 +248,16 @@ public static class NamedPolicy implements Writeable, ToXContent {
222248

223249
static final ParseField NAME = new ParseField("name");
224250
@SuppressWarnings("unchecked")
225-
static final ConstructingObjectParser<NamedPolicy, Void> PARSER = new ConstructingObjectParser<>("named_policy",
226-
args -> new NamedPolicy(
251+
static final ConstructingObjectParser<NamedPolicy, String> PARSER = new ConstructingObjectParser<>(
252+
"named_policy",
253+
false,
254+
(args, policyType) -> new NamedPolicy(
227255
(String) args[0],
228-
new EnrichPolicy((String) args[1],
229-
(QuerySource) args[2],
230-
(List<String>) args[3],
231-
(String) args[4],
232-
(List<String>) args[5])
256+
new EnrichPolicy(policyType,
257+
(QuerySource) args[1],
258+
(List<String>) args[2],
259+
(String) args[3],
260+
(List<String>) args[4])
233261
)
234262
);
235263

@@ -268,16 +296,39 @@ public void writeTo(StreamOutput out) throws IOException {
268296
@Override
269297
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
270298
builder.startObject();
299+
builder.startObject(policy.type);
271300
{
272301
builder.field(NAME.getPreferredName(), name);
273-
policy.toXContent(builder, params);
302+
policy.toInnerXContent(builder);
274303
}
275304
builder.endObject();
305+
builder.endObject();
276306
return builder;
277307
}
278308

279309
public static NamedPolicy fromXContent(XContentParser parser) throws IOException {
280-
return PARSER.parse(parser, null);
310+
Token token = parser.currentToken();
311+
if (token != Token.START_OBJECT) {
312+
token = parser.nextToken();
313+
}
314+
if (token != Token.START_OBJECT) {
315+
throw new ParsingException(parser.getTokenLocation(), "unexpected token");
316+
}
317+
token = parser.nextToken();
318+
if (token != Token.FIELD_NAME) {
319+
throw new ParsingException(parser.getTokenLocation(), "unexpected token");
320+
}
321+
String policyType = parser.currentName();
322+
token = parser.nextToken();
323+
if (token != Token.START_OBJECT) {
324+
throw new ParsingException(parser.getTokenLocation(), "unexpected token");
325+
}
326+
NamedPolicy policy = PARSER.parse(parser, policyType);
327+
token = parser.nextToken();
328+
if (token != Token.END_OBJECT) {
329+
throw new ParsingException(parser.getTokenLocation(), "unexpected token");
330+
}
331+
return policy;
281332
}
282333

283334
@Override

0 commit comments

Comments
 (0)