Repository: tomee Updated Branches: refs/heads/master 32463a387 -> 2b2cca1f1
Adding Microprofile Fault Tollerance fallback example Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/64c4743f Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/64c4743f Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/64c4743f Branch: refs/heads/master Commit: 64c4743f4734743ba15d508b34b1edd8075f98ff Parents: 9f8a299 Author: Weverthon Medeiros <[email protected]> Authored: Fri Dec 21 13:49:54 2018 +0000 Committer: Weverthon Medeiros <[email protected]> Committed: Fri Dec 21 13:49:54 2018 +0000 ---------------------------------------------------------------------- examples/mp-faulttolerance-fallback/README.adoc | 125 +++++++++++++++++++ examples/mp-faulttolerance-fallback/pom.xml | 93 ++++++++++++++ .../rest/WeatherDayStatusFallbackHandler.java | 34 +++++ .../org/superbiz/rest/WeatherException.java | 20 +++ .../java/org/superbiz/rest/WeatherService.java | 62 +++++++++ .../org/superbiz/rest/WeatherServiceTest.java | 74 +++++++++++ .../src/test/resources/arquillian.xml | 30 +++++ .../src/test/resources/beans.xml | 7 ++ examples/pom.xml | 1 + 9 files changed, 446 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/64c4743f/examples/mp-faulttolerance-fallback/README.adoc ---------------------------------------------------------------------- diff --git a/examples/mp-faulttolerance-fallback/README.adoc b/examples/mp-faulttolerance-fallback/README.adoc new file mode 100644 index 0000000..deba96b --- /dev/null +++ b/examples/mp-faulttolerance-fallback/README.adoc @@ -0,0 +1,125 @@ +index-group=Unrevised +type=page +status=published +~~~~~~ +# Microprofile Fault Tolerance - Fallback +This is an example of how to use Microprofile @Fallback in TomEE. + +#### Fallback Feature +Fault Tolerance Fallback provides an alternative execution in case of failure. This alternative will be called when +`Retry` or `CircuitBreaker` has failed. + +To use this feature you need to annotate the method with @Fallback. + +The Fallback policy allows to configure : + +* **value**: A class which implements `FallbackHandler` +* **fallbackMethod**: a method which will be executed. + +The parameters **value** and **fallbackMethod** cannot be specified at the same time. + +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 + +##### Example 1 + +The method `statusOfDay` will always fail throwing a `WeatherException` and as the +`@CircuitBreaker` annotation is configured to `failOn` in case of that exception, the fallback, +`WeatherDayStatusFallbackHandler#handle` will be invoked. + +```java +@RequestScoped +public class WeatherService { + ... + @GET + @Path("/day/status") + @CircuitBreaker(failOn = WeatherException.class) + @Fallback(WeatherDayStatusFallbackHandler.class) + public String dayStatus() { + throw new WeatherException(); + } + ... + } + +public class WeatherDayStatusFallbackHandler implements FallbackHandler<String> { + + @Override + public String handle(ExecutionContext executionContext) { + return "Hi, today is a sunny day!"; + } +} +``` + +Day status call + + GET http://localhost:8080/mp-faulttolerance-fallback/weather/day/status + +Server log +``` +SEVERE [http-nio-8080-exec-2] org.superbiz.rest.WeatherDayStatusFallbackHandler.handle WeatherDayStatusFallbackHandler was triggered due a fail +``` + +Response +``` +Hi, today is a sunny day! +``` + +##### Example 2 + +The method `statusOfDay` will always fail throwing a `WeatherException` and as the +`@Retry` annotation is configured to `maxRetries = 1` in case of fail, the fallback method, +`fallbackForWeekStatus` will be invoked after retrying once. + +```java +@RequestScoped +public class WeatherService { + ... + @GET + @Path("/week/status") + @Retry(maxRetries = 1) + @Fallback(fallbackMethod = "fallbackForWeekStatus") + public String weekStatus() { + throw new WeatherException(); + } + + public String fallbackForWeekStatus() { + return "Hi, week will be mostly sunny!"; + } + ... +} +``` + +Week status call + + GET http://localhost:8080/mp-faulttolerance-fallback/weather/week/status + +Server log + +``` +SEVERE [http-nio-8080-exec-2] org.superbiz.rest.WeatherService.fallbackForWeekStatus Fallback was triggered due a fail + +``` + +Response +``` +Hi, week will be mostly sunny! +``` + + +##### Run the tests + +You can also try it out using the [WeatherServiceTest.java](src/test/java/org/superbiz/rest/WeatherServiceTest.java) available in the project. + + mvn clean test + +``` +[INFO] Results: +[INFO] +[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0 +``` + http://git-wip-us.apache.org/repos/asf/tomee/blob/64c4743f/examples/mp-faulttolerance-fallback/pom.xml ---------------------------------------------------------------------- diff --git a/examples/mp-faulttolerance-fallback/pom.xml b/examples/mp-faulttolerance-fallback/pom.xml new file mode 100644 index 0000000..40e771c --- /dev/null +++ b/examples/mp-faulttolerance-fallback/pom.xml @@ -0,0 +1,93 @@ +<?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"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.superbiz</groupId> + <artifactId>mp-faulttolerance-fallback</artifactId> + <version>8.0.0-SNAPSHOT</version> + <packaging>war</packaging> + <name>OpenEJB :: Examples :: Microprofile Fault Tolerance :: Fallback</name> + + <properties> + <microprofile-fault-tolerance-api.version>1.0</microprofile-fault-tolerance-api.version> + <arquillian-junit-container.version>1.4.0.Final</arquillian-junit-container.version> + <maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version> + <maven-war-plugin.version>3.1.0</maven-war-plugin.version> + <tomee.version>${project.version}</tomee.version> + <javaee-api.version>8.0</javaee-api.version> + <junit.version>4.12</junit.version> + <maven.compiler.source>1.8</maven.compiler.source> + <maven.compiler.target>1.8</maven.compiler.target> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.tomee</groupId> + <artifactId>javaee-api</artifactId> + <version>${javaee-api.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.eclipse.microprofile.fault-tolerance</groupId> + <artifactId>microprofile-fault-tolerance-api</artifactId> + <version>${microprofile-fault-tolerance-api.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>${junit.version}</version> + <scope>test</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>${arquillian-junit-container.version}</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>${project.version}</version> + <configuration> + <tomeeClassifier>microprofile</tomeeClassifier> + <context>${artifactId}</context> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-war-plugin</artifactId> + <version>${maven-war-plugin.version}</version> + <configuration> + <failOnMissingWebXml>false</failOnMissingWebXml> + </configuration> + </plugin> + </plugins> + </build> +</project> http://git-wip-us.apache.org/repos/asf/tomee/blob/64c4743f/examples/mp-faulttolerance-fallback/src/main/java/org/superbiz/rest/WeatherDayStatusFallbackHandler.java ---------------------------------------------------------------------- diff --git a/examples/mp-faulttolerance-fallback/src/main/java/org/superbiz/rest/WeatherDayStatusFallbackHandler.java b/examples/mp-faulttolerance-fallback/src/main/java/org/superbiz/rest/WeatherDayStatusFallbackHandler.java new file mode 100644 index 0000000..8d9101b --- /dev/null +++ b/examples/mp-faulttolerance-fallback/src/main/java/org/superbiz/rest/WeatherDayStatusFallbackHandler.java @@ -0,0 +1,34 @@ +/* + * 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.ExecutionContext; +import org.eclipse.microprofile.faulttolerance.FallbackHandler; + +import java.util.logging.Level; +import java.util.logging.Logger; + +public class WeatherDayStatusFallbackHandler implements FallbackHandler<String> { + + private static Logger logger = Logger.getLogger(WeatherDayStatusFallbackHandler.class.getName()); + + @Override + public String handle(ExecutionContext executionContext) { + logger.log(Level.SEVERE, "Fallback was triggered due a fail"); + return "Hi, today is a sunny day!"; + } +} http://git-wip-us.apache.org/repos/asf/tomee/blob/64c4743f/examples/mp-faulttolerance-fallback/src/main/java/org/superbiz/rest/WeatherException.java ---------------------------------------------------------------------- diff --git a/examples/mp-faulttolerance-fallback/src/main/java/org/superbiz/rest/WeatherException.java b/examples/mp-faulttolerance-fallback/src/main/java/org/superbiz/rest/WeatherException.java new file mode 100644 index 0000000..1133d74 --- /dev/null +++ b/examples/mp-faulttolerance-fallback/src/main/java/org/superbiz/rest/WeatherException.java @@ -0,0 +1,20 @@ +/* + * 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; + +public class WeatherException extends RuntimeException { +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tomee/blob/64c4743f/examples/mp-faulttolerance-fallback/src/main/java/org/superbiz/rest/WeatherService.java ---------------------------------------------------------------------- diff --git a/examples/mp-faulttolerance-fallback/src/main/java/org/superbiz/rest/WeatherService.java b/examples/mp-faulttolerance-fallback/src/main/java/org/superbiz/rest/WeatherService.java new file mode 100644 index 0000000..145b02e --- /dev/null +++ b/examples/mp-faulttolerance-fallback/src/main/java/org/superbiz/rest/WeatherService.java @@ -0,0 +1,62 @@ +/* + * 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.CircuitBreaker; +import org.eclipse.microprofile.faulttolerance.Fallback; +import org.eclipse.microprofile.faulttolerance.Retry; + +import java.util.logging.Level; +import java.util.logging.Logger; + +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 { + + private static Logger logger = Logger.getLogger(WeatherService.class.getName()); + + @GET + @Path("/day/status") + @CircuitBreaker(failOn = WeatherException.class) + @Fallback(WeatherDayStatusFallbackHandler.class) + public String dayStatus() { + throw new WeatherException(); + } + + @GET + @Path("/week/status") + @Retry(maxRetries = 1) + @Fallback(fallbackMethod = "fallbackForWeekStatus") + public String weekStatus() { + throw new WeatherException(); + } + + public String fallbackForWeekStatus() { + logger.log(Level.SEVERE, "Fallback was triggered due a fail"); + return "Hi, week will be mostly sunny!"; + } +} http://git-wip-us.apache.org/repos/asf/tomee/blob/64c4743f/examples/mp-faulttolerance-fallback/src/test/java/org/superbiz/rest/WeatherServiceTest.java ---------------------------------------------------------------------- diff --git a/examples/mp-faulttolerance-fallback/src/test/java/org/superbiz/rest/WeatherServiceTest.java b/examples/mp-faulttolerance-fallback/src/test/java/org/superbiz/rest/WeatherServiceTest.java new file mode 100644 index 0000000..0f511af --- /dev/null +++ b/examples/mp-faulttolerance-fallback/src/test/java/org/superbiz/rest/WeatherServiceTest.java @@ -0,0 +1,74 @@ +/* + * 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.junit.InSequence; +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("Hi, week will be mostly sunny!", response.readEntity(String.class)); + } + + @After + public void after() { + this.client.close(); + } +} http://git-wip-us.apache.org/repos/asf/tomee/blob/64c4743f/examples/mp-faulttolerance-fallback/src/test/resources/arquillian.xml ---------------------------------------------------------------------- diff --git a/examples/mp-faulttolerance-fallback/src/test/resources/arquillian.xml b/examples/mp-faulttolerance-fallback/src/test/resources/arquillian.xml new file mode 100644 index 0000000..3029d48 --- /dev/null +++ b/examples/mp-faulttolerance-fallback/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/64c4743f/examples/mp-faulttolerance-fallback/src/test/resources/beans.xml ---------------------------------------------------------------------- diff --git a/examples/mp-faulttolerance-fallback/src/test/resources/beans.xml b/examples/mp-faulttolerance-fallback/src/test/resources/beans.xml new file mode 100644 index 0000000..d942d7a --- /dev/null +++ b/examples/mp-faulttolerance-fallback/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 http://git-wip-us.apache.org/repos/asf/tomee/blob/64c4743f/examples/pom.xml ---------------------------------------------------------------------- diff --git a/examples/pom.xml b/examples/pom.xml index 8cdcf19..74a6a25 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -100,6 +100,7 @@ <module>movies-complete-meta</module> <module>movies-complete</module> <module>mp-config-example</module> + <module>mp-faulttolerance-fallback</module> <module>mp-faulttolerance-retry</module> <module>mp-metrics-counted</module> <module>mp-metrics-histogram</module>
