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

add multitenant support for search workloads #13713

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

Conversation

kaushalmahi12
Copy link
Contributor

@kaushalmahi12 kaushalmahi12 commented May 16, 2024

Description

This PR add support to add labels to support multitenancy in opensearch. These labels can be consumed by any feature e,g; Query Sandboxing, Query Insights, Slow logs etc;

Sample search request body to pass these labels

curl -X GET "localhost:9200/my-index-*/_search?size=1000&pretty" -H 'Content-Type: application/json' -d '{
  "query" : {
  },
  "labels": {
    "tenant": "analytics"
  }
}'

Related Issues

#12342

Check List

  • New functionality includes testing.
    • All tests pass
  • [] New functionality has been documented.
    • New functionality has javadoc added
  • API changes companion pull request created.
  • Failing checks are inspected and point to the corresponding known issue(s) (See: Troubleshooting Failing Builds)
  • Commits are signed per the DCO using --signoff
  • Commit changes are listed out in CHANGELOG.md file (See: Changelog)
  • Public documentation issue/PR created

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

Signed-off-by: Kaushal Kumar <ravi.kaushal97@gmail.com>
…odes

Signed-off-by: Kaushal Kumar <ravi.kaushal97@gmail.com>
Signed-off-by: Kaushal Kumar <ravi.kaushal97@gmail.com>
Signed-off-by: Kaushal Kumar <ravi.kaushal97@gmail.com>
Signed-off-by: Kaushal Kumar <ravi.kaushal97@gmail.com>
Signed-off-by: Kaushal Kumar <ravi.kaushal97@gmail.com>
Signed-off-by: Kaushal Kumar <ravi.kaushal97@gmail.com>
Signed-off-by: Kaushal Kumar <ravi.kaushal97@gmail.com>
Signed-off-by: Kaushal Kumar <ravi.kaushal97@gmail.com>
Signed-off-by: Kaushal Kumar <ravi.kaushal97@gmail.com>
Signed-off-by: Kaushal Kumar <ravi.kaushal97@gmail.com>
Signed-off-by: Kaushal Kumar <ravi.kaushal97@gmail.com>
Signed-off-by: Kaushal Kumar <ravi.kaushal97@gmail.com>
Signed-off-by: Kaushal Kumar <ravi.kaushal97@gmail.com>
Copy link
Contributor

❌ Gradle check result for 675a105: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Copy link
Contributor

❌ Gradle check result for c8f262b: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@prudhvigodithi
Copy link
Contributor

Hey, If the Gradle check fails with error No such property: post_merge_action, please merge/rebase the PR from upstream to ensure the post_merge_action field is part of the Gradle check setup. More details in the PR 13786.

Comment on lines +604 to +607
String tenant = NOT_PROVIDED;
if (request.source() != null && request.source().multiTenantLabels() != null) {
tenant = (String) request.source().multiTenantLabels().get(MultiTenantLabel.TENANT.name());
}
Copy link
Contributor

Choose a reason for hiding this comment

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

[NIT] Can be done inline like below:

String tenant = Optional.ofNullable(request.source())
.map(source -> source.multiTenantLabels())
.map(tenantLabels -> tenantLabels.get(MultiTenantLabel.TENANT.name())
.orElse(NOT_PROVIDED);

@@ -568,6 +569,7 @@ public void executeQueryPhase(
assert request.canReturnNullResponseIfMatchNoDocs() == false || request.numberOfShards() > 1
: "empty responses require more than one shard";
final IndexShard shard = getShard(request);
setTenantInTask(task, request);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we not also instrument this tenant logic in task for other phases like fetch etc?
If yes, we should ideally populate this tenant info from coordinator level itself so that all tasks automatically have this info?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We do populate the tenancy info at the coordinator level but it would not suffice because of following reasons

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay. But should we also instrument this tenant logic for other phases as well like fetch etc?

@@ -1104,6 +1106,15 @@ private void executeSearch(
concreteLocalIndices,
localShardIterators.size() + remoteShardIterators.size()
);

// Set tenant for this request in the task for tracking the tasks across tenants
String tenant = NOT_PROVIDED;
Copy link
Contributor

Choose a reason for hiding this comment

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

Considering this logic can also be extended to other places like indexing etc, defining this here doesn't make sense.
Either

  1. Define a global string/enum for this in tenant related class
    OR
  2. Leave it tenant name as null, make it Optional and handle it accordingly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks! good catch. I have defined a global string just forgot to use that here.

@@ -297,6 +300,10 @@ public SearchSourceBuilder(StreamInput in) throws IOException {
derivedFields = in.readList(DerivedField::new);
}
}

if (in.getVersion().onOrAfter(Version.V_2_14_0)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

You will need to define this to Version.V_3_0_0 initially in main branch, after backporting to 2.x, you will then need to change it to Version.V_2_14_0

@@ -223,6 +225,7 @@ public static HighlightBuilder highlight() {
private PointInTimeBuilder pointInTimeBuilder = null;

private Map<String, Object> searchPipelineSource = null;
private Map<String, Object> multiTenantLabels = new HashMap<>();
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not just define it to Map<String, String>?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Keeping it generic if want to provide some complex objects as part of tenancy definition.

/**
* Tasks which should be grouped
*/
public interface ResourceLimitGroupTask {
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 we are essentially grouping by "tenants" which internally have resource limits. So this naming doesn't look right to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The naming part we are still discussing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants