-
Notifications
You must be signed in to change notification settings - Fork 147
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
applying multi-tenancy to task apis, deploy, predict apis #3416
Conversation
Signed-off-by: Dhrubo Saha <dhrubo@amazon.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall LGTM pending fix of the comments indicated.
@@ -305,6 +318,8 @@ public static MLTask parse(XContentParser parser) throws IOException { | |||
case REMOTE_JOB_FIELD: | |||
remoteJob = parser.map(); | |||
break; | |||
case TENANT_ID_FIELD: | |||
tenantId = parser.textOrNull(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing a break;
here.
this.modelId = in.readString(); | ||
this.taskId = in.readString(); | ||
this.tenantId = streamInputVersion.onOrAfter(VERSION_2_19_0) ? in.readOptionalString() : null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Style) I guess this works but I've nearly always seen the new fields added at the end of the stream.
(Same comment on the writeTo()
and MLForwardInput
later.)
Since they match it won't create a problem, but from a readability standpoint it requires some extra vigilance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. Addressing this.
FunctionName functionName = mlModel.getAlgorithm(); | ||
Boolean isHidden = mlModel.getIsHidden(); | ||
if (!TenantAwareHelper.validateTenantResource(mlFeatureEnabledSetting, tenantId, mlModel.getTenantId(), listener)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Less a comment for this PR and more one to think about for later. This returns 401 (Unauthorized) but we might want to consider returning 404 (Not Found) in many cases when trying to manipulate a tenant resource that you don't own.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that can be an option. We can decide later and address that in a separate PR.
if (functionName == FunctionName.REMOTE && !mlFeatureEnabledSetting.isRemoteInferenceEnabled()) { | ||
throw new IllegalStateException(REMOTE_INFERENCE_DISABLED_ERR_MSG); | ||
} else if (FunctionName.isDLModel(functionName) && !mlFeatureEnabledSetting.isLocalModelEnabled()) { | ||
throw new IllegalStateException(LOCAL_MODEL_DISABLED_ERR_MSG); | ||
} | ||
if (!isUserInitiatedDeployRequest) { | ||
deployModel(deployModelRequest, mlModel, modelId, wrappedListener, listener); | ||
deployModel(deployModelRequest, mlModel, modelId, tenantId, wrappedListener, listener); | ||
} else if (isHidden != null && isHidden) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not your change, but this readability breaks my brain.
} else if (isHidden != null && isHidden) { | |
} else if (Boolean.TRUE.equals(isHidden)) { |
ActionListener<DeleteResponse> wrappedListener = ActionListener.runBefore(actionListener, context::restore); | ||
|
||
sdkClient | ||
.getDataObjectAsync(getDataObjectRequest, client.threadPool().executor(GENERAL_THREAD_POOL)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought we were avoiding using the thread pool here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missed that, addressing it.
sdkClient | ||
.deleteDataObjectAsync( | ||
DeleteDataObjectRequest.builder().index(deleteRequest.index()).id(deleteRequest.id()).build(), | ||
client.threadPool().executor(GENERAL_THREAD_POOL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment on thread pool
// allow custom deploy plan and not deploy to all case, we need to check if the added nodes in planning worker nodes. | ||
List<String> needRedeployPlanningWorkerNodes = Arrays | ||
.stream(planningWorkerNodes.toArray(new String[0])) | ||
.filter(addedNodes::contains) | ||
.collect(Collectors.toList()); | ||
nodeIds = needRedeployPlanningWorkerNodes.size() > 0 ? planningWorkerNodes.toArray(new String[0]) : null; | ||
.toList(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works on JDK21 but since this will be backported you may want to keep the old version
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good call out.
listener.onResponse(mlModel); | ||
return null; | ||
}).when(mlModelManager).getModel(anyString(), isNull(), any(String[].class), Mockito.isA(ActionListener.class)); | ||
}).when(mlModelManager).getModel(anyString(), any(), isNull(), any(String[].class), Mockito.isA(ActionListener.class)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
picked a random one of these to comment on. I've been using nullable(String.class)
for the tenant ID, but whatever you do, be consistent. any()
should work unless you get an argument conflict.
Signed-off-by: Dhrubo Saha <dhrubo@amazon.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See Dan already approved. Approve directly as maintainer to unblock the merge.
The backport to
To backport manually, run these commands in your terminal: # Fetch latest updates from GitHub
git fetch
# Create a new working tree
git worktree add .worktrees/backport-2.x 2.x
# Navigate to the new working tree
cd .worktrees/backport-2.x
# Create a new branch
git switch --create backport/backport-3416-to-2.x
# Cherry-pick the merged commit of this pull request and resolve the conflicts
git cherry-pick -x --mainline 1 1659a60d8c7e74471a57fa9c2c243aca214c6005
# Push it to GitHub
git push --set-upstream origin backport/backport-3416-to-2.x
# Go back to the original working tree
cd ../..
# Delete the working tree
git worktree remove .worktrees/backport-2.x Then, create a pull request where the |
…-project#3416) * applying multi-tenancy to task, deploy, predict Signed-off-by: Dhrubo Saha <dhrubo@amazon.com> * addressed comments Signed-off-by: Dhrubo Saha <dhrubo@amazon.com> --------- Signed-off-by: Dhrubo Saha <dhrubo@amazon.com>
…-project#3416) * applying multi-tenancy to task, deploy, predict Signed-off-by: Dhrubo Saha <dhrubo@amazon.com> * addressed comments Signed-off-by: Dhrubo Saha <dhrubo@amazon.com> --------- Signed-off-by: Dhrubo Saha <dhrubo@amazon.com>
Description
[applying multi-tenancy to task apis, deploy, predict apis]
Related Issues
Resolves #[Issue number to be closed when this PR is merged]
Check List
--signoff
.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.