{"action":"created","comment":{"url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/pulls/comments/74359629","id":74359629,"diff_hunk":"@@ -1,102 +1,161 @@\n package org.sagebionetworks.repo.web.filter;\n \n import static org.junit.Assert.assertEquals;\n+import static org.junit.Assert.assertNotNull;\n import static org.mockito.Matchers.any;\n import static org.mockito.Mockito.mock;\n import static org.mockito.Mockito.verify;\n import static org.mockito.Mockito.verifyNoMoreInteractions;\n import static org.mockito.Mockito.when;\n-import static org.sagebionetworks.repo.web.filter.UserThrottleFilter.LOCK_TIMOUTE_SEC;\n+import static org.sagebionetworks.repo.web.filter.UserThrottleFilter.CONCURRENT_CONNECTIONS_LOCK_TIMEOUT_SEC;\n import static org.sagebionetworks.repo.web.filter.UserThrottleFilter.MAX_CONCURRENT_LOCKS;\n+import static org.sagebionetworks.repo.web.filter.UserThrottleFilter.REQUEST_FREQUENCY_LOCK_TIMEOUT_SEC;\n+import static org.sagebionetworks.repo.web.filter.UserThrottleFilter.MAX_REQUEST_FREQUENCY_LOCKS;\n \n import javax.servlet.FilterChain;\n import javax.servlet.ServletException;\n \n+import org.apache.http.HttpStatus;\n import org.junit.Before;\n import org.junit.Test;\n+import org.junit.runner.RunWith;\n+import org.mockito.ArgumentCaptor;\n+import org.mockito.Mock;\n+import org.mockito.runners.MockitoJUnitRunner;\n import org.sagebionetworks.cloudwatch.Consumer;\n import org.sagebionetworks.cloudwatch.ProfileData;\n import org.sagebionetworks.repo.model.AuthorizationConstants;\n import org.sagebionetworks.repo.model.AuthorizationConstants.BOOTSTRAP_PRINCIPAL;\n import org.sagebionetworks.repo.model.semaphore.MemoryCountingSemaphore;\n+import org.sagebionetworks.repo.model.semaphore.MemoryTimeBlockCountingSemaphore;\n import org.springframework.mock.web.MockHttpServletRequest;\n import org.springframework.mock.web.MockHttpServletResponse;\n import org.springframework.test.util.ReflectionTestUtils;\n \n+\n+@RunWith(MockitoJUnitRunner.class)\n public class UserThrottleFilterTest {\n \n \tprivate UserThrottleFilter filter;\n-\n+\t\n+\t@Mock\n \tprivate MemoryCountingSemaphore userThrottleGate;\n-\n+\t\n+\t@Mock\n+\tprivate MemoryTimeBlockCountingSemaphore userFrequencyThrottleGate;\n+\t\n+\t@Mock\n+\tprivate FilterChain filterChain;\n+\t\n+\tprivate static final String userId = \"111\";\n+\tprivate static final String concurrentSemaphoreToken = \"concurrentToken\";\n+\t\n+\t\n+\tprivate MockHttpServletRequest request;\n+\tprivate MockHttpServletResponse response;\n \t@Before\n \tpublic void setupFilter() throws Exception {\n-\t\tuserThrottleGate = mock(MemoryCountingSemaphore.class);\n \t\tfilter = new UserThrottleFilter();\n+\t\trequest = new MockHttpServletRequest();\n+\t\tresponse = new MockHttpServletResponse();\n+\t\t\n+\t\trequest.setParameter(AuthorizationConstants.USER_ID_PARAM, userId);\n+\t\t\n \t\tReflectionTestUtils.setField(filter, \"userThrottleMemoryCountingSemaphore\", userThrottleGate);\n+\t\tReflectionTestUtils.setField(filter, \"userThrottleMemoryTimeBlockSemaphore\", userFrequencyThrottleGate);\n+\t\tassertNotNull(userThrottleGate);\n \t}\n \n \t@Test\n \tpublic void testAnonymous() throws Exception {\n-\t\tMockHttpServletRequest request = new MockHttpServletRequest();\n \t\trequest.setParameter(AuthorizationConstants.USER_ID_PARAM, BOOTSTRAP_PRINCIPAL.ANONYMOUS_USER.getPrincipalId().toString());\n-\t\tMockHttpServletResponse response = new MockHttpServletResponse();\n-\t\tFilterChain filterChain = mock(FilterChain.class);\n \n \t\tfilter.doFilter(request, response, filterChain);\n \n \t\tverify(filterChain).doFilter(request, response);\n-\t\tverifyNoMoreInteractions(filterChain, userThrottleGate);\n+\t\tverifyNoMoreInteractions(filterChain, userThrottleGate, userFrequencyThrottleGate);\n \t}\n \n \t@Test\n \tpublic void testNotAnonymous() throws Exception {\n-\t\tMockHttpServletRequest request = new MockHttpServletRequest();\n-\t\trequest.setParameter(AuthorizationConstants.USER_ID_PARAM, \"111\");\n-\t\tMockHttpServletResponse response = new MockHttpServletResponse();\n-\t\tFilterChain filterChain = mock(FilterChain.class);\n+\t\twhen(userThrottleGate.attemptToAcquireLock(userId, CONCURRENT_CONNECTIONS_LOCK_TIMEOUT_SEC, MAX_CONCURRENT_LOCKS)).thenReturn(concurrentSemaphoreToken);\n+\t\twhen(userFrequencyThrottleGate.attemptToAcquireLock(userId, REQUEST_FREQUENCY_LOCK_TIMEOUT_SEC, MAX_REQUEST_FREQUENCY_LOCKS)).thenReturn(true);\n \n-\t\twhen(userThrottleGate.attemptToAcquireLock(\"111\", LOCK_TIMOUTE_SEC, MAX_CONCURRENT_LOCKS)).thenReturn(\"token\");\n \t\tfilter.doFilter(request, response, filterChain);\n \n \t\tverify(filterChain).doFilter(request, response);\n-\t\tverify(userThrottleGate).attemptToAcquireLock(\"111\", LOCK_TIMOUTE_SEC, MAX_CONCURRENT_LOCKS);\n-\t\tverify(userThrottleGate).releaseLock(\"111\", \"token\");\n-\t\tverifyNoMoreInteractions(filterChain, userThrottleGate);\n+\t\tverify(userThrottleGate).attemptToAcquireLock(userId, CONCURRENT_CONNECTIONS_LOCK_TIMEOUT_SEC, MAX_CONCURRENT_LOCKS);\n+\t\tverify(userFrequencyThrottleGate).attemptToAcquireLock(userId, REQUEST_FREQUENCY_LOCK_TIMEOUT_SEC, MAX_REQUEST_FREQUENCY_LOCKS);\n+\n+\t\tverify(userThrottleGate).releaseLock(userId, concurrentSemaphoreToken);\n+\t\t\n+\t\tverifyNoMoreInteractions(filterChain, userThrottleGate, userFrequencyThrottleGate);\n \t}\n \n \t@Test(expected = ServletException.class)\n-\tpublic void testException() throws Exception {\n-\t\tMockHttpServletRequest request = new MockHttpServletRequest();\n-\t\trequest.setParameter(AuthorizationConstants.USER_ID_PARAM, \"111\");\n-\t\tMockHttpServletResponse response = new MockHttpServletResponse();\n-\t\tFilterChain filterChain = mock(FilterChain.class);\n-\n-\t\twhen(userThrottleGate.attemptToAcquireLock(\"111\", LOCK_TIMOUTE_SEC, MAX_CONCURRENT_LOCKS)).thenThrow(new RuntimeException());\n+\tpublic void testConcurrentConnectionsAcquireLockException() throws Exception {\n+\t\twhen(userThrottleGate.attemptToAcquireLock(userId, CONCURRENT_CONNECTIONS_LOCK_TIMEOUT_SEC, MAX_CONCURRENT_LOCKS)).thenThrow(new RuntimeException());\n \t\ttry {\n \t\t\tfilter.doFilter(request, response, filterChain);\n \t\t} finally {\n-\t\t\tverify(userThrottleGate).attemptToAcquireLock(\"111\", LOCK_TIMOUTE_SEC, MAX_CONCURRENT_LOCKS);\n-\t\t\tverifyNoMoreInteractions(filterChain, userThrottleGate);\n+\t\t\tverify(userThrottleGate).attemptToAcquireLock(userId, CONCURRENT_CONNECTIONS_LOCK_TIMEOUT_SEC, MAX_CONCURRENT_LOCKS);\n+\t\t\tverifyNoMoreInteractions(filterChain, userThrottleGate, userFrequencyThrottleGate);\n+\t\t}\n+\t}\n+\t\n+\t@Test(expected = ServletException.class)\n+\tpublic void testRequestFrequencyAcquireLockException() throws Exception {","path":"services/repository/src/test/java/org/sagebionetworks/repo/web/filter/UserThrottleFilterTest.java","position":132,"original_position":132,"commit_id":"936f35392be418dedbed46f8a6435604940cc026","original_commit_id":"936f35392be418dedbed46f8a6435604940cc026","user":{"login":"zimingd","id":8023327,"avatar_url":"https://avatars.githubusercontent.com/u/8023327?v=3","gravatar_id":"","url":"https://api.github.com/users/zimingd","html_url":"https://github.com/zimingd","followers_url":"https://api.github.com/users/zimingd/followers","following_url":"https://api.github.com/users/zimingd/following{/other_user}","gists_url":"https://api.github.com/users/zimingd/gists{/gist_id}","starred_url":"https://api.github.com/users/zimingd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zimingd/subscriptions","organizations_url":"https://api.github.com/users/zimingd/orgs","repos_url":"https://api.github.com/users/zimingd/repos","events_url":"https://api.github.com/users/zimingd/events{/privacy}","received_events_url":"https://api.github.com/users/zimingd/received_events","type":"User","site_admin":false},"body":"remove. method no longer throws exception","created_at":"2016-08-11T01:27:21Z","updated_at":"2016-08-11T01:27:21Z","html_url":"https://github.com/Sage-Bionetworks/Synapse-Repository-Services/pull/2536#discussion_r74359629","pull_request_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/pulls/2536","_links":{"self":{"href":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/pulls/comments/74359629"},"html":{"href":"https://github.com/Sage-Bionetworks/Synapse-Repository-Services/pull/2536#discussion_r74359629"},"pull_request":{"href":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/pulls/2536"}}},"pull_request":{"url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/pulls/2536","id":80857044,"html_url":"https://github.com/Sage-Bionetworks/Synapse-Repository-Services/pull/2536","diff_url":"https://github.com/Sage-Bionetworks/Synapse-Repository-Services/pull/2536.diff","patch_url":"https://github.com/Sage-Bionetworks/Synapse-Repository-Services/pull/2536.patch","issue_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/issues/2536","number":2536,"state":"open","locked":false,"title":"PLFM-3981","user":{"login":"zimingd","id":8023327,"avatar_url":"https://avatars.githubusercontent.com/u/8023327?v=3","gravatar_id":"","url":"https://api.github.com/users/zimingd","html_url":"https://github.com/zimingd","followers_url":"https://api.github.com/users/zimingd/followers","following_url":"https://api.github.com/users/zimingd/following{/other_user}","gists_url":"https://api.github.com/users/zimingd/gists{/gist_id}","starred_url":"https://api.github.com/users/zimingd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zimingd/subscriptions","organizations_url":"https://api.github.com/users/zimingd/orgs","repos_url":"https://api.github.com/users/zimingd/repos","events_url":"https://api.github.com/users/zimingd/events{/privacy}","received_events_url":"https://api.github.com/users/zimingd/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-08-10T19:57:25Z","updated_at":"2016-08-11T01:27:21Z","closed_at":null,"merged_at":null,"merge_commit_sha":"60ad8ceb3168c91b2f0645b86bb7724783a311c1","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/pulls/2536/commits","review_comments_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/pulls/2536/comments","review_comment_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/issues/2536/comments","statuses_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/statuses/936f35392be418dedbed46f8a6435604940cc026","head":{"label":"zimingd:release-147","ref":"release-147","sha":"936f35392be418dedbed46f8a6435604940cc026","user":{"login":"zimingd","id":8023327,"avatar_url":"https://avatars.githubusercontent.com/u/8023327?v=3","gravatar_id":"","url":"https://api.github.com/users/zimingd","html_url":"https://github.com/zimingd","followers_url":"https://api.github.com/users/zimingd/followers","following_url":"https://api.github.com/users/zimingd/following{/other_user}","gists_url":"https://api.github.com/users/zimingd/gists{/gist_id}","starred_url":"https://api.github.com/users/zimingd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zimingd/subscriptions","organizations_url":"https://api.github.com/users/zimingd/orgs","repos_url":"https://api.github.com/users/zimingd/repos","events_url":"https://api.github.com/users/zimingd/events{/privacy}","received_events_url":"https://api.github.com/users/zimingd/received_events","type":"User","site_admin":false},"repo":{"id":62755099,"name":"Synapse-Repository-Services","full_name":"zimingd/Synapse-Repository-Services","owner":{"login":"zimingd","id":8023327,"avatar_url":"https://avatars.githubusercontent.com/u/8023327?v=3","gravatar_id":"","url":"https://api.github.com/users/zimingd","html_url":"https://github.com/zimingd","followers_url":"https://api.github.com/users/zimingd/followers","following_url":"https://api.github.com/users/zimingd/following{/other_user}","gists_url":"https://api.github.com/users/zimingd/gists{/gist_id}","starred_url":"https://api.github.com/users/zimingd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zimingd/subscriptions","organizations_url":"https://api.github.com/users/zimingd/orgs","repos_url":"https://api.github.com/users/zimingd/repos","events_url":"https://api.github.com/users/zimingd/events{/privacy}","received_events_url":"https://api.github.com/users/zimingd/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/zimingd/Synapse-Repository-Services","description":"The Synapse Repository Services project is the home of the JSON REST web services for Synapse.","fork":true,"url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services","forks_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/forks","keys_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/teams","hooks_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/hooks","issue_events_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/issues/events{/number}","events_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/events","assignees_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/assignees{/user}","branches_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/branches{/branch}","tags_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/tags","blobs_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/git/refs{/sha}","trees_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/statuses/{sha}","languages_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/languages","stargazers_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/stargazers","contributors_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/contributors","subscribers_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/subscribers","subscription_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/subscription","commits_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/commits{/sha}","git_commits_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/git/commits{/sha}","comments_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/comments{/number}","issue_comment_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/issues/comments{/number}","contents_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/contents/{+path}","compare_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/merges","archive_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/downloads","issues_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/issues{/number}","pulls_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/pulls{/number}","milestones_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/milestones{/number}","notifications_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/labels{/name}","releases_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/releases{/id}","deployments_url":"https://api.github.com/repos/zimingd/Synapse-Repository-Services/deployments","created_at":"2016-07-06T21:40:17Z","updated_at":"2016-07-06T21:40:26Z","pushed_at":"2016-08-10T23:43:29Z","git_url":"git://github.com/zimingd/Synapse-Repository-Services.git","ssh_url":"git@github.com:zimingd/Synapse-Repository-Services.git","clone_url":"https://github.com/zimingd/Synapse-Repository-Services.git","svn_url":"https://github.com/zimingd/Synapse-Repository-Services","homepage":null,"size":61878,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"develop"}},"base":{"label":"Sage-Bionetworks:release-147","ref":"release-147","sha":"590aa0fbab47bd6ac9b6bd26f01821bafdc583cb","user":{"login":"Sage-Bionetworks","id":1250897,"avatar_url":"https://avatars.githubusercontent.com/u/1250897?v=3","gravatar_id":"","url":"https://api.github.com/users/Sage-Bionetworks","html_url":"https://github.com/Sage-Bionetworks","followers_url":"https://api.github.com/users/Sage-Bionetworks/followers","following_url":"https://api.github.com/users/Sage-Bionetworks/following{/other_user}","gists_url":"https://api.github.com/users/Sage-Bionetworks/gists{/gist_id}","starred_url":"https://api.github.com/users/Sage-Bionetworks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Sage-Bionetworks/subscriptions","organizations_url":"https://api.github.com/users/Sage-Bionetworks/orgs","repos_url":"https://api.github.com/users/Sage-Bionetworks/repos","events_url":"https://api.github.com/users/Sage-Bionetworks/events{/privacy}","received_events_url":"https://api.github.com/users/Sage-Bionetworks/received_events","type":"Organization","site_admin":false},"repo":{"id":4400676,"name":"Synapse-Repository-Services","full_name":"Sage-Bionetworks/Synapse-Repository-Services","owner":{"login":"Sage-Bionetworks","id":1250897,"avatar_url":"https://avatars.githubusercontent.com/u/1250897?v=3","gravatar_id":"","url":"https://api.github.com/users/Sage-Bionetworks","html_url":"https://github.com/Sage-Bionetworks","followers_url":"https://api.github.com/users/Sage-Bionetworks/followers","following_url":"https://api.github.com/users/Sage-Bionetworks/following{/other_user}","gists_url":"https://api.github.com/users/Sage-Bionetworks/gists{/gist_id}","starred_url":"https://api.github.com/users/Sage-Bionetworks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Sage-Bionetworks/subscriptions","organizations_url":"https://api.github.com/users/Sage-Bionetworks/orgs","repos_url":"https://api.github.com/users/Sage-Bionetworks/repos","events_url":"https://api.github.com/users/Sage-Bionetworks/events{/privacy}","received_events_url":"https://api.github.com/users/Sage-Bionetworks/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Sage-Bionetworks/Synapse-Repository-Services","description":"The Synapse Repository Services project is the home of the JSON REST web services for Synapse.","fork":false,"url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services","forks_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/forks","keys_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/teams","hooks_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/hooks","issue_events_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/issues/events{/number}","events_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/events","assignees_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/assignees{/user}","branches_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/branches{/branch}","tags_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/tags","blobs_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/git/refs{/sha}","trees_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/statuses/{sha}","languages_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/languages","stargazers_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/stargazers","contributors_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/contributors","subscribers_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/subscribers","subscription_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/subscription","commits_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/commits{/sha}","git_commits_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/git/commits{/sha}","comments_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/comments{/number}","issue_comment_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/issues/comments{/number}","contents_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/contents/{+path}","compare_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/merges","archive_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/downloads","issues_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/issues{/number}","pulls_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/pulls{/number}","milestones_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/milestones{/number}","notifications_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/labels{/name}","releases_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/releases{/id}","deployments_url":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/deployments","created_at":"2012-05-22T01:06:50Z","updated_at":"2016-06-22T01:28:11Z","pushed_at":"2016-08-11T00:01:00Z","git_url":"git://github.com/Sage-Bionetworks/Synapse-Repository-Services.git","ssh_url":"git@github.com:Sage-Bionetworks/Synapse-Repository-Services.git","clone_url":"https://github.com/Sage-Bionetworks/Synapse-Repository-Services.git","svn_url":"https://github.com/Sage-Bionetworks/Synapse-Repository-Services","homepage":null,"size":63201,"stargazers_count":21,"watchers_count":21,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":27,"mirror_url":null,"open_issues_count":3,"forks":27,"open_issues":3,"watchers":21,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/pulls/2536"},"html":{"href":"https://github.com/Sage-Bionetworks/Synapse-Repository-Services/pull/2536"},"issue":{"href":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/issues/2536"},"comments":{"href":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/issues/2536/comments"},"review_comments":{"href":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/pulls/2536/comments"},"review_comment":{"href":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/pulls/2536/commits"},"statuses":{"href":"https://api.github.com/repos/Sage-Bionetworks/Synapse-Repository-Services/statuses/936f35392be418dedbed46f8a6435604940cc026"}}}}
{"actor":{"display_login":"zimingd"}}