{"action":"created","comment":{"url":"https://api.github.com/repos/all-of-us/workbench/pulls/comments/169737269","pull_request_review_id":98312416,"id":169737269,"diff_hunk":"@@ -223,26 +230,57 @@ private User initializeUserIfNeeded() {\n       }\n     }\n \n-    // On subsequent sign-ins, complete the setup of the FC billing project. There is an\n-    // initialization period for Firecloud projects, so it is not possible to do this immediately\n-    // after project creation (on first sign-in).\n-    if (BillingProjectStatus.PENDING.equals(user.getFreeTierBillingProjectStatus())) {\n-      // If the user has not been granted the BQ job user Google role on the billing project yet,\n-      // give it to them (so they can run BQ queries from notebooks).\n-      try {\n-        fireCloudService.grantGoogleRoleToUser(user.getFreeTierBillingProjectName(),\n-            FireCloudService.BIGQUERY_JOB_USER_GOOGLE_ROLE, user.getEmail());\n-      } catch (ApiException e) {\n-        log.log(Level.INFO, String.format(\n-            \"granting BigQuery role on free tier billing project failed, this is expected \" +\n-            \"shortly after creation of the project; will retry on next initialization attempt\", e));\n-        // Allow the user to continue, as most workbench functionality will still be usable.\n+    // Free tier billing project setup is complete; nothing to do.\n+    if (!BillingProjectStatus.PENDING.equals(user.getFreeTierBillingProjectStatus())) {\n+      return user;\n+    }\n+\n+    // On subsequent sign-ins to the first, attempt to complete the setup of the FC billing project\n+    // and mark the Workbench's project setup as completed. FC project creation is asynchronous, so\n+    // first confirm whether Firecloud claims the project setup is complete.\n+    BillingProjectStatus status = null;\n+    try {\n+      status = fireCloudService.getBillingProjectMemberships().stream()\n+          .filter(m -> user.getFreeTierBillingProjectName().equals(m.getProjectName()))\n+          .map(m -> fcToWorkbenchBillingMap.get(m.getCreationStatus()))\n+          // Should be at most one matching billing project; though we're not asserting this.\n+          .findFirst()\n+          .orElse(BillingProjectStatus.NONE);\n+    } catch (ApiException e) {\n+      log.log(Level.WARNING, \"failed to retrieve billing projects, continuing\", e);\n+      return user;\n+    }\n+    switch (status) {\n+      case NONE:\n+      case PENDING:\n+        log.log(Level.INFO, \"free tier project is still initializing, continuing\");\n         return user;\n-      }\n-      user.setFreeTierBillingProjectStatus(BillingProjectStatus.READY);\n-      return userDao.save(user);\n+\n+      case ERROR:\n+        log.log(Level.SEVERE, String.format(\n+            \"free tier project %s failed to be created\", user.getFreeTierBillingProjectName()));\n+        user.setFreeTierBillingProjectStatus(status);\n+        return userDao.save(user);\n+\n+      case READY:\n+        break;\n+    }\n+\n+    // Grant the user BQ job access on the billing project so that they can run BQ queries from\n+    // notebooks.\n+    try {\n+      fireCloudService.grantGoogleRoleToUser(user.getFreeTierBillingProjectName(),\n+          FireCloudService.BIGQUERY_JOB_USER_GOOGLE_ROLE, user.getEmail());\n+    } catch (ApiException e) {\n+      log.log(Level.INFO,","path":"api/src/main/java/org/pmiops/workbench/api/ProfileController.java","position":null,"original_position":118,"commit_id":"47b939271cbb953b62f84318efd74eee9587967f","original_commit_id":"8f1ded3170eda876c1d149190be8a329d468ffe6","user":{"login":"calbach","id":822298,"avatar_url":"https://avatars0.githubusercontent.com/u/822298?v=4","gravatar_id":"","url":"https://api.github.com/users/calbach","html_url":"https://github.com/calbach","followers_url":"https://api.github.com/users/calbach/followers","following_url":"https://api.github.com/users/calbach/following{/other_user}","gists_url":"https://api.github.com/users/calbach/gists{/gist_id}","starred_url":"https://api.github.com/users/calbach/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/calbach/subscriptions","organizations_url":"https://api.github.com/users/calbach/orgs","repos_url":"https://api.github.com/users/calbach/repos","events_url":"https://api.github.com/users/calbach/events{/privacy}","received_events_url":"https://api.github.com/users/calbach/received_events","type":"User","site_admin":false},"body":"Yes, forgot to update - updated and made it a warning. I don't want to return a 500 - the approach we've taken so far is that the user should be able to interact with the application, despite their free tier billing project potentially being in a bad state, or still initializing. So a transient error shouldn't block the user anymore than FC's normal delay in project initialization.","created_at":"2018-02-21T18:40:34Z","updated_at":"2018-02-21T18:40:34Z","html_url":"https://github.com/all-of-us/workbench/pull/508#discussion_r169737269","pull_request_url":"https://api.github.com/repos/all-of-us/workbench/pulls/508","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/all-of-us/workbench/pulls/comments/169737269"},"html":{"href":"https://github.com/all-of-us/workbench/pull/508#discussion_r169737269"},"pull_request":{"href":"https://api.github.com/repos/all-of-us/workbench/pulls/508"}},"in_reply_to_id":169676568},"pull_request":{"url":"https://api.github.com/repos/all-of-us/workbench/pulls/508","id":169275036,"html_url":"https://github.com/all-of-us/workbench/pull/508","diff_url":"https://github.com/all-of-us/workbench/pull/508.diff","patch_url":"https://github.com/all-of-us/workbench/pull/508.patch","issue_url":"https://api.github.com/repos/all-of-us/workbench/issues/508","number":508,"state":"open","locked":false,"title":"Synchronize clone() behavior with create()","user":{"login":"calbach","id":822298,"avatar_url":"https://avatars0.githubusercontent.com/u/822298?v=4","gravatar_id":"","url":"https://api.github.com/users/calbach","html_url":"https://github.com/calbach","followers_url":"https://api.github.com/users/calbach/followers","following_url":"https://api.github.com/users/calbach/following{/other_user}","gists_url":"https://api.github.com/users/calbach/gists{/gist_id}","starred_url":"https://api.github.com/users/calbach/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/calbach/subscriptions","organizations_url":"https://api.github.com/users/calbach/orgs","repos_url":"https://api.github.com/users/calbach/repos","events_url":"https://api.github.com/users/calbach/events{/privacy}","received_events_url":"https://api.github.com/users/calbach/received_events","type":"User","site_admin":false},"body":"- Proposing moving BigQuery role granting from `CreateWorkspace()` -> `initializeUser()`; this seemed a more appropriate place, and I don't think we should be seeing any projects in AoU that we haven't initialized ourselves (and if we did, I'm not sure we should be granting any roles to them, or if we would even expect that call to succeed). Please check, as there may be a reason that it needs to be in `CreateWorkspace` currently.\r\n- Write the config file when cloning, as is done during workspace creation","created_at":"2018-02-15T02:54:51Z","updated_at":"2018-02-21T18:40:34Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6fa19c3fbe1cfe469272562ad20288fc56ba2b62","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/all-of-us/workbench/pulls/508/commits","review_comments_url":"https://api.github.com/repos/all-of-us/workbench/pulls/508/comments","review_comment_url":"https://api.github.com/repos/all-of-us/workbench/pulls/comments{/number}","comments_url":"https://api.github.com/repos/all-of-us/workbench/issues/508/comments","statuses_url":"https://api.github.com/repos/all-of-us/workbench/statuses/47b939271cbb953b62f84318efd74eee9587967f","head":{"label":"all-of-us:ch/clone-clean","ref":"ch/clone-clean","sha":"47b939271cbb953b62f84318efd74eee9587967f","user":{"login":"all-of-us","id":22846942,"avatar_url":"https://avatars0.githubusercontent.com/u/22846942?v=4","gravatar_id":"","url":"https://api.github.com/users/all-of-us","html_url":"https://github.com/all-of-us","followers_url":"https://api.github.com/users/all-of-us/followers","following_url":"https://api.github.com/users/all-of-us/following{/other_user}","gists_url":"https://api.github.com/users/all-of-us/gists{/gist_id}","starred_url":"https://api.github.com/users/all-of-us/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/all-of-us/subscriptions","organizations_url":"https://api.github.com/users/all-of-us/orgs","repos_url":"https://api.github.com/users/all-of-us/repos","events_url":"https://api.github.com/users/all-of-us/events{/privacy}","received_events_url":"https://api.github.com/users/all-of-us/received_events","type":"Organization","site_admin":false},"repo":{"id":95247186,"name":"workbench","full_name":"all-of-us/workbench","owner":{"login":"all-of-us","id":22846942,"avatar_url":"https://avatars0.githubusercontent.com/u/22846942?v=4","gravatar_id":"","url":"https://api.github.com/users/all-of-us","html_url":"https://github.com/all-of-us","followers_url":"https://api.github.com/users/all-of-us/followers","following_url":"https://api.github.com/users/all-of-us/following{/other_user}","gists_url":"https://api.github.com/users/all-of-us/gists{/gist_id}","starred_url":"https://api.github.com/users/all-of-us/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/all-of-us/subscriptions","organizations_url":"https://api.github.com/users/all-of-us/orgs","repos_url":"https://api.github.com/users/all-of-us/repos","events_url":"https://api.github.com/users/all-of-us/events{/privacy}","received_events_url":"https://api.github.com/users/all-of-us/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/all-of-us/workbench","description":null,"fork":false,"url":"https://api.github.com/repos/all-of-us/workbench","forks_url":"https://api.github.com/repos/all-of-us/workbench/forks","keys_url":"https://api.github.com/repos/all-of-us/workbench/keys{/key_id}","collaborators_url":"https://api.github.com/repos/all-of-us/workbench/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/all-of-us/workbench/teams","hooks_url":"https://api.github.com/repos/all-of-us/workbench/hooks","issue_events_url":"https://api.github.com/repos/all-of-us/workbench/issues/events{/number}","events_url":"https://api.github.com/repos/all-of-us/workbench/events","assignees_url":"https://api.github.com/repos/all-of-us/workbench/assignees{/user}","branches_url":"https://api.github.com/repos/all-of-us/workbench/branches{/branch}","tags_url":"https://api.github.com/repos/all-of-us/workbench/tags","blobs_url":"https://api.github.com/repos/all-of-us/workbench/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/all-of-us/workbench/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/all-of-us/workbench/git/refs{/sha}","trees_url":"https://api.github.com/repos/all-of-us/workbench/git/trees{/sha}","statuses_url":"https://api.github.com/repos/all-of-us/workbench/statuses/{sha}","languages_url":"https://api.github.com/repos/all-of-us/workbench/languages","stargazers_url":"https://api.github.com/repos/all-of-us/workbench/stargazers","contributors_url":"https://api.github.com/repos/all-of-us/workbench/contributors","subscribers_url":"https://api.github.com/repos/all-of-us/workbench/subscribers","subscription_url":"https://api.github.com/repos/all-of-us/workbench/subscription","commits_url":"https://api.github.com/repos/all-of-us/workbench/commits{/sha}","git_commits_url":"https://api.github.com/repos/all-of-us/workbench/git/commits{/sha}","comments_url":"https://api.github.com/repos/all-of-us/workbench/comments{/number}","issue_comment_url":"https://api.github.com/repos/all-of-us/workbench/issues/comments{/number}","contents_url":"https://api.github.com/repos/all-of-us/workbench/contents/{+path}","compare_url":"https://api.github.com/repos/all-of-us/workbench/compare/{base}...{head}","merges_url":"https://api.github.com/repos/all-of-us/workbench/merges","archive_url":"https://api.github.com/repos/all-of-us/workbench/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/all-of-us/workbench/downloads","issues_url":"https://api.github.com/repos/all-of-us/workbench/issues{/number}","pulls_url":"https://api.github.com/repos/all-of-us/workbench/pulls{/number}","milestones_url":"https://api.github.com/repos/all-of-us/workbench/milestones{/number}","notifications_url":"https://api.github.com/repos/all-of-us/workbench/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/all-of-us/workbench/labels{/name}","releases_url":"https://api.github.com/repos/all-of-us/workbench/releases{/id}","deployments_url":"https://api.github.com/repos/all-of-us/workbench/deployments","created_at":"2017-06-23T18:44:24Z","updated_at":"2018-02-02T17:32:23Z","pushed_at":"2018-02-21T18:38:52Z","git_url":"git://github.com/all-of-us/workbench.git","ssh_url":"git@github.com:all-of-us/workbench.git","clone_url":"https://github.com/all-of-us/workbench.git","svn_url":"https://github.com/all-of-us/workbench","homepage":null,"size":20996,"stargazers_count":2,"watchers_count":2,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":12,"license":null,"forks":1,"open_issues":12,"watchers":2,"default_branch":"master"}},"base":{"label":"all-of-us:master","ref":"master","sha":"e948b4fcfb799ae50e8a4e3a95a32244d4570ef1","user":{"login":"all-of-us","id":22846942,"avatar_url":"https://avatars0.githubusercontent.com/u/22846942?v=4","gravatar_id":"","url":"https://api.github.com/users/all-of-us","html_url":"https://github.com/all-of-us","followers_url":"https://api.github.com/users/all-of-us/followers","following_url":"https://api.github.com/users/all-of-us/following{/other_user}","gists_url":"https://api.github.com/users/all-of-us/gists{/gist_id}","starred_url":"https://api.github.com/users/all-of-us/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/all-of-us/subscriptions","organizations_url":"https://api.github.com/users/all-of-us/orgs","repos_url":"https://api.github.com/users/all-of-us/repos","events_url":"https://api.github.com/users/all-of-us/events{/privacy}","received_events_url":"https://api.github.com/users/all-of-us/received_events","type":"Organization","site_admin":false},"repo":{"id":95247186,"name":"workbench","full_name":"all-of-us/workbench","owner":{"login":"all-of-us","id":22846942,"avatar_url":"https://avatars0.githubusercontent.com/u/22846942?v=4","gravatar_id":"","url":"https://api.github.com/users/all-of-us","html_url":"https://github.com/all-of-us","followers_url":"https://api.github.com/users/all-of-us/followers","following_url":"https://api.github.com/users/all-of-us/following{/other_user}","gists_url":"https://api.github.com/users/all-of-us/gists{/gist_id}","starred_url":"https://api.github.com/users/all-of-us/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/all-of-us/subscriptions","organizations_url":"https://api.github.com/users/all-of-us/orgs","repos_url":"https://api.github.com/users/all-of-us/repos","events_url":"https://api.github.com/users/all-of-us/events{/privacy}","received_events_url":"https://api.github.com/users/all-of-us/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/all-of-us/workbench","description":null,"fork":false,"url":"https://api.github.com/repos/all-of-us/workbench","forks_url":"https://api.github.com/repos/all-of-us/workbench/forks","keys_url":"https://api.github.com/repos/all-of-us/workbench/keys{/key_id}","collaborators_url":"https://api.github.com/repos/all-of-us/workbench/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/all-of-us/workbench/teams","hooks_url":"https://api.github.com/repos/all-of-us/workbench/hooks","issue_events_url":"https://api.github.com/repos/all-of-us/workbench/issues/events{/number}","events_url":"https://api.github.com/repos/all-of-us/workbench/events","assignees_url":"https://api.github.com/repos/all-of-us/workbench/assignees{/user}","branches_url":"https://api.github.com/repos/all-of-us/workbench/branches{/branch}","tags_url":"https://api.github.com/repos/all-of-us/workbench/tags","blobs_url":"https://api.github.com/repos/all-of-us/workbench/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/all-of-us/workbench/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/all-of-us/workbench/git/refs{/sha}","trees_url":"https://api.github.com/repos/all-of-us/workbench/git/trees{/sha}","statuses_url":"https://api.github.com/repos/all-of-us/workbench/statuses/{sha}","languages_url":"https://api.github.com/repos/all-of-us/workbench/languages","stargazers_url":"https://api.github.com/repos/all-of-us/workbench/stargazers","contributors_url":"https://api.github.com/repos/all-of-us/workbench/contributors","subscribers_url":"https://api.github.com/repos/all-of-us/workbench/subscribers","subscription_url":"https://api.github.com/repos/all-of-us/workbench/subscription","commits_url":"https://api.github.com/repos/all-of-us/workbench/commits{/sha}","git_commits_url":"https://api.github.com/repos/all-of-us/workbench/git/commits{/sha}","comments_url":"https://api.github.com/repos/all-of-us/workbench/comments{/number}","issue_comment_url":"https://api.github.com/repos/all-of-us/workbench/issues/comments{/number}","contents_url":"https://api.github.com/repos/all-of-us/workbench/contents/{+path}","compare_url":"https://api.github.com/repos/all-of-us/workbench/compare/{base}...{head}","merges_url":"https://api.github.com/repos/all-of-us/workbench/merges","archive_url":"https://api.github.com/repos/all-of-us/workbench/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/all-of-us/workbench/downloads","issues_url":"https://api.github.com/repos/all-of-us/workbench/issues{/number}","pulls_url":"https://api.github.com/repos/all-of-us/workbench/pulls{/number}","milestones_url":"https://api.github.com/repos/all-of-us/workbench/milestones{/number}","notifications_url":"https://api.github.com/repos/all-of-us/workbench/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/all-of-us/workbench/labels{/name}","releases_url":"https://api.github.com/repos/all-of-us/workbench/releases{/id}","deployments_url":"https://api.github.com/repos/all-of-us/workbench/deployments","created_at":"2017-06-23T18:44:24Z","updated_at":"2018-02-02T17:32:23Z","pushed_at":"2018-02-21T18:38:52Z","git_url":"git://github.com/all-of-us/workbench.git","ssh_url":"git@github.com:all-of-us/workbench.git","clone_url":"https://github.com/all-of-us/workbench.git","svn_url":"https://github.com/all-of-us/workbench","homepage":null,"size":20996,"stargazers_count":2,"watchers_count":2,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":12,"license":null,"forks":1,"open_issues":12,"watchers":2,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/all-of-us/workbench/pulls/508"},"html":{"href":"https://github.com/all-of-us/workbench/pull/508"},"issue":{"href":"https://api.github.com/repos/all-of-us/workbench/issues/508"},"comments":{"href":"https://api.github.com/repos/all-of-us/workbench/issues/508/comments"},"review_comments":{"href":"https://api.github.com/repos/all-of-us/workbench/pulls/508/comments"},"review_comment":{"href":"https://api.github.com/repos/all-of-us/workbench/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/all-of-us/workbench/pulls/508/commits"},"statuses":{"href":"https://api.github.com/repos/all-of-us/workbench/statuses/47b939271cbb953b62f84318efd74eee9587967f"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"calbach"}}