[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