{"action":"created","comment":{"url":"https://api.github.com/repos/broadinstitute/rawls/pulls/comments/45126379","id":45126379,"diff_hunk":"@@ -187,6 +211,211 @@ class UserService(protected val userInfo: UserInfo, dataSource: DataSource, prot\n     }\n   }\n \n+  def listAdmins() = {\n+    asAdmin {\n+      gcsDAO.listAdmins.map(RequestComplete(StatusCodes.OK, _)).recover{ case throwable =>\n+        RequestComplete(ErrorReport(StatusCodes.BadGateway,\"Unable to list admins.\",gcsDAO.toErrorReport(throwable)))\n+      }\n+    }\n+  }\n+\n+  def isAdmin(userId: String) = {\n+    asAdmin {\n+      tryIsAdmin(userId) map { admin =>\n+        if (admin) RequestComplete(StatusCodes.NoContent)\n+        else RequestComplete(ErrorReport(StatusCodes.NotFound, s\"User ${userId} is not an admin.\"))\n+      } recover { case throwable =>\n+        RequestComplete(ErrorReport(StatusCodes.BadGateway, s\"Unable to determine whether ${userId} is an admin.\", gcsDAO.toErrorReport(throwable)))\n+      }\n+    }\n+  }\n+\n+  def addAdmin(userId: String) = {\n+    asAdmin {\n+      tryIsAdmin(userId) flatMap { admin =>\n+        if (admin) {\n+          Future.successful(RequestComplete(StatusCodes.NoContent))\n+        } else {\n+          gcsDAO.addAdmin(userId) map (_ => RequestComplete(StatusCodes.Created)) recover { case throwable =>\n+            RequestComplete(ErrorReport(StatusCodes.BadGateway, s\"Unable to add ${userId} as an admin.\", gcsDAO.toErrorReport(throwable)))\n+          }\n+        }\n+      } recover { case throwable =>\n+        RequestComplete(ErrorReport(StatusCodes.BadGateway, s\"Unable to determine whether ${userId} is an admin.\", gcsDAO.toErrorReport(throwable)))\n+      }\n+    }\n+  }\n+\n+  def deleteAdmin(userId: String) = {\n+    asAdmin {\n+      tryIsAdmin(userId) flatMap { admin =>\n+        if (admin) {\n+          gcsDAO.deleteAdmin(userId) map (_ => RequestComplete(StatusCodes.NoContent)) recover { case throwable =>\n+            RequestComplete(ErrorReport(StatusCodes.BadGateway, s\"Unable to delete ${userId} as an admin.\", gcsDAO.toErrorReport(throwable)))\n+          }\n+        } else {\n+          Future.successful(RequestComplete(ErrorReport(StatusCodes.NotFound,s\"${userId} is not an admin.\")))\n+        }\n+      } recover { case throwable =>\n+        RequestComplete(ErrorReport(StatusCodes.BadGateway, s\"Unable to determine whether ${userId} is an admin.\", gcsDAO.toErrorReport(throwable)))\n+      }\n+    }\n+  }\n+\n+\n+  def listGroupMembers(groupName: String) = {\n+    asAdmin {\n+      dataSource.inFutureTransaction() { txn =>\n+        Future {\n+          containerDAO.authDAO.loadGroup(RawlsGroupRef(RawlsGroupName(groupName)), txn) match {\n+            case None => RequestComplete(ErrorReport(StatusCodes.NotFound, s\"Group ${groupName} does not exist\"))\n+            case Some(group) =>\n+              val memberUsers = group.users.map(u => containerDAO.authDAO.loadUser(u, txn).get.userEmail.value)\n+              val memberGroups = group.subGroups.map(g => containerDAO.authDAO.loadGroup(g, txn).get.groupEmail.value)\n+              RequestComplete(StatusCodes.OK, UserList((memberUsers ++ memberGroups).toSeq))\n+          }\n+        }\n+      }\n+    }\n+  }\n+\n+  def createGroup(groupRef: RawlsGroupRef) = {\n+    asAdmin {\n+      dataSource.inTransaction() { txn =>\n+        containerDAO.authDAO.loadGroup(groupRef, txn) match {\n+          case Some(_) => Future.successful(RequestComplete(ErrorReport(StatusCodes.Conflict, s\"Group ${groupRef.groupName} already exists\")))\n+          case None =>\n+            containerDAO.authDAO.createGroup(RawlsGroup(groupRef.groupName, RawlsGroupEmail(gcsDAO.toGoogleGroupName(groupRef.groupName)), Set.empty[RawlsUserRef], Set.empty[RawlsGroupRef]), txn)\n+            gcsDAO.createGoogleGroup(groupRef) map { _ => RequestComplete(StatusCodes.Created) }\n+        }\n+      }\n+    }\n+  }\n+\n+  def deleteGroup(groupRef: RawlsGroupRef) = {\n+    asAdmin {\n+      dataSource.inTransaction() { txn =>\n+        withGroup(groupRef) { group =>\n+          containerDAO.authDAO.deleteGroup(groupRef, txn)\n+          gcsDAO.deleteGoogleGroup(groupRef) map { _ => RequestComplete(StatusCodes.OK) }\n+        }\n+      }\n+    }\n+  }\n+\n+  //ideally this would probably just return the already loaded users to avoid loading twice\n+  def allMembersExist(memberList: RawlsGroupMemberList): Boolean = {\n+    dataSource.inTransaction() { txn =>\n+      memberList.userEmails.foreach { user =>\n+        containerDAO.authDAO.loadUserByEmail(user, txn).getOrElse(return false)\n+      }\n+      memberList.subGroupEmails.foreach { subGroup =>\n+        containerDAO.authDAO.loadGroupByEmail(subGroup, txn).getOrElse(return false)\n+      }\n+      true\n+    }\n+  }\n+\n+  def addGroupMembers(groupRef: RawlsGroupRef, memberList: RawlsGroupMemberList) = {\n+    asAdmin {\n+      dataSource.inFutureTransaction() { txn =>\n+        if (!allMembersExist(memberList))\n+          Future.successful(RequestComplete(StatusCodes.NotFound, \"Not all members are registered. Please ensure that all users/groups exist\"))\n+        else {\n+          val addMap = memberList.userEmails.map { user =>\n+            val theUser = containerDAO.authDAO.loadUserByEmail(user, txn).get\n+            val addTry = toFutureTry(gcsDAO.addMemberToGoogleGroup(groupRef, Left(theUser)))\n+            addTry.map(Left(theUser) -> _)\n+          } ++ memberList.subGroupEmails.map { subGroup =>\n+            val theGroup = containerDAO.authDAO.loadGroupByEmail(subGroup, txn).get\n+            val addTry = toFutureTry(gcsDAO.addMemberToGoogleGroup(groupRef, Right(theGroup)))\n+            addTry.map(Right(theGroup) -> _)\n+          }\n+\n+          val list: Future[Seq[Try[_]]] = Future.sequence(addMap) map { pairs =>\n+            pairs.map { case (member: Either[RawlsUser, RawlsGroup], result: Try[Unit]) =>\n+              result match {\n+                case Success(_) =>\n+                  Success(member match {\n+                    case Left(theUser) =>\n+                      val group = containerDAO.authDAO.loadGroup(groupRef, txn).getOrElse(throw new RawlsException(\"Unable to load group\"))","path":"src/main/scala/org/broadinstitute/dsde/rawls/user/UserService.scala","position":189,"original_position":189,"commit_id":"faafdc1da91c61a97edd329fc92cd38172b7ffb9","original_commit_id":"faafdc1da91c61a97edd329fc92cd38172b7ffb9","user":{"login":"jmthibault79","id":2701406,"avatar_url":"https://avatars.githubusercontent.com/u/2701406?v=3","gravatar_id":"","url":"https://api.github.com/users/jmthibault79","html_url":"https://github.com/jmthibault79","followers_url":"https://api.github.com/users/jmthibault79/followers","following_url":"https://api.github.com/users/jmthibault79/following{/other_user}","gists_url":"https://api.github.com/users/jmthibault79/gists{/gist_id}","starred_url":"https://api.github.com/users/jmthibault79/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jmthibault79/subscriptions","organizations_url":"https://api.github.com/users/jmthibault79/orgs","repos_url":"https://api.github.com/users/jmthibault79/repos","events_url":"https://api.github.com/users/jmthibault79/events{/privacy}","received_events_url":"https://api.github.com/users/jmthibault79/received_events","type":"User","site_admin":false},"body":"The group is loaded and saved once per new member.  It would be better to collect the new members so they can be added all at once.","created_at":"2015-11-17T21:47:57Z","updated_at":"2015-11-17T21:47:57Z","html_url":"https://github.com/broadinstitute/rawls/pull/223#discussion_r45126379","pull_request_url":"https://api.github.com/repos/broadinstitute/rawls/pulls/223","_links":{"self":{"href":"https://api.github.com/repos/broadinstitute/rawls/pulls/comments/45126379"},"html":{"href":"https://github.com/broadinstitute/rawls/pull/223#discussion_r45126379"},"pull_request":{"href":"https://api.github.com/repos/broadinstitute/rawls/pulls/223"}}},"pull_request":{"url":"https://api.github.com/repos/broadinstitute/rawls/pulls/223","id":50998182,"html_url":"https://github.com/broadinstitute/rawls/pull/223","diff_url":"https://github.com/broadinstitute/rawls/pull/223.diff","patch_url":"https://github.com/broadinstitute/rawls/pull/223.patch","issue_url":"https://api.github.com/repos/broadinstitute/rawls/issues/223","number":223,"state":"open","locked":false,"title":"Mb group admin endpoints (take two)","user":{"login":"MatthewBemis","id":7257391,"avatar_url":"https://avatars.githubusercontent.com/u/7257391?v=3","gravatar_id":"","url":"https://api.github.com/users/MatthewBemis","html_url":"https://github.com/MatthewBemis","followers_url":"https://api.github.com/users/MatthewBemis/followers","following_url":"https://api.github.com/users/MatthewBemis/following{/other_user}","gists_url":"https://api.github.com/users/MatthewBemis/gists{/gist_id}","starred_url":"https://api.github.com/users/MatthewBemis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MatthewBemis/subscriptions","organizations_url":"https://api.github.com/users/MatthewBemis/orgs","repos_url":"https://api.github.com/users/MatthewBemis/repos","events_url":"https://api.github.com/users/MatthewBemis/events{/privacy}","received_events_url":"https://api.github.com/users/MatthewBemis/received_events","type":"User","site_admin":false},"body":"Note: this contains the previous PR where I moved admin endpoints to UserService.\r\n\r\nThis should cover all of the feedback from #207 \r\n\r\nhttps://broadinstitute.atlassian.net/browse/DSDEEPB-1803\r\n\r\n- [x] **Submitter**: Rebase to develop. DO NOT SQUASH\r\n- [x] **Submitter**: Make sure Swagger is updated if API changes\r\n- [x] **Submitter**: Make sure documentation for code is complete\r\n- [x] **Submitter**: Review code comments; remove done TODOs, create stories for remaining TODOs\r\n- [x] **Submitter**: Include the JIRA issue number in the PR description\r\n- [x] **Submitter**: Add description or comments on the PR explaining the hows/whys (if not obvious)\r\n- [x] Tell ![](http://i.imgur.com/9dLzbPd.png) that the PR exists if he wants to look at it\r\n- [x] Anoint a lead reviewer (LR). **Assign PR to LR**\r\n- [ ] **LR**: Initial review by LR and others.\r\n- [ ] Comment / review / update cycle:\r\n  * Rest of team may comments on PR at will\r\n  * **LR assigns to submitter** for feedback fixes\r\n  * Submitter updates documentation as needed\r\n  * Submitter rebases to develop again if necessary\r\n  * Submitter makes further commits. DO NOT SQUASH. **Reassign to LR** for further feedback\r\n- [ ] ![](http://i.imgur.com/9dLzbPd.png) sign off\r\n- [ ] **LR** sign off\r\n- [ ] **Assign to submitter** to finalize\r\n- [ ] **Submitter**: Squash commits, rebase if necessary\r\n- [ ] **Submitter**: Verify all tests go green, including CI tests\r\n- [ ] **Submitter**: Merge to develop \r\n- [ ] **Submitter**: Delete branch after merge\r\n- [ ] **Submitter**: Check configuration files in Jenkins in case they need changes\r\n- [ ] **Submitter**: Verify swagger UI on dev server still works after deployment\r\n- [ ] **Submitter**: Inform other teams of any API changes via hipchat and/or email\r\n- [ ] **Submitter**: Mark JIRA issue as resolved once this checklist is completed","created_at":"2015-11-17T20:14:18Z","updated_at":"2015-11-17T21:47:57Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1233e01669130ae20f9275a857fcad089c3ee8b9","assignee":{"login":"jmthibault79","id":2701406,"avatar_url":"https://avatars.githubusercontent.com/u/2701406?v=3","gravatar_id":"","url":"https://api.github.com/users/jmthibault79","html_url":"https://github.com/jmthibault79","followers_url":"https://api.github.com/users/jmthibault79/followers","following_url":"https://api.github.com/users/jmthibault79/following{/other_user}","gists_url":"https://api.github.com/users/jmthibault79/gists{/gist_id}","starred_url":"https://api.github.com/users/jmthibault79/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jmthibault79/subscriptions","organizations_url":"https://api.github.com/users/jmthibault79/orgs","repos_url":"https://api.github.com/users/jmthibault79/repos","events_url":"https://api.github.com/users/jmthibault79/events{/privacy}","received_events_url":"https://api.github.com/users/jmthibault79/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/broadinstitute/rawls/pulls/223/commits","review_comments_url":"https://api.github.com/repos/broadinstitute/rawls/pulls/223/comments","review_comment_url":"https://api.github.com/repos/broadinstitute/rawls/pulls/comments{/number}","comments_url":"https://api.github.com/repos/broadinstitute/rawls/issues/223/comments","statuses_url":"https://api.github.com/repos/broadinstitute/rawls/statuses/faafdc1da91c61a97edd329fc92cd38172b7ffb9","head":{"label":"broadinstitute:mb_group_admin_endpoints","ref":"mb_group_admin_endpoints","sha":"faafdc1da91c61a97edd329fc92cd38172b7ffb9","user":{"login":"broadinstitute","id":393552,"avatar_url":"https://avatars.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://avatars.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}","created_at":"2015-04-17T17:16:07Z","updated_at":"2015-10-05T19:19:46Z","pushed_at":"2015-11-17T20:30:12Z","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":2282,"stargazers_count":4,"watchers_count":4,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":3,"forks":0,"open_issues":3,"watchers":4,"default_branch":"develop"}},"base":{"label":"broadinstitute:develop","ref":"develop","sha":"65bb09dcc495ba73c941454c5f8e387b83282882","user":{"login":"broadinstitute","id":393552,"avatar_url":"https://avatars.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://avatars.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}","created_at":"2015-04-17T17:16:07Z","updated_at":"2015-10-05T19:19:46Z","pushed_at":"2015-11-17T20:30:12Z","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":2282,"stargazers_count":4,"watchers_count":4,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":3,"forks":0,"open_issues":3,"watchers":4,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/broadinstitute/rawls/pulls/223"},"html":{"href":"https://github.com/broadinstitute/rawls/pull/223"},"issue":{"href":"https://api.github.com/repos/broadinstitute/rawls/issues/223"},"comments":{"href":"https://api.github.com/repos/broadinstitute/rawls/issues/223/comments"},"review_comments":{"href":"https://api.github.com/repos/broadinstitute/rawls/pulls/223/comments"},"review_comment":{"href":"https://api.github.com/repos/broadinstitute/rawls/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/broadinstitute/rawls/pulls/223/commits"},"statuses":{"href":"https://api.github.com/repos/broadinstitute/rawls/statuses/faafdc1da91c61a97edd329fc92cd38172b7ffb9"}}}}