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

[CA-1149] Add initial pass at user disable monitor #504

Merged
merged 14 commits into from
Mar 4, 2021

Conversation

s-rubenstein
Copy link
Contributor

@s-rubenstein s-rubenstein commented Feb 8, 2021

Ticket:


PR checklist

  • I've followed the instructions if I've made any changes to the API, especially if they're breaking changes
  • I've updated the RC_XXX release ticket with any manual steps required to release this change
  • I've updated the FISMA documentation if I've made any security-related changes, including auth, encryption, or auditing

@coveralls
Copy link

coveralls commented Feb 8, 2021

Coverage Status

Coverage decreased (-0.3%) to 78.54% when pulling 8121faa on sr-user-disable-monitor into 4b981bf on develop.

Copy link
Collaborator

@dvoet dvoet left a comment

Choose a reason for hiding this comment

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

some tests too please

Comment on lines 129 to 131
userService
.disableUser(message.contents.parseJson.convertTo[WorkbenchUserId], samRequestContext = SamRequestContext(Option(span)))
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think you are missing something here to message back to the actor to ack the message. Something ending in pipeTo self

case object StartMonitorPass

sealed abstract class DisableUserResult(ackId: String)
final case class ReportMessage(value: Map[WorkbenchEmail, Seq[SyncReportItem]], ackId: String) extends DisableUserResult(ackId = ackId)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think SyncReportItem is specific to google group sync. The value here probably needs to be different and constructed at the end of case Some(message: PubSubMessage).


sealed abstract class DisableUserResult(ackId: String)
final case class ReportMessage(value: Map[WorkbenchEmail, Seq[SyncReportItem]], ackId: String) extends DisableUserResult(ackId = ackId)
final case class FailToSynchronize(t: Throwable, ackId: String) extends DisableUserResult(ackId = ackId)
Copy link
Collaborator

Choose a reason for hiding this comment

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

FailToDisable?

Copy link
Contributor

@gpolumbo-broad gpolumbo-broad left a comment

Choose a reason for hiding this comment

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

certainly do not need to wait for my thumb, I just wanted to take a look and had a few questions.

case ReceiveTimeout =>
throw new WorkbenchException("DisableUsersMonitorActor has received no messages for too long")

case x => logger.info(s"unhandled $x")
Copy link
Contributor

Choose a reason for hiding this comment

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

I would make this message a little more descriptive, maybe:

Suggested change
case x => logger.info(s"unhandled $x")
case x => logger.info(s"Received unhandleable message in DisableUsersMonitor: $x")

Copy link
Collaborator

Choose a reason for hiding this comment

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

actually doing $x is a big no no because it writes only the exception message and loses critical information: the exception class and stack trace.

logger.info(s"Received unhandleable message in DisableUsersMonitor", x) is correct

object DisableUsersMonitor {
case object StartMonitorPass

sealed abstract class DisableUserResult(ackId: String)
Copy link
Collaborator

Choose a reason for hiding this comment

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

is there benefit to this having ackId? The common pattern is for this to be a sealed trait and used only as a marker so that when the compiler sees a match on DisableUserResult it can determine that the cases are comprehensive or not. But actually embedding the common field ackId does not buy us anything as we never treat these objects generically.

case ReceiveTimeout =>
throw new WorkbenchException("DisableUsersMonitorActor has received no messages for too long")

case x => logger.info(s"unhandled $x")
Copy link
Collaborator

Choose a reason for hiding this comment

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

actually doing $x is a big no no because it writes only the exception message and loses critical information: the exception class and stack trace.

logger.info(s"Received unhandleable message in DisableUsersMonitor", x) is correct

Comment on lines 137 to 141
case userNotFound: WorkbenchExceptionWithErrorReport if userNotFound.errorReport.statusCode.contains(StatusCodes.NotFound) =>
// this can happen if a user is deleted before the disable message is handled
// acknowledge it so we don't have to handle it again
acknowledgeMessage(ackId).map(_ => StartMonitorPass) pipeTo self
logger.info(s"user to disable not found: ${userNotFound.errorReport}")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this actually true? It looks like disabling a user that does not exist just returns None from userService.disableUser

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I noticed that. I think maybe there's no special casing here.

// try to use `Retrying[Future[T]]`, which gets weird when we're using mockito together with it.
// Hence adding ascribing [Unit] explicitly here so that `eventually` will use `Retrying[Unit]`
eventually[Unit] {
assertResult(1) { mockGooglePubSubDAO.acks.size() }
Copy link
Collaborator

Choose a reason for hiding this comment

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

if you move this to after the call the verify you can remove the () below and [Unit] above and get rid of the comment

Comment on lines 88 to 91
// `eventually` now requires an implicit `Retrying` instance. When the statement inside returns future, it'll

// try to use `Retrying[Future[T]]`, which gets weird when we're using mockito together with it.
// Hence adding ascribing [Unit] explicitly here so that `eventually` will use `Retrying[Unit]`
Copy link
Collaborator

Choose a reason for hiding this comment

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

copy pasta error

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

1 similar comment
@s-rubenstein
Copy link
Contributor Author

Jenkins retest

Copy link
Contributor

@marctalbott marctalbott left a comment

Choose a reason for hiding this comment

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

Looks good! I suggested one more test, but not sure if the test is viable/useful so consider it nonblocking

@@ -0,0 +1,92 @@
package org.broadinstitute.dsde.workbench.sam.google
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be possible/valuable to add a test that goes through the FailToDisable path? It doesn't seem like that path will really happen since disableUser always seems to return a successful Future, but I'm not positive

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think it will ever go through that path, since either disableUser will either return a successful future or a none. I could add a test which throws an exception just in case we add some exceptions to the endpoint? But that feels future-proof-y, and not necessarily correct for current behavior.

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@@ -31,6 +31,11 @@ final case class GoogleServicesConfig(
groupSyncTopic: String,
groupSyncSubscription: String,
groupSyncWorkerCount: Int,
Copy link
Contributor

Choose a reason for hiding this comment

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

Should there be a disableUsersPubSubProject value here too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So, it wasn't used. I did a bit of searching though, and the only usage of the groupSyncPubSubProject was in setting up the googlePubSubDao, so maybe we should do a refactor of that in general.

disableUsersPollJitter: FiniteDuration,
disableUsersTopic: String,
disableUsersSubscription: String,
disableUsersWorkerCount: Int,
Copy link
Contributor

Choose a reason for hiding this comment

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

I also wouldn't mind seeing this and the config for groupSync broken into separate PubSubConfig classes like we have with the GoogleKeyCacheConfig, especially if we'd need these same values for any future pubsub topics we might add to Sam

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, will do some abstraction into a separate config.

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

1 similar comment
@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

5 similar comments
@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

2 similar comments
@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

[CA-1190] Change pubSubDAO to be one DAO for each topic
@s-rubenstein
Copy link
Contributor Author

Jenkins retest

3 similar comments
@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

7 similar comments
@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein
Copy link
Contributor Author

Jenkins retest

@s-rubenstein s-rubenstein merged commit 3b24828 into develop Mar 4, 2021
@s-rubenstein s-rubenstein deleted the sr-user-disable-monitor branch March 4, 2021 20:36
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

5 participants