[TOMEE-2291] - Fault Tolerance Microprofile example for @Retry

Created Rest Resource WeatherService which publish /weather
Created WeatherGatewayTimeoutException and WeatherGatewayBusyServiceException 
which extends FaultToleranceException to handle the exceptions thrown by the 
business logic from WeatherGateway.
Created WeatherGateway which makes the use of @Retry annotation
Created WeatherServiceTest
Created README.md to describe the example (incomplete)


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/2314bf9b
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/2314bf9b
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/2314bf9b

Branch: refs/heads/master
Commit: 2314bf9bd28cc483b401a7604427d60812a06680
Parents: 388460f
Author: josehenriqueventura <J2705hvq*>
Authored: Mon Dec 3 20:13:20 2018 +0000
Committer: josehenriqueventura <jose.vent...@protonmail.com>
Committed: Wed Dec 5 22:51:27 2018 +0000

----------------------------------------------------------------------
 examples/mp-faulttolerance-retry/README.md      | 228 +++++++++++++++++++
 examples/mp-faulttolerance-retry/pom.xml        |  69 ++++++
 .../java/org/superbiz/rest/WeatherGateway.java  | 115 ++++++++++
 .../WeatherGatewayBusyServiceException.java     |  22 ++
 .../rest/WeatherGatewayTimeoutException.java    |  23 ++
 .../java/org/superbiz/rest/WeatherService.java  |  73 ++++++
 .../org/superbiz/rest/WeatherServiceTest.java   |  87 +++++++
 .../src/test/resources/arquillian.xml           |  30 +++
 .../src/test/resources/beans.xml                |   7 +
 9 files changed, 654 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/2314bf9b/examples/mp-faulttolerance-retry/README.md
