diff --git a/docs/changelog/104909.yaml b/docs/changelog/104909.yaml new file mode 100644 index 0000000000000..6d250c22a745a --- /dev/null +++ b/docs/changelog/104909.yaml @@ -0,0 +1,5 @@ +pr: 104909 +summary: "[Connectors API] Relax strict response parsing for get/list operations" +area: Application +type: enhancement +issues: [] diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/Connector.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/Connector.java index fdbf27929789f..b7ddf560247ed 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/Connector.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/Connector.java @@ -356,34 +356,38 @@ public static Connector fromXContent(XContentParser parser, String docId) throws return PARSER.parse(parser, docId); } + public void toInnerXContent(XContentBuilder builder, Params params) throws IOException { + // The "id": connectorId is included in GET and LIST responses to provide the connector's docID. + // Note: This ID is not written to the Elasticsearch index; it's only for API response purposes. + if (connectorId != null) { + builder.field(ID_FIELD.getPreferredName(), connectorId); + } + builder.field(API_KEY_ID_FIELD.getPreferredName(), apiKeyId); + builder.xContentValuesMap(CONFIGURATION_FIELD.getPreferredName(), configuration); + builder.xContentValuesMap(CUSTOM_SCHEDULING_FIELD.getPreferredName(), customScheduling); + builder.field(DESCRIPTION_FIELD.getPreferredName(), description); + builder.field(ERROR_FIELD.getPreferredName(), error); + builder.field(FEATURES_FIELD.getPreferredName(), features); + builder.xContentList(FILTERING_FIELD.getPreferredName(), filtering); + builder.field(INDEX_NAME_FIELD.getPreferredName(), indexName); + builder.field(IS_NATIVE_FIELD.getPreferredName(), isNative); + builder.field(LANGUAGE_FIELD.getPreferredName(), language); + builder.field(LAST_SEEN_FIELD.getPreferredName(), lastSeen); + syncInfo.toXContent(builder, params); + builder.field(NAME_FIELD.getPreferredName(), name); + builder.field(PIPELINE_FIELD.getPreferredName(), pipeline); + builder.field(SCHEDULING_FIELD.getPreferredName(), scheduling); + builder.field(SERVICE_TYPE_FIELD.getPreferredName(), serviceType); + builder.field(SYNC_CURSOR_FIELD.getPreferredName(), syncCursor); + builder.field(STATUS_FIELD.getPreferredName(), status.toString()); + builder.field(SYNC_NOW_FIELD.getPreferredName(), syncNow); + } + @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); { - // The "id": connectorId is included in GET and LIST responses to provide the connector's docID. - // Note: This ID is not written to the Elasticsearch index; it's only for API response purposes. - if (connectorId != null) { - builder.field(ID_FIELD.getPreferredName(), connectorId); - } - builder.field(API_KEY_ID_FIELD.getPreferredName(), apiKeyId); - builder.xContentValuesMap(CONFIGURATION_FIELD.getPreferredName(), configuration); - builder.xContentValuesMap(CUSTOM_SCHEDULING_FIELD.getPreferredName(), customScheduling); - builder.field(DESCRIPTION_FIELD.getPreferredName(), description); - builder.field(ERROR_FIELD.getPreferredName(), error); - builder.field(FEATURES_FIELD.getPreferredName(), features); - builder.xContentList(FILTERING_FIELD.getPreferredName(), filtering); - builder.field(INDEX_NAME_FIELD.getPreferredName(), indexName); - builder.field(IS_NATIVE_FIELD.getPreferredName(), isNative); - builder.field(LANGUAGE_FIELD.getPreferredName(), language); - builder.field(LAST_SEEN_FIELD.getPreferredName(), lastSeen); - syncInfo.toXContent(builder, params); - builder.field(NAME_FIELD.getPreferredName(), name); - builder.field(PIPELINE_FIELD.getPreferredName(), pipeline); - builder.field(SCHEDULING_FIELD.getPreferredName(), scheduling); - builder.field(SERVICE_TYPE_FIELD.getPreferredName(), serviceType); - builder.field(SYNC_CURSOR_FIELD.getPreferredName(), syncCursor); - builder.field(STATUS_FIELD.getPreferredName(), status.toString()); - builder.field(SYNC_NOW_FIELD.getPreferredName(), syncNow); + toInnerXContent(builder, params); } builder.endObject(); return builder; diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorIndexService.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorIndexService.java index d92074dacc129..47eb97835dd7f 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorIndexService.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorIndexService.java @@ -30,7 +30,6 @@ import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.sort.SortOrder; import org.elasticsearch.xcontent.ToXContent; -import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xpack.application.connector.action.PostConnectorAction; import org.elasticsearch.xpack.application.connector.action.PutConnectorAction; import org.elasticsearch.xpack.application.connector.action.UpdateConnectorConfigurationAction; @@ -175,7 +174,7 @@ private Connector createConnectorWithDefaultValues( * @param connectorId The id of the connector object. * @param listener The action listener to invoke on response/failure. */ - public void getConnector(String connectorId, ActionListener listener) { + public void getConnector(String connectorId, ActionListener listener) { try { final GetRequest getRequest = new GetRequest(CONNECTOR_INDEX_NAME).id(connectorId).realtime(true); @@ -185,11 +184,11 @@ public void getConnector(String connectorId, ActionListener listener) return; } try { - final Connector connector = Connector.fromXContentBytes( - getResponse.getSourceAsBytesRef(), - connectorId, - XContentType.JSON - ); + final ConnectorSearchResult connector = new ConnectorSearchResult.Builder().setId(connectorId) + .setResultBytes(getResponse.getSourceAsBytesRef()) + .setResultMap(getResponse.getSourceAsMap()) + .build(); + l.onResponse(connector); } catch (Exception e) { listener.onFailure(e); @@ -567,7 +566,9 @@ public void updateConnectorServiceType(UpdateConnectorServiceTypeAction.Request String connectorId = request.getConnectorId(); getConnector(connectorId, listener.delegateFailure((l, connector) -> { - ConnectorStatus prevStatus = connector.getStatus(); + ConnectorStatus prevStatus = ConnectorStatus.connectorStatus( + (String) connector.getResultMap().get(Connector.STATUS_FIELD.getPreferredName()) + ); ConnectorStatus newStatus = prevStatus == ConnectorStatus.CREATED ? ConnectorStatus.CREATED : ConnectorStatus.NEEDS_CONFIGURATION; @@ -603,20 +604,23 @@ public void updateConnectorServiceType(UpdateConnectorServiceTypeAction.Request } private static ConnectorIndexService.ConnectorResult mapSearchResponseToConnectorList(SearchResponse response) { - final List connectorResults = Arrays.stream(response.getHits().getHits()) + final List connectorResults = Arrays.stream(response.getHits().getHits()) .map(ConnectorIndexService::hitToConnector) .toList(); return new ConnectorIndexService.ConnectorResult(connectorResults, (int) response.getHits().getTotalHits().value); } - private static Connector hitToConnector(SearchHit searchHit) { + private static ConnectorSearchResult hitToConnector(SearchHit searchHit) { // todo: don't return sensitive data from configuration in list endpoint - return Connector.fromXContentBytes(searchHit.getSourceRef(), searchHit.getId(), XContentType.JSON); + return new ConnectorSearchResult.Builder().setId(searchHit.getId()) + .setResultBytes(searchHit.getSourceRef()) + .setResultMap(searchHit.getSourceAsMap()) + .build(); } - public record ConnectorResult(List connectors, long totalResults) {} + public record ConnectorResult(List connectors, long totalResults) {} /** * Listeners that checks failures for IndexNotFoundException, and transforms them in ResourceNotFoundException, diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorSearchResult.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorSearchResult.java new file mode 100644 index 0000000000000..d054542e0865a --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorSearchResult.java @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector; + +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.io.stream.StreamInput; + +import java.io.IOException; +import java.util.Map; + +public class ConnectorSearchResult extends ConnectorsAPISearchResult { + + public ConnectorSearchResult(StreamInput in) throws IOException { + super(in); + } + + private ConnectorSearchResult(BytesReference resultBytes, Map resultMap, String id) { + super(resultBytes, resultMap, id); + } + + public static class Builder { + + private BytesReference resultBytes; + private Map resultMap; + private String id; + + public Builder setResultBytes(BytesReference resultBytes) { + this.resultBytes = resultBytes; + return this; + } + + public Builder setResultMap(Map resultMap) { + this.resultMap = resultMap; + return this; + } + + public Builder setId(String id) { + this.id = id; + return this; + } + + public ConnectorSearchResult build() { + return new ConnectorSearchResult(resultBytes, resultMap, id); + } + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorsAPISearchResult.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorsAPISearchResult.java new file mode 100644 index 0000000000000..a00e3748565d8 --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorsAPISearchResult.java @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector; + +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.xcontent.ToXContentObject; +import org.elasticsearch.xcontent.XContentBuilder; +import org.elasticsearch.xpack.application.connector.syncjob.ConnectorSyncJob; + +import java.io.IOException; +import java.util.Map; +import java.util.Objects; + +/** + * Represents the outcome of a search query in the connectors and sync job index, encapsulating the search result. + * It includes a raw byte reference to the result which can be deserialized into a {@link Connector} or {@link ConnectorSyncJob} object, + * and a result map for returning the data without strict deserialization. + */ +public class ConnectorsAPISearchResult implements Writeable, ToXContentObject { + + private final BytesReference resultBytes; + private final Map resultMap; + private final String docId; + + protected ConnectorsAPISearchResult(BytesReference resultBytes, Map resultMap, String id) { + this.resultBytes = resultBytes; + this.resultMap = resultMap; + this.docId = id; + } + + public ConnectorsAPISearchResult(StreamInput in) throws IOException { + this.resultBytes = in.readBytesReference(); + this.resultMap = in.readGenericMap(); + this.docId = in.readString(); + } + + public BytesReference getSourceRef() { + return resultBytes; + } + + public Map getResultMap() { + return resultMap; + } + + public String getDocId() { + return docId; + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + { + builder.field("id", docId); + builder.mapContents(resultMap); + } + builder.endObject(); + return builder; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeBytesReference(resultBytes); + out.writeGenericMap(resultMap); + out.writeString(docId); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ConnectorsAPISearchResult that = (ConnectorsAPISearchResult) o; + return Objects.equals(resultBytes, that.resultBytes) + && Objects.equals(resultMap, that.resultMap) + && Objects.equals(docId, that.docId); + } + + @Override + public int hashCode() { + return Objects.hash(resultBytes, resultMap, docId); + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/GetConnectorAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/GetConnectorAction.java index 88eacc8f437b4..a9792458f1963 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/GetConnectorAction.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/GetConnectorAction.java @@ -19,7 +19,7 @@ import org.elasticsearch.xcontent.ToXContentObject; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentParser; -import org.elasticsearch.xpack.application.connector.Connector; +import org.elasticsearch.xpack.application.connector.ConnectorSearchResult; import java.io.IOException; import java.util.Objects; @@ -110,15 +110,15 @@ public static Request parse(XContentParser parser) { public static class Response extends ActionResponse implements ToXContentObject { - private final Connector connector; + private final ConnectorSearchResult connector; - public Response(Connector connector) { + public Response(ConnectorSearchResult connector) { this.connector = connector; } public Response(StreamInput in) throws IOException { super(in); - this.connector = new Connector(in); + this.connector = new ConnectorSearchResult(in); } @Override @@ -131,10 +131,6 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws return connector.toXContent(builder, params); } - public static GetConnectorAction.Response fromXContent(XContentParser parser, String docId) throws IOException { - return new GetConnectorAction.Response(Connector.fromXContent(parser, docId)); - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/ListConnectorAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/ListConnectorAction.java index 3b286569ce881..b4a3a2c0d3632 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/ListConnectorAction.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/ListConnectorAction.java @@ -18,7 +18,7 @@ import org.elasticsearch.xcontent.ToXContentObject; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentParser; -import org.elasticsearch.xpack.application.connector.Connector; +import org.elasticsearch.xpack.application.connector.ConnectorSearchResult; import org.elasticsearch.xpack.core.action.util.PageParams; import org.elasticsearch.xpack.core.action.util.QueryPage; @@ -105,14 +105,14 @@ public static class Response extends ActionResponse implements ToXContentObject public static final ParseField RESULT_FIELD = new ParseField("results"); - final QueryPage queryPage; + final QueryPage queryPage; public Response(StreamInput in) throws IOException { super(in); - this.queryPage = new QueryPage<>(in, Connector::new); + this.queryPage = new QueryPage<>(in, ConnectorSearchResult::new); } - public Response(List items, Long totalResults) { + public Response(List items, Long totalResults) { this.queryPage = new QueryPage<>(items, totalResults, RESULT_FIELD); } @@ -126,7 +126,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws return queryPage.toXContent(builder, params); } - public QueryPage queryPage() { + public QueryPage queryPage() { return queryPage; } diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJob.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJob.java index 48f3f2a117d63..fb34035e5400b 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJob.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJob.java @@ -200,7 +200,7 @@ private ConnectorSyncJob( this.createdAt = createdAt; this.deletedDocumentCount = deletedDocumentCount; this.error = error; - this.id = Objects.requireNonNull(id, "[id] cannot be null"); + this.id = id; this.indexedDocumentCount = indexedDocumentCount; this.indexedDocumentVolume = indexedDocumentVolume; this.jobType = Objects.requireNonNullElse(jobType, ConnectorSyncJobType.FULL); @@ -235,10 +235,10 @@ public ConnectorSyncJob(StreamInput in) throws IOException { } @SuppressWarnings("unchecked") - private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( + private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( "connector_sync_job", true, - (args) -> { + (args, docId) -> { int i = 0; return new Builder().setCancellationRequestedAt((Instant) args[i++]) .setCanceledAt((Instant) args[i++]) @@ -247,7 +247,7 @@ public ConnectorSyncJob(StreamInput in) throws IOException { .setCreatedAt((Instant) args[i++]) .setDeletedDocumentCount((Long) args[i++]) .setError((String) args[i++]) - .setId((String) args[i++]) + .setId(docId) .setIndexedDocumentCount((Long) args[i++]) .setIndexedDocumentVolume((Long) args[i++]) .setJobType((ConnectorSyncJobType) args[i++]) @@ -295,7 +295,6 @@ public ConnectorSyncJob(StreamInput in) throws IOException { ); PARSER.declareLong(constructorArg(), DELETED_DOCUMENT_COUNT_FIELD); PARSER.declareStringOrNull(optionalConstructorArg(), ERROR_FIELD); - PARSER.declareString(constructorArg(), ID_FIELD); PARSER.declareLong(constructorArg(), INDEXED_DOCUMENT_COUNT_FIELD); PARSER.declareLong(constructorArg(), INDEXED_DOCUMENT_VOLUME_FIELD); PARSER.declareField( @@ -383,16 +382,16 @@ public ConnectorSyncJob(StreamInput in) throws IOException { ); } - public static ConnectorSyncJob fromXContentBytes(BytesReference source, XContentType xContentType) { + public static ConnectorSyncJob fromXContentBytes(BytesReference source, String docId, XContentType xContentType) { try (XContentParser parser = XContentHelper.createParser(XContentParserConfiguration.EMPTY, source, xContentType)) { - return ConnectorSyncJob.fromXContent(parser); + return ConnectorSyncJob.fromXContent(parser, docId); } catch (IOException e) { throw new ElasticsearchParseException("Failed to parse a connector sync job document.", e); } } - public static ConnectorSyncJob fromXContent(XContentParser parser) throws IOException { - return PARSER.parse(parser, null); + public static ConnectorSyncJob fromXContent(XContentParser parser, String docId) throws IOException { + return PARSER.parse(parser, docId); } public static Connector syncJobConnectorFromXContentBytes(BytesReference source, String connectorId, XContentType xContentType) { @@ -479,70 +478,73 @@ public String getWorkerHostname() { return workerHostname; } - @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject(); + public void toInnerXContent(XContentBuilder builder, Params params) throws IOException { + if (cancelationRequestedAt != null) { + builder.field(CANCELATION_REQUESTED_AT_FIELD.getPreferredName(), cancelationRequestedAt); + } + if (canceledAt != null) { + builder.field(CANCELED_AT_FIELD.getPreferredName(), canceledAt); + } + if (completedAt != null) { + builder.field(COMPLETED_AT_FIELD.getPreferredName(), completedAt); + } + + builder.startObject(CONNECTOR_FIELD.getPreferredName()); { - if (cancelationRequestedAt != null) { - builder.field(CANCELATION_REQUESTED_AT_FIELD.getPreferredName(), cancelationRequestedAt); - } - if (canceledAt != null) { - builder.field(CANCELED_AT_FIELD.getPreferredName(), canceledAt); + if (connector.getConnectorId() != null) { + builder.field(Connector.ID_FIELD.getPreferredName(), connector.getConnectorId()); } - if (completedAt != null) { - builder.field(COMPLETED_AT_FIELD.getPreferredName(), completedAt); + if (connector.getSyncJobFiltering() != null) { + builder.field(Connector.FILTERING_FIELD.getPreferredName(), connector.getSyncJobFiltering()); } - - builder.startObject(CONNECTOR_FIELD.getPreferredName()); - { - if (connector.getConnectorId() != null) { - builder.field(Connector.ID_FIELD.getPreferredName(), connector.getConnectorId()); - } - if (connector.getSyncJobFiltering() != null) { - builder.field(Connector.FILTERING_FIELD.getPreferredName(), connector.getSyncJobFiltering()); - } - if (connector.getIndexName() != null) { - builder.field(Connector.INDEX_NAME_FIELD.getPreferredName(), connector.getIndexName()); - } - if (connector.getLanguage() != null) { - builder.field(Connector.LANGUAGE_FIELD.getPreferredName(), connector.getLanguage()); - } - if (connector.getPipeline() != null) { - builder.field(Connector.PIPELINE_FIELD.getPreferredName(), connector.getPipeline()); - } - if (connector.getServiceType() != null) { - builder.field(Connector.SERVICE_TYPE_FIELD.getPreferredName(), connector.getServiceType()); - } - if (connector.getConfiguration() != null) { - builder.field(Connector.CONFIGURATION_FIELD.getPreferredName(), connector.getConfiguration()); - } + if (connector.getIndexName() != null) { + builder.field(Connector.INDEX_NAME_FIELD.getPreferredName(), connector.getIndexName()); } - builder.endObject(); - - builder.field(CREATED_AT_FIELD.getPreferredName(), createdAt); - builder.field(DELETED_DOCUMENT_COUNT_FIELD.getPreferredName(), deletedDocumentCount); - if (error != null) { - builder.field(ERROR_FIELD.getPreferredName(), error); + if (connector.getLanguage() != null) { + builder.field(Connector.LANGUAGE_FIELD.getPreferredName(), connector.getLanguage()); } - builder.field(ID_FIELD.getPreferredName(), id); - builder.field(INDEXED_DOCUMENT_COUNT_FIELD.getPreferredName(), indexedDocumentCount); - builder.field(INDEXED_DOCUMENT_VOLUME_FIELD.getPreferredName(), indexedDocumentVolume); - builder.field(JOB_TYPE_FIELD.getPreferredName(), jobType); - if (lastSeen != null) { - builder.field(LAST_SEEN_FIELD.getPreferredName(), lastSeen); + if (connector.getPipeline() != null) { + builder.field(Connector.PIPELINE_FIELD.getPreferredName(), connector.getPipeline()); } - builder.field(METADATA_FIELD.getPreferredName(), metadata); - if (startedAt != null) { - builder.field(STARTED_AT_FIELD.getPreferredName(), startedAt); + if (connector.getServiceType() != null) { + builder.field(Connector.SERVICE_TYPE_FIELD.getPreferredName(), connector.getServiceType()); } - builder.field(STATUS_FIELD.getPreferredName(), status); - builder.field(TOTAL_DOCUMENT_COUNT_FIELD.getPreferredName(), totalDocumentCount); - builder.field(TRIGGER_METHOD_FIELD.getPreferredName(), triggerMethod); - if (workerHostname != null) { - builder.field(WORKER_HOSTNAME_FIELD.getPreferredName(), workerHostname); + if (connector.getConfiguration() != null) { + builder.field(Connector.CONFIGURATION_FIELD.getPreferredName(), connector.getConfiguration()); } } builder.endObject(); + + builder.field(CREATED_AT_FIELD.getPreferredName(), createdAt); + builder.field(DELETED_DOCUMENT_COUNT_FIELD.getPreferredName(), deletedDocumentCount); + if (error != null) { + builder.field(ERROR_FIELD.getPreferredName(), error); + } + builder.field(INDEXED_DOCUMENT_COUNT_FIELD.getPreferredName(), indexedDocumentCount); + builder.field(INDEXED_DOCUMENT_VOLUME_FIELD.getPreferredName(), indexedDocumentVolume); + builder.field(JOB_TYPE_FIELD.getPreferredName(), jobType); + if (lastSeen != null) { + builder.field(LAST_SEEN_FIELD.getPreferredName(), lastSeen); + } + builder.field(METADATA_FIELD.getPreferredName(), metadata); + if (startedAt != null) { + builder.field(STARTED_AT_FIELD.getPreferredName(), startedAt); + } + builder.field(STATUS_FIELD.getPreferredName(), status); + builder.field(TOTAL_DOCUMENT_COUNT_FIELD.getPreferredName(), totalDocumentCount); + builder.field(TRIGGER_METHOD_FIELD.getPreferredName(), triggerMethod); + if (workerHostname != null) { + builder.field(WORKER_HOSTNAME_FIELD.getPreferredName(), workerHostname); + } + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + { + toInnerXContent(builder, params); + } + builder.endObject(); return builder; } diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobIndexService.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobIndexService.java index 01a297a11103b..b6d20b9f0e777 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobIndexService.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobIndexService.java @@ -97,14 +97,11 @@ public void createConnectorSyncJob( ); try { - String syncJobId = generateId(); - final IndexRequest indexRequest = new IndexRequest(CONNECTOR_SYNC_JOB_INDEX_NAME).id(syncJobId) - .opType(DocWriteRequest.OpType.INDEX) + final IndexRequest indexRequest = new IndexRequest(CONNECTOR_SYNC_JOB_INDEX_NAME).opType(DocWriteRequest.OpType.INDEX) .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE); - ConnectorSyncJob syncJob = new ConnectorSyncJob.Builder().setId(syncJobId) - .setJobType(jobType) + ConnectorSyncJob syncJob = new ConnectorSyncJob.Builder().setJobType(jobType) .setTriggerMethod(triggerMethod) .setStatus(ConnectorSyncJob.DEFAULT_INITIAL_STATUS) .setConnector(connector) @@ -195,7 +192,7 @@ public void checkInConnectorSyncJob(String connectorSyncJobId, ActionListener listener) { + public void getConnectorSyncJob(String connectorSyncJobId, ActionListener listener) { final GetRequest getRequest = new GetRequest(CONNECTOR_SYNC_JOB_INDEX_NAME).id(connectorSyncJobId).realtime(true); try { @@ -208,11 +205,10 @@ public void getConnectorSyncJob(String connectorSyncJobId, ActionListener connectorSyncJobs = Arrays.stream(searchResponse.getHits().getHits()) + final List connectorSyncJobs = Arrays.stream(searchResponse.getHits().getHits()) .map(ConnectorSyncJobIndexService::hitToConnectorSyncJob) .toList(); @@ -346,13 +342,17 @@ private ConnectorSyncJobsResult mapSearchResponseToConnectorSyncJobsList(SearchR ); } - private static ConnectorSyncJob hitToConnectorSyncJob(SearchHit searchHit) { + private static ConnectorSyncJobSearchResult hitToConnectorSyncJob(SearchHit searchHit) { // TODO: don't return sensitive data from configuration inside connector in list endpoint - return ConnectorSyncJob.fromXContentBytes(searchHit.getSourceRef(), XContentType.JSON); + return new ConnectorSyncJobSearchResult.Builder().setId(searchHit.getId()) + .setResultBytes(searchHit.getSourceRef()) + .setResultMap(searchHit.getSourceAsMap()) + .build(); + } - public record ConnectorSyncJobsResult(List connectorSyncJobs, long totalResults) {} + public record ConnectorSyncJobsResult(List connectorSyncJobs, long totalResults) {} /** * Updates the ingestion stats of the {@link ConnectorSyncJob} in the underlying index. diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobSearchResult.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobSearchResult.java new file mode 100644 index 0000000000000..7ab2719dcbea2 --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobSearchResult.java @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.connector.syncjob; + +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.xpack.application.connector.ConnectorsAPISearchResult; + +import java.io.IOException; +import java.util.Map; + +public class ConnectorSyncJobSearchResult extends ConnectorsAPISearchResult { + + public ConnectorSyncJobSearchResult(StreamInput in) throws IOException { + super(in); + } + + private ConnectorSyncJobSearchResult(BytesReference resultBytes, Map resultMap, String id) { + super(resultBytes, resultMap, id); + } + + public static class Builder { + + private BytesReference resultBytes; + private Map resultMap; + private String id; + + public Builder setResultBytes(BytesReference resultBytes) { + this.resultBytes = resultBytes; + return this; + } + + public Builder setResultMap(Map resultMap) { + this.resultMap = resultMap; + return this; + } + + public Builder setId(String id) { + this.id = id; + return this; + } + + public ConnectorSyncJobSearchResult build() { + return new ConnectorSyncJobSearchResult(resultBytes, resultMap, id); + } + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/action/GetConnectorSyncJobAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/action/GetConnectorSyncJobAction.java index 9e21ba7e94f1f..31441883f061c 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/action/GetConnectorSyncJobAction.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/action/GetConnectorSyncJobAction.java @@ -19,8 +19,8 @@ import org.elasticsearch.xcontent.ToXContentObject; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentParser; -import org.elasticsearch.xpack.application.connector.syncjob.ConnectorSyncJob; import org.elasticsearch.xpack.application.connector.syncjob.ConnectorSyncJobConstants; +import org.elasticsearch.xpack.application.connector.syncjob.ConnectorSyncJobSearchResult; import java.io.IOException; import java.util.Objects; @@ -110,15 +110,15 @@ public static Request parse(XContentParser parser) { } public static class Response extends ActionResponse implements ToXContentObject { - private final ConnectorSyncJob connectorSyncJob; + private final ConnectorSyncJobSearchResult connectorSyncJob; - public Response(ConnectorSyncJob connectorSyncJob) { + public Response(ConnectorSyncJobSearchResult connectorSyncJob) { this.connectorSyncJob = connectorSyncJob; } public Response(StreamInput in) throws IOException { super(in); - this.connectorSyncJob = new ConnectorSyncJob(in); + this.connectorSyncJob = new ConnectorSyncJobSearchResult(in); } @Override diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/action/ListConnectorSyncJobsAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/action/ListConnectorSyncJobsAction.java index 298eee466bfb2..c81df8b642b37 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/action/ListConnectorSyncJobsAction.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/syncjob/action/ListConnectorSyncJobsAction.java @@ -20,6 +20,7 @@ import org.elasticsearch.xcontent.XContentParser; import org.elasticsearch.xpack.application.connector.ConnectorSyncStatus; import org.elasticsearch.xpack.application.connector.syncjob.ConnectorSyncJob; +import org.elasticsearch.xpack.application.connector.syncjob.ConnectorSyncJobSearchResult; import org.elasticsearch.xpack.core.action.util.PageParams; import org.elasticsearch.xpack.core.action.util.QueryPage; @@ -133,14 +134,14 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws public static class Response extends ActionResponse implements ToXContentObject { public static final ParseField RESULTS_FIELD = new ParseField("results"); - final QueryPage queryPage; + final QueryPage queryPage; public Response(StreamInput in) throws IOException { super(in); - this.queryPage = new QueryPage<>(in, ConnectorSyncJob::new); + this.queryPage = new QueryPage<>(in, ConnectorSyncJobSearchResult::new); } - public Response(List items, Long totalResults) { + public Response(List items, Long totalResults) { this.queryPage = new QueryPage<>(items, totalResults, RESULTS_FIELD); } diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIndexServiceTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIndexServiceTests.java index 542ea948c12df..a3c2d80ef48fb 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIndexServiceTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIndexServiceTests.java @@ -14,6 +14,7 @@ import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.test.ESSingleNodeTestCase; +import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xpack.application.connector.action.PostConnectorAction; import org.elasticsearch.xpack.application.connector.action.PutConnectorAction; import org.elasticsearch.xpack.application.connector.action.UpdateConnectorConfigurationAction; @@ -401,7 +402,13 @@ private Connector awaitGetConnector(String connectorId) throws Exception { final AtomicReference exc = new AtomicReference<>(null); connectorIndexService.getConnector(connectorId, new ActionListener<>() { @Override - public void onResponse(Connector connector) { + public void onResponse(ConnectorSearchResult connectorResult) { + // Serialize the sourceRef to Connector class for unit tests + Connector connector = Connector.fromXContentBytes( + connectorResult.getSourceRef(), + connectorResult.getDocId(), + XContentType.JSON + ); resp.set(connector); latch.countDown(); } diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTestUtils.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTestUtils.java index 74b84e914a942..ecfcfcf9e4af4 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTestUtils.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTestUtils.java @@ -7,6 +7,9 @@ package org.elasticsearch.xpack.application.connector; +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.xcontent.XContentHelper; +import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xpack.application.connector.action.PostConnectorAction; import org.elasticsearch.xpack.application.connector.action.PutConnectorAction; import org.elasticsearch.xpack.application.connector.configuration.ConfigurationDependency; @@ -24,6 +27,7 @@ import org.elasticsearch.xpack.application.connector.filtering.FilteringValidationState; import org.elasticsearch.xpack.core.scheduler.Cron; +import java.io.IOException; import java.time.Instant; import java.util.Collections; import java.util.HashMap; @@ -262,6 +266,30 @@ public static Connector getRandomConnector() { .build(); } + private static BytesReference convertConnectorToBytesReference(Connector connector) { + try { + return XContentHelper.toXContent((builder, params) -> { + connector.toInnerXContent(builder, params); + return builder; + }, XContentType.JSON, null, false); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static Map convertConnectorToGenericMap(Connector connector) { + return XContentHelper.convertToMap(convertConnectorToBytesReference(connector), true, XContentType.JSON).v2(); + } + + public static ConnectorSearchResult getRandomConnectorSearchResult() { + Connector connector = getRandomConnector(); + + return new ConnectorSearchResult.Builder().setResultBytes(convertConnectorToBytesReference(connector)) + .setResultMap(convertConnectorToGenericMap(connector)) + .setId(randomAlphaOfLength(10)) + .build(); + } + private static ConnectorFeatures.FeatureEnabled randomConnectorFeatureEnabled() { return new ConnectorFeatures.FeatureEnabled(randomBoolean()); } diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/GetConnectorActionResponseBWCSerializingTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/GetConnectorActionResponseBWCSerializingTests.java index 168e9ec8f433e..cc47e9d35afb0 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/GetConnectorActionResponseBWCSerializingTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/GetConnectorActionResponseBWCSerializingTests.java @@ -9,16 +9,12 @@ import org.elasticsearch.TransportVersion; import org.elasticsearch.common.io.stream.Writeable; -import org.elasticsearch.xcontent.XContentParser; -import org.elasticsearch.xpack.application.connector.Connector; import org.elasticsearch.xpack.application.connector.ConnectorTestUtils; -import org.elasticsearch.xpack.core.ml.AbstractBWCSerializationTestCase; +import org.elasticsearch.xpack.core.ml.AbstractBWCWireSerializationTestCase; import java.io.IOException; -public class GetConnectorActionResponseBWCSerializingTests extends AbstractBWCSerializationTestCase { - - private Connector connector; +public class GetConnectorActionResponseBWCSerializingTests extends AbstractBWCWireSerializationTestCase { @Override protected Writeable.Reader instanceReader() { @@ -27,8 +23,7 @@ protected Writeable.Reader instanceReader() { @Override protected GetConnectorAction.Response createTestInstance() { - this.connector = ConnectorTestUtils.getRandomConnector(); - return new GetConnectorAction.Response(this.connector); + return new GetConnectorAction.Response(ConnectorTestUtils.getRandomConnectorSearchResult()); } @Override @@ -36,11 +31,6 @@ protected GetConnectorAction.Response mutateInstance(GetConnectorAction.Response return randomValueOtherThan(instance, this::createTestInstance); } - @Override - protected GetConnectorAction.Response doParseInstance(XContentParser parser) throws IOException { - return GetConnectorAction.Response.fromXContent(parser, connector.getConnectorId()); - } - @Override protected GetConnectorAction.Response mutateInstanceForVersion(GetConnectorAction.Response instance, TransportVersion version) { return instance; diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/ListConnectorActionResponseBWCSerializingTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/ListConnectorActionResponseBWCSerializingTests.java index 1e4ee0d086462..ac8c85def542e 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/ListConnectorActionResponseBWCSerializingTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/ListConnectorActionResponseBWCSerializingTests.java @@ -22,7 +22,10 @@ protected Writeable.Reader instanceReader() { @Override protected ListConnectorAction.Response createTestInstance() { - return new ListConnectorAction.Response(randomList(10, ConnectorTestUtils::getRandomConnector), randomLongBetween(0, 100)); + return new ListConnectorAction.Response( + randomList(10, ConnectorTestUtils::getRandomConnectorSearchResult), + randomLongBetween(0, 100) + ); } @Override diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobIndexServiceTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobIndexServiceTests.java index 170ed25c0b302..2bbcf6c74b6fd 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobIndexServiceTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobIndexServiceTests.java @@ -22,6 +22,7 @@ import org.elasticsearch.test.ESSingleNodeTestCase; import org.elasticsearch.xcontent.ParseField; import org.elasticsearch.xcontent.ToXContent; +import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xpack.application.connector.Connector; import org.elasticsearch.xpack.application.connector.ConnectorFiltering; import org.elasticsearch.xpack.application.connector.ConnectorIndexService; @@ -100,7 +101,6 @@ public void testCreateConnectorSyncJob() throws Exception { ConnectorSyncJob connectorSyncJob = awaitGetConnectorSyncJob(response.getId()); - assertThat(connectorSyncJob.getId(), notNullValue()); assertThat(connectorSyncJob.getJobType(), equalTo(requestJobType)); assertThat(connectorSyncJob.getTriggerMethod(), equalTo(requestTriggerMethod)); assertThat(connectorSyncJob.getStatus(), equalTo(ConnectorSyncJob.DEFAULT_INITIAL_STATUS)); @@ -283,11 +283,31 @@ public void testListConnectorSyncJobs() throws Exception { ConnectorSyncJobIndexService.ConnectorSyncJobsResult nextTwoSyncJobs = awaitListConnectorSyncJobs(2, 2, null, null); ConnectorSyncJobIndexService.ConnectorSyncJobsResult lastSyncJobs = awaitListConnectorSyncJobs(4, 100, null, null); - ConnectorSyncJob firstSyncJob = firstTwoSyncJobs.connectorSyncJobs().get(0); - ConnectorSyncJob secondSyncJob = firstTwoSyncJobs.connectorSyncJobs().get(1); - ConnectorSyncJob thirdSyncJob = nextTwoSyncJobs.connectorSyncJobs().get(0); - ConnectorSyncJob fourthSyncJob = nextTwoSyncJobs.connectorSyncJobs().get(1); - ConnectorSyncJob fifthSyncJob = lastSyncJobs.connectorSyncJobs().get(0); + ConnectorSyncJob firstSyncJob = ConnectorSyncJob.fromXContentBytes( + firstTwoSyncJobs.connectorSyncJobs().get(0).getSourceRef(), + firstTwoSyncJobs.connectorSyncJobs().get(0).getDocId(), + XContentType.JSON + ); + ConnectorSyncJob secondSyncJob = ConnectorSyncJob.fromXContentBytes( + firstTwoSyncJobs.connectorSyncJobs().get(1).getSourceRef(), + firstTwoSyncJobs.connectorSyncJobs().get(1).getDocId(), + XContentType.JSON + ); + ConnectorSyncJob thirdSyncJob = ConnectorSyncJob.fromXContentBytes( + nextTwoSyncJobs.connectorSyncJobs().get(0).getSourceRef(), + nextTwoSyncJobs.connectorSyncJobs().get(0).getDocId(), + XContentType.JSON + ); + ConnectorSyncJob fourthSyncJob = ConnectorSyncJob.fromXContentBytes( + nextTwoSyncJobs.connectorSyncJobs().get(1).getSourceRef(), + nextTwoSyncJobs.connectorSyncJobs().get(1).getDocId(), + XContentType.JSON + ); + ConnectorSyncJob fifthSyncJob = ConnectorSyncJob.fromXContentBytes( + lastSyncJobs.connectorSyncJobs().get(0).getSourceRef(), + lastSyncJobs.connectorSyncJobs().get(0).getDocId(), + XContentType.JSON + ); assertThat(firstTwoSyncJobs.connectorSyncJobs().size(), equalTo(2)); assertThat(firstTwoSyncJobs.totalResults(), equalTo(5L)); @@ -337,7 +357,7 @@ public void testListConnectorSyncJobs_WithStatusPending_GivenOnePendingTwoCancel ConnectorSyncStatus.PENDING ); long numberOfResults = connectorSyncJobsResult.totalResults(); - String idOfReturnedSyncJob = connectorSyncJobsResult.connectorSyncJobs().get(0).getId(); + String idOfReturnedSyncJob = connectorSyncJobsResult.connectorSyncJobs().get(0).getDocId(); assertThat(numberOfResults, equalTo(1L)); assertThat(idOfReturnedSyncJob, equalTo(syncJobOneId)); @@ -363,7 +383,11 @@ public void testListConnectorSyncJobs_WithConnectorOneId_GivenTwoOverallOneFromC ); long numberOfResults = connectorSyncJobsResult.totalResults(); - String connectorIdOfReturnedSyncJob = connectorSyncJobsResult.connectorSyncJobs().get(0).getConnector().getConnectorId(); + String connectorIdOfReturnedSyncJob = ConnectorSyncJob.fromXContentBytes( + connectorSyncJobsResult.connectorSyncJobs().get(0).getSourceRef(), + connectorSyncJobsResult.connectorSyncJobs().get(0).getDocId(), + XContentType.JSON + ).getConnector().getConnectorId(); assertThat(numberOfResults, equalTo(1L)); assertThat(connectorIdOfReturnedSyncJob, equalTo(connectorOneId)); @@ -699,9 +723,15 @@ private ConnectorSyncJob awaitGetConnectorSyncJob(String connectorSyncJobId) thr final AtomicReference resp = new AtomicReference<>(null); final AtomicReference exc = new AtomicReference<>(null); - connectorSyncJobIndexService.getConnectorSyncJob(connectorSyncJobId, new ActionListener() { + connectorSyncJobIndexService.getConnectorSyncJob(connectorSyncJobId, new ActionListener() { @Override - public void onResponse(ConnectorSyncJob connectorSyncJob) { + public void onResponse(ConnectorSyncJobSearchResult searchResult) { + // Serialize the sourceRef to ConnectorSyncJob class for unit tests + ConnectorSyncJob connectorSyncJob = ConnectorSyncJob.fromXContentBytes( + searchResult.getSourceRef(), + searchResult.getDocId(), + XContentType.JSON + ); resp.set(connectorSyncJob); latch.countDown(); } diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobTestUtils.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobTestUtils.java index 96a12c9efac51..c53231cd79219 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobTestUtils.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobTestUtils.java @@ -7,7 +7,10 @@ package org.elasticsearch.xpack.application.connector.syncjob; +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.core.Tuple; +import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xpack.application.connector.ConnectorTestUtils; import org.elasticsearch.xpack.application.connector.syncjob.action.CancelConnectorSyncJobAction; import org.elasticsearch.xpack.application.connector.syncjob.action.CheckInConnectorSyncJobAction; @@ -19,7 +22,9 @@ import org.elasticsearch.xpack.application.connector.syncjob.action.UpdateConnectorSyncJobIngestionStatsAction; import org.elasticsearch.xpack.application.search.SearchApplicationTestUtils; +import java.io.IOException; import java.time.Instant; +import java.util.Map; import static org.elasticsearch.test.ESTestCase.randomAlphaOfLength; import static org.elasticsearch.test.ESTestCase.randomAlphaOfLengthBetween; @@ -65,6 +70,30 @@ public static ConnectorSyncJob getRandomConnectorSyncJob() { .build(); } + private static BytesReference convertSyncJobToBytesReference(ConnectorSyncJob syncJob) { + try { + return XContentHelper.toXContent((builder, params) -> { + syncJob.toInnerXContent(builder, params); + return builder; + }, XContentType.JSON, null, false); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static Map convertSyncJobToGenericMap(ConnectorSyncJob syncJob) { + return XContentHelper.convertToMap(convertSyncJobToBytesReference(syncJob), true, XContentType.JSON).v2(); + } + + public static ConnectorSyncJobSearchResult getRandomSyncJobSearchResult() { + ConnectorSyncJob syncJob = getRandomConnectorSyncJob(); + + return new ConnectorSyncJobSearchResult.Builder().setId(randomAlphaOfLength(10)) + .setResultMap(convertSyncJobToGenericMap(syncJob)) + .setResultBytes(convertSyncJobToBytesReference(syncJob)) + .build(); + } + public static ConnectorSyncJobTriggerMethod getRandomConnectorSyncJobTriggerMethod() { ConnectorSyncJobTriggerMethod[] values = ConnectorSyncJobTriggerMethod.values(); return values[randomInt(values.length - 1)]; @@ -146,7 +175,7 @@ public static GetConnectorSyncJobAction.Request getRandomGetConnectorSyncJobRequ } public static GetConnectorSyncJobAction.Response getRandomGetConnectorSyncJobResponse() { - return new GetConnectorSyncJobAction.Response(getRandomConnectorSyncJob()); + return new GetConnectorSyncJobAction.Response(getRandomSyncJobSearchResult()); } public static ListConnectorSyncJobsAction.Request getRandomListConnectorSyncJobsActionRequest() { diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobTests.java index 64f11923ce164..7b1a0f7d8dcf7 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobTests.java @@ -87,7 +87,6 @@ public void testFromXContent_WithAllFields_AllSet() throws IOException { "created_at": "2023-12-01T14:18:43.07693Z", "deleted_document_count": 10, "error": "some-error", - "id": "HIC-JYwB9RqKhB7x_hIE", "indexed_document_count": 10, "indexed_document_volume": 10, "job_type": "full", @@ -101,7 +100,7 @@ public void testFromXContent_WithAllFields_AllSet() throws IOException { } """); - ConnectorSyncJob syncJob = ConnectorSyncJob.fromXContentBytes(new BytesArray(content), XContentType.JSON); + ConnectorSyncJob syncJob = ConnectorSyncJob.fromXContentBytes(new BytesArray(content), "HIC-JYwB9RqKhB7x_hIE", XContentType.JSON); assertThat(syncJob.getCancelationRequestedAt(), equalTo(Instant.parse("2023-12-01T14:19:39.394194Z"))); assertThat(syncJob.getCanceledAt(), equalTo(Instant.parse("2023-12-01T14:19:39.394194Z"))); @@ -170,7 +169,6 @@ public void testFromXContent_WithOnlyNonNullableFieldsSet_DoesNotThrow() throws }, "created_at": "2023-12-01T14:18:43.07693Z", "deleted_document_count": 10, - "id": "HIC-JYwB9RqKhB7x_hIE", "indexed_document_count": 10, "indexed_document_volume": 10, "job_type": "full", @@ -182,7 +180,7 @@ public void testFromXContent_WithOnlyNonNullableFieldsSet_DoesNotThrow() throws } """); - ConnectorSyncJob.fromXContentBytes(new BytesArray(content), XContentType.JSON); + ConnectorSyncJob.fromXContentBytes(new BytesArray(content), "HIC-JYwB9RqKhB7x_hIE", XContentType.JSON); } public void testFromXContent_WithAllNullableFieldsSetToNull_DoesNotThrow() throws IOException { @@ -230,7 +228,6 @@ public void testFromXContent_WithAllNullableFieldsSetToNull_DoesNotThrow() throw "created_at": "2023-12-01T14:18:43.07693Z", "deleted_document_count": 10, "error": null, - "id": "HIC-JYwB9RqKhB7x_hIE", "indexed_document_count": 10, "indexed_document_volume": 10, "job_type": "full", @@ -244,7 +241,7 @@ public void testFromXContent_WithAllNullableFieldsSetToNull_DoesNotThrow() throw } """); - ConnectorSyncJob.fromXContentBytes(new BytesArray(content), XContentType.JSON); + ConnectorSyncJob.fromXContentBytes(new BytesArray(content), "HIC-JYwB9RqKhB7x_hIE", XContentType.JSON); } public void testSyncJobConnectorFromXContent_WithAllFieldsSet() throws IOException { diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/action/ListConnectorSyncJobsActionResponseBWCSerializingTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/action/ListConnectorSyncJobsActionResponseBWCSerializingTests.java index 48a358ad043cd..bc7b6320dddbe 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/action/ListConnectorSyncJobsActionResponseBWCSerializingTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/action/ListConnectorSyncJobsActionResponseBWCSerializingTests.java @@ -33,7 +33,7 @@ protected Writeable.Reader instanceReader( @Override protected ListConnectorSyncJobsAction.Response createTestInstance() { return new ListConnectorSyncJobsAction.Response( - randomList(10, ConnectorSyncJobTestUtils::getRandomConnectorSyncJob), + randomList(10, ConnectorSyncJobTestUtils::getRandomSyncJobSearchResult), randomLongBetween(0, 100) ); }