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

[WOR-1456] Add requester pays setting #3032

Merged
merged 4 commits into from
Sep 24, 2024
Merged

[WOR-1456] Add requester pays setting #3032

merged 4 commits into from
Sep 24, 2024

Conversation

trholdridge
Copy link
Contributor

@trholdridge trholdridge commented Sep 16, 2024

Ticket: https://broadworkbench.atlassian.net/browse/WOR-1456

Adds requester pays as a workspace setting.

Workspace settings previously didn't play nice with requester pays workspaces, so this PR also fixes that behavior. Workspace settings requests now always pass a user project (the workspace's google project), which works when requester pays is off as well as on.


PR checklist

  • Include the JIRA issue number in the PR description and title
  • Make sure Swagger is updated if API changes
    • ...and Orchestration's Swagger too!
  • If you changed anything in model/, then you should publish a new official rawls-model and update rawls-model in Orchestration's dependencies.
  • Get two thumbsworth of PR review
  • Verify all tests go green, including CI tests
  • Squash commits and merge to develop (branches are automatically deleted after merging)
  • Inform other teams of any substantial changes via Slack and/or email

.setBucketLifecycle(
GcsBucketName(bucketName),
lifecycle,
bucketTargetOptions = List(BucketTargetOption.userProject(userProject.value))
Copy link
Contributor Author

@trholdridge trholdridge Sep 17, 2024

Choose a reason for hiding this comment

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

This passes the project so that, when requester pays is on, the workspace settings requests are accepted. I added the same line to all three settings in the DAO. I could break it out into a separate function but I thought it was straightforward enough to use multiple times. Alternate opinions are welcome.

@@ -94,6 +96,7 @@ class WorkspaceSettingService(protected val ctx: RawlsRequestContext,
)
case _ => None
}
case GcpBucketRequesterPaysSetting(GcpBucketRequesterPaysConfig(_)) => None
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Requester pays configs are valid if all the types are correct.


case GcpBucketRequesterPaysSetting(GcpBucketRequesterPaysConfig(enabled)) =>
for {
_ <- gcsDAO.setRequesterPays(workspace.bucketName, enabled, workspace.googleProjectId)
_ <- workspaceSettingRepository.markWorkspaceSettingApplied(workspace.workspaceIdAsUUID,
setting.settingType
Copy link
Contributor Author

Choose a reason for hiding this comment

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

On the note of code duplication though, some of this is getting more clunky now that there are three settings. Again, feedback welcome if there are spots which could use some abstraction.

Copy link
Contributor

Choose a reason for hiding this comment

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

One option would be to extract the case statement here into a separate WorkspaceSetting => Future[Unit] function which would perform the cloud call to apply the setting. Then you'd call that function from a single for-comp which would first apply the setting in the cloud and then mark the setting applied in the db. Something like this:

def doTheThing(workspaceSetting: WorkspaceSetting): Future[Unit] = workspaceSetting match { 
  // call the appropriate gcsDAO method
}

(for {
  _ <- doTheThing(setting)
  _ <- workspaceSettingRepository.markWorkspaceSettingApplied(workspace.workspaceIdAsUUID,
                                                                        setting.settingType
            )
} yield None).recoverWith { case e =>
  logger.error(
          s"Failed to apply settings. [workspaceId=${workspace.workspaceIdAsUUID},settingType=${setting.settingType}]",
          e
  )
  workspaceSettingRepository
    .removePendingSetting(workspace.workspaceIdAsUUID, setting.settingType)
    .map(_ => Some((setting.settingType, ErrorReport(StatusCodes.InternalServerError, e.getMessage))))
}

@trholdridge trholdridge marked this pull request as ready for review September 17, 2024 14:55
@trholdridge trholdridge requested review from a team, cahrens and marctalbott and removed request for a team September 17, 2024 14:55
@@ -206,7 +205,8 @@ class WorkspaceSettingServiceUnitTests extends AnyFlatSpec with MockitoTestUtils
).thenReturn(Future.successful(true))

val gcsDAO = mock[GoogleServicesDAO]
when(gcsDAO.setBucketLifecycle(workspace.bucketName, List())).thenReturn(Future.successful())
when(gcsDAO.setBucketLifecycle(ArgumentMatchers.eq(workspace.bucketName), ArgumentMatchers.eq(List()), any()))
Copy link
Contributor

Choose a reason for hiding this comment

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

You could check here that the right google project ID is being sent.

when(
gcsDAO.setBucketLifecycle(ArgumentMatchers.eq(workspace.bucketName),
ArgumentMatchers.eq(List(newSettingGoogleRule)),
any()
Copy link
Contributor

Choose a reason for hiding this comment

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

Same note here.

when(
gcsDAO.setBucketLifecycle(ArgumentMatchers.eq(workspace.bucketName),
ArgumentMatchers.eq(List(newSettingGoogleRule)),
any()
Copy link
Contributor

Choose a reason for hiding this comment

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

And here.

ArgumentMatchers.eq(List(newSettingGoogleRule)),
any()
)
).thenReturn(Future.failed(new Exception("failed to apply settings")))

val service =
Copy link
Contributor

Choose a reason for hiding this comment

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

There is no unit test coverage of calling the gcsDAO for soft delete or requester pays settings?

@@ -5980,6 +5982,14 @@ components:
retentionDurationInSeconds:
type: integer
description: The length of time to retain soft-deleted objects for, in seconds
WorkspaceSettingGcpBucketRequesterPaysConfig:
Copy link
Contributor

Choose a reason for hiding this comment

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

Remember that you will need to update orchestration swagger also.

@trholdridge trholdridge merged commit 5a80e2c into develop Sep 24, 2024
29 checks passed
@trholdridge trholdridge deleted the WOR-1456 branch September 24, 2024 14:58
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.

3 participants