Skip to content

Commit

Permalink
[Connectors API] Make nullable fields optional in the parser inside C…
Browse files Browse the repository at this point in the history
…onnectorSyncJob (elastic#103262) (elastic#103544)

Make nullable fields optional in the ConnectorSyncJob parser.

(cherry picked from commit 2f01a37)

Co-authored-by: Tim Grein <[email protected]>
  • Loading branch information
jedrazb and timgrein authored Dec 19, 2023
1 parent 8a27f7a commit 01e6a46
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ private Connector(
this.error = error;
this.features = features;
this.filtering = Objects.requireNonNull(filtering, "[filtering] cannot be null");
this.indexName = Objects.requireNonNull(indexName, "[index_name] cannot be null");
this.indexName = indexName;
this.isNative = isNative;
this.language = language;
this.lastSeen = lastSeen;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.io.IOException;
import java.time.Instant;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -349,20 +350,19 @@ private static Instant parseNullableInstant(XContentParser p) throws IOException
(p, c) -> ConnectorFiltering.fromXContent(p),
Connector.FILTERING_FIELD
);
SYNC_JOB_CONNECTOR_PARSER.declareString(optionalConstructorArg(), Connector.INDEX_NAME_FIELD);
SYNC_JOB_CONNECTOR_PARSER.declareString(optionalConstructorArg(), Connector.LANGUAGE_FIELD);
SYNC_JOB_CONNECTOR_PARSER.declareField(
SYNC_JOB_CONNECTOR_PARSER.declareStringOrNull(optionalConstructorArg(), Connector.INDEX_NAME_FIELD);
SYNC_JOB_CONNECTOR_PARSER.declareStringOrNull(optionalConstructorArg(), Connector.LANGUAGE_FIELD);
SYNC_JOB_CONNECTOR_PARSER.declareObjectOrNull(
optionalConstructorArg(),
(p, c) -> ConnectorIngestPipeline.fromXContent(p),
Connector.PIPELINE_FIELD,
ObjectParser.ValueType.OBJECT
null,
Connector.PIPELINE_FIELD
);
SYNC_JOB_CONNECTOR_PARSER.declareString(optionalConstructorArg(), Connector.SERVICE_TYPE_FIELD);
SYNC_JOB_CONNECTOR_PARSER.declareField(
SYNC_JOB_CONNECTOR_PARSER.declareStringOrNull(optionalConstructorArg(), Connector.SERVICE_TYPE_FIELD);
SYNC_JOB_CONNECTOR_PARSER.declareObject(
optionalConstructorArg(),
(parser, context) -> parser.map(),
Connector.CONFIGURATION_FIELD,
ObjectParser.ValueType.OBJECT
(p, c) -> p.map(HashMap::new, ConnectorConfiguration::fromXContent),
Connector.CONFIGURATION_FIELD
);
}

Expand All @@ -378,6 +378,14 @@ public static ConnectorSyncJob fromXContent(XContentParser parser) throws IOExce
return PARSER.parse(parser, null);
}

public static Connector syncJobConnectorFromXContentBytes(BytesReference source, XContentType xContentType) {
try (XContentParser parser = XContentHelper.createParser(XContentParserConfiguration.EMPTY, source, xContentType)) {
return ConnectorSyncJob.syncJobConnectorFromXContent(parser);
} catch (IOException e) {
throw new ElasticsearchParseException("Failed to parse a connector document.", e);
}
}

public static Connector syncJobConnectorFromXContent(XContentParser parser) throws IOException {
return SYNC_JOB_CONNECTOR_PARSER.parse(parser, null);
}
Expand Down Expand Up @@ -470,7 +478,9 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws

builder.startObject(CONNECTOR_FIELD.getPreferredName());
{
builder.field(Connector.ID_FIELD.getPreferredName(), connector.getConnectorId());
if (connector.getConnectorId() != null) {
builder.field(Connector.ID_FIELD.getPreferredName(), connector.getConnectorId());
}
if (connector.getFiltering() != null) {
builder.field(Connector.FILTERING_FIELD.getPreferredName(), connector.getFiltering());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,151 @@ public void testFromXContent_WithAllNullableFieldsSetToNull_DoesNotThrow() throw
ConnectorSyncJob.fromXContentBytes(new BytesArray(content), XContentType.JSON);
}

public void testSyncJobConnectorFromXContent_WithAllFieldsSet() throws IOException {
String content = XContentHelper.stripWhitespace("""
{
"id": "connector-id",
"filtering": [
{
"active": {
"advanced_snippet": {
"created_at": "2023-12-01T14:18:37.397819Z",
"updated_at": "2023-12-01T14:18:37.397819Z",
"value": {}
},
"rules": [
{
"created_at": "2023-12-01T14:18:37.397819Z",
"field": "_",
"id": "DEFAULT",
"order": 0,
"policy": "include",
"rule": "regex",
"updated_at": "2023-12-01T14:18:37.397819Z",
"value": ".*"
}
],
"validation": {
"errors": [],
"state": "valid"
}
},
"domain": "DEFAULT",
"draft": {
"advanced_snippet": {
"created_at": "2023-12-01T14:18:37.397819Z",
"updated_at": "2023-12-01T14:18:37.397819Z",
"value": {}
},
"rules": [
{
"created_at": "2023-12-01T14:18:37.397819Z",
"field": "_",
"id": "DEFAULT",
"order": 0,
"policy": "include",
"rule": "regex",
"updated_at": "2023-12-01T14:18:37.397819Z",
"value": ".*"
}
],
"validation": {
"errors": [],
"state": "valid"
}
}
}
],
"index_name": "search-connector",
"language": "english",
"pipeline": {
"extract_binary_content": true,
"name": "ent-search-generic-ingestion",
"reduce_whitespace": true,
"run_ml_inference": false
},
"service_type": "service type",
"configuration": {}
}
""");

Connector connector = ConnectorSyncJob.syncJobConnectorFromXContentBytes(new BytesArray(content), XContentType.JSON);

assertThat(connector.getConnectorId(), equalTo("connector-id"));
assertThat(connector.getFiltering().size(), equalTo(1));
assertThat(connector.getIndexName(), equalTo("search-connector"));
assertThat(connector.getLanguage(), equalTo("english"));
assertThat(connector.getPipeline(), notNullValue());
assertThat(connector.getServiceType(), equalTo("service type"));
assertThat(connector.getConfiguration(), notNullValue());
}

public void testSyncJobConnectorFromXContent_WithAllNonOptionalFieldsSet_DoesNotThrow() throws IOException {
String content = XContentHelper.stripWhitespace("""
{
"id": "connector-id",
"filtering": [
{
"active": {
"advanced_snippet": {
"created_at": "2023-12-01T14:18:37.397819Z",
"updated_at": "2023-12-01T14:18:37.397819Z",
"value": {}
},
"rules": [
{
"created_at": "2023-12-01T14:18:37.397819Z",
"field": "_",
"id": "DEFAULT",
"order": 0,
"policy": "include",
"rule": "regex",
"updated_at": "2023-12-01T14:18:37.397819Z",
"value": ".*"
}
],
"validation": {
"errors": [],
"state": "valid"
}
},
"domain": "DEFAULT",
"draft": {
"advanced_snippet": {
"created_at": "2023-12-01T14:18:37.397819Z",
"updated_at": "2023-12-01T14:18:37.397819Z",
"value": {}
},
"rules": [
{
"created_at": "2023-12-01T14:18:37.397819Z",
"field": "_",
"id": "DEFAULT",
"order": 0,
"policy": "include",
"rule": "regex",
"updated_at": "2023-12-01T14:18:37.397819Z",
"value": ".*"
}
],
"validation": {
"errors": [],
"state": "valid"
}
}
}
],
"index_name": null,
"language": null,
"pipeline": null,
"service_type": null,
"configuration": {}
}
""");

ConnectorSyncJob.syncJobConnectorFromXContentBytes(new BytesArray(content), XContentType.JSON);
}

private void assertTransportSerialization(ConnectorSyncJob testInstance) throws IOException {
ConnectorSyncJob deserializedInstance = copyInstance(testInstance);
assertNotSame(testInstance, deserializedInstance);
Expand Down

0 comments on commit 01e6a46

Please sign in to comment.