Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Connector API] Support soft-deletes of connectors #118669

Open
wants to merge 24 commits into
base: main
Choose a base branch
from

Conversation

jedrazb
Copy link
Member

@jedrazb jedrazb commented Dec 13, 2024

Soft deletes for connectors

Add support for soft-deletes of connectors. Why?

  • In order to improve UX on connectors on agentless we need to track what connectors were deleted vs. what connector records are not yet created

Changes

  • introduce deleted flag in the connector index mappings, indicates whether connector has been soft deleted
  • adapt delete, get and list operations logic to support this feature
    • if we pass deleted=true flag we return also deleted connectors in the response
  • update docs
  • add yaml tests and unit tests

Related work

  • In a follow-up PR I will address adding index mapping migrations for connector index. I'm coordinating here with @navarone-feekery as he might be adding SystemIndexDecriptor for connector indices soon, this will help updating mappings a lot as there is SystemIndexMappingUpdateService
  • follow-up: support force deletes, e.g pass force=true to delete endpoint to completely remove the connector

Copy link
Contributor

Documentation preview:

@elasticsearchmachine
Copy link
Collaborator

Hi @jedrazb, I've created a changelog YAML for you.

@jedrazb
Copy link
Member Author

jedrazb commented Dec 17, 2024

@elasticmachine merge upstream

@jedrazb jedrazb marked this pull request as ready for review December 17, 2024 16:02
@elasticsearchmachine elasticsearchmachine added the Team:SearchOrg Meta label for the Search Org (Enterprise Search) label Dec 17, 2024
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/search-eng (Team:SearchOrg)

@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/search-extract-and-transform (Team:Search - Extract & Transform)

@jedrazb
Copy link
Member Author

jedrazb commented Dec 18, 2024

@elasticmachine merge upstream

Copy link
Contributor

@navarone-feekery navarone-feekery left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Just one comment about a possible test case.

Also, I'm curious about unique validations. Do we allow shared values across soft-deleted and live Connectors? E.g. can a new Connector have an index_name value identical to a soft-deleted Connector?

@@ -279,4 +278,145 @@ setup:
connector.list: { }


---
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this could benefit from a test case covering when a connector was soft deleted and we don't want to see soft-deleted connectors in the list response.

so like

  1. Soft delete 1 connector
  2. Fetch with deleted: false
  3. Ensure there are 2 results

Copy link
Member Author

@jedrazb jedrazb Dec 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This exact scenario is covered here "List Connectors - Single soft deleted connector":

Be default the deleted flag is false when not defined

@jedrazb
Copy link
Member Author

jedrazb commented Dec 19, 2024

Also, I'm curious about unique validations. Do we allow shared values across soft-deleted and live Connectors?

Good point. By default, the logic stays the same, meaning deleted connectors remain invisible to any logic associated with existing connectors.

Copy link
Contributor

@navarone-feekery navarone-feekery left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@jedrazb
Copy link
Member Author

jedrazb commented Dec 19, 2024

can a new Connector have an index_name value identical to a soft-deleted Connector

That was the single edge case I didn't cover because we have custom check (with query) for index names already in use ... fixed in 7525c99

Copy link
Contributor

@timgrein timgrein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments, but I think nothing preventing this PR from being merged

@@ -27,6 +27,9 @@ To get started with Connector APIs, check out <<es-connectors-tutorial-api, our
`<connector_id>`::
(Required, string)

`deleted`::
(Optional, boolean) A flag indicating whether to also include connectors that have been soft-deleted. Defaults to `false`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(Optional, boolean) A flag indicating whether to also include connectors that have been soft-deleted. Defaults to `false`.
(Optional, boolean) A flag indicating whether to also return connectors that have been soft-deleted. Defaults to `false`.

consistency nit

"deleted": {
"type": "boolean",
"default": false,
"description": "A flag indicating whether to list connectors that have been soft-deleted."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"description": "A flag indicating whether to list connectors that have been soft-deleted."
"description": "A flag indicating whether to return connectors that have been soft-deleted."

consistency nit, feel free to ignore if it makes sense to use "list" here

@@ -1138,6 +1159,11 @@ private Map<String, Object> getConnectorConfigurationFromSearchResult(ConnectorS
return (Map<String, Object>) searchResult.getResultMap().get(Connector.CONFIGURATION_FIELD.getPreferredName());
}

private boolean getIsDeletedFromSearchResult(ConnectorSearchResult searchResult) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private boolean getIsDeletedFromSearchResult(ConnectorSearchResult searchResult) {
private boolean isConnectorDeleted(ConnectorSearchResult searchResult) {

I was a bit confused by the name in the beginning. Would isConnectorDeleted make it more obvious?

@@ -212,6 +214,10 @@ public void getConnector(String connectorId, ActionListener<ConnectorSearchResul
.setResultMap(getResponse.getSourceAsMap())
.build();

if (isDeleted == false && getIsDeletedFromSearchResult(connector)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (isDeleted == false && getIsDeletedFromSearchResult(connector)) {
boolean didNotFindNonDeletedConnector = isDeleted == false && getIsDeletedFromSearchResult(connector)
if (didNotFindNonDeletedConnector) {

@@ -1156,8 +1182,8 @@ private static ConnectorSearchResult hitToConnector(SearchHit searchHit) {
}

/**
* This method determines if any documents in the connector index have the same index name as the one specified,
* excluding the document with the given _id if it is provided.
* This method determines if any records in the connector index have the same index name as the one specified,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it stay documents here, if the next line uses docs? Or should both be records?

@@ -469,6 +479,7 @@ public void writeTo(StreamOutput out) throws IOException {
out.writeEnum(status);
out.writeGenericValue(syncCursor);
out.writeBoolean(syncNow);
out.writeBoolean(isDeleted);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious: do we need a new transport version, if we add something at the end of an entity, which is serialized over the wire? Does a potentially old node simply discard everything after syncNow? Never tested that (I assume it works without a transport version check, but just to double-check)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should ConnectorTests extend AbstractWireSerializingTestCase btw as it can be serialized over the wire?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>feature :SearchOrg/Extract&Transform Label for the Search E&T team Team:Search - Extract & Transform Team:SearchOrg Meta label for the Search Org (Enterprise Search) v9.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants