aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorszimano <szimano@szimano.org>2018-03-19 12:41:31 -0400
committerszimano <szimano@szimano.org>2018-03-19 12:41:31 -0400
commit1eec6fa34ac69311ee5c70d9dc3a2deb463673e6 (patch)
treef758a30c80a0a1ca2c9498dfcc9f295f7c803f25
parent27f2822ba560d6a897b2425d14210e761c32a911 (diff)
downloadsttp-1eec6fa34ac69311ee5c70d9dc3a2deb463673e6.tar.gz
sttp-1eec6fa34ac69311ee5c70d9dc3a2deb463673e6.tar.bz2
sttp-1eec6fa34ac69311ee5c70d9dc3a2deb463673e6.zip
hystrix take 2
-rw-r--r--build.sbt12
-rw-r--r--circuit-breaker/hystrix-backend/src/main/scala/com/softwaremill/sttp/hystrix/HystrixBackend.scala33
-rw-r--r--circuit-breaker/hystrix-backend/src/test/scala/com/softwaremill/sttp/hystrix/HystrixBackendTest.scala32
3 files changed, 77 insertions, 0 deletions
diff --git a/build.sbt b/build.sbt
index c4331fe..b218909 100644
--- a/build.sbt
+++ b/build.sbt
@@ -59,6 +59,7 @@ lazy val rootProject = (project in file("."))
json4s,
braveBackend,
prometheusBackend,
+ hystrixBackend,
tests
)
@@ -203,6 +204,17 @@ lazy val prometheusBackend: Project = (project in file("metrics/prometheus-backe
)
.dependsOn(core)
+lazy val hystrixBackend: Project = (project in file("circuit-breaker/hystrix-backend"))
+ .settings(commonSettings: _*)
+ .settings(
+ name := "hystrix-backend",
+ libraryDependencies ++= Seq(
+ "com.netflix.hystrix" % "hystrix-core" % "1.5.12",
+ scalaTest % "test"
+ )
+ )
+ .dependsOn(core)
+
lazy val tests: Project = (project in file("tests"))
.settings(commonSettings: _*)
.settings(
diff --git a/circuit-breaker/hystrix-backend/src/main/scala/com/softwaremill/sttp/hystrix/HystrixBackend.scala b/circuit-breaker/hystrix-backend/src/main/scala/com/softwaremill/sttp/hystrix/HystrixBackend.scala
new file mode 100644
index 0000000..bd57357
--- /dev/null
+++ b/circuit-breaker/hystrix-backend/src/main/scala/com/softwaremill/sttp/hystrix/HystrixBackend.scala
@@ -0,0 +1,33 @@
+package com.softwaremill.sttp.hystrix
+
+import com.netflix.hystrix.HystrixCommand.Setter
+import com.netflix.hystrix.{HystrixCommand, HystrixCommandGroupKey, HystrixCommandProperties}
+import com.softwaremill.sttp.{MonadError, Request, Response, SttpBackend}
+
+class HystrixBackend[R[_], S] private (delegate: SttpBackend[R, S]) extends SttpBackend[R, S] {
+
+ class SttpCMD[T](request: Request[T, S], delegate: SttpBackend[R, S])
+ extends HystrixCommand[R[Response[T]]](
+ Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("SttpCommand"))
+ .andCommandPropertiesDefaults(HystrixCommandProperties.Setter().withMetricsHealthSnapshotIntervalInMilliseconds(10))
+ ) {
+
+ override def run(): R[Response[T]] = delegate.send(request)
+ }
+
+ override def send[T](request: Request[T, S]): R[Response[T]] = {
+ new SttpCMD(request, delegate).execute()
+ }
+
+ override def close(): Unit = delegate.close()
+
+ /**
+ * The monad in which the responses are wrapped. Allows writing wrapper
+ * backends, which map/flatMap over the return value of [[send]].
+ */
+ override def responseMonad: MonadError[R] = delegate.responseMonad
+}
+
+object HystrixBackend {
+ def apply[R[_], S](delegate: SttpBackend[R, S]) = new HystrixBackend(delegate)
+} \ No newline at end of file
diff --git a/circuit-breaker/hystrix-backend/src/test/scala/com/softwaremill/sttp/hystrix/HystrixBackendTest.scala b/circuit-breaker/hystrix-backend/src/test/scala/com/softwaremill/sttp/hystrix/HystrixBackendTest.scala
new file mode 100644
index 0000000..15cc55a
--- /dev/null
+++ b/circuit-breaker/hystrix-backend/src/test/scala/com/softwaremill/sttp/hystrix/HystrixBackendTest.scala
@@ -0,0 +1,32 @@
+package com.softwaremill.sttp.prometheus
+
+import com.netflix.hystrix.{HystrixCommandKey, HystrixCommandMetrics}
+import com.softwaremill.sttp.hystrix.HystrixBackend
+import com.softwaremill.sttp.testing.SttpBackendStub
+import com.softwaremill.sttp.{HttpURLConnectionBackend, Id, sttp, _}
+import org.scalatest.concurrent.Eventually
+import org.scalatest.{BeforeAndAfter, FlatSpec, Matchers, OptionValues}
+
+class HystrixBackendTest extends FlatSpec with Matchers with BeforeAndAfter with Eventually with OptionValues {
+
+ before {
+ }
+
+ it should "use default hystrix commands" in {
+ // given
+ val backendStub = SttpBackendStub(HttpURLConnectionBackend()).whenAnyRequest.thenRespondOk()
+ val backend = HystrixBackend[Id, Nothing](backendStub)
+ val requestsNumber = 10
+
+ // when
+ (0 until requestsNumber).map(_ => backend.send(sttp.get(uri"http://127.0.0.1/foo"))).foreach(println)
+
+ // then
+ val metrics = HystrixCommandMetrics.getInstance(HystrixCommandKey.Factory.asKey("SttpCMD"))
+ println(metrics.getExecutionTimeMean)
+ println(metrics.getExecutionTimePercentile(10))
+ println(metrics.getHealthCounts)
+ println(metrics.getCommandGroup)
+ }
+
+}