diff --git a/ratpack/pom.xml b/ratpack/pom.xml
index 7a75ec50b7..3f953b3ed0 100644
--- a/ratpack/pom.xml
+++ b/ratpack/pom.xml
@@ -40,16 +40,38 @@
ratpack-hikari
${ratpack.version}
+
+ io.ratpack
+ ratpack-hystrix
+ ${ratpack.version}
+
+
+ io.ratpack
+ ratpack-rx
+ ${ratpack.version}
+
io.ratpack
ratpack-test
${ratpack.version}
+ test
com.h2database
h2
1.4.193
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.3
+
+
+ org.apache.httpcomponents
+ httpcore
+ 4.4.6
+
diff --git a/ratpack/src/main/java/com/baeldung/hystrix/HystrixAsyncHttpCommand.java b/ratpack/src/main/java/com/baeldung/hystrix/HystrixAsyncHttpCommand.java
new file mode 100644
index 0000000000..a1a19150c3
--- /dev/null
+++ b/ratpack/src/main/java/com/baeldung/hystrix/HystrixAsyncHttpCommand.java
@@ -0,0 +1,54 @@
+package com.baeldung.hystrix;
+
+import com.netflix.hystrix.HystrixCommand;
+import com.netflix.hystrix.HystrixCommandGroupKey;
+import com.netflix.hystrix.HystrixCommandProperties;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.util.EntityUtils;
+
+import java.net.URI;
+import java.util.Collections;
+
+/**
+ * @author aiet
+ */
+public class HystrixAsyncHttpCommand extends HystrixCommand {
+
+ private URI uri;
+ private RequestConfig requestConfig;
+
+ HystrixAsyncHttpCommand(URI uri, int timeoutMillis) {
+ super(Setter
+ .withGroupKey(HystrixCommandGroupKey.Factory.asKey("hystrix-ratpack-async"))
+ .andCommandPropertiesDefaults(HystrixCommandProperties
+ .Setter()
+ .withExecutionTimeoutInMilliseconds(timeoutMillis)));
+ requestConfig = RequestConfig
+ .custom()
+ .setSocketTimeout(timeoutMillis)
+ .setConnectTimeout(timeoutMillis)
+ .setConnectionRequestTimeout(timeoutMillis)
+ .build();
+ this.uri = uri;
+ }
+
+ @Override
+ protected String run() throws Exception {
+ return EntityUtils.toString(HttpClientBuilder
+ .create()
+ .setDefaultRequestConfig(requestConfig)
+ .setDefaultHeaders(Collections.singleton(new BasicHeader("User-Agent", "Baeldung Blocking HttpClient")))
+ .build()
+ .execute(new HttpGet(uri))
+ .getEntity());
+ }
+
+ @Override
+ protected String getFallback() {
+ return "eugenp's async fallback profile";
+ }
+
+}
diff --git a/ratpack/src/main/java/com/baeldung/hystrix/HystrixReactiveHttpCommand.java b/ratpack/src/main/java/com/baeldung/hystrix/HystrixReactiveHttpCommand.java
new file mode 100644
index 0000000000..f9f85c705b
--- /dev/null
+++ b/ratpack/src/main/java/com/baeldung/hystrix/HystrixReactiveHttpCommand.java
@@ -0,0 +1,44 @@
+package com.baeldung.hystrix;
+
+import com.netflix.hystrix.HystrixCommandGroupKey;
+import com.netflix.hystrix.HystrixCommandProperties;
+import com.netflix.hystrix.HystrixObservableCommand;
+import ratpack.http.client.HttpClient;
+import ratpack.rx.RxRatpack;
+import rx.Observable;
+
+import java.net.URI;
+
+/**
+ * @author aiet
+ */
+public class HystrixReactiveHttpCommand extends HystrixObservableCommand {
+
+ private HttpClient httpClient;
+ private URI uri;
+
+ HystrixReactiveHttpCommand(HttpClient httpClient, URI uri, int timeoutMillis) {
+ super(Setter
+ .withGroupKey(HystrixCommandGroupKey.Factory.asKey("hystrix-ratpack-reactive"))
+ .andCommandPropertiesDefaults(HystrixCommandProperties
+ .Setter()
+ .withExecutionTimeoutInMilliseconds(timeoutMillis)));
+ this.httpClient = httpClient;
+ this.uri = uri;
+ }
+
+ @Override
+ protected Observable construct() {
+ return RxRatpack.observe(httpClient
+ .get(uri, requestSpec -> requestSpec.headers(mutableHeaders -> mutableHeaders.add("User-Agent", "Baeldung HttpClient")))
+ .map(receivedResponse -> receivedResponse
+ .getBody()
+ .getText()));
+ }
+
+ @Override
+ protected Observable resumeWithFallback() {
+ return Observable.just("eugenp's reactive fallback profile");
+ }
+
+}
diff --git a/ratpack/src/main/java/com/baeldung/hystrix/HystrixSyncHttpCommand.java b/ratpack/src/main/java/com/baeldung/hystrix/HystrixSyncHttpCommand.java
new file mode 100644
index 0000000000..7c848331ca
--- /dev/null
+++ b/ratpack/src/main/java/com/baeldung/hystrix/HystrixSyncHttpCommand.java
@@ -0,0 +1,55 @@
+package com.baeldung.hystrix;
+
+import com.netflix.hystrix.HystrixCommand;
+import com.netflix.hystrix.HystrixCommandGroupKey;
+import com.netflix.hystrix.HystrixCommandProperties;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.util.EntityUtils;
+
+import java.net.URI;
+import java.util.Collections;
+
+/**
+ * @author aiet
+ */
+public class HystrixSyncHttpCommand extends HystrixCommand {
+
+ private URI uri;
+ private RequestConfig requestConfig;
+
+ HystrixSyncHttpCommand(URI uri, int timeoutMillis) {
+ super(Setter
+ .withGroupKey(HystrixCommandGroupKey.Factory.asKey("hystrix-ratpack-sync"))
+ .andCommandPropertiesDefaults(HystrixCommandProperties
+ .Setter()
+ .withExecutionTimeoutInMilliseconds(timeoutMillis)));
+ requestConfig = RequestConfig
+ .custom()
+ .setSocketTimeout(timeoutMillis)
+ .setConnectTimeout(timeoutMillis)
+ .setConnectionRequestTimeout(timeoutMillis)
+ .build();
+ this.uri = uri;
+ }
+
+ @Override
+ protected String run() throws Exception {
+ HttpGet request = new HttpGet(uri);
+ return EntityUtils.toString(HttpClientBuilder
+ .create()
+ .setDefaultRequestConfig(requestConfig)
+ .setDefaultHeaders(Collections.singleton(new BasicHeader("User-Agent", "Baeldung Blocking HttpClient")))
+ .build()
+ .execute(request)
+ .getEntity());
+ }
+
+ @Override
+ protected String getFallback() {
+ return "eugenp's sync fallback profile";
+ }
+
+}
diff --git a/ratpack/src/main/java/com/baeldung/hystrix/RatpackHystrixApp.java b/ratpack/src/main/java/com/baeldung/hystrix/RatpackHystrixApp.java
new file mode 100644
index 0000000000..1e4724bd96
--- /dev/null
+++ b/ratpack/src/main/java/com/baeldung/hystrix/RatpackHystrixApp.java
@@ -0,0 +1,30 @@
+package com.baeldung.hystrix;
+
+import ratpack.guice.Guice;
+import ratpack.http.client.HttpClient;
+import ratpack.hystrix.HystrixMetricsEventStreamHandler;
+import ratpack.hystrix.HystrixModule;
+import ratpack.server.RatpackServer;
+
+import java.net.URI;
+
+public class RatpackHystrixApp {
+
+ public static void main(String[] args) throws Exception {
+ final int timeout = Integer.valueOf(System.getProperty("ratpack.hystrix.timeout"));
+ final URI eugenGithubProfileUri = new URI("https://api.github.com/users/eugenp");
+
+ RatpackServer.start(server -> server
+ .registry(Guice.registry(bindingsSpec -> bindingsSpec.module(new HystrixModule().sse())))
+ .handlers(chain -> chain
+ .get("rx", ctx -> new HystrixReactiveHttpCommand(ctx.get(HttpClient.class), eugenGithubProfileUri, timeout)
+ .toObservable()
+ .subscribe(ctx::render))
+ .get("async", ctx -> ctx.render(new HystrixAsyncHttpCommand(eugenGithubProfileUri, timeout)
+ .queue()
+ .get()))
+ .get("sync", ctx -> ctx.render(new HystrixSyncHttpCommand(eugenGithubProfileUri, timeout).execute()))
+ .get("hystrix", new HystrixMetricsEventStreamHandler())));
+
+ }
+}
diff --git a/ratpack/src/test/java/com/baeldung/hystrix/RatpackHystrixAppFallbackLiveTest.java b/ratpack/src/test/java/com/baeldung/hystrix/RatpackHystrixAppFallbackLiveTest.java
new file mode 100644
index 0000000000..25287a5cbd
--- /dev/null
+++ b/ratpack/src/test/java/com/baeldung/hystrix/RatpackHystrixAppFallbackLiveTest.java
@@ -0,0 +1,50 @@
+package com.baeldung.hystrix;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import ratpack.test.MainClassApplicationUnderTest;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertThat;
+
+/**
+ * @author aiet
+ */
+public class RatpackHystrixAppFallbackLiveTest {
+
+ static MainClassApplicationUnderTest appUnderTest;
+
+ @BeforeClass
+ public static void setup() {
+ System.setProperty("ratpack.hystrix.timeout", "10");
+ appUnderTest = new MainClassApplicationUnderTest(RatpackHystrixApp.class);
+ }
+
+ @Test
+ public void whenFetchReactive_thenGotFallbackProfile() {
+ assertThat(appUnderTest
+ .getHttpClient()
+ .getText("rx"), containsString("reactive fallback profile"));
+ }
+
+ @Test
+ public void whenFetchAsync_thenGotFallbackProfile() {
+ assertThat(appUnderTest
+ .getHttpClient()
+ .getText("async"), containsString("async fallback profile"));
+ }
+
+ @Test
+ public void whenFetchSync_thenGotFallbackProfile() {
+ assertThat(appUnderTest
+ .getHttpClient()
+ .getText("sync"), containsString("sync fallback profile"));
+ }
+
+ @AfterClass
+ public static void clean() {
+ appUnderTest.close();
+ }
+
+}
diff --git a/ratpack/src/test/java/com/baeldung/hystrix/RatpackHystrixAppLiveTest.java b/ratpack/src/test/java/com/baeldung/hystrix/RatpackHystrixAppLiveTest.java
new file mode 100644
index 0000000000..843ef68e13
--- /dev/null
+++ b/ratpack/src/test/java/com/baeldung/hystrix/RatpackHystrixAppLiveTest.java
@@ -0,0 +1,50 @@
+package com.baeldung.hystrix;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import ratpack.test.MainClassApplicationUnderTest;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertThat;
+
+/**
+ * @author aiet
+ */
+public class RatpackHystrixAppLiveTest {
+
+ static MainClassApplicationUnderTest appUnderTest;
+
+ @BeforeClass
+ public static void setup() {
+ System.setProperty("ratpack.hystrix.timeout", "5000");
+ appUnderTest = new MainClassApplicationUnderTest(RatpackHystrixApp.class);
+ }
+
+ @Test
+ public void whenFetchReactive_thenGotEugenProfile() {
+ assertThat(appUnderTest
+ .getHttpClient()
+ .getText("rx"), containsString("www.baeldung.com"));
+ }
+
+ @Test
+ public void whenFetchAsync_thenGotEugenProfile() {
+ assertThat(appUnderTest
+ .getHttpClient()
+ .getText("async"), containsString("www.baeldung.com"));
+ }
+
+ @Test
+ public void whenFetchSync_thenGotEugenProfile() {
+ assertThat(appUnderTest
+ .getHttpClient()
+ .getText("sync"), containsString("www.baeldung.com"));
+ }
+
+ @AfterClass
+ public static void clean() {
+ appUnderTest.close();
+ }
+
+}