----------------------------------------------------------------------
diff --git a/examples/mp-faulttolerance-retry/README.md 
b/examples/mp-faulttolerance-retry/README.md
new file mode 100644
index 0000000..5ea4369
--- /dev/null
+++ b/examples/mp-faulttolerance-retry/README.md
@@ -0,0 +1,228 @@
+# Microprofile Fault Tolerance - Retry policy
+This is an example of how to use Microprofile @Retry in TomEE.
+
+#### Retry Feature
+Microprofile Fault Tolerance has a feature called Retry that can be used to 
recover an operation from failure, invoking the same operation again.
+
+The Retry policy allows to configure :
+
+**maxRetries**: the maximum retries 
+
+**delay**: delays between each retry
+
+**delayUnit**: the delay unit
+
+**maxDuration**: maximum duration to perform the retry for.
+
+**durationUnit**: duration unit
+
+**jitter:** the random vary of retry delays
+
+**jitterDelayUnit:** the jitter unit
+
+**retryOn:** specify the failures to retry on
+
+**abortOn:** specify the failures to abort on
+
+To use this feature you can annotate a class and/or a method with the @Retry 
annotation. 
+Check the 
[specification](http://download.eclipse.org/microprofile/microprofile-fault-tolerance-1.1/microprofile-fault-tolerance-spec.html)
 for more details.
+
+### Examples
+
+##### Run the application
+
+    mvn clean install tomee:run 
+    
+##### and 4 endpoints will available
+
+    1 - http://localhost:8080/mp-faulttolerance-retry/weather/day/status
+    2 - http://localhost:8080/mp-faulttolerance-retry/weather/week/status 
+    3 - http://localhost:8080/mp-faulttolerance-retry/weather/weekend/status
+    4 - http://localhost:8080/mp-faulttolerance-retry/weather/year/status    
+    
+##### Example 1
+
+The method statusOfDay will fail three times, each time, throwing a 
`WeatherGatewayTimeoutException` and as the
+@Retry annotation is configured to `retryOn` in case of failure, the FailSafe 
library will take the `maxRetry` value and
+retry the same operation until it reaches the number maximum of attempts, 
which is 3 (default value).  
+
+``` 
+@Path("/weather")
+@Produces(MediaType.TEXT_PLAIN)
+@RequestScoped
+public class WeatherService {
+    ...
+
+    @GET
+    @Path("/day/status")
+    public String dayStatus() {
+        return weatherService.statusOfDay();
+    }
+    ...
+}
+
+```
+
+```
+@RequestScoped
+public class WeatherGateway{ 
+   ...
+   @Retry(maxRetry=3, retryOn = WeatherGatewayTimeoutException.class)
+   public String statusOfDay(){
+       if(counterStatusOfDay.addAndGet(1) <= DEFAULT_MAX_RETRY){
+           LOGGER.warning(String.format(FORECAST_TIMEOUT_MESSAGE, 
DEFAULT_MAX_RETRY, counterStatusOfDay.get()));
+           throw new WeatherGatewayTimeoutException();
+       }
+       return "Today is a sunny day!";
+   }
+   ...
+ }
+```
+
+Day status call
+
+    GET http://localhost:8080/mp-faulttolerance-retry/weather/day/status
+    
+Server log
+```
+WARNING ...statusOfDay - Timeout when accessing AccuWeather Forecast Service. 
Max of Attempts: (3), Attempts: (1)
+WARNING ...statusOfDay - Timeout when accessing AccuWeather Forecast Service. 
Max of Attempts: (3), Attempts: (2)
+WARNING ...statusOfDay - Timeout when accessing AccuWeather Forecast Service. 
Max of Attempts: (3), Attempts: (3)
+```
+
+Response
+``` 
+Today is a sunny day!
+```
+
+##### Example 2
+
+The method weekStatus will fail two times, each time, throwing a 
`WeatherGatewayTimeoutException` because `retryOn` is configured and instead of 
+returning a response to the caller, the logic states that at the third 
attempt, a `WeatherGatewayBusyServiceException` will be thrown.
+ As the `@Retry` annotation is configured to `abortOn` in case of 
`WeatherGatewayTimeoutException` happens, the remaining attempt won't be 
+ executed and the caller must handle the exception.
+
+``` 
+    @Retry(maxRetries = 3, retryOn = WeatherGatewayTimeoutException.class, 
abortOn = WeatherGatewayBusyServiceException.class)
+    public String statusOfWeek(){
+        if(counterStatusOfWeek.addAndGet(1) <= DEFAULT_MAX_RETRY){
+            LOGGER.warning(String.format(FORECAST_TIMEOUT_MESSAGE_ATTEMPTS, 
DEFAULT_MAX_RETRY, counterStatusOfWeek.get()));
+            throw new WeatherGatewayTimeoutException();
+        }
+        LOGGER.log(Level.SEVERE, String.format(FORECAST_BUSY_MESSAGE, 
counterStatusOfWeek.get()));
+        throw new WeatherGatewayBusyServiceException();
+    }
+    
+```
+
+Week status call
+
+    GET http://localhost:8080/mp-faulttolerance-retry/weather/week/status
+
+Server log
+
+```
+WARNING ...statusOfWeek - Timeout when accessing AccuWeather Forecast Service. 
Max of Attempts: (3), Attempts: (1)
+WARNING ...statusOfWeek - Timeout when accessing AccuWeather Forecast Service. 
Max of Attempts: (3), Attempts: (2)
+WARNING ...statusOfWeek - Timeout when accessing AccuWeather Forecast Service. 
Max of Attempts: (3), Attempts: (3)
+SEVERE  ...statusOfWeek - Error AccuWeather Forecast Service is busy. Number 
of Attempts: (4) 
+```
+
+Response
+``` 
+WeatherGateway Service is Busy. Retry later
+```
+
+##### Example 3
+
+The `@Retry` annotation allows to configure a delay for each new attempt be 
executed giving a chance to service
+requested to recover itself and answerer the request properly. For each new 
retry follow the delay configure,
+is needed to set `jitter` to zero (0). Otherwise the delay of each new attempt 
will be randomized.
+
+Analysing the logged messages, is possible to see that all attempts took the 
pretty much the same time to execute.
+
+``` 
+    @Retry(retryOn = WeatherGatewayTimeoutException.class, maxRetries = 5, 
delay = 500, jitter = 0)
+    public String statusOfWeekend() {
+        if (counterStatusOfWeekend.addAndGet(1) <= 5) {
+            logTimeoutMessage(statusOfWeekendInstant);
+            statusOfWeekendInstant = Instant.now();
+            throw new WeatherGatewayTimeoutException();
+        }
+        return "The Forecast for the Weekend is Scattered Showers.";
+    }
+    
+}
+```
+
+Weekend status call
+
+    GET http://localhost:8080/mp-faulttolerance-retry/weather/weekend/status
+    
+Server log
+
+```
+WARNING ...logTimeoutMessage - Timeout when accessing AccuWeather Forecast 
Service.
+WARNING ...logTimeoutMessage - Timeout when accessing AccuWeather Forecast 
Service. Delay of each attempt: (501) millis
+WARNING ...logTimeoutMessage - Timeout when accessing AccuWeather Forecast 
Service. Delay of each attempt: (501) millis
+WARNING ...logTimeoutMessage - Timeout when accessing AccuWeather Forecast 
Service. Delay of each attempt: (501) millis
+WARNING ...logTimeoutMessage - Timeout when accessing AccuWeather Forecast 
Service. Delay of each attempt: (500) millis
+```
+
+##### Example 4
+
+Basically with the same behaviour of the `Example 3`, this example sets the 
`delay` and `jitter` with 500 millis to randomly
+create a new delay for each new attempt after the first failure.
+
+Analysing the logged messages, is possible to see how long each attempt had to 
wait until its execution.
+
+``` 
+    @Retry(retryOn = WeatherGatewayTimeoutException.class, delay = 500, jitter 
= 500)
+    public String statusOfMonth() {
+        if (counterStatusOfWeekend.addAndGet(1) <= DEFAULT_MAX_RETRY) {
+            logTimeoutMessage(statusOfMonthInstant);
+            statusOfMonthInstant = Instant.now();
+            throw new WeatherGatewayTimeoutException();
+        }
+        return "The Forecast for the Weekend is Scattered Showers.";
+    }
+```
+
+Month status call
+
+    GET http://localhost:8080/mp-faulttolerance-retry/weather/month/status
+    
+Server log
+
+```
+WARNING ...logTimeoutMessage - Timeout when accessing AccuWeather Forecast 
Service.
+WARNING ...logTimeoutMessage - Timeout when accessing AccuWeather Forecast 
Service. Delay of each attempt: (417) millis
+WARNING ...logTimeoutMessage - Timeout when accessing AccuWeather Forecast 
Service. Delay of each attempt: (90) millis
+```
+
+##### Example 5
+
+``` 
+    @Retry(retryOn = WeatherGatewayTimeoutException.class, maxRetries = 5, 
delay = 500, jitter = 500, maxDuration = 1000)
+    public String statusOfYear() {
+        if (counterStatusOfWeekend.addAndGet(1) <= 5) {
+            logTimeoutMessage(statusOfYearInstant);
+            statusOfYearInstant = Instant.now();
+            throw new WeatherGatewayTimeoutException();
+        }
+        return "Status of the Year is unavailable.";
+    }
+```
+
+Year status call
+
+    GET http://localhost:8080/mp-faulttolerance-retry/weather/weekend/status
+
+Server log
+
+```
+WARNING ...logTimeoutMessage - Timeout when accessing AccuWeather Forecast 
Service.
+WARNING ...logTimeoutMessage - Timeout when accessing AccuWeather Forecast 
Service. Delay of each attempt: (666) millis
+WARNING ...logTimeoutMessage - Timeout when accessing AccuWeather Forecast 
Service. Delay of each attempt: (266) millis
+WARNING ...logTimeoutMessage - Timeout when accessing AccuWeather Forecast 
Service. Delay of each attempt: (66) millis
+```
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/2314bf9b/examples/mp-faulttolerance-retry/pom.xml
----------------------------------------------------------------------
diff --git a/examples/mp-faulttolerance-retry/pom.xml 
b/examples/mp-faulttolerance-retry/pom.xml
new file mode 100644
index 0000000..66f55be
--- /dev/null
+++ b/examples/mp-faulttolerance-retry/pom.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <parent>
+        <artifactId>examples</artifactId>
+        <groupId>org.apache.tomee</groupId>
+        <version>8.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>mp-faulttolerance-retry</artifactId>
+    <packaging>war</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tomee</groupId>
+            <artifactId>javaee-api</artifactId>
+            <version>8.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.microprofile.fault-tolerance</groupId>
+            <artifactId>microprofile-fault-tolerance-api</artifactId>
+            <version>1.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tomee</groupId>
+            <artifactId>openejb-cxf-rs</artifactId>
+            <version>${tomee.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.arquillian.junit</groupId>
+            <artifactId>arquillian-junit-container</artifactId>
+            <version>1.0.3.Final</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tomee</groupId>
+            <artifactId>arquillian-tomee-remote</artifactId>
+            <version>${tomee.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tomee</groupId>
+            <artifactId>apache-tomee</artifactId>
+            <version>${tomee.version}</version>
+            <type>zip</type>
+            <classifier>microprofile</classifier>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.tomee.maven</groupId>
+                <artifactId>tomee-maven-plugin</artifactId>
+                <version>8.0.0-SNAPSHOT</version>
+                <configuration>
+                    <tomeeClassifier>microprofile</tomeeClassifier>
+                    <context>${artifactId}</context>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

http://git-wip-us.apache.org/repos/asf/tomee/blob/2314bf9b/examples/mp-faulttolerance-retry/src/main/java/org/superbiz/rest/WeatherGateway.java
----------------------------------------------------------------------
diff --git 
a/examples/mp-faulttolerance-retry/src/main/java/org/superbiz/rest/WeatherGateway.java
 
b/examples/mp-faulttolerance-retry/src/main/java/org/superbiz/rest/WeatherGateway.java
new file mode 100644
index 0000000..110113a
--- /dev/null
+++ 
b/examples/mp-faulttolerance-retry/src/main/java/org/superbiz/rest/WeatherGateway.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz.rest;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.enterprise.context.RequestScoped;
+import org.eclipse.microprofile.faulttolerance.Retry;
+
+
+@RequestScoped
+public class WeatherGateway {
+
+    private static Logger LOGGER = 
Logger.getLogger(WeatherGateway.class.getName());
+
+    private static final String FORECAST_TIMEOUT_MESSAGE_ATTEMPTS =
+            "Timeout when accessing AccuWeather Forecast Service. Max of 
Attempts: (%d), Attempts: (%d)";
+
+    private static final String FORECAST_TIMEOUT_MESSAGE =
+            "Timeout when accessing AccuWeather Forecast Service.";
+
+    private static final String FORECAST_TIMEOUT_MESSAGE_DELAY =
+            "Timeout when accessing AccuWeather Forecast Service. Delay of 
each attempt: (%d)";
+
+    private static final String FORECAST_BUSY_MESSAGE =
+            "Error AccuWeather Forecast Service is busy. Number of Attempts: 
(%d) \n";
+
+    /**
+     * {@link Retry#maxRetries()}
+     */
+    private static final int DEFAULT_MAX_RETRY = 3;
+
+    private AtomicInteger counterStatusOfDay = new AtomicInteger();
+    private AtomicInteger counterStatusOfWeek = new AtomicInteger();
+    private AtomicInteger counterStatusOfWeekend = new AtomicInteger();
+
+    private Instant statusOfWeekendInstant = null;
+    private Instant statusOfMonthInstant = null;
+    private Instant statusOfYearInstant = null;
+
+    @Retry(maxRetries = 3, retryOn = WeatherGatewayTimeoutException.class)
+    public String statusOfDay(){
+        if(counterStatusOfDay.addAndGet(1) <= DEFAULT_MAX_RETRY){
+            LOGGER.warning(String.format(FORECAST_TIMEOUT_MESSAGE_ATTEMPTS, 
DEFAULT_MAX_RETRY, counterStatusOfDay.get()));
+            throw new WeatherGatewayTimeoutException();
+        }
+        return "Hi, today is a sunny day!";
+    }
+
+    @Retry(maxRetries = 3, retryOn = WeatherGatewayTimeoutException.class, 
abortOn = WeatherGatewayBusyServiceException.class)
+    public String statusOfWeek(){
+        if(counterStatusOfWeek.addAndGet(1) <= DEFAULT_MAX_RETRY){
+            LOGGER.warning(String.format(FORECAST_TIMEOUT_MESSAGE_ATTEMPTS, 
DEFAULT_MAX_RETRY, counterStatusOfWeek.get()));
+            throw new WeatherGatewayTimeoutException();
+        }
+        LOGGER.log(Level.SEVERE, String.format(FORECAST_BUSY_MESSAGE, 
counterStatusOfWeek.get()));
+        throw new WeatherGatewayBusyServiceException();
+    }
+    
+    @Retry(retryOn = WeatherGatewayTimeoutException.class, maxRetries = 5, 
delay = 500, jitter = 0)
+    public String statusOfWeekend() {
+        if (counterStatusOfWeekend.addAndGet(1) <= 5) {
+            logTimeoutMessage(statusOfWeekendInstant);
+            statusOfWeekendInstant = Instant.now();
+            throw new WeatherGatewayTimeoutException();
+        }
+        return "The Forecast for the Weekend is Scattered Showers.";
+    }
+
+    @Retry(retryOn = WeatherGatewayTimeoutException.class, delay = 500, jitter 
= 500)
+    public String statusOfMonth() {
+        if (counterStatusOfWeekend.addAndGet(1) <= DEFAULT_MAX_RETRY) {
+            logTimeoutMessage(statusOfMonthInstant);
+            statusOfMonthInstant = Instant.now();
+            throw new WeatherGatewayTimeoutException();
+        }
+        return "The Forecast for the Weekend is Scattered Showers.";
+    }
+
+    @Retry(retryOn = WeatherGatewayTimeoutException.class, maxRetries = 5, 
delay = 500, jitter = 500, maxDuration = 1000)
+    public String statusOfYear() {
+        if (counterStatusOfWeekend.addAndGet(1) <= 5) {
+            logTimeoutMessage(statusOfYearInstant);
+            statusOfYearInstant = Instant.now();
+            throw new WeatherGatewayTimeoutException();
+        }
+        return "Status of the Year is unavailable.";
+    }
+
+    private void logTimeoutMessage(Instant instant) {
+        if(instant == null){
+            LOGGER.warning(FORECAST_TIMEOUT_MESSAGE);
+        }else{
+            LOGGER.warning(String.format(FORECAST_TIMEOUT_MESSAGE_DELAY,
+                    Duration.between(instant, Instant.now()).toMillis()));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/2314bf9b/examples/mp-faulttolerance-retry/src/main/java/org/superbiz/rest/WeatherGatewayBusyServiceException.java
----------------------------------------------------------------------
diff --git 
a/examples/mp-faulttolerance-retry/src/main/java/org/superbiz/rest/WeatherGatewayBusyServiceException.java
 
b/examples/mp-faulttolerance-retry/src/main/java/org/superbiz/rest/WeatherGatewayBusyServiceException.java
new file mode 100644
index 0000000..d598f5d
--- /dev/null
+++ 
b/examples/mp-faulttolerance-retry/src/main/java/org/superbiz/rest/WeatherGatewayBusyServiceException.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz.rest;
+
+import 
org.eclipse.microprofile.faulttolerance.exceptions.FaultToleranceException;
+
+public class WeatherGatewayBusyServiceException extends 
FaultToleranceException {
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/2314bf9b/examples/mp-faulttolerance-retry/src/main/java/org/superbiz/rest/WeatherGatewayTimeoutException.java
----------------------------------------------------------------------
diff --git 
a/examples/mp-faulttolerance-retry/src/main/java/org/superbiz/rest/WeatherGatewayTimeoutException.java
 
b/examples/mp-faulttolerance-retry/src/main/java/org/superbiz/rest/WeatherGatewayTimeoutException.java
new file mode 100644
index 0000000..e519c14
--- /dev/null
+++ 
b/examples/mp-faulttolerance-retry/src/main/java/org/superbiz/rest/WeatherGatewayTimeoutException.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz.rest;
+
+import 
org.eclipse.microprofile.faulttolerance.exceptions.FaultToleranceException;
+
+
+public class WeatherGatewayTimeoutException extends FaultToleranceException {
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/2314bf9b/examples/mp-faulttolerance-retry/src/main/java/org/superbiz/rest/WeatherService.java
----------------------------------------------------------------------
diff --git 
a/examples/mp-faulttolerance-retry/src/main/java/org/superbiz/rest/WeatherService.java
 
b/examples/mp-faulttolerance-retry/src/main/java/org/superbiz/rest/WeatherService.java
new file mode 100644
index 0000000..f21bf8f
--- /dev/null
+++ 
b/examples/mp-faulttolerance-retry/src/main/java/org/superbiz/rest/WeatherService.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz.rest;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+
+@Path("/weather")
+@Produces(MediaType.TEXT_PLAIN)
+@RequestScoped
+public class WeatherService {
+
+    @Inject
+    private WeatherGateway weatherService;
+
+    @GET
+    @Path("/day/status")
+    public String dayStatus() {
+        return weatherService.statusOfDay();
+    }
+
+    @GET
+    @Path("/week/status")
+    public Response weekStatus() {
+        try {
+            return Response.ok().entity(weatherService.statusOfWeek()).build();
+        } catch (WeatherGatewayBusyServiceException e) {
+            return Response.serverError().entity("WeatherGateway Service is 
Busy. Retry later").build();
+        }
+    }
+
+    @GET
+    @Path("/weekend/status")
+    public Response weekendStatus() {
+        return Response.ok().entity(weatherService.statusOfWeekend()).build();
+    }
+
+    @GET
+    @Path("/month/status")
+    public Response monthStatus() {
+        return Response.ok().entity(weatherService.statusOfMonth()).build();
+    }
+
+    @GET
+    @Path("/year/status")
+    public Response yearStatus() {
+        try {
+            return Response.ok().entity(weatherService.statusOfYear()).build();
+        } catch (WeatherGatewayTimeoutException e) {
+            return Response.serverError().entity("WeatherGateway Service 
Timeout").build();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/2314bf9b/examples/mp-faulttolerance-retry/src/test/java/org/superbiz/rest/WeatherServiceTest.java
----------------------------------------------------------------------
diff --git 
a/examples/mp-faulttolerance-retry/src/test/java/org/superbiz/rest/WeatherServiceTest.java
 
b/examples/mp-faulttolerance-retry/src/test/java/org/superbiz/rest/WeatherServiceTest.java
new file mode 100644
index 0000000..4f43926
--- /dev/null
+++ 
b/examples/mp-faulttolerance-retry/src/test/java/org/superbiz/rest/WeatherServiceTest.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz.rest;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Response;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.net.URL;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(Arquillian.class)
+public class WeatherServiceTest {
+
+    @ArquillianResource
+    private URL base;
+
+    private Client client;
+
+    @Deployment(testable = false)
+    public static WebArchive createDeployment() {
+        return ShrinkWrap.create(WebArchive.class, 
"test.war").addPackage(WeatherService.class.getPackage());
+    }
+
+    @Before
+    public void before() {
+        this.client = ClientBuilder.newClient();
+    }
+
+    @Test
+    public void testStatusOfDay() {
+        WebTarget webTarget = this.client.target(this.base.toExternalForm());
+        Response response = 
webTarget.path("/weather/day/status").request().get();
+        assertEquals("Hi, today is a sunny day!", 
response.readEntity(String.class));
+    }
+
+    @Test
+    public void testStatusOfWeek() {
+        WebTarget webTarget = this.client.target(this.base.toExternalForm());
+        Response response = 
webTarget.path("/weather/week/status").request().get();
+        assertEquals("WeatherGateway Service is Busy. Retry later", 
response.readEntity(String.class));
+    }
+
+    @Test
+    public void testStatusOfWeekend() {
+        WebTarget webTarget = this.client.target(this.base.toExternalForm());
+        Response response = 
webTarget.path("/weather/weekend/status").request().get();
+        assertEquals("The Forecast for the Weekend is Scattered Showers.", 
response.readEntity(String.class));
+    }
+
+    @Test
+    public void testStatusOfYear() {
+        WebTarget webTarget = this.client.target(this.base.toExternalForm());
+        Response response = 
webTarget.path("/weather/year/status").request().get();
+        assertEquals("WeatherGateway Service Timeout", 
response.readEntity(String.class));
+    }
+
+    @After
+    public void after() {
+        this.client.close();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/2314bf9b/examples/mp-faulttolerance-retry/src/test/resources/arquillian.xml
----------------------------------------------------------------------
diff --git a/examples/mp-faulttolerance-retry/src/test/resources/arquillian.xml 
b/examples/mp-faulttolerance-retry/src/test/resources/arquillian.xml
new file mode 100644
index 0000000..3029d48
--- /dev/null
+++ b/examples/mp-faulttolerance-retry/src/test/resources/arquillian.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
+
+  <container qualifier="tomee" default="true">
+    <configuration>
+      <property name="httpPort">-1</property>
+      <property name="stopPort">-1</property>
+      <property name="classifier">microprofile</property>
+      <property name="dir">target/apache-tomee-remote</property>
+      <property 
name="appWorkingDir">target/arquillian-test-working-dir</property>
+    </configuration>
+  </container>
+</arquillian>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/2314bf9b/examples/mp-faulttolerance-retry/src/test/resources/beans.xml
----------------------------------------------------------------------
diff --git a/examples/mp-faulttolerance-retry/src/test/resources/beans.xml 
b/examples/mp-faulttolerance-retry/src/test/resources/beans.xml
new file mode 100644
index 0000000..d942d7a
--- /dev/null
+++ b/examples/mp-faulttolerance-retry/src/test/resources/beans.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://java.sun.com/xml/ns/javaee";
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="
+      http://java.sun.com/xml/ns/javaee
+      http://java.sun.com/xml/ns/javaee/beans_1_0.xsd";>
+</beans>
\ No newline at end of file

Reply via email to