-
Notifications
You must be signed in to change notification settings - Fork 12
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
PROD-972 ID-1324 Deduplicate group synchronization calls to google. #1472
Conversation
src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAO.scala
Outdated
Show resolved
Hide resolved
I think you also need to update the group version somewhere in or before GoogleExtension.onGroupUpdate. This is the logic that figures out all the policies related to an auth domain that must be synced. The related policies need to have their versions bumped so that the GoogleGroupSynchronizer doesn't ignore them. |
also need to update the group version in overwritePolicyMembersInternal |
add condition to last synchronized version
Add authdomain test fix google extensions tests
case _: BasicWorkbenchGroup => verify(mockDirectoryDAO).updateSynchronizedDateAndVersion(target, samRequestContext) | ||
case p: AccessPolicy => | ||
verify(mockDirectoryDAO).updateSynchronizedDateAndVersion(p.copy(members = p.members + CloudExtensions.allUsersGroupName), samRequestContext) | ||
} |
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 started failing because updateSynchronizedDateAndVersion was being called for the policy with the addition of the all users group in the policy. Still trying to get my head around exactly why. A lot is mocked out here and this test is really only focused around group emails so I think this change is fine.
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.
probably because the policy is set to public
@@ -298,6 +287,7 @@ class ResourceService( | |||
} else IO.unit | |||
policies <- listResourcePolicies(resource, samRequestContext) | |||
_ <- accessPolicyDAO.addResourceAuthDomain(resource, authDomains, samRequestContext) | |||
_ <- policies.traverse(p => directoryDAO.updateGroupUpdatedDateAndVersionWithSession(FullyQualifiedPolicyId(resource, p.policyName), samRequestContext)) |
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 updates all of the policies when an auth domain is added to a resource
@@ -45,7 +45,9 @@ trait DirectoryDAO { | |||
|
|||
def isGroupMember(groupId: WorkbenchGroupIdentity, member: WorkbenchSubject, samRequestContext: SamRequestContext): IO[Boolean] | |||
|
|||
def updateSynchronizedDate(groupId: WorkbenchGroupIdentity, samRequestContext: SamRequestContext): IO[Unit] | |||
def updateSynchronizedDateAndVersion(group: WorkbenchGroup, samRequestContext: SamRequestContext): IO[Unit] |
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.
We want to pass in the group here so that we can use the version of the group that is held in memory when the sync started.
def updateSynchronizedDate(groupId: WorkbenchGroupIdentity, samRequestContext: SamRequestContext): IO[Unit] | ||
def updateSynchronizedDateAndVersion(group: WorkbenchGroup, samRequestContext: SamRequestContext): IO[Unit] | ||
|
||
def updateGroupUpdatedDateAndVersionWithSession(groupId: WorkbenchGroupIdentity, samRequestContext: SamRequestContext): IO[Unit] |
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 is needed to update the policies in resource service and it just creates a write db session and then calls updateGroupUpdatedDateAndVersion
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.
updateGroupUpdatedDateAndVersion is also only on PostgresGroupDAO which ResourceService doesnt have access to
members: Set[WorkbenchSubject], | ||
email: WorkbenchEmail, | ||
version: Int = 1, | ||
lastSynchronizedVersion: Option[Int] = None |
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.
Defaulting these values (including in the other models) was to avoid having to change BasicWorkbenchGroup in a ton of places. With the proper tests in place I think this is ok.
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.
1 comment but don't hold this up based on it
if (group.version > group.lastSynchronizedVersion.getOrElse(0)) { | ||
IO.unit | ||
} else { | ||
IO.raiseError(new GroupAlreadySynchronized) |
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 don't really like handling this with an exception since this is not really an exceptional situation, we just want an early escape.
case _: BasicWorkbenchGroup => verify(mockDirectoryDAO).updateSynchronizedDateAndVersion(target, samRequestContext) | ||
case p: AccessPolicy => | ||
verify(mockDirectoryDAO).updateSynchronizedDateAndVersion(p.copy(members = p.members + CloudExtensions.allUsersGroupName), samRequestContext) | ||
} |
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.
probably because the policy is set to public
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.
Thanks @Ghost-in-a-Jar! 🎉
Quality Gate passedIssues Measures |
Ticket: https://broadworkbench.atlassian.net/browse/ID-1324
What:
We make a LOT of calls to the google groups api, a lot of which are duplicated and unnecessary. This PR aims to reduce the number of calls to google group apis during the group syncing
Why:
We are hitting the quota for listing group memberships every day and ended up with a prod incident over the weekend.
How:
The plan is to record the last synchronized version and current version of group, only synchronize group if group version is greater than last synchronized version.
Pseudocode:
In DB migration set initial values of current group version to 1 and last synchronized version to 0
Testing/monitoring notes:
PR checklist