{"action":"created","comment":{"url":"https://api.github.com/repos/paypal/squbs/pulls/comments/140059240","pull_request_review_id":64078397,"id":140059240,"diff_hunk":"@@ -0,0 +1,307 @@\n+/*\n+ * Copyright 2017 PayPal\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ * http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+package org.squbs.streams\n+\n+import java.util.Optional\n+\n+import akka.NotUsed\n+import akka.http.org.squbs.util.JavaConverters\n+import akka.japi.Pair\n+import akka.stream.Attributes.InputBuffer\n+import akka.stream.scaladsl.{BidiFlow, Flow}\n+import akka.stream.stage._\n+import akka.stream._\n+import akka.stream.OverflowStrategy._\n+\n+import scala.collection.mutable\n+import scala.util.{Failure, Try}\n+\n+object RetryBidi {\n+  /**\n+    * Creates a [[BidiFlow]] that can be used to provide Retry functionality.\n+    * This API is specifically for flows that are using [[Try]]'s for elements that may occasionally fail.  By default,\n+    * any [[Failure]] is considered a failure that should be retried. However, a failureDecider function can be\n+    * specified to control what constitutes a failure.\n+    *\n+    * Retry functionality requires each element passing through this flow to be uniquely identifiable for retrying, so\n+    * it requires a [[Context]], of any type carried along with the flow's input and output element as a\n+    * [[Tuple2]] (Scala) or [[Pair]] (Java).  The requirement is that either the [[Context]] type itself or a mapping\n+    * from [[Context]] should be able to uniquely identify each element passing through flow.\n+    *\n+    * Here are the ways a unique id can be provided:\n+    *\n+    *   - [[Context]] itself is a type that can be used as a unique id, e.g., [[Int]], [[Long]], [[java.util.UUID]]\n+    *   - [[Context]] extends [[UniqueId.Provider]] and implements [[UniqueId.Provider.uniqueId]] method\n+    *   - [[Context]] is of type [[UniqueId.Envelope]]\n+    *   - [[Context]] can be mapped to a unique id by calling {{{uniqueIdMapper}}}\n+    *\n+    * This stage supports a default in-flight maximum number of elements based on stage Attribute InputBuffer max.\n+    * This maximum buffer size includes all elements currently failing (and being re-tried) as well as any elements\n+    * in-flight.  To increase this size you can update the stage attribute max value for InputBuffer.\n+    *\n+    * @param maxRetries     the maximum number of retry attempts on any failures before giving up.\n+    * @param uniqueIdMapper the function that maps [[Context]] to a unique id\n+    * @param failureDecider function to determine if an element passed by the joined [[Flow]] is\n+    *                       actually a failure or not\n+    * @param overflowStrategy the overflowStrategy to use on Retry buffer filling\n+    * @tparam In      the type of elements pulled from upstream along with the [[Context]]\n+    * @tparam Out     the type of the elements that are pushed to downstream along with the [[Context]]\n+    * @tparam Context the type of the context that is carried along with the elements.\n+    * @return a [[BidiFlow]] with Retry functionality\n+    */\n+  def apply[In, Out, Context](maxRetries: Long, uniqueIdMapper: Context => Option[Any] = (_: Any) => None,\n+                              failureDecider: Option[Try[Out] => Boolean] = None,\n+                              overflowStrategy: OverflowStrategy = OverflowStrategy.backpressure):\n+  BidiFlow[(In, Context), (In, Context), (Try[Out], Context), (Try[Out], Context), NotUsed] =\n+    BidiFlow.fromGraph(new RetryBidi(maxRetries, uniqueIdMapper, failureDecider, overflowStrategy))\n+\n+  import scala.compat.java8.OptionConverters._\n+  /**\n+    * Java API\n+    * Creates a [[akka.stream.javadsl.BidiFlow]] that can be joined with a [[akka.stream.javadsl.Flow]] to add\n+    * Retry functionality with uniqueIdMapper, custom failure decider and OverflowStrategy.\n+    */\n+  def create[In, Out, Context](maxRetries: Long, uniqueIdMapper: java.util.function.Function[Context, Optional[Any]],\n+                               failureDecider: Optional[java.util.function.Function[Try[Out], Boolean]],\n+                               overflowStrategy: OverflowStrategy):\n+  javadsl.BidiFlow[Pair[In, Context], Pair[In, Context], Pair[Try[Out], Context], Pair[Try[Out], Context], NotUsed] =\n+    JavaConverters.toJava(apply[In, Out, Context](maxRetries,\n+      uniqueIdMapper = UniqueId.javaUniqueIdMapperAsScala(uniqueIdMapper),\n+      failureDecider = failureDecider.asScala.map(f => (out: Try[Out]) => f(out)),\n+      overflowStrategy))\n+\n+  /**\n+    * Java API\n+    * @see above for details about each parameter\n+    */\n+  def create[In, Out, Context](maxRetries: Long,\n+                               failureDecider: Optional[java.util.function.Function[Try[Out], Boolean]],\n+                               overflowStrategy: OverflowStrategy):\n+  javadsl.BidiFlow[Pair[In, Context], Pair[In, Context], Pair[Try[Out], Context], Pair[Try[Out], Context], NotUsed] =\n+    JavaConverters.toJava(apply[In, Out, Context](maxRetries,\n+      failureDecider = failureDecider.asScala.map(f => (out: Try[Out]) => f(out)),\n+      overflowStrategy = overflowStrategy))\n+\n+  /**\n+    * Java API\n+    * @see above for details about each parameter.\n+    */\n+  def create[In, Out, Context](maxRetries: Long, uniqueIdMapper: java.util.function.Function[Context, Optional[Any]],\n+                               overflowStrategy: OverflowStrategy):\n+  javadsl.BidiFlow[Pair[In, Context], Pair[In, Context], Pair[Try[Out], Context], Pair[Try[Out], Context], NotUsed] =\n+    JavaConverters.toJava(apply[In, Out, Context](maxRetries,\n+      uniqueIdMapper = UniqueId.javaUniqueIdMapperAsScala(uniqueIdMapper),\n+      overflowStrategy = overflowStrategy))\n+\n+  /**\n+    * Java API\n+    * @see above for details about each parameter.\n+    */\n+  def create[In, Out, Context](maxRetries: Long):\n+  javadsl.BidiFlow[Pair[In, Context], Pair[In, Context], Pair[Try[Out], Context], Pair[Try[Out], Context], NotUsed] =\n+    JavaConverters.toJava(apply[In, Out, Context](maxRetries))\n+}\n+\n+/**\n+  * A bidi [[GraphStage]] that can be joined with flows that produce [[Try]]'s to add Retry functionality\n+  * when there are any failures.  When the joined [[Flow]] has a failure then based on the provided\n+  * max retries count, it will retry the failures.\n+  *\n+  * '''Emits when''' a Success is available from joined flow or a failure has been retried the maximum number of retries\n+  *\n+  * '''Backpressures when''' the element is not a failure and downstream backpressures or the retry buffer is full\n+  *\n+  * '''Completes when''' upstream completes\n+  *\n+  * '''Cancels when''' downstream cancels\n+  *\n+  * {{{\n+  *          upstream      +------+      downstream\n+  *       (In, Context) ~> |      | ~> (In, Context)\n+  *            In1         | bidi |        Out1\n+  * (Try[Out], Context) <~ |      | <~ (Try[Out], Context)\n+  *           Out2         +------+        In2\n+  * }}}\n+  *\n+  * @param maxRetries maximum number of retry attempts on any failing [[Try]]'s\n+  * @param uniqueIdMapper function that maps a [[Context]] to a unique value per element\n+  * @param failureDecider function that gets called to determine if an element passed by the joined [[Flow]] is a\n+  *                       failure\n+  * @tparam In the type of elements pulled from the upstream along with the [[Context]]\n+  * @tparam Out the type of the elements that are pushed by the joined [[Flow]] along with the [[Context]].\n+  *             This then gets wrapped with a [[Try]] and pushed downstream with a [[Context]]\n+  * @tparam Context the type of the context that is carried around along with the elements.\n+  */\n+final class RetryBidi[In, Out, Context] private[streams](maxRetries: Long, uniqueIdMapper: Context => Option[Any],\n+                                                         failureDecider: Option[Try[Out] => Boolean] = None,\n+                                                         strategy: OverflowStrategy = OverflowStrategy.backpressure)\n+  extends GraphStage[BidiShape[(In, Context), (In, Context), (Try[Out], Context), (Try[Out], Context)]] {\n+\n+  require(maxRetries > 0)\n+\n+  private val in1 = Inlet[(In, Context)](\"RetryBidi.in1\")\n+  private val out1 = Outlet[(In, Context)](\"RetryBidi.out1\")\n+  private val in2 = Inlet[(Try[Out], Context)](\"RetryBidi.in2\")\n+  private val out2 = Outlet[(Try[Out], Context)](\"RetryBidi.out2\")\n+  override val shape = BidiShape(in1, out1, in2, out2)\n+\n+  private[streams] def uniqueId(context: Context) =\n+    uniqueIdMapper(context).getOrElse {\n+      context match {\n+        case uniqueIdProvider: UniqueId.Provider ⇒ uniqueIdProvider.uniqueId\n+        case `context` ⇒ `context`\n+      }\n+    }\n+\n+  private[streams] val isFailure = failureDecider.getOrElse((e: Try[Out]) => e.isFailure)\n+\n+  override def createLogic(inheritedAttributes: Attributes): GraphStageLogic = new GraphStageLogic(shape)\n+    with StageLogging {\n+\n+    val internalBufferSize: Int =\n+      inheritedAttributes.get[InputBuffer] match {\n+        case None ⇒ throw new IllegalStateException(s\"Couldn't find InputBuffer Attribute for $this\")\n+        case Some(InputBuffer(_, max)) ⇒ max\n+      }\n+\n+    // A map of all the in flight (including failed) in elements with their retry count (bounded by size)\n+    private val retryRegistry = mutable.LinkedHashMap.empty[Any, (In, Context, Long)]\n+    private val readyToRetry = mutable.Queue.empty[(In, Context)] // Queue of elements ready to be emitted on out1\n+    private var upstreamFinished = false","path":"squbs-ext/src/main/scala/org/squbs/streams/RetryBidi.scala","position":184,"original_position":184,"commit_id":"1b8e8325c52a5e0da6546fc0a77696b10ed2200a","original_commit_id":"1b8e8325c52a5e0da6546fc0a77696b10ed2200a","user":{"login":"codacy-bot","id":19940114,"avatar_url":"https://avatars1.githubusercontent.com/u/19940114?v=4","gravatar_id":"","url":"https://api.github.com/users/codacy-bot","html_url":"https://github.com/codacy-bot","followers_url":"https://api.github.com/users/codacy-bot/followers","following_url":"https://api.github.com/users/codacy-bot/following{/other_user}","gists_url":"https://api.github.com/users/codacy-bot/gists{/gist_id}","starred_url":"https://api.github.com/users/codacy-bot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codacy-bot/subscriptions","organizations_url":"https://api.github.com/users/codacy-bot/orgs","repos_url":"https://api.github.com/users/codacy-bot/repos","events_url":"https://api.github.com/users/codacy-bot/events{/privacy}","received_events_url":"https://api.github.com/users/codacy-bot/received_events","type":"User","site_admin":false},"body":"![Codacy](https://www.codacy.com/assets/images/favicon.png) Issue found: [Avoid mutable fields](https://www.codacy.com/app/akara-sucharitakul/squbs/pullRequest?prid=808722)","created_at":"2017-09-20T18:48:38Z","updated_at":"2017-09-20T18:48:38Z","html_url":"https://github.com/paypal/squbs/pull/486#discussion_r140059240","pull_request_url":"https://api.github.com/repos/paypal/squbs/pulls/486","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/paypal/squbs/pulls/comments/140059240"},"html":{"href":"https://github.com/paypal/squbs/pull/486#discussion_r140059240"},"pull_request":{"href":"https://api.github.com/repos/paypal/squbs/pulls/486"}}},"pull_request":{"url":"https://api.github.com/repos/paypal/squbs/pulls/486","id":133280666,"html_url":"https://github.com/paypal/squbs/pull/486","diff_url":"https://github.com/paypal/squbs/pull/486.diff","patch_url":"https://github.com/paypal/squbs/pull/486.patch","issue_url":"https://api.github.com/repos/paypal/squbs/issues/486","number":486,"state":"open","locked":false,"title":"Retry stage 417","user":{"login":"sebady","id":1269980,"avatar_url":"https://avatars1.githubusercontent.com/u/1269980?v=4","gravatar_id":"","url":"https://api.github.com/users/sebady","html_url":"https://github.com/sebady","followers_url":"https://api.github.com/users/sebady/followers","following_url":"https://api.github.com/users/sebady/following{/other_user}","gists_url":"https://api.github.com/users/sebady/gists{/gist_id}","starred_url":"https://api.github.com/users/sebady/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sebady/subscriptions","organizations_url":"https://api.github.com/users/sebady/orgs","repos_url":"https://api.github.com/users/sebady/repos","events_url":"https://api.github.com/users/sebady/events{/privacy}","received_events_url":"https://api.github.com/users/sebady/received_events","type":"User","site_admin":false},"body":"Thanks for your pull request.  Please review the following guidelines.\r\n\r\n- [x] Title includes issue id.\r\n- [x] Description of the change added.\r\n- [x] Commits are squashed.\r\n- [x] Tests added.\r\n- [x] Documentation added/updated.\r\n- [ ] Also please review [CONTRIBUTING.md](https://github.com/paypal/squbs/blob/master/CONTRIBUTING.md).\r\n","created_at":"2017-07-31T16:00:20Z","updated_at":"2017-09-20T18:48:38Z","closed_at":null,"merged_at":null,"merge_commit_sha":"fc61caa995d7a83c1c348c00ab07e67cbcbe1315","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/paypal/squbs/pulls/486/commits","review_comments_url":"https://api.github.com/repos/paypal/squbs/pulls/486/comments","review_comment_url":"https://api.github.com/repos/paypal/squbs/pulls/comments{/number}","comments_url":"https://api.github.com/repos/paypal/squbs/issues/486/comments","statuses_url":"https://api.github.com/repos/paypal/squbs/statuses/1b8e8325c52a5e0da6546fc0a77696b10ed2200a","head":{"label":"sebady:patch-sebady-417","ref":"patch-sebady-417","sha":"1b8e8325c52a5e0da6546fc0a77696b10ed2200a","user":{"login":"sebady","id":1269980,"avatar_url":"https://avatars1.githubusercontent.com/u/1269980?v=4","gravatar_id":"","url":"https://api.github.com/users/sebady","html_url":"https://github.com/sebady","followers_url":"https://api.github.com/users/sebady/followers","following_url":"https://api.github.com/users/sebady/following{/other_user}","gists_url":"https://api.github.com/users/sebady/gists{/gist_id}","starred_url":"https://api.github.com/users/sebady/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sebady/subscriptions","organizations_url":"https://api.github.com/users/sebady/orgs","repos_url":"https://api.github.com/users/sebady/repos","events_url":"https://api.github.com/users/sebady/events{/privacy}","received_events_url":"https://api.github.com/users/sebady/received_events","type":"User","site_admin":false},"repo":{"id":80593288,"name":"squbs","full_name":"sebady/squbs","owner":{"login":"sebady","id":1269980,"avatar_url":"https://avatars1.githubusercontent.com/u/1269980?v=4","gravatar_id":"","url":"https://api.github.com/users/sebady","html_url":"https://github.com/sebady","followers_url":"https://api.github.com/users/sebady/followers","following_url":"https://api.github.com/users/sebady/following{/other_user}","gists_url":"https://api.github.com/users/sebady/gists{/gist_id}","starred_url":"https://api.github.com/users/sebady/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sebady/subscriptions","organizations_url":"https://api.github.com/users/sebady/orgs","repos_url":"https://api.github.com/users/sebady/repos","events_url":"https://api.github.com/users/sebady/events{/privacy}","received_events_url":"https://api.github.com/users/sebady/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/sebady/squbs","description":"Akka/Spray for Large-Scale Production Deployments","fork":true,"url":"https://api.github.com/repos/sebady/squbs","forks_url":"https://api.github.com/repos/sebady/squbs/forks","keys_url":"https://api.github.com/repos/sebady/squbs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sebady/squbs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sebady/squbs/teams","hooks_url":"https://api.github.com/repos/sebady/squbs/hooks","issue_events_url":"https://api.github.com/repos/sebady/squbs/issues/events{/number}","events_url":"https://api.github.com/repos/sebady/squbs/events","assignees_url":"https://api.github.com/repos/sebady/squbs/assignees{/user}","branches_url":"https://api.github.com/repos/sebady/squbs/branches{/branch}","tags_url":"https://api.github.com/repos/sebady/squbs/tags","blobs_url":"https://api.github.com/repos/sebady/squbs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sebady/squbs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sebady/squbs/git/refs{/sha}","trees_url":"https://api.github.com/repos/sebady/squbs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sebady/squbs/statuses/{sha}","languages_url":"https://api.github.com/repos/sebady/squbs/languages","stargazers_url":"https://api.github.com/repos/sebady/squbs/stargazers","contributors_url":"https://api.github.com/repos/sebady/squbs/contributors","subscribers_url":"https://api.github.com/repos/sebady/squbs/subscribers","subscription_url":"https://api.github.com/repos/sebady/squbs/subscription","commits_url":"https://api.github.com/repos/sebady/squbs/commits{/sha}","git_commits_url":"https://api.github.com/repos/sebady/squbs/git/commits{/sha}","comments_url":"https://api.github.com/repos/sebady/squbs/comments{/number}","issue_comment_url":"https://api.github.com/repos/sebady/squbs/issues/comments{/number}","contents_url":"https://api.github.com/repos/sebady/squbs/contents/{+path}","compare_url":"https://api.github.com/repos/sebady/squbs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sebady/squbs/merges","archive_url":"https://api.github.com/repos/sebady/squbs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sebady/squbs/downloads","issues_url":"https://api.github.com/repos/sebady/squbs/issues{/number}","pulls_url":"https://api.github.com/repos/sebady/squbs/pulls{/number}","milestones_url":"https://api.github.com/repos/sebady/squbs/milestones{/number}","notifications_url":"https://api.github.com/repos/sebady/squbs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sebady/squbs/labels{/name}","releases_url":"https://api.github.com/repos/sebady/squbs/releases{/id}","deployments_url":"https://api.github.com/repos/sebady/squbs/deployments","created_at":"2017-02-01T05:47:55Z","updated_at":"2017-02-01T05:47:57Z","pushed_at":"2017-09-20T18:42:09Z","git_url":"git://github.com/sebady/squbs.git","ssh_url":"git@github.com:sebady/squbs.git","clone_url":"https://github.com/sebady/squbs.git","svn_url":"https://github.com/sebady/squbs","homepage":"http://paypal.github.io/squbs","size":7014,"stargazers_count":0,"watchers_count":0,"language":"Scala","has_issues":false,"has_projects":true,"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":"master"}},"base":{"label":"paypal:master","ref":"master","sha":"e036f0f6b9224ce4f7e92fd6e95c4c369031cfa6","user":{"login":"paypal","id":476675,"avatar_url":"https://avatars1.githubusercontent.com/u/476675?v=4","gravatar_id":"","url":"https://api.github.com/users/paypal","html_url":"https://github.com/paypal","followers_url":"https://api.github.com/users/paypal/followers","following_url":"https://api.github.com/users/paypal/following{/other_user}","gists_url":"https://api.github.com/users/paypal/gists{/gist_id}","starred_url":"https://api.github.com/users/paypal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paypal/subscriptions","organizations_url":"https://api.github.com/users/paypal/orgs","repos_url":"https://api.github.com/users/paypal/repos","events_url":"https://api.github.com/users/paypal/events{/privacy}","received_events_url":"https://api.github.com/users/paypal/received_events","type":"Organization","site_admin":false},"repo":{"id":38714007,"name":"squbs","full_name":"paypal/squbs","owner":{"login":"paypal","id":476675,"avatar_url":"https://avatars1.githubusercontent.com/u/476675?v=4","gravatar_id":"","url":"https://api.github.com/users/paypal","html_url":"https://github.com/paypal","followers_url":"https://api.github.com/users/paypal/followers","following_url":"https://api.github.com/users/paypal/following{/other_user}","gists_url":"https://api.github.com/users/paypal/gists{/gist_id}","starred_url":"https://api.github.com/users/paypal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paypal/subscriptions","organizations_url":"https://api.github.com/users/paypal/orgs","repos_url":"https://api.github.com/users/paypal/repos","events_url":"https://api.github.com/users/paypal/events{/privacy}","received_events_url":"https://api.github.com/users/paypal/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/paypal/squbs","description":"Akka/Akka HTTP for Large-Scale Production Deployments","fork":false,"url":"https://api.github.com/repos/paypal/squbs","forks_url":"https://api.github.com/repos/paypal/squbs/forks","keys_url":"https://api.github.com/repos/paypal/squbs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/paypal/squbs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/paypal/squbs/teams","hooks_url":"https://api.github.com/repos/paypal/squbs/hooks","issue_events_url":"https://api.github.com/repos/paypal/squbs/issues/events{/number}","events_url":"https://api.github.com/repos/paypal/squbs/events","assignees_url":"https://api.github.com/repos/paypal/squbs/assignees{/user}","branches_url":"https://api.github.com/repos/paypal/squbs/branches{/branch}","tags_url":"https://api.github.com/repos/paypal/squbs/tags","blobs_url":"https://api.github.com/repos/paypal/squbs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/paypal/squbs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/paypal/squbs/git/refs{/sha}","trees_url":"https://api.github.com/repos/paypal/squbs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/paypal/squbs/statuses/{sha}","languages_url":"https://api.github.com/repos/paypal/squbs/languages","stargazers_url":"https://api.github.com/repos/paypal/squbs/stargazers","contributors_url":"https://api.github.com/repos/paypal/squbs/contributors","subscribers_url":"https://api.github.com/repos/paypal/squbs/subscribers","subscription_url":"https://api.github.com/repos/paypal/squbs/subscription","commits_url":"https://api.github.com/repos/paypal/squbs/commits{/sha}","git_commits_url":"https://api.github.com/repos/paypal/squbs/git/commits{/sha}","comments_url":"https://api.github.com/repos/paypal/squbs/comments{/number}","issue_comment_url":"https://api.github.com/repos/paypal/squbs/issues/comments{/number}","contents_url":"https://api.github.com/repos/paypal/squbs/contents/{+path}","compare_url":"https://api.github.com/repos/paypal/squbs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/paypal/squbs/merges","archive_url":"https://api.github.com/repos/paypal/squbs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/paypal/squbs/downloads","issues_url":"https://api.github.com/repos/paypal/squbs/issues{/number}","pulls_url":"https://api.github.com/repos/paypal/squbs/pulls{/number}","milestones_url":"https://api.github.com/repos/paypal/squbs/milestones{/number}","notifications_url":"https://api.github.com/repos/paypal/squbs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/paypal/squbs/labels{/name}","releases_url":"https://api.github.com/repos/paypal/squbs/releases{/id}","deployments_url":"https://api.github.com/repos/paypal/squbs/deployments","created_at":"2015-07-07T20:48:12Z","updated_at":"2017-09-20T00:53:03Z","pushed_at":"2017-09-20T18:42:12Z","git_url":"git://github.com/paypal/squbs.git","ssh_url":"git@github.com:paypal/squbs.git","clone_url":"https://github.com/paypal/squbs.git","svn_url":"https://github.com/paypal/squbs","homepage":"http://paypal.github.io/squbs","size":6969,"stargazers_count":942,"watchers_count":942,"language":"Scala","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":161,"mirror_url":null,"open_issues_count":52,"forks":161,"open_issues":52,"watchers":942,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/paypal/squbs/pulls/486"},"html":{"href":"https://github.com/paypal/squbs/pull/486"},"issue":{"href":"https://api.github.com/repos/paypal/squbs/issues/486"},"comments":{"href":"https://api.github.com/repos/paypal/squbs/issues/486/comments"},"review_comments":{"href":"https://api.github.com/repos/paypal/squbs/pulls/486/comments"},"review_comment":{"href":"https://api.github.com/repos/paypal/squbs/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/paypal/squbs/pulls/486/commits"},"statuses":{"href":"https://api.github.com/repos/paypal/squbs/statuses/1b8e8325c52a5e0da6546fc0a77696b10ed2200a"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"codacy-bot"}}