Skip to content
This repository has been archived by the owner on Sep 29, 2023. It is now read-only.

Commit

Permalink
Retry requests (#19)
Browse files Browse the repository at this point in the history
* add "atoms" dependency
* retry
* export the variables to 
* mock the test IAMClientSpec
* update the version number 0.2.2 for future release
* update the read version
* correct README.md
  • Loading branch information
raychenon authored and dmitrykrivaltsevich committed Feb 21, 2017
1 parent 1dd0a36 commit 13ef3a7
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 12 deletions.
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Clients of this library don't need to change their code in order to protect endp
Configure libraries dependencies in your `build.sbt`:

```scala
libraryDependencies += "org.zalando" %% "play-zhewbacca" % "0.2.1"
libraryDependencies += "org.zalando" %% "play-zhewbacca" % "0.2.2"
```

To configure Development environment:
Expand Down Expand Up @@ -92,12 +92,18 @@ authorisation.iam.endpoint = "https://info.services.auth.zalando.com/oauth2/toke
# Maximum number of failures before opening the circuit
authorisation.iam.cb.maxFailures = 4
# Duration of time in milliseconds after which to consider a call a failure
# Duration in milliseconds after which to consider a call a failure
authorisation.iam.cb.callTimeout = 2000
# Duration of time in milliseconds after which to attempt to close the circuit
# Duration in milliseconds after which to attempt to close the circuit
authorisation.iam.cb.resetTimeout = 60000
# Maximum number of retries
authorisation.iam.maxRetries = 3
# Duration in milliseconds of the exponential backoff
authorisation.iam.retry.backoff.duration = 100
# IAMClient depends on Play internal WS client so it also has to be configured.
# The maximum time to wait when connecting to the remote host.
# Play's default is 120 seconds
Expand Down
20 changes: 12 additions & 8 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import scalariform.formatter.preferences._

val commonSettings = Seq(
organization := "org.zalando",
version := "0.2.1.1",
version := "0.2.2",
scalaVersion := "2.11.8",
scalacOptions := Seq("-unchecked", "-deprecation", "-encoding", "utf8"),
publishTo := {
Expand Down Expand Up @@ -34,19 +34,23 @@ lazy val testDependencies =

lazy val playDependencies =
Seq(
"com.typesafe.play" %% "play-json" % playFrameworkVersion,
"com.typesafe.play" %% "play-ws" % playFrameworkVersion,
"com.typesafe.play" %% "play" % playFrameworkVersion,
"com.typesafe.play" %% "play-test" % playFrameworkVersion % "test",
"com.typesafe.play" %% "play-specs2" % playFrameworkVersion % "test"
"com.typesafe.play" %% "play-json" % playFrameworkVersion,
"com.typesafe.play" %% "play-ws" % playFrameworkVersion,
"com.typesafe.play" %% "play" % playFrameworkVersion,
"com.typesafe.play" %% "play-test" % playFrameworkVersion % "test",
"com.typesafe.play" %% "play-specs2" % playFrameworkVersion % "test"
)

lazy val libraries =
Seq(
"io.zman" %% "atmos" % "2.1"
)

lazy val root = (project in file("."))
.settings(commonSettings: _*)
.settings(name := "play-Zhewbacca")
.settings(version := "0.2.1.1")
.settings(libraryDependencies ++= (testDependencies ++ playDependencies))
.settings(version := "0.2.2")
.settings(libraryDependencies ++= (testDependencies ++ playDependencies ++ libraries))
.settings(parallelExecution in Test := false)

// Define a special task which does not fail when any publish task fails for any module,
Expand Down
23 changes: 22 additions & 1 deletion src/main/scala/org/zalando/zhewbacca/IAMClient.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, Future}
import scala.util.control.NonFatal

import atmos.dsl._
import atmos.dsl.Slf4jSupport._

/**
* Retrieves TokenInfo for given OAuth2 token using IAM API.
*
Expand Down Expand Up @@ -57,6 +60,14 @@ class IAMClient @Inject() (
throw new IllegalArgumentException("Authorisation: Circuit Breaker reset timeout is not configured")
).millis

val breakerMaxRetries = config.getInt("authorisation.iam.maxRetries").getOrElse(
throw new IllegalArgumentException("Authorisation: Circuit Breaker max retries is not configured")
).attempts

val breakerRetryBackoff = config.getInt("authorisation.iam.retry.backoff.duration").getOrElse(
throw new IllegalArgumentException("Authorisation: Circuit Breaker the duration of exponential backoff is not configured")
).millis

lazy val breaker: CircuitBreaker = new CircuitBreaker(
actorSystem.scheduler,
breakerMaxFailures,
Expand All @@ -72,7 +83,11 @@ class IAMClient @Inject() (

override def apply(token: OAuth2Token): Future[Option[TokenInfo]] = {
breaker.withCircuitBreaker(
plugableMetrics.timing(ws.url(authEndpoint).withQueryString(("access_token", token.value)).get())
plugableMetrics.timing(
retryAsync(s"Calling $authEndpoint") {
ws.url(authEndpoint).withQueryString(("access_token", token.value)).get()
}
)
).map { response =>
response.status match {
case OK => Some(response.json.as[TokenInfo])
Expand All @@ -85,4 +100,10 @@ class IAMClient @Inject() (
}
}

implicit val retryRecover = retryFor { breakerMaxRetries } using {
exponentialBackoff { breakerRetryBackoff }
} monitorWith {
logger.logger onRetrying logNothing onInterrupted logWarning onAborted logError
}

}
2 changes: 2 additions & 0 deletions src/test/scala/org/zalando/zhewbacca/IAMClientSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ class IAMClientSpec extends Specification {
"authorisation.iam.cb.maxFailures" -> 4,
"authorisation.iam.cb.callTimeout" -> 2000,
"authorisation.iam.cb.resetTimeout" -> 60000,
"authorisation.iam.maxRetries" -> 3,
"authorisation.iam.retry.backoff.duration" -> 100,
"play.ws.timeout.connection" -> 2000,
"play.ws.timeout.idle" -> 2000,
"play.ws.timeout.request" -> 2000
Expand Down

0 comments on commit 13ef3a7

Please sign in to comment.