shounakmk219 commented on code in PR #11077:
URL: https://github.com/apache/pinot/pull/11077#discussion_r1270578701


##########
pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotInstanceRestletResource.java:
##########
@@ -416,4 +422,112 @@ public List<OperationValidationResponse> 
instanceDropSafetyCheck(
           Response.Status.INTERNAL_SERVER_ERROR, e);
     }
   }
+
+  @POST
+  @Path("/instances/updateTags/validate")
+  @Produces(MediaType.APPLICATION_JSON)
+  @ApiOperation(value = "Check if it's safe to update the tags of the given 
instances. If not list all the reasons.")
+  @ApiResponses(value = {
+      @ApiResponse(code = 200, message = "Success"),
+      @ApiResponse(code = 500, message = "Internal error")
+  })
+  public List<OperationValidationResponse> 
instanceTagUpdateSafetyCheck(List<InstanceTagUpdateRequest> instances) {
+    LOGGER.info("Performing safety check on tag update request received for 
instances: {}",
+        
instances.stream().map(InstanceTagUpdateRequest::getInstanceName).collect(Collectors.toList()));
+    Map<String, Integer> tagMinServerMap = 
_pinotHelixResourceManager.minimumInstancesRequiredForTags();
+    Map<String, Integer> tagDeficiency = computeTagDeficiency(instances, 
tagMinServerMap);
+
+    Map<String, List<OperationValidationResponse.ErrorWrapper>> responseMap = 
new HashMap<>(instances.size());
+    List<OperationValidationResponse.ErrorWrapper> tenantIssues = new 
ArrayList<>();
+    instances.forEach(instance -> responseMap.put(instance.getInstanceName(), 
new ArrayList<>()));
+    for (InstanceTagUpdateRequest instance : instances) {
+      String name = instance.getInstanceName();
+      Set<String> oldTags;
+      try {
+        oldTags = new 
HashSet<>(_pinotHelixResourceManager.getTagsForInstance(name));
+      } catch (NullPointerException exception) {
+        throw new ControllerApplicationException(LOGGER,
+            String.format("Instance %s is not a valid instance name.", name), 
Response.Status.PRECONDITION_FAILED);
+      }
+      Set<String> newTags = new HashSet<>(instance.getNewTags());
+      // tags removed from instance
+      for (String tag : Sets.difference(oldTags, newTags)) {
+        Integer deficiency = tagDeficiency.get(tag);
+        if (deficiency != null && deficiency > 0) {
+          String tenant = TagNameUtils.getTenantFromTag(tag);
+          String tagType = getInstanceTypeFromTag(tag);
+          responseMap.get(name).add(new 
OperationValidationResponse.ErrorWrapper(
+              
OperationValidationResponse.ErrorCode.MINIMUM_INSTANCE_UNSATISFIED, tenant, 
tagType, tag, tagType, name));
+          tagDeficiency.put(tag, deficiency - 1);
+        }
+      }
+      // newly added tags to instance
+      for (String tag : newTags) {
+        String tagType = getInstanceTypeFromTag(tag);
+        if (tagType == null && 
(name.startsWith(CommonConstants.Helix.PREFIX_OF_BROKER_INSTANCE)
+            || 
name.startsWith(CommonConstants.Helix.PREFIX_OF_SERVER_INSTANCE))) {
+          responseMap.get(name).add(new 
OperationValidationResponse.ErrorWrapper(
+              OperationValidationResponse.ErrorCode.UNRECOGNISED_TAG_TYPE, 
tag));
+          continue;
+        }
+        Integer deficiency = tagDeficiency.get(tag);
+        if (deficiency != null && deficiency > 0) {
+          tenantIssues.add(new OperationValidationResponse.ErrorWrapper(
+              OperationValidationResponse.ErrorCode.ALREADY_DEFICIENT_TENANT, 
TagNameUtils.getTenantFromTag(tag),

Review Comment:
   `MINIMUM_INSTANCE_UNSATISFIED ` -> The tenant currently satisfies minimum 
instances requirement, but the validation request removes few instances from it 
due to which the tenant ends up with instance deficiency.
   `ALREADY_DEFICIENT_TENANT` -> The tenant is already deficient on instances, 
and even though the validation request adds few instances to it, its still 
deficient.
   
   I have made this segregation so that user is aware about the existing 
deficiencies and not wonder why the validation is failing even though we are 
adding instances to a tenant.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to