{"action":"created","comment":{"url":"https://api.github.com/repos/broadinstitute/rawls/pulls/comments/121751555","pull_request_review_id":43805252,"id":121751555,"diff_hunk":"@@ -733,11 +756,22 @@ trait WorkspaceComponent {\n   }\n \n   private def groupByWorkspaceId(runningSubmissions: Seq[(UUID, Int)]): Map[UUID, Int] = {\n-    runningSubmissions.groupBy{ case (wsId, count) => wsId }.mapValues { case Seq((_, count)) => count }\n+    CollectionUtils.groupPairs(runningSubmissions.toList)\n   }\n \n   private def groupByWorkspaceIdThenStatus(workflowDates: Seq[(UUID, String, Option[Timestamp])]): Map[UUID, Map[String, Option[Timestamp]]] = {\n-    workflowDates.groupBy { case (wsId, _, _) => wsId }.mapValues(_.groupBy { case (_, status, _) => status }.mapValues { case Seq((_, _, timestamp)) => timestamp })\n+    // There is no Monoid instance for Option[Timestamp] so we need to bring one into scope.\n+    // However a Monoid for Timestamp doesn't really make sense -- what would it do, add them together?\n+    // We can take advantage of the _universal_ monoid for Option which combines Option values using\n+    // Option.orElse. It's called universal because it works no matter the type inside the Option.\n+    // This is fine in this case because there are guaranteed no key conflicts due to the SQL query\n+    // structure (group by, etc).\n+    //\n+    // TL/DR: The following line brings into scope a Monoid[Option[Timestamp]] which combines values\n+    // using Option.orElse.","path":"core/src/main/scala/org/broadinstitute/dsde/rawls/dataaccess/slick/WorkspaceComponent.scala","position":104,"original_position":104,"commit_id":"ee31eb5b882e32c9cd4c5cc6d86d39c4acd7bc2e","original_commit_id":"ee31eb5b882e32c9cd4c5cc6d86d39c4acd7bc2e","user":{"login":"rtitle","id":5368863,"avatar_url":"https://avatars0.githubusercontent.com/u/5368863?v=3","gravatar_id":"","url":"https://api.github.com/users/rtitle","html_url":"https://github.com/rtitle","followers_url":"https://api.github.com/users/rtitle/followers","following_url":"https://api.github.com/users/rtitle/following{/other_user}","gists_url":"https://api.github.com/users/rtitle/gists{/gist_id}","starred_url":"https://api.github.com/users/rtitle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rtitle/subscriptions","organizations_url":"https://api.github.com/users/rtitle/orgs","repos_url":"https://api.github.com/users/rtitle/repos","events_url":"https://api.github.com/users/rtitle/events{/privacy}","received_events_url":"https://api.github.com/users/rtitle/received_events","type":"User","site_admin":false},"body":"At least the `orElse` is explicit now. Before, in this code:\r\n```\r\n...mapValues { case Seq((_, _, timestamp)) => timestamp })\r\n```\r\nit's still expecting a unique UUID/String combo, but if that were not the case, there would be a runtime `MatchError`. ","created_at":"2017-06-13T17:58:01Z","updated_at":"2017-06-13T17:58:01Z","html_url":"https://github.com/broadinstitute/rawls/pull/709#discussion_r121751555","pull_request_url":"https://api.github.com/repos/broadinstitute/rawls/pulls/709","_links":{"self":{"href":"https://api.github.com/repos/broadinstitute/rawls/pulls/comments/121751555"},"html":{"href":"https://github.com/broadinstitute/rawls/pull/709#discussion_r121751555"},"pull_request":{"href":"https://api.github.com/repos/broadinstitute/rawls/pulls/709"}}},"pull_request":{"url":"https://api.github.com/repos/broadinstitute/rawls/pulls/709","id":124952455,"html_url":"https://github.com/broadinstitute/rawls/pull/709","diff_url":"https://github.com/broadinstitute/rawls/pull/709.diff","patch_url":"https://github.com/broadinstitute/rawls/pull/709.patch","issue_url":"https://api.github.com/repos/broadinstitute/rawls/issues/709","number":709,"state":"open","locked":false,"title":"[GAWB-2056] The status of the last run is showing green when there are errors in them","user":{"login":"rtitle","id":5368863,"avatar_url":"https://avatars0.githubusercontent.com/u/5368863?v=3","gravatar_id":"","url":"https://api.github.com/users/rtitle","html_url":"https://github.com/rtitle","followers_url":"https://api.github.com/users/rtitle/followers","following_url":"https://api.github.com/users/rtitle/following{/other_user}","gists_url":"https://api.github.com/users/rtitle/gists{/gist_id}","starred_url":"https://api.github.com/users/rtitle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rtitle/subscriptions","organizations_url":"https://api.github.com/users/rtitle/orgs","repos_url":"https://api.github.com/users/rtitle/repos","events_url":"https://api.github.com/users/rtitle/events{/privacy}","received_events_url":"https://api.github.com/users/rtitle/received_events","type":"User","site_admin":false},"body":"https://broadinstitute.atlassian.net/browse/GAWB-2056 (see latest comments)\r\n\r\n### Problem: \r\nIn \"get workspace\" calls, Rawls was returning the timestamps of the most recent successful and failed workflows. This is used in the UI to display either green or red in the workspace summary and list pages (red if latest failed workflow timestamp > latest successful workflow timestamp; green otherwise).\r\n\r\nHowever, these workflows might be in the same submission. In the UI, a submission is red if _any_ of its workflows failed. This led to confusing behavior: a workspace might be green in the Summary tab, but have only failed submissions in the Monitor tab.\r\n\r\n### Solution:\r\nChange semantics of `WorkspaceSubmissionStats` to return the timestamps of the most recent successful and failed _submission_, taking into account the logic that a submission is a failure if any of its workflows are a failure.\r\n\r\nTested via unit tests and manually using a UI. Also confirmed the generated slick query matches the query in the [comments](https://github.com/broadinstitute/rawls/compare/rt-gawb-2056?expand=1#diff-ce257bad14de3e732d04d31146839b87R511).\r\n\r\nAlso, query explain plan: \r\n![image](https://user-images.githubusercontent.com/5368863/26995875-2914d2fe-4d3d-11e7-8c1a-6048635934d2.png)\r\n\r\n\r\n\r\n\r\n\r\n- [x] **Submitter**: Include the JIRA issue number in the PR description\r\n- [x] **Submitter**: Check that the **Product Owner** has signed off on any user-facing changes\r\n- [x] **Submitter**: Make sure Swagger is updated if API changes\r\n  - [x] **...and Orchestration's Swagger too!**\r\n- [x] **Submitter**: If updating admin endpoints, also update [firecloud-admin-cli](https://github.com/broadinstitute/firecloud-admin-cli)\r\n- [x] **Submitter**: Check documentation and code comments. Add explanatory PR comments if helpful.\r\n- [x] **Submitter**: JIRA ticket checks:\r\n  * Acceptance criteria exists and is met\r\n  * Note any changes to implementation from the description\r\n  * To Demo flag is set\r\n  * Release Summary is filled out, if applicable\r\n  * Add notes on how to QA\r\n- [x] **Submitter**: Update RC_XXX release ticket with any config or environment changes necessary\r\n- [x] **Submitter**: Database checks:\r\n  * If PR includes new or changed db queries, include the explain plans in the description\r\n  * Make sure liquibase is updated if appropriate\r\n  * If doing a migration, take a backup of the\r\n  [dev](https://console.cloud.google.com/sql/instances/terraform-qfarbdq3lrexxck5htofjs5z6m/backups?project=broad-dsde-dev&organizationId=548622027621)\r\n  and\r\n  [alpha](https://console.cloud.google.com/sql/instances/terraform-r4caezzc35c4tb7pgdhwkmme4y/backups?project=broad-dsde-alpha&organizationId=548622027621)\r\n  DBs in Google Cloud Console\r\n- [x] **Submitter**: Update FISMA documentation if changes to:\r\n  * Authentication\r\n  * Authorization\r\n  * Encryption\r\n  * Audit trails\r\n- [ ] Tell your tech lead (TL) that the PR exists if they want to look at it\r\n- [ ] Anoint a lead reviewer (LR). **Assign PR to LR**\r\n* Review cycle:\r\n  * LR reviews\r\n  * Rest of team may comment on PR at will\r\n  * **LR assigns to submitter** for feedback fixes\r\n  * Submitter rebases to develop again if necessary\r\n  * Submitter makes further commits. DO NOT SQUASH\r\n  * Submitter updates documentation as needed\r\n  * Submitter **reassigns to LR** for further feedback\r\n- [ ] **TL** sign off\r\n- [ ] **LR** sign off\r\n- [ ] **Assign to submitter** to finalize\r\n- [ ] **Submitter**: Verify all tests go green, including CI tests\r\n- [ ] **Submitter**: Squash commits and merge to develop\r\n- [ ] **Submitter**: Delete branch after merge\r\n- [ ] **Submitter**: **Test this change works on dev environment after deployment**. YOU own getting it fixed if dev isn't working for ANY reason!\r\n- [ ] **Submitter**: Verify swagger UI on dev environment still works after deployment\r\n- [ ] **Submitter**: Inform other teams of any API changes via Slack and/or email\r\n- [ ] **Submitter**: Mark JIRA issue as resolved once this checklist is completed\r\n","created_at":"2017-06-09T21:20:00Z","updated_at":"2017-06-13T17:58:01Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7afb6fc8b66cad96aa43f1d300b20a8fd0123d2c","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/broadinstitute/rawls/pulls/709/commits","review_comments_url":"https://api.github.com/repos/broadinstitute/rawls/pulls/709/comments","review_comment_url":"https://api.github.com/repos/broadinstitute/rawls/pulls/comments{/number}","comments_url":"https://api.github.com/repos/broadinstitute/rawls/issues/709/comments","statuses_url":"https://api.github.com/repos/broadinstitute/rawls/statuses/ee31eb5b882e32c9cd4c5cc6d86d39c4acd7bc2e","head":{"label":"broadinstitute:rt-gawb-2056","ref":"rt-gawb-2056","sha":"ee31eb5b882e32c9cd4c5cc6d86d39c4acd7bc2e","user":{"login":"broadinstitute","id":393552,"avatar_url":"https://avatars3.githubusercontent.com/u/393552?v=3","gravatar_id":"","url":"https://api.github.com/users/broadinstitute","html_url":"https://github.com/broadinstitute","followers_url":"https://api.github.com/users/broadinstitute/followers","following_url":"https://api.github.com/users/broadinstitute/following{/other_user}","gists_url":"https://api.github.com/users/broadinstitute/gists{/gist_id}","starred_url":"https://api.github.com/users/broadinstitute/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/broadinstitute/subscriptions","organizations_url":"https://api.github.com/users/broadinstitute/orgs","repos_url":"https://api.github.com/users/broadinstitute/repos","events_url":"https://api.github.com/users/broadinstitute/events{/privacy}","received_events_url":"https://api.github.com/users/broadinstitute/received_events","type":"Organization","site_admin":false},"repo":{"id":34129770,"name":"rawls","full_name":"broadinstitute/rawls","owner":{"login":"broadinstitute","id":393552,"avatar_url":"https://avatars3.githubusercontent.com/u/393552?v=3","gravatar_id":"","url":"https://api.github.com/users/broadinstitute","html_url":"https://github.com/broadinstitute","followers_url":"https://api.github.com/users/broadinstitute/followers","following_url":"https://api.github.com/users/broadinstitute/following{/other_user}","gists_url":"https://api.github.com/users/broadinstitute/gists{/gist_id}","starred_url":"https://api.github.com/users/broadinstitute/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/broadinstitute/subscriptions","organizations_url":"https://api.github.com/users/broadinstitute/orgs","repos_url":"https://api.github.com/users/broadinstitute/repos","events_url":"https://api.github.com/users/broadinstitute/events{/privacy}","received_events_url":"https://api.github.com/users/broadinstitute/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/broadinstitute/rawls","description":"Rawls service for DSDE","fork":false,"url":"https://api.github.com/repos/broadinstitute/rawls","forks_url":"https://api.github.com/repos/broadinstitute/rawls/forks","keys_url":"https://api.github.com/repos/broadinstitute/rawls/keys{/key_id}","collaborators_url":"https://api.github.com/repos/broadinstitute/rawls/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/broadinstitute/rawls/teams","hooks_url":"https://api.github.com/repos/broadinstitute/rawls/hooks","issue_events_url":"https://api.github.com/repos/broadinstitute/rawls/issues/events{/number}","events_url":"https://api.github.com/repos/broadinstitute/rawls/events","assignees_url":"https://api.github.com/repos/broadinstitute/rawls/assignees{/user}","branches_url":"https://api.github.com/repos/broadinstitute/rawls/branches{/branch}","tags_url":"https://api.github.com/repos/broadinstitute/rawls/tags","blobs_url":"https://api.github.com/repos/broadinstitute/rawls/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/broadinstitute/rawls/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/broadinstitute/rawls/git/refs{/sha}","trees_url":"https://api.github.com/repos/broadinstitute/rawls/git/trees{/sha}","statuses_url":"https://api.github.com/repos/broadinstitute/rawls/statuses/{sha}","languages_url":"https://api.github.com/repos/broadinstitute/rawls/languages","stargazers_url":"https://api.github.com/repos/broadinstitute/rawls/stargazers","contributors_url":"https://api.github.com/repos/broadinstitute/rawls/contributors","subscribers_url":"https://api.github.com/repos/broadinstitute/rawls/subscribers","subscription_url":"https://api.github.com/repos/broadinstitute/rawls/subscription","commits_url":"https://api.github.com/repos/broadinstitute/rawls/commits{/sha}","git_commits_url":"https://api.github.com/repos/broadinstitute/rawls/git/commits{/sha}","comments_url":"https://api.github.com/repos/broadinstitute/rawls/comments{/number}","issue_comment_url":"https://api.github.com/repos/broadinstitute/rawls/issues/comments{/number}","contents_url":"https://api.github.com/repos/broadinstitute/rawls/contents/{+path}","compare_url":"https://api.github.com/repos/broadinstitute/rawls/compare/{base}...{head}","merges_url":"https://api.github.com/repos/broadinstitute/rawls/merges","archive_url":"https://api.github.com/repos/broadinstitute/rawls/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/broadinstitute/rawls/downloads","issues_url":"https://api.github.com/repos/broadinstitute/rawls/issues{/number}","pulls_url":"https://api.github.com/repos/broadinstitute/rawls/pulls{/number}","milestones_url":"https://api.github.com/repos/broadinstitute/rawls/milestones{/number}","notifications_url":"https://api.github.com/repos/broadinstitute/rawls/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/broadinstitute/rawls/labels{/name}","releases_url":"https://api.github.com/repos/broadinstitute/rawls/releases{/id}","deployments_url":"https://api.github.com/repos/broadinstitute/rawls/deployments","created_at":"2015-04-17T17:16:07Z","updated_at":"2016-11-04T19:53:29Z","pushed_at":"2017-06-13T15:15:53Z","git_url":"git://github.com/broadinstitute/rawls.git","ssh_url":"git@github.com:broadinstitute/rawls.git","clone_url":"https://github.com/broadinstitute/rawls.git","svn_url":"https://github.com/broadinstitute/rawls","homepage":null,"size":4998,"stargazers_count":6,"watchers_count":6,"language":"Scala","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":2,"forks":2,"open_issues":2,"watchers":6,"default_branch":"develop"}},"base":{"label":"broadinstitute:develop","ref":"develop","sha":"3d9e6d7f415cc80b43b681c3d4f150ce1f870ae2","user":{"login":"broadinstitute","id":393552,"avatar_url":"https://avatars3.githubusercontent.com/u/393552?v=3","gravatar_id":"","url":"https://api.github.com/users/broadinstitute","html_url":"https://github.com/broadinstitute","followers_url":"https://api.github.com/users/broadinstitute/followers","following_url":"https://api.github.com/users/broadinstitute/following{/other_user}","gists_url":"https://api.github.com/users/broadinstitute/gists{/gist_id}","starred_url":"https://api.github.com/users/broadinstitute/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/broadinstitute/subscriptions","organizations_url":"https://api.github.com/users/broadinstitute/orgs","repos_url":"https://api.github.com/users/broadinstitute/repos","events_url":"https://api.github.com/users/broadinstitute/events{/privacy}","received_events_url":"https://api.github.com/users/broadinstitute/received_events","type":"Organization","site_admin":false},"repo":{"id":34129770,"name":"rawls","full_name":"broadinstitute/rawls","owner":{"login":"broadinstitute","id":393552,"avatar_url":"https://avatars3.githubusercontent.com/u/393552?v=3","gravatar_id":"","url":"https://api.github.com/users/broadinstitute","html_url":"https://github.com/broadinstitute","followers_url":"https://api.github.com/users/broadinstitute/followers","following_url":"https://api.github.com/users/broadinstitute/following{/other_user}","gists_url":"https://api.github.com/users/broadinstitute/gists{/gist_id}","starred_url":"https://api.github.com/users/broadinstitute/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/broadinstitute/subscriptions","organizations_url":"https://api.github.com/users/broadinstitute/orgs","repos_url":"https://api.github.com/users/broadinstitute/repos","events_url":"https://api.github.com/users/broadinstitute/events{/privacy}","received_events_url":"https://api.github.com/users/broadinstitute/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/broadinstitute/rawls","description":"Rawls service for DSDE","fork":false,"url":"https://api.github.com/repos/broadinstitute/rawls","forks_url":"https://api.github.com/repos/broadinstitute/rawls/forks","keys_url":"https://api.github.com/repos/broadinstitute/rawls/keys{/key_id}","collaborators_url":"https://api.github.com/repos/broadinstitute/rawls/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/broadinstitute/rawls/teams","hooks_url":"https://api.github.com/repos/broadinstitute/rawls/hooks","issue_events_url":"https://api.github.com/repos/broadinstitute/rawls/issues/events{/number}","events_url":"https://api.github.com/repos/broadinstitute/rawls/events","assignees_url":"https://api.github.com/repos/broadinstitute/rawls/assignees{/user}","branches_url":"https://api.github.com/repos/broadinstitute/rawls/branches{/branch}","tags_url":"https://api.github.com/repos/broadinstitute/rawls/tags","blobs_url":"https://api.github.com/repos/broadinstitute/rawls/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/broadinstitute/rawls/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/broadinstitute/rawls/git/refs{/sha}","trees_url":"https://api.github.com/repos/broadinstitute/rawls/git/trees{/sha}","statuses_url":"https://api.github.com/repos/broadinstitute/rawls/statuses/{sha}","languages_url":"https://api.github.com/repos/broadinstitute/rawls/languages","stargazers_url":"https://api.github.com/repos/broadinstitute/rawls/stargazers","contributors_url":"https://api.github.com/repos/broadinstitute/rawls/contributors","subscribers_url":"https://api.github.com/repos/broadinstitute/rawls/subscribers","subscription_url":"https://api.github.com/repos/broadinstitute/rawls/subscription","commits_url":"https://api.github.com/repos/broadinstitute/rawls/commits{/sha}","git_commits_url":"https://api.github.com/repos/broadinstitute/rawls/git/commits{/sha}","comments_url":"https://api.github.com/repos/broadinstitute/rawls/comments{/number}","issue_comment_url":"https://api.github.com/repos/broadinstitute/rawls/issues/comments{/number}","contents_url":"https://api.github.com/repos/broadinstitute/rawls/contents/{+path}","compare_url":"https://api.github.com/repos/broadinstitute/rawls/compare/{base}...{head}","merges_url":"https://api.github.com/repos/broadinstitute/rawls/merges","archive_url":"https://api.github.com/repos/broadinstitute/rawls/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/broadinstitute/rawls/downloads","issues_url":"https://api.github.com/repos/broadinstitute/rawls/issues{/number}","pulls_url":"https://api.github.com/repos/broadinstitute/rawls/pulls{/number}","milestones_url":"https://api.github.com/repos/broadinstitute/rawls/milestones{/number}","notifications_url":"https://api.github.com/repos/broadinstitute/rawls/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/broadinstitute/rawls/labels{/name}","releases_url":"https://api.github.com/repos/broadinstitute/rawls/releases{/id}","deployments_url":"https://api.github.com/repos/broadinstitute/rawls/deployments","created_at":"2015-04-17T17:16:07Z","updated_at":"2016-11-04T19:53:29Z","pushed_at":"2017-06-13T15:15:53Z","git_url":"git://github.com/broadinstitute/rawls.git","ssh_url":"git@github.com:broadinstitute/rawls.git","clone_url":"https://github.com/broadinstitute/rawls.git","svn_url":"https://github.com/broadinstitute/rawls","homepage":null,"size":4998,"stargazers_count":6,"watchers_count":6,"language":"Scala","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":2,"forks":2,"open_issues":2,"watchers":6,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/broadinstitute/rawls/pulls/709"},"html":{"href":"https://github.com/broadinstitute/rawls/pull/709"},"issue":{"href":"https://api.github.com/repos/broadinstitute/rawls/issues/709"},"comments":{"href":"https://api.github.com/repos/broadinstitute/rawls/issues/709/comments"},"review_comments":{"href":"https://api.github.com/repos/broadinstitute/rawls/pulls/709/comments"},"review_comment":{"href":"https://api.github.com/repos/broadinstitute/rawls/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/broadinstitute/rawls/pulls/709/commits"},"statuses":{"href":"https://api.github.com/repos/broadinstitute/rawls/statuses/ee31eb5b882e32c9cd4c5cc6d86d39c4acd7bc2e"}}}}
{"actor":{"display_login":"rtitle"}}