Thanks Arun for your comments, I have looked into normalizing the requests within the CapacityScheduler.
It doesn't seem that the call to LeafQueue.assignContainer(..) come via CapacityScheduler.allocate(). It gets called through the call path:
LeafQueue.assignContainer(..) <- assignNodeLocalContainers(..) <-- LeafQueue.assignContainersOnNode(..) <- LeafQueue.assignContainers(..)
There are alternative paths, but all lead to the same source.
The SchedulerApp application (in the LeafQueue.assignContainers(..) call) is one of the Map<ApplicationAttemptId, SchedulerApp> applicationsMap values. This applicationsMap is only populated through LeafQueue.addApplication(..).
The LeafQueue.addApplication(..) is called through the path: LeafQueue.addApplication(..) <- LeafQueue.submitApplication(..) <- CapacityScheduler.addApplication(..).
So I have added code to CapacityScheduler.addApplication(..) to normalize all resource requests for the SchedulerApp before submitting to the queue.
If the LeafQueue is interminably tied to CS, we may need to update the references in LeafQueue to use CapacityScheduler instead of CapacitySchedulerContext, this will make such dependency clear and avoid future confusions. I haven't made this interface change in the attached patch, as it requires more changes to other components, but if we agree about it, I can do it in a following issue.