You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2020/09/04 01:34:20 UTC
[tomee] branch master updated: Examples and documentation
TOMEE-2706 New TomEE Embedded Bootstrap
This is an automated email from the ASF dual-hosted git repository.
dblevins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomee.git
The following commit(s) were added to refs/heads/master by this push:
new 142f035 Examples and documentation TOMEE-2706 New TomEE Embedded Bootstrap
142f035 is described below
commit 142f035e454b43192c51db7a66b9395982502d47
Author: David Blevins <da...@gmail.com>
AuthorDate: Thu Sep 3 18:34:01 2020 -0700
Examples and documentation
TOMEE-2706 New TomEE Embedded Bootstrap
---
.../src/main/java/org/superbiz/movie/wp/Api.java | 24 +++
.../src/main/java/org/superbiz/movie/wp/Movie.java | 77 ++++++++++
.../java/org/superbiz/movie/wp/MovieService.java | 60 ++++++++
.../org/superbiz/movie/wp/MovieServiceTest.java | 87 +++++++++++
examples/serverless-tomee-plume/README.adoc | 168 +++++++++++++++++++++
examples/serverless-tomee-plume/pom.xml | 74 +++++++++
.../src/main/java/org/superbiz/movie/Api.java | 24 +++
.../src/main/java/org/superbiz/movie/Movie.java | 77 ++++++++++
.../main/java/org/superbiz/movie/MovieService.java | 60 ++++++++
.../src/test/java/org/superbiz/movie/Main.java | 35 +++++
.../java/org/superbiz/movie/MovieServiceTest.java | 87 +++++++++++
examples/serverless-tomee-plus/README.adoc | 168 +++++++++++++++++++++
examples/serverless-tomee-plus/pom.xml | 74 +++++++++
.../src/main/java/org/superbiz/movie/Api.java | 24 +++
.../src/main/java/org/superbiz/movie/Movie.java | 77 ++++++++++
.../main/java/org/superbiz/movie/MovieService.java | 60 ++++++++
.../src/test/java/org/superbiz/movie/Main.java | 35 +++++
.../java/org/superbiz/movie/MovieServiceTest.java | 87 +++++++++++
examples/serverless-tomee-webprofile/README.adoc | 168 +++++++++++++++++++++
examples/serverless-tomee-webprofile/pom.xml | 74 +++++++++
.../src/main/java/org/superbiz/movie/wp/Api.java | 24 +++
.../src/main/java/org/superbiz/movie/wp/Movie.java | 77 ++++++++++
.../java/org/superbiz/movie/wp/MovieService.java | 60 ++++++++
.../src/test/java/org/superbiz/movie/wp/Main.java | 33 ++++
.../org/superbiz/movie/wp/MovieServiceTest.java | 87 +++++++++++
25 files changed, 1821 insertions(+)
diff --git a/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/Api.java b/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/Api.java
new file mode 100644
index 0000000..320fddc
--- /dev/null
+++ b/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/Api.java
@@ -0,0 +1,24 @@
+/*
+ * 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.movie.wp;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+@ApplicationPath("/api")
+public class Api extends Application {
+}
diff --git a/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/Movie.java b/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/Movie.java
new file mode 100644
index 0000000..b5b02df
--- /dev/null
+++ b/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/Movie.java
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+package org.superbiz.movie.wp;
+
+public class Movie {
+
+ private String title;
+ private String director;
+ private String genre;
+ private int id;
+ private int year;
+
+ public Movie() {
+ }
+
+ public Movie(final String title, final String director, final String genre, final int id, final int year) {
+ this.title = title;
+ this.director = director;
+ this.genre = genre;
+ this.id = id;
+ this.year = year;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(final String title) {
+ this.title = title;
+ }
+
+ public String getDirector() {
+ return director;
+ }
+
+ public void setDirector(final String director) {
+ this.director = director;
+ }
+
+ public String getGenre() {
+ return genre;
+ }
+
+ public void setGenre(final String genre) {
+ this.genre = genre;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(final int id) {
+ this.id = id;
+ }
+
+ public int getYear() {
+ return year;
+ }
+
+ public void setYear(final int year) {
+ this.year = year;
+ }
+}
diff --git a/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/MovieService.java b/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/MovieService.java
new file mode 100644
index 0000000..d12ef58
--- /dev/null
+++ b/examples/serverless-tomee-microprofile/src/main/java/org/superbiz/movie/wp/MovieService.java
@@ -0,0 +1,60 @@
+/*
+ * 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.movie.wp;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.RequestScoped;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Path("/movies")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestScoped
+public class MovieService {
+
+ private Map<Integer, Movie> store = new ConcurrentHashMap<>();
+
+ @PostConstruct
+ public void construct(){
+ this.addMovie(new Movie("Wedding Crashers", "David Dobkin", "Comedy", 1, 2005));
+ this.addMovie(new Movie("Starsky & Hutch", "Todd Phillips", "Action", 2, 2004));
+ this.addMovie(new Movie("Shanghai Knights", "David Dobkin", "Action", 3, 2003));
+ this.addMovie(new Movie("I-Spy", "Betty Thomas", "Adventure", 4, 2002));
+ this.addMovie(new Movie("The Royal Tenenbaums", "Wes Anderson", "Comedy", 5, 2001));
+ this.addMovie(new Movie("Zoolander", "Ben Stiller", "Comedy", 6, 2001));
+ }
+ @GET
+ public List<Movie> getAllMovies() {
+ return new ArrayList<>(store.values());
+ }
+
+ @POST
+ public Movie addMovie(final Movie newMovie) {
+ store.put(newMovie.getId(), newMovie);
+ return newMovie;
+ }
+
+}
diff --git a/examples/serverless-tomee-microprofile/src/test/java/org/superbiz/movie/wp/MovieServiceTest.java b/examples/serverless-tomee-microprofile/src/test/java/org/superbiz/movie/wp/MovieServiceTest.java
new file mode 100644
index 0000000..23e1274
--- /dev/null
+++ b/examples/serverless-tomee-microprofile/src/test/java/org/superbiz/movie/wp/MovieServiceTest.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
+ *
+ * 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.
+ */
+package org.superbiz.movie.wp;
+
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import java.net.URI;
+
+import static javax.ws.rs.client.Entity.entity;
+import static org.junit.Assert.assertEquals;
+
+public class MovieServiceTest {
+
+ private static URI serverURI;
+
+ @BeforeClass
+ public static void setup() {
+ // Add any classes you need to an Archive
+ // or add them to a jar via any means
+ final Archive classes = Archive.archive()
+ .add(Api.class)
+ .add(Movie.class)
+ .add(MovieService.class);
+
+ // Place the classes where you would want
+ // them in a Tomcat install
+ final Server server = Server.builder()
+ // This effectively creates a webapp called ROOT
+ .add("webapps/ROOT/WEB-INF/classes", classes)
+ .build();
+
+ serverURI = server.getURI();
+ }
+
+ @Test
+ public void getAllMovies() {
+ final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+ final Movie[] movies = target.path("/api/movies").request().get(Movie[].class);
+
+ assertEquals(6, movies.length);
+
+ final Movie movie = movies[1];
+ assertEquals("Todd Phillips", movie.getDirector());
+ assertEquals("Starsky & Hutch", movie.getTitle());
+ assertEquals("Action", movie.getGenre());
+ assertEquals(2004, movie.getYear());
+ assertEquals(2, movie.getId());
+ }
+
+ @Test
+ public void addMovie() {
+ final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+ final Movie movie = new Movie("Shanghai Noon", "Tom Dey", "Comedy", 7, 2000);
+
+ final Movie posted = target.path("/api/movies").request()
+ .post(entity(movie, MediaType.APPLICATION_JSON))
+ .readEntity(Movie.class);
+
+ assertEquals("Tom Dey", posted.getDirector());
+ assertEquals("Shanghai Noon", posted.getTitle());
+ assertEquals("Comedy", posted.getGenre());
+ assertEquals(2000, posted.getYear());
+ assertEquals(7, posted.getId());
+ }
+}
diff --git a/examples/serverless-tomee-plume/README.adoc b/examples/serverless-tomee-plume/README.adoc
new file mode 100644
index 0000000..73a2ed4
--- /dev/null
+++ b/examples/serverless-tomee-plume/README.adoc
@@ -0,0 +1,168 @@
+:index-group: Serverless
+:jbake-type: page
+:jbake-status: status=published
+= Serverless TomEE Plume
+
+Apache TomEE can be run as a library inside your JVM with no need for separate processes or a standalone server install. In this approach we include the right libraries in our project and then bootstrap TomEE using the `Server.Builder` API.
+
+== Include the `tomee-plume` dependency
+
+To make things as easy as possible there is just one dependency that will give you a classpath that is 100% identical to your favorite Apache TomEE distribution. The following dependency will pull give you an environment identical to an Apache TomEE Plume binary distribution.
+
+[source,xml]
+----
+<dependency>
+ <groupId>org.apache.tomee.bom</groupId>
+ <artifactId>tomee-plume</artifactId>
+ <version>${version.tomee}</version>
+</dependency>
+----
+
+NOTE: The `org.apache.tomee.bom:tomee-plume` is actually generated by analyzing the apache-tomee-plume-x.y.z.zip, so is guaranteed to be 100% identical making it easy to transition from a zip file to a simple maven dependency.
+
+== Write Regular Code
+
+Here we see a simple JAX-RS API for sending/recieving `Movie` objects as JSON.
+
+[source,java]
+----
+@Path("/movies")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestScoped
+public class MovieService {
+
+ private Map<Integer, Movie> store = new ConcurrentHashMap<>();
+
+ @PostConstruct
+ public void construct(){
+ this.addMovie(new Movie("Wedding Crashers", "David Dobkin", "Comedy", 1, 2005));
+ this.addMovie(new Movie("Starsky & Hutch", "Todd Phillips", "Action", 2, 2004));
+ this.addMovie(new Movie("Shanghai Knights", "David Dobkin", "Action", 3, 2003));
+ this.addMovie(new Movie("I-Spy", "Betty Thomas", "Adventure", 4, 2002));
+ this.addMovie(new Movie("The Royal Tenenbaums", "Wes Anderson", "Comedy", 5, 2001));
+ this.addMovie(new Movie("Zoolander", "Ben Stiller", "Comedy", 6, 2001));
+ }
+ @GET
+ public List<Movie> getAllMovies() {
+ return new ArrayList<>(store.values());
+ }
+
+ @POST
+ public Movie addMovie(final Movie newMovie) {
+ store.put(newMovie.getId(), newMovie);
+ return newMovie;
+ }
+
+}
+----
+
+== Bootstrap TomEE with the Server Builder
+
+A this point we have a Maven project with the right dependencies and some application code in our project. From here we use the `Server.Builder` API to construct a `Server` instance inside our JVM.
+
+Here we see a simple Main class that bootstraps a `Server` instance on port `8080` and blocks:
+
+[source,java]
+----
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+
+import java.util.concurrent.Semaphore;
+
+public class Main {
+ public static void main(String[] args) throws InterruptedException {
+
+ final Server server = Server.builder()
+ .httpPort(8080)
+ .add("webapps/ROOT/WEB-INF/classes", Archive.archive()
+ .add(Api.class)
+ .add(Movie.class)
+ .add(MovieService.class))
+ .build();
+
+ System.out.println("Listening for requests at " + server.getURI());
+ new Semaphore(0).acquire();
+ }
+}
+----
+
+The example below bootstraps a `Server` instance on random ports inside a test case and exits when the test case is complete:
+
+[source,java]
+----
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+//...
+
+public class MovieServiceTest {
+
+ private static URI serverURI;
+
+ @BeforeClass
+ public static void setup() {
+ // Add any classes you need to an Archive
+ // or add them to a jar via any means
+ final Archive classes = Archive.archive()
+ .add(Api.class)
+ .add(Movie.class)
+ .add(MovieService.class);
+
+ // Place the classes where you would want
+ // them in a Tomcat install
+ final Server server = Server.builder()
+ // This effectively creates a webapp called ROOT
+ .add("webapps/ROOT/WEB-INF/classes", classes)
+ .build();
+
+ serverURI = server.getURI();
+ }
+
+ @Test
+ public void getAllMovies() {
+ final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+ final Movie[] movies = target.path("/api/movies").request().get(Movie[].class);
+
+ assertEquals(6, movies.length);
+
+ final Movie movie = movies[1];
+ assertEquals("Todd Phillips", movie.getDirector());
+ assertEquals("Starsky & Hutch", movie.getTitle());
+ assertEquals("Action", movie.getGenre());
+ assertEquals(2004, movie.getYear());
+ assertEquals(2, movie.getId());
+ }
+}
+----
+
+In the above code we have assembled the classes `Api`, `Movie` and `MovieService` into a virtual archive, then we add that archive into a virtual Tomcat install at the location `webapps/ROOT/WEB-INF/classes`. When we call `build()` the Tomcat server instance is started in our JVM and will begin serving HTTP requests at the host/port identified by `server.getURI()`
+
+In short, we've bootstrapped a Tomcat server in our JVM that has a very tiny disk footprint; three classes and a handful of default configuration files.
+
+== Running
+
+Were we to run the above Main class or Test Case we'd see output like the following:
+
+[source,bash]
+----
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener deployApplication
+INFO: org.apache.cxf.jaxrs.validation.ValidationExceptionMapper@2d313c8c
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO: REST Application: http://localhost:8080/api -> org.superbiz.movie.Api@6b2dd3df
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO: Service URI: http://localhost:8080/api/movies -> Pojo org.superbiz.movie.MovieService
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO: GET http://localhost:8080/api/movies -> List<Movie> getAllMovies()
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO: POST http://localhost:8080/api/movies -> Movie addMovie(Movie)
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Deployment of web application directory [/private/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp14966428831095231081dir/apache-tomee/webapps/ROOT] has finished in [1,798] ms
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Starting ProtocolHandler ["http-nio-8080"]
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Server startup in [1877] milliseconds
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Full bootstrap in [3545] milliseconds
+Listening for requests at http://localhost:8080
+----
diff --git a/examples/serverless-tomee-plume/pom.xml b/examples/serverless-tomee-plume/pom.xml
new file mode 100644
index 0000000..b7fd7f9
--- /dev/null
+++ b/examples/serverless-tomee-plume/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+-->
+<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/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.superbiz</groupId>
+ <artifactId>serverless-tomee-plume</artifactId>
+ <version>8.0.5-SNAPSHOT</version>
+
+ <name>TomEE :: Examples :: Serverless Apache TomEE Plume</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <version.tomee>8.0.5-SNAPSHOT</version.tomee>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tomee.bom</groupId>
+ <artifactId>tomee-webprofile</artifactId>
+ <version>${version.tomee}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.5.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <!--
+ This section allows you to configure where to publish libraries for sharing.
+ It is not required and may be deleted. For more information see:
+ http://maven.apache.org/plugins/maven-deploy-plugin/
+ -->
+ <distributionManagement>
+ <repository>
+ <id>localhost</id>
+ <url>file://${basedir}/target/repo/</url>
+ </repository>
+ <snapshotRepository>
+ <id>localhost</id>
+ <url>file://${basedir}/target/snapshot-repo/</url>
+ </snapshotRepository>
+ </distributionManagement>
+</project>
diff --git a/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/Api.java b/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/Api.java
new file mode 100644
index 0000000..a7c43d3
--- /dev/null
+++ b/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/Api.java
@@ -0,0 +1,24 @@
+/*
+ * 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.movie;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+@ApplicationPath("/api")
+public class Api extends Application {
+}
diff --git a/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/Movie.java b/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/Movie.java
new file mode 100644
index 0000000..450959b
--- /dev/null
+++ b/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/Movie.java
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+package org.superbiz.movie;
+
+public class Movie {
+
+ private String title;
+ private String director;
+ private String genre;
+ private int id;
+ private int year;
+
+ public Movie() {
+ }
+
+ public Movie(final String title, final String director, final String genre, final int id, final int year) {
+ this.title = title;
+ this.director = director;
+ this.genre = genre;
+ this.id = id;
+ this.year = year;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(final String title) {
+ this.title = title;
+ }
+
+ public String getDirector() {
+ return director;
+ }
+
+ public void setDirector(final String director) {
+ this.director = director;
+ }
+
+ public String getGenre() {
+ return genre;
+ }
+
+ public void setGenre(final String genre) {
+ this.genre = genre;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(final int id) {
+ this.id = id;
+ }
+
+ public int getYear() {
+ return year;
+ }
+
+ public void setYear(final int year) {
+ this.year = year;
+ }
+}
diff --git a/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/MovieService.java b/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/MovieService.java
new file mode 100644
index 0000000..b8acbc2
--- /dev/null
+++ b/examples/serverless-tomee-plume/src/main/java/org/superbiz/movie/MovieService.java
@@ -0,0 +1,60 @@
+/*
+ * 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.movie;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.RequestScoped;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Path("/movies")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestScoped
+public class MovieService {
+
+ private Map<Integer, Movie> store = new ConcurrentHashMap<>();
+
+ @PostConstruct
+ public void construct(){
+ this.addMovie(new Movie("Wedding Crashers", "David Dobkin", "Comedy", 1, 2005));
+ this.addMovie(new Movie("Starsky & Hutch", "Todd Phillips", "Action", 2, 2004));
+ this.addMovie(new Movie("Shanghai Knights", "David Dobkin", "Action", 3, 2003));
+ this.addMovie(new Movie("I-Spy", "Betty Thomas", "Adventure", 4, 2002));
+ this.addMovie(new Movie("The Royal Tenenbaums", "Wes Anderson", "Comedy", 5, 2001));
+ this.addMovie(new Movie("Zoolander", "Ben Stiller", "Comedy", 6, 2001));
+ }
+ @GET
+ public List<Movie> getAllMovies() {
+ return new ArrayList<>(store.values());
+ }
+
+ @POST
+ public Movie addMovie(final Movie newMovie) {
+ store.put(newMovie.getId(), newMovie);
+ return newMovie;
+ }
+
+}
diff --git a/examples/serverless-tomee-plume/src/test/java/org/superbiz/movie/Main.java b/examples/serverless-tomee-plume/src/test/java/org/superbiz/movie/Main.java
new file mode 100644
index 0000000..2f077aa
--- /dev/null
+++ b/examples/serverless-tomee-plume/src/test/java/org/superbiz/movie/Main.java
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+package org.superbiz.movie;
+
+import org.apache.tomee.bootstrap.Server;
+
+public class Main {
+ public static void main(String[] args) {
+ final Server server = Server.builder().build();
+
+ System.out.println("Listening for requests at " + server.getURI());
+ }
+
+
+// public static void main(String[] args) {
+// Server.builder()
+// .home(file -> Stream.of(file.listFiles()).forEach(System.out::println))
+// .build();
+// }
+//
+}
diff --git a/examples/serverless-tomee-plume/src/test/java/org/superbiz/movie/MovieServiceTest.java b/examples/serverless-tomee-plume/src/test/java/org/superbiz/movie/MovieServiceTest.java
new file mode 100644
index 0000000..08b5a69
--- /dev/null
+++ b/examples/serverless-tomee-plume/src/test/java/org/superbiz/movie/MovieServiceTest.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
+ *
+ * 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.
+ */
+package org.superbiz.movie;
+
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import java.net.URI;
+
+import static javax.ws.rs.client.Entity.entity;
+import static org.junit.Assert.assertEquals;
+
+public class MovieServiceTest {
+
+ private static URI serverURI;
+
+ @BeforeClass
+ public static void setup() {
+ // Add any classes you need to an Archive
+ // or add them to a jar via any means
+ final Archive classes = Archive.archive()
+ .add(Api.class)
+ .add(Movie.class)
+ .add(MovieService.class);
+
+ // Place the classes where you would want
+ // them in a Tomcat install
+ final Server server = Server.builder()
+ // This effectively creates a webapp called ROOT
+ .add("webapps/ROOT/WEB-INF/classes", classes)
+ .build();
+
+ serverURI = server.getURI();
+ }
+
+ @Test
+ public void getAllMovies() {
+ final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+ final Movie[] movies = target.path("/api/movies").request().get(Movie[].class);
+
+ assertEquals(6, movies.length);
+
+ final Movie movie = movies[1];
+ assertEquals("Todd Phillips", movie.getDirector());
+ assertEquals("Starsky & Hutch", movie.getTitle());
+ assertEquals("Action", movie.getGenre());
+ assertEquals(2004, movie.getYear());
+ assertEquals(2, movie.getId());
+ }
+
+ @Test
+ public void addMovie() {
+ final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+ final Movie movie = new Movie("Shanghai Noon", "Tom Dey", "Comedy", 7, 2000);
+
+ final Movie posted = target.path("/api/movies").request()
+ .post(entity(movie, MediaType.APPLICATION_JSON))
+ .readEntity(Movie.class);
+
+ assertEquals("Tom Dey", posted.getDirector());
+ assertEquals("Shanghai Noon", posted.getTitle());
+ assertEquals("Comedy", posted.getGenre());
+ assertEquals(2000, posted.getYear());
+ assertEquals(7, posted.getId());
+ }
+}
diff --git a/examples/serverless-tomee-plus/README.adoc b/examples/serverless-tomee-plus/README.adoc
new file mode 100644
index 0000000..5852df5
--- /dev/null
+++ b/examples/serverless-tomee-plus/README.adoc
@@ -0,0 +1,168 @@
+:index-group: Serverless
+:jbake-type: page
+:jbake-status: status=published
+= Serverless TomEE Plus
+
+Apache TomEE can be run as a library inside your JVM with no need for separate processes or a standalone server install. In this approach we include the right libraries in our project and then bootstrap TomEE using the `Server.Builder` API.
+
+== Include the `tomee-plus` dependency
+
+To make things as easy as possible there is just one dependency that will give you a classpath that is 100% identical to your favorite Apache TomEE distribution. The following dependency will pull give you an environment identical to an Apache TomEE Plus binary distribution.
+
+[source,xml]
+----
+<dependency>
+ <groupId>org.apache.tomee.bom</groupId>
+ <artifactId>tomee-plus</artifactId>
+ <version>${version.tomee}</version>
+</dependency>
+----
+
+NOTE: The `org.apache.tomee.bom:tomee-plus` is actually generated by analyzing the apache-tomee-plus-x.y.z.zip, so is guaranteed to be 100% identical making it easy to transition from a zip file to a simple maven dependency.
+
+== Write Regular Code
+
+Here we see a simple JAX-RS API for sending/recieving `Movie` objects as JSON.
+
+[source,java]
+----
+@Path("/movies")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestScoped
+public class MovieService {
+
+ private Map<Integer, Movie> store = new ConcurrentHashMap<>();
+
+ @PostConstruct
+ public void construct(){
+ this.addMovie(new Movie("Wedding Crashers", "David Dobkin", "Comedy", 1, 2005));
+ this.addMovie(new Movie("Starsky & Hutch", "Todd Phillips", "Action", 2, 2004));
+ this.addMovie(new Movie("Shanghai Knights", "David Dobkin", "Action", 3, 2003));
+ this.addMovie(new Movie("I-Spy", "Betty Thomas", "Adventure", 4, 2002));
+ this.addMovie(new Movie("The Royal Tenenbaums", "Wes Anderson", "Comedy", 5, 2001));
+ this.addMovie(new Movie("Zoolander", "Ben Stiller", "Comedy", 6, 2001));
+ }
+ @GET
+ public List<Movie> getAllMovies() {
+ return new ArrayList<>(store.values());
+ }
+
+ @POST
+ public Movie addMovie(final Movie newMovie) {
+ store.put(newMovie.getId(), newMovie);
+ return newMovie;
+ }
+
+}
+----
+
+== Bootstrap TomEE with the Server Builder
+
+A this point we have a Maven project with the right dependencies and some application code in our project. From here we use the `Server.Builder` API to construct a `Server` instance inside our JVM.
+
+Here we see a simple Main class that bootstraps a `Server` instance on port `8080` and blocks:
+
+[source,java]
+----
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+
+import java.util.concurrent.Semaphore;
+
+public class Main {
+ public static void main(String[] args) throws InterruptedException {
+
+ final Server server = Server.builder()
+ .httpPort(8080)
+ .add("webapps/ROOT/WEB-INF/classes", Archive.archive()
+ .add(Api.class)
+ .add(Movie.class)
+ .add(MovieService.class))
+ .build();
+
+ System.out.println("Listening for requests at " + server.getURI());
+ new Semaphore(0).acquire();
+ }
+}
+----
+
+The example below bootstraps a `Server` instance on random ports inside a test case and exits when the test case is complete:
+
+[source,java]
+----
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+//...
+
+public class MovieServiceTest {
+
+ private static URI serverURI;
+
+ @BeforeClass
+ public static void setup() {
+ // Add any classes you need to an Archive
+ // or add them to a jar via any means
+ final Archive classes = Archive.archive()
+ .add(Api.class)
+ .add(Movie.class)
+ .add(MovieService.class);
+
+ // Place the classes where you would want
+ // them in a Tomcat install
+ final Server server = Server.builder()
+ // This effectively creates a webapp called ROOT
+ .add("webapps/ROOT/WEB-INF/classes", classes)
+ .build();
+
+ serverURI = server.getURI();
+ }
+
+ @Test
+ public void getAllMovies() {
+ final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+ final Movie[] movies = target.path("/api/movies").request().get(Movie[].class);
+
+ assertEquals(6, movies.length);
+
+ final Movie movie = movies[1];
+ assertEquals("Todd Phillips", movie.getDirector());
+ assertEquals("Starsky & Hutch", movie.getTitle());
+ assertEquals("Action", movie.getGenre());
+ assertEquals(2004, movie.getYear());
+ assertEquals(2, movie.getId());
+ }
+}
+----
+
+In the above code we have assembled the classes `Api`, `Movie` and `MovieService` into a virtual archive, then we add that archive into a virtual Tomcat install at the location `webapps/ROOT/WEB-INF/classes`. When we call `build()` the Tomcat server instance is started in our JVM and will begin serving HTTP requests at the host/port identified by `server.getURI()`
+
+In short, we've bootstrapped a Tomcat server in our JVM that has a very tiny disk footprint; three classes and a handful of default configuration files.
+
+== Running
+
+Were we to run the above Main class or Test Case we'd see output like the following:
+
+[source,bash]
+----
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener deployApplication
+INFO: org.apache.cxf.jaxrs.validation.ValidationExceptionMapper@2d313c8c
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO: REST Application: http://localhost:8080/api -> org.superbiz.movie.Api@6b2dd3df
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO: Service URI: http://localhost:8080/api/movies -> Pojo org.superbiz.movie.MovieService
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO: GET http://localhost:8080/api/movies -> List<Movie> getAllMovies()
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO: POST http://localhost:8080/api/movies -> Movie addMovie(Movie)
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Deployment of web application directory [/private/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp14966428831095231081dir/apache-tomee/webapps/ROOT] has finished in [1,798] ms
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Starting ProtocolHandler ["http-nio-8080"]
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Server startup in [1877] milliseconds
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Full bootstrap in [3545] milliseconds
+Listening for requests at http://localhost:8080
+----
diff --git a/examples/serverless-tomee-plus/pom.xml b/examples/serverless-tomee-plus/pom.xml
new file mode 100644
index 0000000..6c06365
--- /dev/null
+++ b/examples/serverless-tomee-plus/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+-->
+<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/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.superbiz</groupId>
+ <artifactId>serverless-tomee-plus</artifactId>
+ <version>8.0.5-SNAPSHOT</version>
+
+ <name>TomEE :: Examples :: Serverless Apache TomEE Plus</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <version.tomee>8.0.5-SNAPSHOT</version.tomee>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tomee.bom</groupId>
+ <artifactId>tomee-plus</artifactId>
+ <version>${version.tomee}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.5.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <!--
+ This section allows you to configure where to publish libraries for sharing.
+ It is not required and may be deleted. For more information see:
+ http://maven.apache.org/plugins/maven-deploy-plugin/
+ -->
+ <distributionManagement>
+ <repository>
+ <id>localhost</id>
+ <url>file://${basedir}/target/repo/</url>
+ </repository>
+ <snapshotRepository>
+ <id>localhost</id>
+ <url>file://${basedir}/target/snapshot-repo/</url>
+ </snapshotRepository>
+ </distributionManagement>
+</project>
diff --git a/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/Api.java b/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/Api.java
new file mode 100644
index 0000000..a7c43d3
--- /dev/null
+++ b/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/Api.java
@@ -0,0 +1,24 @@
+/*
+ * 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.movie;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+@ApplicationPath("/api")
+public class Api extends Application {
+}
diff --git a/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/Movie.java b/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/Movie.java
new file mode 100644
index 0000000..450959b
--- /dev/null
+++ b/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/Movie.java
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+package org.superbiz.movie;
+
+public class Movie {
+
+ private String title;
+ private String director;
+ private String genre;
+ private int id;
+ private int year;
+
+ public Movie() {
+ }
+
+ public Movie(final String title, final String director, final String genre, final int id, final int year) {
+ this.title = title;
+ this.director = director;
+ this.genre = genre;
+ this.id = id;
+ this.year = year;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(final String title) {
+ this.title = title;
+ }
+
+ public String getDirector() {
+ return director;
+ }
+
+ public void setDirector(final String director) {
+ this.director = director;
+ }
+
+ public String getGenre() {
+ return genre;
+ }
+
+ public void setGenre(final String genre) {
+ this.genre = genre;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(final int id) {
+ this.id = id;
+ }
+
+ public int getYear() {
+ return year;
+ }
+
+ public void setYear(final int year) {
+ this.year = year;
+ }
+}
diff --git a/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/MovieService.java b/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/MovieService.java
new file mode 100644
index 0000000..b8acbc2
--- /dev/null
+++ b/examples/serverless-tomee-plus/src/main/java/org/superbiz/movie/MovieService.java
@@ -0,0 +1,60 @@
+/*
+ * 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.movie;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.RequestScoped;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Path("/movies")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestScoped
+public class MovieService {
+
+ private Map<Integer, Movie> store = new ConcurrentHashMap<>();
+
+ @PostConstruct
+ public void construct(){
+ this.addMovie(new Movie("Wedding Crashers", "David Dobkin", "Comedy", 1, 2005));
+ this.addMovie(new Movie("Starsky & Hutch", "Todd Phillips", "Action", 2, 2004));
+ this.addMovie(new Movie("Shanghai Knights", "David Dobkin", "Action", 3, 2003));
+ this.addMovie(new Movie("I-Spy", "Betty Thomas", "Adventure", 4, 2002));
+ this.addMovie(new Movie("The Royal Tenenbaums", "Wes Anderson", "Comedy", 5, 2001));
+ this.addMovie(new Movie("Zoolander", "Ben Stiller", "Comedy", 6, 2001));
+ }
+ @GET
+ public List<Movie> getAllMovies() {
+ return new ArrayList<>(store.values());
+ }
+
+ @POST
+ public Movie addMovie(final Movie newMovie) {
+ store.put(newMovie.getId(), newMovie);
+ return newMovie;
+ }
+
+}
diff --git a/examples/serverless-tomee-plus/src/test/java/org/superbiz/movie/Main.java b/examples/serverless-tomee-plus/src/test/java/org/superbiz/movie/Main.java
new file mode 100644
index 0000000..2f077aa
--- /dev/null
+++ b/examples/serverless-tomee-plus/src/test/java/org/superbiz/movie/Main.java
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+package org.superbiz.movie;
+
+import org.apache.tomee.bootstrap.Server;
+
+public class Main {
+ public static void main(String[] args) {
+ final Server server = Server.builder().build();
+
+ System.out.println("Listening for requests at " + server.getURI());
+ }
+
+
+// public static void main(String[] args) {
+// Server.builder()
+// .home(file -> Stream.of(file.listFiles()).forEach(System.out::println))
+// .build();
+// }
+//
+}
diff --git a/examples/serverless-tomee-plus/src/test/java/org/superbiz/movie/MovieServiceTest.java b/examples/serverless-tomee-plus/src/test/java/org/superbiz/movie/MovieServiceTest.java
new file mode 100644
index 0000000..08b5a69
--- /dev/null
+++ b/examples/serverless-tomee-plus/src/test/java/org/superbiz/movie/MovieServiceTest.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
+ *
+ * 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.
+ */
+package org.superbiz.movie;
+
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import java.net.URI;
+
+import static javax.ws.rs.client.Entity.entity;
+import static org.junit.Assert.assertEquals;
+
+public class MovieServiceTest {
+
+ private static URI serverURI;
+
+ @BeforeClass
+ public static void setup() {
+ // Add any classes you need to an Archive
+ // or add them to a jar via any means
+ final Archive classes = Archive.archive()
+ .add(Api.class)
+ .add(Movie.class)
+ .add(MovieService.class);
+
+ // Place the classes where you would want
+ // them in a Tomcat install
+ final Server server = Server.builder()
+ // This effectively creates a webapp called ROOT
+ .add("webapps/ROOT/WEB-INF/classes", classes)
+ .build();
+
+ serverURI = server.getURI();
+ }
+
+ @Test
+ public void getAllMovies() {
+ final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+ final Movie[] movies = target.path("/api/movies").request().get(Movie[].class);
+
+ assertEquals(6, movies.length);
+
+ final Movie movie = movies[1];
+ assertEquals("Todd Phillips", movie.getDirector());
+ assertEquals("Starsky & Hutch", movie.getTitle());
+ assertEquals("Action", movie.getGenre());
+ assertEquals(2004, movie.getYear());
+ assertEquals(2, movie.getId());
+ }
+
+ @Test
+ public void addMovie() {
+ final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+ final Movie movie = new Movie("Shanghai Noon", "Tom Dey", "Comedy", 7, 2000);
+
+ final Movie posted = target.path("/api/movies").request()
+ .post(entity(movie, MediaType.APPLICATION_JSON))
+ .readEntity(Movie.class);
+
+ assertEquals("Tom Dey", posted.getDirector());
+ assertEquals("Shanghai Noon", posted.getTitle());
+ assertEquals("Comedy", posted.getGenre());
+ assertEquals(2000, posted.getYear());
+ assertEquals(7, posted.getId());
+ }
+}
diff --git a/examples/serverless-tomee-webprofile/README.adoc b/examples/serverless-tomee-webprofile/README.adoc
new file mode 100644
index 0000000..c1bdbd0
--- /dev/null
+++ b/examples/serverless-tomee-webprofile/README.adoc
@@ -0,0 +1,168 @@
+:index-group: Serverless
+:jbake-type: page
+:jbake-status: status=published
+= Serverless TomEE WebProfile
+
+Apache TomEE can be run as a library inside your JVM with no need for separate processes or a standalone server install. In this approach we include the right libraries in our project and then bootstrap TomEE using the `Server.Builder` API.
+
+== Include the `tomee-webprofile` dependency
+
+To make things as easy as possible there is just one dependency that will give you a classpath that is 100% identical to your favorite Apache TomEE distribution. The following dependency will pull give you an environment identical to an Apache TomEE WebProfile binary distribution.
+
+[source,xml]
+----
+<dependency>
+ <groupId>org.apache.tomee.bom</groupId>
+ <artifactId>tomee-webprofile</artifactId>
+ <version>${version.tomee}</version>
+</dependency>
+----
+
+NOTE: The `org.apache.tomee.bom:tomee-webprofile` is actually generated by analyzing the apache-tomee-webprofile-x.y.z.zip, so is guaranteed to be 100% identical making it easy to transition from a zip file to a simple maven dependency.
+
+== Write Regular Code
+
+Here we see a simple JAX-RS API for sending/recieving `Movie` objects as JSON.
+
+[source,java]
+----
+@Path("/movies")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestScoped
+public class MovieService {
+
+ private Map<Integer, Movie> store = new ConcurrentHashMap<>();
+
+ @PostConstruct
+ public void construct(){
+ this.addMovie(new Movie("Wedding Crashers", "David Dobkin", "Comedy", 1, 2005));
+ this.addMovie(new Movie("Starsky & Hutch", "Todd Phillips", "Action", 2, 2004));
+ this.addMovie(new Movie("Shanghai Knights", "David Dobkin", "Action", 3, 2003));
+ this.addMovie(new Movie("I-Spy", "Betty Thomas", "Adventure", 4, 2002));
+ this.addMovie(new Movie("The Royal Tenenbaums", "Wes Anderson", "Comedy", 5, 2001));
+ this.addMovie(new Movie("Zoolander", "Ben Stiller", "Comedy", 6, 2001));
+ }
+ @GET
+ public List<Movie> getAllMovies() {
+ return new ArrayList<>(store.values());
+ }
+
+ @POST
+ public Movie addMovie(final Movie newMovie) {
+ store.put(newMovie.getId(), newMovie);
+ return newMovie;
+ }
+
+}
+----
+
+== Bootstrap TomEE with the Server Builder
+
+A this point we have a Maven project with the right dependencies and some application code in our project. From here we use the `Server.Builder` API to construct a `Server` instance inside our JVM.
+
+Here we see a simple Main class that bootstraps a `Server` instance on port `8080` and blocks:
+
+[source,java]
+----
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+
+import java.util.concurrent.Semaphore;
+
+public class Main {
+ public static void main(String[] args) throws InterruptedException {
+
+ final Server server = Server.builder()
+ .httpPort(8080)
+ .add("webapps/ROOT/WEB-INF/classes", Archive.archive()
+ .add(Api.class)
+ .add(Movie.class)
+ .add(MovieService.class))
+ .build();
+
+ System.out.println("Listening for requests at " + server.getURI());
+ new Semaphore(0).acquire();
+ }
+}
+----
+
+The example below bootstraps a `Server` instance on random ports inside a test case and exits when the test case is complete:
+
+[source,java]
+----
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+//...
+
+public class MovieServiceTest {
+
+ private static URI serverURI;
+
+ @BeforeClass
+ public static void setup() {
+ // Add any classes you need to an Archive
+ // or add them to a jar via any means
+ final Archive classes = Archive.archive()
+ .add(Api.class)
+ .add(Movie.class)
+ .add(MovieService.class);
+
+ // Place the classes where you would want
+ // them in a Tomcat install
+ final Server server = Server.builder()
+ // This effectively creates a webapp called ROOT
+ .add("webapps/ROOT/WEB-INF/classes", classes)
+ .build();
+
+ serverURI = server.getURI();
+ }
+
+ @Test
+ public void getAllMovies() {
+ final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+ final Movie[] movies = target.path("/api/movies").request().get(Movie[].class);
+
+ assertEquals(6, movies.length);
+
+ final Movie movie = movies[1];
+ assertEquals("Todd Phillips", movie.getDirector());
+ assertEquals("Starsky & Hutch", movie.getTitle());
+ assertEquals("Action", movie.getGenre());
+ assertEquals(2004, movie.getYear());
+ assertEquals(2, movie.getId());
+ }
+}
+----
+
+In the above code we have assembled the classes `Api`, `Movie` and `MovieService` into a virtual archive, then we add that archive into a virtual Tomcat install at the location `webapps/ROOT/WEB-INF/classes`. When we call `build()` the Tomcat server instance is started in our JVM and will begin serving HTTP requests at the host/port identified by `server.getURI()`
+
+In short, we've bootstrapped a Tomcat server in our JVM that has a very tiny disk footprint; three classes and a handful of default configuration files.
+
+== Running
+
+Were we to run the above Main class or Test Case we'd see output like the following:
+
+[source,bash]
+----
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener deployApplication
+INFO: org.apache.cxf.jaxrs.validation.ValidationExceptionMapper@2d313c8c
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO: REST Application: http://localhost:8080/api -> org.superbiz.movie.Api@6b2dd3df
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO: Service URI: http://localhost:8080/api/movies -> Pojo org.superbiz.movie.MovieService
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO: GET http://localhost:8080/api/movies -> List<Movie> getAllMovies()
+Sep 03, 2020 8:41:29 AM org.apache.openejb.server.cxf.rs.CxfRsHttpListener logEndpoints
+INFO: POST http://localhost:8080/api/movies -> Movie addMovie(Movie)
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Deployment of web application directory [/private/var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp14966428831095231081dir/apache-tomee/webapps/ROOT] has finished in [1,798] ms
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Starting ProtocolHandler ["http-nio-8080"]
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Server startup in [1877] milliseconds
+Sep 03, 2020 8:41:29 AM jdk.internal.reflect.DelegatingMethodAccessorImpl invoke
+INFO: Full bootstrap in [3545] milliseconds
+Listening for requests at http://localhost:8080
+----
diff --git a/examples/serverless-tomee-webprofile/pom.xml b/examples/serverless-tomee-webprofile/pom.xml
new file mode 100644
index 0000000..b778eef
--- /dev/null
+++ b/examples/serverless-tomee-webprofile/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+-->
+<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/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.superbiz</groupId>
+ <artifactId>serverless-tomee-webprofile</artifactId>
+ <version>8.0.5-SNAPSHOT</version>
+
+ <name>TomEE :: Examples :: Serverless Apache TomEE WebProfile</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <version.tomee>8.0.5-SNAPSHOT</version.tomee>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tomee.bom</groupId>
+ <artifactId>tomee-webprofile</artifactId>
+ <version>${version.tomee}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.5.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <!--
+ This section allows you to configure where to publish libraries for sharing.
+ It is not required and may be deleted. For more information see:
+ http://maven.apache.org/plugins/maven-deploy-plugin/
+ -->
+ <distributionManagement>
+ <repository>
+ <id>localhost</id>
+ <url>file://${basedir}/target/repo/</url>
+ </repository>
+ <snapshotRepository>
+ <id>localhost</id>
+ <url>file://${basedir}/target/snapshot-repo/</url>
+ </snapshotRepository>
+ </distributionManagement>
+</project>
diff --git a/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/Api.java b/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/Api.java
new file mode 100644
index 0000000..320fddc
--- /dev/null
+++ b/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/Api.java
@@ -0,0 +1,24 @@
+/*
+ * 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.movie.wp;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+@ApplicationPath("/api")
+public class Api extends Application {
+}
diff --git a/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/Movie.java b/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/Movie.java
new file mode 100644
index 0000000..b5b02df
--- /dev/null
+++ b/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/Movie.java
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+package org.superbiz.movie.wp;
+
+public class Movie {
+
+ private String title;
+ private String director;
+ private String genre;
+ private int id;
+ private int year;
+
+ public Movie() {
+ }
+
+ public Movie(final String title, final String director, final String genre, final int id, final int year) {
+ this.title = title;
+ this.director = director;
+ this.genre = genre;
+ this.id = id;
+ this.year = year;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(final String title) {
+ this.title = title;
+ }
+
+ public String getDirector() {
+ return director;
+ }
+
+ public void setDirector(final String director) {
+ this.director = director;
+ }
+
+ public String getGenre() {
+ return genre;
+ }
+
+ public void setGenre(final String genre) {
+ this.genre = genre;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(final int id) {
+ this.id = id;
+ }
+
+ public int getYear() {
+ return year;
+ }
+
+ public void setYear(final int year) {
+ this.year = year;
+ }
+}
diff --git a/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/MovieService.java b/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/MovieService.java
new file mode 100644
index 0000000..d12ef58
--- /dev/null
+++ b/examples/serverless-tomee-webprofile/src/main/java/org/superbiz/movie/wp/MovieService.java
@@ -0,0 +1,60 @@
+/*
+ * 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.movie.wp;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.RequestScoped;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Path("/movies")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestScoped
+public class MovieService {
+
+ private Map<Integer, Movie> store = new ConcurrentHashMap<>();
+
+ @PostConstruct
+ public void construct(){
+ this.addMovie(new Movie("Wedding Crashers", "David Dobkin", "Comedy", 1, 2005));
+ this.addMovie(new Movie("Starsky & Hutch", "Todd Phillips", "Action", 2, 2004));
+ this.addMovie(new Movie("Shanghai Knights", "David Dobkin", "Action", 3, 2003));
+ this.addMovie(new Movie("I-Spy", "Betty Thomas", "Adventure", 4, 2002));
+ this.addMovie(new Movie("The Royal Tenenbaums", "Wes Anderson", "Comedy", 5, 2001));
+ this.addMovie(new Movie("Zoolander", "Ben Stiller", "Comedy", 6, 2001));
+ }
+ @GET
+ public List<Movie> getAllMovies() {
+ return new ArrayList<>(store.values());
+ }
+
+ @POST
+ public Movie addMovie(final Movie newMovie) {
+ store.put(newMovie.getId(), newMovie);
+ return newMovie;
+ }
+
+}
diff --git a/examples/serverless-tomee-webprofile/src/test/java/org/superbiz/movie/wp/Main.java b/examples/serverless-tomee-webprofile/src/test/java/org/superbiz/movie/wp/Main.java
new file mode 100644
index 0000000..df2b47e
--- /dev/null
+++ b/examples/serverless-tomee-webprofile/src/test/java/org/superbiz/movie/wp/Main.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+package org.superbiz.movie.wp;
+
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+
+public class Main {
+ public static void main(String[] args) {
+ final Server server = Server.builder()
+ .add("webapps/ROOT/WEB-INF/classes", Archive.archive()
+ .add(Api.class)
+ .add(Movie.class)
+ .add(MovieService.class))
+ .build();
+
+ System.out.println("Listening for requests at " + server.getURI());
+ }
+}
diff --git a/examples/serverless-tomee-webprofile/src/test/java/org/superbiz/movie/wp/MovieServiceTest.java b/examples/serverless-tomee-webprofile/src/test/java/org/superbiz/movie/wp/MovieServiceTest.java
new file mode 100644
index 0000000..23e1274
--- /dev/null
+++ b/examples/serverless-tomee-webprofile/src/test/java/org/superbiz/movie/wp/MovieServiceTest.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
+ *
+ * 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.
+ */
+package org.superbiz.movie.wp;
+
+import org.apache.tomee.bootstrap.Archive;
+import org.apache.tomee.bootstrap.Server;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import java.net.URI;
+
+import static javax.ws.rs.client.Entity.entity;
+import static org.junit.Assert.assertEquals;
+
+public class MovieServiceTest {
+
+ private static URI serverURI;
+
+ @BeforeClass
+ public static void setup() {
+ // Add any classes you need to an Archive
+ // or add them to a jar via any means
+ final Archive classes = Archive.archive()
+ .add(Api.class)
+ .add(Movie.class)
+ .add(MovieService.class);
+
+ // Place the classes where you would want
+ // them in a Tomcat install
+ final Server server = Server.builder()
+ // This effectively creates a webapp called ROOT
+ .add("webapps/ROOT/WEB-INF/classes", classes)
+ .build();
+
+ serverURI = server.getURI();
+ }
+
+ @Test
+ public void getAllMovies() {
+ final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+ final Movie[] movies = target.path("/api/movies").request().get(Movie[].class);
+
+ assertEquals(6, movies.length);
+
+ final Movie movie = movies[1];
+ assertEquals("Todd Phillips", movie.getDirector());
+ assertEquals("Starsky & Hutch", movie.getTitle());
+ assertEquals("Action", movie.getGenre());
+ assertEquals(2004, movie.getYear());
+ assertEquals(2, movie.getId());
+ }
+
+ @Test
+ public void addMovie() {
+ final WebTarget target = ClientBuilder.newClient().target(serverURI);
+
+ final Movie movie = new Movie("Shanghai Noon", "Tom Dey", "Comedy", 7, 2000);
+
+ final Movie posted = target.path("/api/movies").request()
+ .post(entity(movie, MediaType.APPLICATION_JSON))
+ .readEntity(Movie.class);
+
+ assertEquals("Tom Dey", posted.getDirector());
+ assertEquals("Shanghai Noon", posted.getTitle());
+ assertEquals("Comedy", posted.getGenre());
+ assertEquals(2000, posted.getYear());
+ assertEquals(7, posted.getId());
+ }
+}