You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2022/06/23 20:10:10 UTC

[juneau-petstore] branch master updated: Updates to petstore app for 9.0-B1

This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau-petstore.git


The following commit(s) were added to refs/heads/master by this push:
     new 96e4344  Updates to petstore app for 9.0-B1
     new 341ef22  Merge branch 'master' of https://gitbox.apache.org/repos/asf/juneau-petstore.git
96e4344 is described below

commit 96e4344e4776e18f6714c67f57fe96ffbc5e6798
Author: JamesBognar <ja...@salesforce.com>
AuthorDate: Thu Jun 23 16:09:01 2022 -0400

    Updates to petstore app for 9.0-B1
---
 .asf.yaml                                          |  21 +++
 .../java/org/apache/juneau/petstore/PetStore.java  | 157 ++++++++++----------
 .../apache/juneau/petstore/dto/CreateOrder.java    |   2 +-
 .../org/apache/juneau/petstore/dto/CreatePet.java  |   6 +-
 .../apache/juneau/petstore/dto/ExpiresAfter.java   |  11 +-
 .../org/apache/juneau/petstore/dto/IdConflict.java |   4 +-
 .../org/apache/juneau/petstore/dto/IdNotFound.java |   4 +-
 .../org/apache/juneau/petstore/dto/InvalidId.java  |   4 +-
 .../apache/juneau/petstore/dto/InvalidLogin.java   |   4 +-
 .../apache/juneau/petstore/dto/InvalidSpecies.java |   4 +-
 .../org/apache/juneau/petstore/dto/InvalidTag.java |   4 +-
 .../juneau/petstore/dto/InvalidUsername.java       |   4 +-
 .../java/org/apache/juneau/petstore/dto/Order.java |   8 +-
 .../java/org/apache/juneau/petstore/dto/Pet.java   |   6 +-
 .../org/apache/juneau/petstore/dto/PetTag.java     |   2 +-
 .../apache/juneau/petstore/dto/PetTagNameSwap.java |   6 +-
 .../org/apache/juneau/petstore/dto/UpdatePet.java  |   4 +-
 .../java/org/apache/juneau/petstore/dto/User.java  |   4 +-
 .../main/java/org/apache/juneau/petstore/Main.java |   2 +-
 juneau-petstore-server/pom.xml                     |   2 +-
 .../main/java/org/apache/juneau/petstore/App.java  |  45 ++++--
 .../apache/juneau/petstore/AppConfiguration.java   |  48 -------
 .../juneau/petstore/rest/PetStoreResource.java     | 159 ++++++++-------------
 .../apache/juneau/petstore/rest/RootResources.java |   8 +-
 .../org/apache/juneau/petstore/test/MockTest.java  |  32 ++---
 pom.xml                                            |   2 +-
 26 files changed, 257 insertions(+), 296 deletions(-)

diff --git a/.asf.yaml b/.asf.yaml
new file mode 100644
index 0000000..a4e3f3c
--- /dev/null
+++ b/.asf.yaml
@@ -0,0 +1,21 @@
+notifications:
+  commits:      commits@juneau.apache.org
+  issues:       dev@juneau.apache.org
+  pullrequests: dev@juneau.apache.org
+  jira_options: link label worklog
+  jobs:         dev@juneau.apache.org
+  discussions:  dev@juneau.apache.org
+  
+github:
+  description: "Apache Juneau"
+  homepage: https://juneau.apache.org/
+  labels:
+    - json
+    - juneau
+    - http
+    - rest
+    - apache
+  features:
+    wiki: true
+    issues: true
+    projects: true
\ No newline at end of file
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/PetStore.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/PetStore.java
index 76d184f..89aa1f1 100755
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/PetStore.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/PetStore.java
@@ -12,16 +12,12 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.petstore;
 
-import static org.apache.juneau.http.HttpMethod.*;
-
 import java.util.*;
 
-import org.apache.juneau.jsonschema.annotation.Items;
 import org.apache.juneau.petstore.dto.*;
 import org.apache.juneau.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.http.remote.*;
-import org.apache.juneau.http.exception.*;
 import org.apache.juneau.http.response.*;
 
 /**
@@ -50,7 +46,7 @@ public interface PetStore {
 	 * @return All pets in the database.
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 */
-	@RemoteMethod(method=GET, path="/pet")
+	@RemoteGet("/pet")
 	public Collection<Pet> getPets() throws NotAcceptable;
 
 	/**
@@ -61,12 +57,11 @@ public interface PetStore {
 	 * @throws IdNotFound Pet was not found.
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 */
-	@RemoteMethod(path="/pet/{petId}") /* method inferred from method name */
+	@RemoteGet("/pet/{petId}") /* method inferred from method name */
 	public Pet getPet(
 		@Path(
 			name="petId",
-			description="ID of pet to return",
-			example="123"
+			schema=@Schema(description="ID of pet to return")
 		)
 		long petId
 	) throws IdNotFound, NotAcceptable;
@@ -80,11 +75,12 @@ public interface PetStore {
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 * @throws UnsupportedMediaType Unsupported <c>Content-Type</c> header specified.
 	 */
-	@RemoteMethod(method=POST, path="/pet")
+	@RemotePost("/pet")
 	public long createPet(
-		@Body(
-			description="Pet object to add to the store"
-		) CreatePet pet
+		@Content(
+			schema=@Schema(description="Pet object to add to the store")
+		)
+		CreatePet pet
 	) throws IdConflict, NotAcceptable, UnsupportedMediaType;
 
 	/**
@@ -96,11 +92,12 @@ public interface PetStore {
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 * @throws UnsupportedMediaType Unsupported <c>Content-Type</c> header specified.
 	 */
-	@RemoteMethod(method=PUT, path="/pet/{petId}")
+	@RemotePut("/pet/{petId}")
 	public Ok updatePet(
-		@Body(
-			description="Pet object that needs to be added to the store"
-		) UpdatePet pet
+		@Content(
+			schema=@Schema(description="Pet object that needs to be added to the store")
+		)
+		UpdatePet pet
 	) throws IdNotFound, NotAcceptable, UnsupportedMediaType;
 
 	/**
@@ -110,20 +107,21 @@ public interface PetStore {
 	 * @return The pets that match the specified statuses.
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 */
-	@RemoteMethod(method=GET, path="/pet/findByStatus")
+	@RemoteGet("/pet/findByStatus")
 	public Collection<Pet> findPetsByStatus(
 		@Query(
 			name="status",
-			description="Status values that need to be considered for filter.",
-			required=true,
-			type="array",
-			collectionFormat="csv",
-			items=@Items(
-				type="string",
-				_enum="AVAILABLE,PENDING,SOLD",
-				_default="AVAILABLE"
-			),
-			example="AVALIABLE,PENDING"
+			schema=@Schema(
+				description="Status values that need to be considered for filter.",
+				required=true,
+				type="array",
+				collectionFormat="csv",
+				items=@Items(
+					type="string",
+					_enum="AVAILABLE,PENDING,SOLD",
+					_default="AVAILABLE"
+				)
+			)
 		)
 		PetStatus[] status
 	) throws NotAcceptable;
@@ -137,19 +135,19 @@ public interface PetStore {
 	 * @throws IdNotFound Pet not found.
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 */
-	@RemoteMethod(method=DELETE, path="/pet/{petId}")
+	@RemoteDelete("/pet/{petId}")
 	public Ok deletePet(
 		@Header(
 			name="api_key",
-			description="Security API key",
-			required=true,
-			example="foobar"
+			schema=@Schema(
+				description="Security API key",
+				required=true
+			)
 		)
 		String apiKey,
 		@Path(
 			name="petId",
-			description="Pet id to delete",
-			example="123"
+			schema=@Schema(description="Pet id to delete")
 		)
 		long petId
 	) throws IdNotFound, NotAcceptable;
@@ -159,7 +157,7 @@ public interface PetStore {
 	 *
 	 * @return {@link Ok} if successful.
 	 */
-	@RemoteMethod(method=DELETE, path="/pet")
+	@RemoteDelete("/pet")
 	public Ok deleteAllPets();
 
 	//------------------------------------------------------------------------------------------------------------------
@@ -172,7 +170,7 @@ public interface PetStore {
 	 * @return All orders in the database.
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 */
-	@RemoteMethod(method=GET, path="/store/order")
+	@RemoteGet("/store/order")
 	public Collection<Order> getOrders() throws NotAcceptable;
 
 	/**
@@ -184,14 +182,15 @@ public interface PetStore {
 	 * @throws IdNotFound Order was not found.
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 */
-	@RemoteMethod(method=GET, path="/store/order/{orderId}")
+	@RemoteGet("/store/order/{orderId}")
 	public Order getOrder(
 		@Path(
 			name="orderId",
-			description="ID of order to fetch",
-			maximum="1000",
-			minimum="1",
-			example="123"
+			schema=@Schema(
+				description="ID of order to fetch",
+				maximum="1000",
+				minimum="1"
+			)
 		)
 		long orderId
 	) throws InvalidId, IdNotFound, NotAcceptable;
@@ -206,16 +205,16 @@ public interface PetStore {
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 * @throws UnsupportedMediaType Unsupported <c>Content-Type</c> header specified.
 	 */
-	@RemoteMethod(method=POST, path="/store/order")
+	@RemotePost("/store/order")
 	public long placeOrder(
 		@FormData(
 			name="petId",
-			description="Pet ID"
+			schema=@Schema(description="Pet ID")
 		)
 		long petId,
 		@FormData(
 			name="username",
-			description="The username of the user creating the order"
+			schema=@Schema(description="The username of the user creating the order")
 		)
 		String username
 	) throws IdConflict, NotAcceptable, UnsupportedMediaType;
@@ -229,13 +228,14 @@ public interface PetStore {
 	 * @throws IdNotFound Order not found.
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 */
-	@RemoteMethod(method=DELETE, path="/store/order/{orderId}")
+	@RemoteDelete("/store/order/{orderId}")
 	public Ok deleteOrder(
 		@Path(
 			name="orderId",
-			description="ID of the order that needs to be deleted",
-			minimum="1",
-			example="5"
+			schema=@Schema(
+				description="ID of the order that needs to be deleted",
+				minimum="1"
+			)
 		)
 		long orderId
 	) throws InvalidId, IdNotFound, NotAcceptable;
@@ -245,7 +245,7 @@ public interface PetStore {
 	 *
 	 * @return {@link Ok} if successful.
 	 */
-	@RemoteMethod(method=DELETE, path="/store/order")
+	@RemoteDelete("/store/order")
 	public Ok deleteAllOrders();
 
 	/**
@@ -254,7 +254,7 @@ public interface PetStore {
 	 * @return An inventory of pet statuses and counts.
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 */
-	@RemoteMethod(method=GET, path="/store/inventory")
+	@RemoteGet("/store/inventory")
 	public Map<PetStatus,Integer> getStoreInventory() throws NotAcceptable;
 
 	//------------------------------------------------------------------------------------------------------------------
@@ -267,7 +267,7 @@ public interface PetStore {
 	 * @return All users in the database.
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 */
-	@RemoteMethod(method=GET, path="/user")
+	@RemoteGet("/user")
 	public Collection<User> getUsers() throws NotAcceptable;
 
 	/**
@@ -279,11 +279,11 @@ public interface PetStore {
 	 * @throws IdNotFound username not found.
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 */
-	@RemoteMethod(method=GET, path="/user/{username}")
+	@RemoteGet("/user/{username}")
 	public User getUser(
 		@Path(
 			name="username",
-			description="The name that needs to be fetched. Use user1 for testing."
+			schema=@Schema(description="The name that needs to be fetched. Use user1 for testing.")
 		)
 		String username
 	) throws InvalidUsername, IdNotFound, NotAcceptable;
@@ -298,10 +298,10 @@ public interface PetStore {
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 * @throws UnsupportedMediaType Unsupported <c>Content-Type</c> header specified.
 	 */
-	@RemoteMethod(method=POST, path="/user")
+	@RemotePost("/user")
 	public Ok createUser(
-		@Body(
-			description="Created user object"
+		@Content(
+			schema=@Schema(description="Created user object")
 		)
 		User user
 	) throws InvalidUsername, IdConflict, NotAcceptable, UnsupportedMediaType;
@@ -316,10 +316,10 @@ public interface PetStore {
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 * @throws UnsupportedMediaType Unsupported <c>Content-Type</c> header specified.
 	 */
-	@RemoteMethod(method=POST, path="/user/createWithArray")
+	@RemotePost("/user/createWithArray")
 	public Ok createUsers(
-		@Body(
-			description="List of user objects"
+		@Content(
+			schema=@Schema(description="List of user objects")
 		)
 		User[] users
 	) throws InvalidUsername, IdConflict, NotAcceptable, UnsupportedMediaType;
@@ -335,15 +335,15 @@ public interface PetStore {
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 * @throws UnsupportedMediaType Unsupported <c>Content-Type</c> header specified.
 	 */
-	@RemoteMethod(method=PUT, path="/user/{username}")
+	@RemotePut("/user/{username}")
 	public Ok updateUser(
 		@Path(
 			name="username",
-			description="Name that need to be updated"
+			schema=@Schema(description="Name that need to be updated")
 		)
 		String username,
-		@Body(
-			description="Updated user object"
+		@Content(
+			schema=@Schema(description="Updated user object")
 		)
 		User user
 	) throws InvalidUsername, IdNotFound, NotAcceptable, UnsupportedMediaType;
@@ -357,11 +357,11 @@ public interface PetStore {
 	 * @throws IdNotFound User was not found.
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 */
-	@RemoteMethod(method=DELETE, path="/user/{username}")
+	@RemoteDelete("/user/{username}")
 	public Ok deleteUser(
 		@Path(
 			name="username",
-			description="The name that needs to be deleted"
+			schema=@Schema(description="The name that needs to be deleted")
 		)
 		String username
 	) throws InvalidUsername, IdNotFound, NotAcceptable;
@@ -371,7 +371,7 @@ public interface PetStore {
 	 *
 	 * @return {@link Ok} if successful.
 	 */
-	@RemoteMethod(method=DELETE, path="/user")
+	@RemoteDelete("/user")
 	public Ok deleteAllUsers();
 
 	/**
@@ -379,36 +379,29 @@ public interface PetStore {
 	 *
 	 * @param username The username for login.
 	 * @param password The password for login in clear text.
-	 * @param rateLimit Calls per hour allowed by the user.
 	 * @param expiresAfter The <bc>Expires-After</bc> response header.
 	 * @return {@link Ok} if successful.
 	 * @throws InvalidLogin Login was unsuccessful.
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 */
-	@RemoteMethod(method=GET, path="/user/login")
+	@RemoteGet("/user/login")
 	public Ok login(
 		@Query(
 			name="username",
-			description="The username for login.",
-			required=true,
-			example="myuser"
+			schema=@Schema(
+				description="The username for login.",
+				required=true
+			)
 		)
 		String username,
 		@Query(
 			name="password",
-			description="The password for login in clear text.",
-			required=true,
-			example="abc123"
+			schema=@Schema(
+				description="The password for login in clear text.",
+				required=true
+			)
 		)
 		String password,
-		@ResponseHeader(
-			name="X-Rate-Limit",
-			type="integer",
-			format="int32",
-			description="Calls per hour allowed by the user.",
-			example="123"
-		)
-		Value<Integer> rateLimit,
 		Value<ExpiresAfter> expiresAfter
 	) throws InvalidLogin, NotAcceptable;
 
@@ -418,6 +411,6 @@ public interface PetStore {
 	 * @return {@link Ok} if successful.
 	 * @throws NotAcceptable Unsupported <c>Accept</c> header specified.
 	 */
-	@RemoteMethod(method=GET, path="/user/logout")
+	@RemoteGet("/user/logout")
 	public Ok logout() throws NotAcceptable;
 }
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/CreateOrder.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/CreateOrder.java
index 108d632..2bacf4a 100755
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/CreateOrder.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/CreateOrder.java
@@ -21,7 +21,7 @@ import org.apache.juneau.annotation.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-@Bean(fluentSetters=true, properties="petId,username")
+@Bean(findFluentSetters=true, properties="petId,username")
 public class CreateOrder {
 
 	private long petId;
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/CreatePet.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/CreatePet.java
index a886616..55d7982 100755
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/CreatePet.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/CreatePet.java
@@ -13,7 +13,7 @@
 package org.apache.juneau.petstore.dto;
 
 import org.apache.juneau.annotation.*;
-import org.apache.juneau.jsonschema.annotation.*;
+import org.apache.juneau.http.annotation.Schema;
 
 /**
  * Bean for creating {@link Pet} objects.
@@ -22,7 +22,7 @@ import org.apache.juneau.jsonschema.annotation.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-@Bean(fluentSetters=true, properties="name,price,species,tags")
+@Bean(findFluentSetters=true, properties="name,price,species,tags")
 public class CreatePet {
 
 	@Schema(description="Pet name.", minLength=3, maxLength=50)
@@ -34,7 +34,7 @@ public class CreatePet {
 	@Schema(description="Pet species.")
 	private Species species;
 
-	@Schema(description="Pet attributes.", example="friendly,smart")
+	@Schema(description="Pet attributes.")
 	private String[] tags;
 
 	/**
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/ExpiresAfter.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/ExpiresAfter.java
index 8273edf..454b954 100755
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/ExpiresAfter.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/ExpiresAfter.java
@@ -23,12 +23,13 @@ import org.apache.juneau.http.annotation.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-@ResponseHeader(
+@Header(
 	name="X-Expires-After",
-	type="string",
-	format="date-time",
-	description="Date in UTC when token expires",
-	example="2012-10-21"
+	schema=@Schema(
+		type="string",
+		format="date-time",
+		description="Date in UTC when token expires"
+	)
 )
 public class ExpiresAfter {
 	private final Calendar c;
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/IdConflict.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/IdConflict.java
index 5a22a1d..20a3c20 100755
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/IdConflict.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/IdConflict.java
@@ -13,7 +13,7 @@
 package org.apache.juneau.petstore.dto;
 
 import org.apache.juneau.http.annotation.*;
-import org.apache.juneau.http.exception.*;
+import org.apache.juneau.http.response.Conflict;
 
 /**
  * Exception thrown when trying to add an entry where the ID is already in use.
@@ -23,7 +23,7 @@ import org.apache.juneau.http.exception.*;
  * </ul>
  */
 @SuppressWarnings("serial")
-@Response(description="ID already in use")
+@Response(schema=@Schema(description="ID already in use"))
 public class IdConflict extends Conflict {
 
 	/**
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/IdNotFound.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/IdNotFound.java
index b086f8e..39cdf76 100755
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/IdNotFound.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/IdNotFound.java
@@ -13,7 +13,7 @@
 package org.apache.juneau.petstore.dto;
 
 import org.apache.juneau.http.annotation.*;
-import org.apache.juneau.http.exception.*;
+import org.apache.juneau.http.response.NotFound;
 
 /**
  * Exception thrown when trying to add an entry where the ID is already in use.
@@ -23,7 +23,7 @@ import org.apache.juneau.http.exception.*;
  * </ul>
  */
 @SuppressWarnings("serial")
-@Response(description="ID not found")
+@Response
 public class IdNotFound extends NotFound {
 
 	/**
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidId.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidId.java
index d7ee807..f7baee3 100755
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidId.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidId.java
@@ -13,7 +13,7 @@
 package org.apache.juneau.petstore.dto;
 
 import org.apache.juneau.http.annotation.*;
-import org.apache.juneau.http.exception.*;
+import org.apache.juneau.http.response.BadRequest;
 
 /**
  * Exception thrown when trying to add an entry where the ID is already in use.
@@ -23,7 +23,7 @@ import org.apache.juneau.http.exception.*;
  * </ul>
  */
 @SuppressWarnings("serial")
-@Response(description="Invalid ID provided")
+@Response(schema=@Schema(description="Invalid ID provided"))
 public class InvalidId extends BadRequest {
 
 	/**
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidLogin.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidLogin.java
index 25f6bd9..9a1efad 100755
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidLogin.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidLogin.java
@@ -13,7 +13,7 @@
 package org.apache.juneau.petstore.dto;
 
 import org.apache.juneau.http.annotation.*;
-import org.apache.juneau.http.exception.*;
+import org.apache.juneau.http.response.Unauthorized;
 
 /**
  * Exception thrown when an invalid username or password is provided.
@@ -23,7 +23,7 @@ import org.apache.juneau.http.exception.*;
  * </ul>
  */
 @SuppressWarnings("serial")
-@Response(description="Invalid username or password provided")
+@Response(schema=@Schema(description="Invalid username or password provided"))
 public class InvalidLogin extends Unauthorized {
 
 	/**
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidSpecies.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidSpecies.java
index 19cef69..7815867 100755
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidSpecies.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidSpecies.java
@@ -13,7 +13,7 @@
 package org.apache.juneau.petstore.dto;
 
 import org.apache.juneau.http.annotation.*;
-import org.apache.juneau.http.exception.*;
+import org.apache.juneau.http.response.BadRequest;
 
 /**
  * Exception thrown when an invalid species is looked up.
@@ -23,7 +23,7 @@ import org.apache.juneau.http.exception.*;
  * </ul>
  */
 @SuppressWarnings("serial")
-@Response(description="Invalid species provided")
+@Response(schema=@Schema(description="Invalid species provided"))
 public class InvalidSpecies extends BadRequest {
 
 	/**
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidTag.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidTag.java
index 4e2199e..663fb45 100755
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidTag.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidTag.java
@@ -13,7 +13,7 @@
 package org.apache.juneau.petstore.dto;
 
 import org.apache.juneau.http.annotation.*;
-import org.apache.juneau.http.exception.*;
+import org.apache.juneau.http.response.BadRequest;
 
 /**
  * Exception thrown when trying to add an entry where the ID is already in use.
@@ -23,7 +23,7 @@ import org.apache.juneau.http.exception.*;
  * </ul>
  */
 @SuppressWarnings("serial")
-@Response(description="Invalid tag provided")
+@Response(schema=@Schema(description="Invalid tag provided"))
 public class InvalidTag extends BadRequest {
 
 	/**
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidUsername.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidUsername.java
index 46644a3..1645c29 100755
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidUsername.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/InvalidUsername.java
@@ -13,7 +13,7 @@
 package org.apache.juneau.petstore.dto;
 
 import org.apache.juneau.http.annotation.*;
-import org.apache.juneau.http.exception.*;
+import org.apache.juneau.http.response.BadRequest;
 
 /**
  * Exception thrown when trying to add an entry where the ID is already in use.
@@ -23,7 +23,7 @@ import org.apache.juneau.http.exception.*;
  * </ul>
  */
 @SuppressWarnings("serial")
-@Response(description="Invalid username provided")
+@Response(schema=@Schema(description="Invalid username provided"))
 public class InvalidUsername extends BadRequest {
 
 	/**
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/Order.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/Order.java
index 27fb0b3..b3bbd34 100755
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/Order.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/Order.java
@@ -20,9 +20,9 @@ import javax.persistence.*;
 
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.html.annotation.*;
+import org.apache.juneau.http.annotation.Schema;
 import org.apache.juneau.internal.*;
-import org.apache.juneau.jsonschema.annotation.*;
-import org.apache.juneau.transforms.*;
+import org.apache.juneau.swaps.TemporalDateSwap;
 
 /**
  * Order bean.
@@ -31,7 +31,7 @@ import org.apache.juneau.transforms.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-@Bean(fluentSetters=true, properties="id,petId,username,status,shipDate")
+@Bean(findFluentSetters=true, properties="id,petId,username,status,shipDate")
 @Example("{id:123,petId:456,shipDate:'2012-12-21',status:'APPROVED'}")
 @Entity(name="PetstoreOrder")
 public class Order {
@@ -188,7 +188,7 @@ public class Order {
 			.username("sampleuser")
 			.petId(456)
 			.status(OrderStatus.APPROVED)
-			.shipDate(DateUtils.parseISO8601("2020-10-10"))
+			.shipDate(DateUtils.parseISO8601Calendar("2020-10-10").getTime())
 		;
 	}
 }
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/Pet.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/Pet.java
index c7fb76b..24ce045 100755
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/Pet.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/Pet.java
@@ -21,7 +21,7 @@ import javax.persistence.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.html.*;
 import org.apache.juneau.html.annotation.*;
-import org.apache.juneau.jsonschema.annotation.*;
+import org.apache.juneau.http.annotation.Schema;
 import org.apache.juneau.serializer.*;
 
 /**
@@ -31,7 +31,7 @@ import org.apache.juneau.serializer.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-@Bean(typeName="Pet", fluentSetters=true, properties="id,species,name,tags,price,status")
+@Bean(typeName="Pet", findFluentSetters=true, properties="id,species,name,tags,price,status")
 @Entity(name="PetstorePet")
 public class Pet {
 
@@ -54,7 +54,7 @@ public class Pet {
 	private Species species;
 
 	@ElementCollection(fetch=FetchType.EAGER) @OrderColumn
-	@Schema(description="Pet attributes.", example="friendly,smart")
+	@Schema(description="Pet attributes.")
 	private List<String> tags;
 
 	@Column @Enumerated(STRING)
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/PetTag.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/PetTag.java
index 34577ab..c6d0178 100755
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/PetTag.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/PetTag.java
@@ -24,7 +24,7 @@ import org.apache.juneau.internal.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-@Bean(typeName="Tag", fluentSetters=true)
+@Bean(typeName="Tag", findFluentSetters=true)
 @Swap(PetTagNameSwap.class)
 public class PetTag {
 	private long id;
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/PetTagNameSwap.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/PetTagNameSwap.java
index 7e1442f..67a258a 100755
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/PetTagNameSwap.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/PetTagNameSwap.java
@@ -13,8 +13,8 @@
 package org.apache.juneau.petstore.dto;
 
 import org.apache.juneau.*;
-import org.apache.juneau.http.*;
-import org.apache.juneau.transform.*;
+import org.apache.juneau.http.header.MediaType;
+import org.apache.juneau.swap.StringSwap;
 
 /**
  * Swap for {@link PetTag} beans.
@@ -23,7 +23,7 @@ import org.apache.juneau.transform.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-public class PetTagNameSwap extends PojoSwap<PetTag,String> {
+public class PetTagNameSwap extends StringSwap<PetTag> {
 
 	/**
 	 * Swap PetTag with name.
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/UpdatePet.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/UpdatePet.java
index d4b671f..1f6aae6 100755
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/UpdatePet.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/UpdatePet.java
@@ -13,7 +13,7 @@
 package org.apache.juneau.petstore.dto;
 
 import org.apache.juneau.annotation.*;
-import org.apache.juneau.jsonschema.annotation.*;
+import org.apache.juneau.http.annotation.Schema;
 
 /**
  * Bean for updating {@link Pet} objects.
@@ -22,7 +22,7 @@ import org.apache.juneau.jsonschema.annotation.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-@Bean(fluentSetters=true, properties="id,name,price,species,tags,status")
+@Bean(findFluentSetters=true, properties="id,name,price,species,tags,status")
 public class UpdatePet extends CreatePet {
 
 	@Schema(description="Pet identifier.", minimum="1")
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/User.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/User.java
index eefa4c5..f8730ce 100755
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/User.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/User.java
@@ -18,7 +18,7 @@ import javax.persistence.*;
 
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.html.annotation.*;
-import org.apache.juneau.jsonschema.annotation.*;
+import org.apache.juneau.http.annotation.Schema;
 
 /**
  * User bean.
@@ -27,7 +27,7 @@ import org.apache.juneau.jsonschema.annotation.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-@Bean(typeName="User", fluentSetters=true, properties="username,firstName,lastName,email,password,phone,userStatus")
+@Bean(typeName="User", findFluentSetters=true, properties="username,firstName,lastName,email,password,phone,userStatus")
 @Entity(name="PetstoreUser")
 public class User {
 
diff --git a/juneau-petstore-client/src/main/java/org/apache/juneau/petstore/Main.java b/juneau-petstore-client/src/main/java/org/apache/juneau/petstore/Main.java
index 7560b14..9f851e8 100755
--- a/juneau-petstore-client/src/main/java/org/apache/juneau/petstore/Main.java
+++ b/juneau-petstore-client/src/main/java/org/apache/juneau/petstore/Main.java
@@ -21,7 +21,7 @@ import org.apache.juneau.json.*;
 import org.apache.juneau.marshall.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.petstore.dto.*;
-import org.apache.juneau.rest.client2.*;
+import org.apache.juneau.rest.client.*;
 
 /**
  * Example code showing how to connect to the PetStore application using a remote proxy.
diff --git a/juneau-petstore-server/pom.xml b/juneau-petstore-server/pom.xml
index c6ed179..fa31dc0 100755
--- a/juneau-petstore-server/pom.xml
+++ b/juneau-petstore-server/pom.xml
@@ -41,7 +41,7 @@
 
 		<maven.javadoc.skip>true</maven.javadoc.skip>
 
-		<juneau.version>8.2.0</juneau.version>
+		<juneau.version>9.0.0-SNAPSHOT</juneau.version>
 	</properties>
 
 	<packaging>war</packaging>
diff --git a/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/App.java b/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/App.java
index a124a63..83d4365 100755
--- a/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/App.java
+++ b/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/App.java
@@ -14,13 +14,18 @@ package org.apache.juneau.petstore;
 
 import java.io.*;
 
+import javax.servlet.*;
+
+import org.apache.juneau.petstore.rest.*;
 import org.apache.juneau.petstore.service.*;
-import org.apache.juneau.rest.springboot.JuneauRestInitializer;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.*;
 import org.springframework.cache.annotation.EnableCaching;
 import org.springframework.context.*;
+import org.springframework.context.annotation.*;
 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.stereotype.*;
 
 /**
  * Entry point for PetStore application.
@@ -29,21 +34,43 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
 @EnableJpaRepositories(basePackages = "org.apache.juneau.petstore")
 @EnableCaching
 @SuppressWarnings("javadoc")
+@Controller
 public class App {
 
-	public static void main(String[] args) {
-		new App().start(args);
-	}
-
-	protected void start(String[] args) {
-		ConfigurableApplicationContext ctx = new SpringApplicationBuilder(App.class)
-			.initializers(new JuneauRestInitializer(App.class)) // Needed for Juneau resources as injectible Spring beans.
-			.run(args);
+	//-----------------------------------------------------------------------------------------------------------------
+	// Beans
+	//-----------------------------------------------------------------------------------------------------------------
 
+	public static void main(String[] args) {
 		try {
+			ConfigurableApplicationContext ctx = new SpringApplicationBuilder(App.class).run(args);
 			ctx.getBean(PetStoreService.class).initDirect(new PrintWriter(System.out));
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
 	}
+
+	//-----------------------------------------------------------------------------------------------------------------
+	// Beans
+	//-----------------------------------------------------------------------------------------------------------------
+
+	@Bean
+	public PetStoreService petStoreService() {
+		return new PetStoreService();
+	}
+
+	@Bean
+	public RootResources rootResources() {
+		return new RootResources();
+	}
+
+	@Bean
+	public PetStoreResource petStoreResource() {
+		return new PetStoreResource();
+	}
+
+	@Bean
+	public ServletRegistrationBean<Servlet> getRootServlet(RootResources rootResources) {
+		return new ServletRegistrationBean<>(rootResources, "/*");
+	}
 }
diff --git a/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/AppConfiguration.java b/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/AppConfiguration.java
deleted file mode 100755
index 79ccb12..0000000
--- a/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/AppConfiguration.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// ***************************************************************************************************************************
-// * 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.apache.juneau.petstore;
-
-
-import org.apache.juneau.petstore.rest.*;
-import org.apache.juneau.petstore.service.*;
-import org.apache.juneau.rest.springboot.annotation.JuneauRestRoot;
-import org.springframework.context.annotation.*;
-
-@SuppressWarnings("javadoc")
-@Configuration
-public class AppConfiguration {
-
-	//-----------------------------------------------------------------------------------------------------------------
-	// Services
-	//-----------------------------------------------------------------------------------------------------------------
-
-	@Bean
-	public PetStoreService petStoreService() {
-		return new PetStoreService();
-	}
-
-	//-----------------------------------------------------------------------------------------------------------------
-	// REST
-	//-----------------------------------------------------------------------------------------------------------------
-
-	@Bean
-	@JuneauRestRoot
-	public RootResources rootResources2() {
-		return new RootResources();
-	}
-
-	@Bean
-	public PetStoreResource petStoreResource() {
-		return new PetStoreResource();
-	}
-}
diff --git a/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/rest/PetStoreResource.java b/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/rest/PetStoreResource.java
index 642c6de..73c5dfb 100755
--- a/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/rest/PetStoreResource.java
+++ b/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/rest/PetStoreResource.java
@@ -12,14 +12,11 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.petstore.rest;
 
-import static org.apache.juneau.dto.swagger.ui.SwaggerUI.*;
-import static org.apache.juneau.http.HttpMethod.*;
 import static org.apache.juneau.http.response.Ok.*;
 
 import java.util.*;
 import java.util.Map;
 
-import org.apache.juneau.jsonschema.annotation.*;
 import org.apache.juneau.petstore.*;
 import org.apache.juneau.petstore.dto.*;
 import org.apache.juneau.petstore.service.*;
@@ -29,14 +26,14 @@ import org.apache.juneau.html.annotation.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.http.exception.*;
-import org.apache.juneau.rest.helper.*;
+import org.apache.juneau.rest.beans.*;
+import org.apache.juneau.rest.config.*;
+import org.apache.juneau.rest.converter.*;
+import org.apache.juneau.rest.servlet.*;
 import org.apache.juneau.http.response.*;
 import org.apache.juneau.rest.widget.*;
-import org.apache.juneau.transforms.*;
+import org.apache.juneau.swaps.*;
 import org.springframework.beans.factory.annotation.*;
-import org.springframework.web.bind.annotation.CrossOrigin;
-import org.apache.juneau.rest.converters.*;
 
 /**
  * Sample Petstore application.
@@ -52,11 +49,7 @@ import org.apache.juneau.rest.converters.*;
 		"This is a sample server Petstore server based on the Petstore sample at Swagger.io.",
 		"You can find out more about Swagger at http://swagger.io.",
 	},
-	properties= {
-		// Resolve recursive references when showing schema info in the swagger.
-		@Property(name=SWAGGERUI_resolveRefsMaxDepth, value="99")
-	},
-	swagger=@ResourceSwagger(
+	swagger=@Swagger(
 		version="1.0.0",
 		title="Swagger Petstore",
 		termsOfService="You are on your own.",
@@ -95,8 +88,7 @@ import org.apache.juneau.rest.converters.*;
 				)
 			)
 		}
-	),
-	staticFiles={"htdocs:/htdocs"}  // Expose static files in htdocs subpackage.
+	)
 )
 @HtmlDocConfig(
 	widgets={
@@ -104,7 +96,8 @@ import org.apache.juneau.rest.converters.*;
 	},
 	navlinks={
 		"up: request:/..",
-		"options: servlet:/?method=OPTIONS",
+		"api: servlet:/api",
+		"stats: servlet:/stats",
 		"$W{ContentTypeMenuItem}",
 		"source: $C{Source/gitHub}/org/apache/juneau/petstore/rest/$R{servletClassSimple}.java"
 	},
@@ -112,8 +105,8 @@ import org.apache.juneau.rest.converters.*;
 		"<link rel='icon' href='$U{servlet:/htdocs/cat.png}'/>"  // Add a cat icon to the page.
 	},
 	header={
-		"<h1>$R{resourceTitle}</h1>",
-		"<h2>$R{methodSummary}</h2>",
+		"<h1>$RS{title}</h1>",  // Use @Rest(title)
+		"<h2>$RS{operationSummary,description}</h2>", // Use either @RestOp(summary) or @Rest(description)
 		"$C{PetStore/headerImage}"
 	},
 	aside={
@@ -126,7 +119,7 @@ import org.apache.juneau.rest.converters.*;
 	},
 	stylesheet="servlet:/htdocs/themes/dark.css"  // Use dark theme by default.
 )
-public class PetStoreResource extends BasicRest implements PetStore {
+public class PetStoreResource extends BasicRestObject implements BasicUniversalConfig, PetStore {
 
 	@Autowired
 	private PetStoreService store;
@@ -136,8 +129,7 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	 *
 	 * @return Navigation page contents.
 	 */
-	@RestMethod(
-		name=GET,
+	@RestGet(
 		path="/",
 		summary="Navigation page"
 	)
@@ -165,11 +157,10 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=GET,
+	@RestGet(
 		path="/pet",
 		summary="All pets in the store",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="pet",
 			parameters={
 				Queryable.SWAGGER_PARAMS  // Documents searching.
@@ -177,21 +168,17 @@ public class PetStoreResource extends BasicRest implements PetStore {
 		),
 		converters={Queryable.class}  // Searching support.
 	)
-	@BeanConfig(
-		bpx="Pet: tags,photo"  // In this view, don't serialize tags/photos properties.
-	)
+	@Bean(on="Pet", excludeProperties="tags,photo")
 	public Collection<Pet> getPets() throws NotAcceptable {
 		return store.getPets();
 	}
 
 	@Override /* PetStore */
-	@CrossOrigin(origins = "http://localhost:3000", maxAge = 3600)
-	@RestMethod(
-		name=GET,
+	@RestGet(
 		path="/pet/{petId}",
 		summary="Find pet by ID",
 		description="Returns a single pet",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="pet"
 		)
 	)
@@ -200,11 +187,10 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=POST,
+	@RestPost(
 		path="/pet",
 		summary="Add a new pet to the store",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="pet"
 		)
 		//roleGuard="ROLE_ADMIN || (ROLE_USER && ROLE_WRITABLE)"  // Restrict access to this method.
@@ -214,11 +200,10 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=PUT,
+	@RestPut(
 		path="/pet/{petId}",
 		summary="Update an existing pet",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="pet"
 		)
 	)
@@ -228,12 +213,11 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=GET,
+	@RestGet(
 		path="/pet/findByStatus",
 		summary="Finds Pets by status",
 		description="Multiple status values can be provided with comma separated strings.",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="pet"
 		)
 	)
@@ -242,11 +226,10 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=DELETE,
+	@RestDelete(
 		path="/pet/{petId}",
 		summary="Deletes a pet",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="pet"
 		)
 	)
@@ -256,8 +239,7 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=DELETE,
+	@RestDelete(
 		path="/pets",
 		summary="Delete all pets",
 		description="This can be done only by the logged in user."
@@ -276,9 +258,9 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	 *
 	 * @return Store navigation page contents.
 	 */
-	@RestMethod(
+	@RestGet(
 		summary="Store navigation page",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="store"
 		)
 	)
@@ -290,11 +272,10 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=GET,
+	@RestGet(
 		path="/store/order",
 		summary="Petstore orders",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="store"
 		)
 	)
@@ -313,12 +294,11 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=GET,
+	@RestGet(
 		path="/store/order/{orderId}",
 		summary="Find purchase order by ID",
 		description="Returns a purchase order by ID.",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="store"
 		)
 	)
@@ -329,16 +309,15 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=POST,
+	@RestPost(
 		path="/store/order",
 		summary="Place an order for a pet",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="store"
-		),
-		pojoSwaps={
-			TemporalDateSwap.IsoLocalDate.class
-		}
+		)
+	)
+	@BeanConfig(
+		swaps = TemporalDateSwap.IsoLocalDate.class
 	)
 	public long placeOrder(long petId, String username) throws IdConflict, NotAcceptable, UnsupportedMediaType {
 		CreateOrder co = new CreateOrder(petId, username);
@@ -346,15 +325,14 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=DELETE,
+	@RestDelete(
 		path="/store/order/{orderId}",
 		summary="Delete purchase order by ID",
 		description= {
 			"For valid response try integer IDs with positive integer value.",
 			"Negative or non-integer values will generate API errors."
 		},
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="store"
 		)
 	)
@@ -366,8 +344,7 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=DELETE,
+	@RestDelete(
 		path="/orders",
 		summary="Delete all orders",
 		description="This can be done only by the logged in user."
@@ -378,12 +355,11 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=GET,
+	@RestGet(
 		path="/store/inventory",
 		summary="Returns pet inventories by status",
 		description="Returns a map of status codes to quantities",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="store",
 			responses={
 				"200:{ 'x-example':{AVAILABLE:123} }",
@@ -399,25 +375,23 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=GET,
+	@RestGet(
 		path="/user",
 		summary="Petstore users",
-		bpx="User: email,password,phone",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="user"
 		)
 	)
+	@Bean(on="User", excludeProperties="email,password,phone")
 	public Collection<User> getUsers() throws NotAcceptable {
 		return store.getUsers();
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=GET,
+	@RestGet(
 		path="/user/{username}",
 		summary="Get user by user name",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="user"
 		)
 	)
@@ -426,12 +400,11 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=POST,
+	@RestPost(
 		path="/user",
 		summary="Create user",
 		description="This can only be done by the logged in user.",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="user"
 		)
 	)
@@ -441,11 +414,10 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=POST,
+	@RestPost(
 		path="/user/createWithArray",
 		summary="Creates list of users with given input array",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="user"
 		)
 	)
@@ -456,12 +428,11 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=PUT,
+	@RestPut(
 		path="/user/{username}",
 		summary="Update user",
 		description="This can only be done by the logged in user.",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="user"
 		)
 	)
@@ -471,12 +442,11 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=DELETE,
+	@RestDelete(
 		path="/user/{username}",
 		summary="Delete user",
 		description="This can only be done by the logged in user.",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="user"
 		)
 	)
@@ -486,8 +456,7 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=DELETE,
+	@RestDelete(
 		path="/users",
 		summary="Delete all users",
 		description="This can be done only by the admin."
@@ -498,18 +467,16 @@ public class PetStoreResource extends BasicRest implements PetStore {
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=GET,
+	@RestGet(
 		path="/user/login",
 		summary="Logs user into the system",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="user"
 		)
 	)
 	public Ok login(
 			String username,
 			String password,
-			Value<Integer> rateLimit,
 			Value<ExpiresAfter> expiresAfter
 		) throws InvalidLogin, NotAcceptable {
 
@@ -520,17 +487,15 @@ public class PetStoreResource extends BasicRest implements PetStore {
 
 		Date d = new Date(System.currentTimeMillis() + 30 * 60 * 1000);
 		req.getSession().setAttribute("login-expires", d);
-		rateLimit.set(1000);
 		expiresAfter.set(new ExpiresAfter(d));
 		return OK;
 	}
 
 	@Override /* PetStore */
-	@RestMethod(
-		name=GET,
+	@RestGet(
 		path="/user/logout",
 		summary="Logs out current logged in user session",
-		swagger=@MethodSwagger(
+		swagger=@OpSwagger(
 			tags="user"
 		)
 	)
diff --git a/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/rest/RootResources.java b/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/rest/RootResources.java
index a00c013..069b037 100755
--- a/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/rest/RootResources.java
+++ b/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/rest/RootResources.java
@@ -13,8 +13,9 @@
 package org.apache.juneau.petstore.rest;
 
 import org.apache.juneau.html.annotation.*;
-import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.config.*;
+import org.apache.juneau.rest.servlet.*;
 import org.apache.juneau.rest.widget.*;
 
 /**
@@ -37,7 +38,8 @@ import org.apache.juneau.rest.widget.*;
 		ContentTypeMenuItem.class
 	},
 	navlinks={
-		"options: ?method=OPTIONS",
+		"api: servlet:/api",
+		"stats: servlet:/stats",
 		"$W{ContentTypeMenuItem}",
 		"source: $C{Source/gitHub}/org/apache/juneau/petstore/rest/$R{servletClassSimple}.java"
 	},
@@ -52,6 +54,6 @@ import org.apache.juneau.rest.widget.*;
 		"</div>"
 	}
 )
-public class RootResources extends BasicRestServletGroup {
+public class RootResources extends BasicRestServletGroup implements BasicUniversalConfig {
 	private static final long serialVersionUID = 1L;
 }
diff --git a/juneau-petstore-server/src/test/java/org/apache/juneau/petstore/test/MockTest.java b/juneau-petstore-server/src/test/java/org/apache/juneau/petstore/test/MockTest.java
index 29a3244..0f120f6 100755
--- a/juneau-petstore-server/src/test/java/org/apache/juneau/petstore/test/MockTest.java
+++ b/juneau-petstore-server/src/test/java/org/apache/juneau/petstore/test/MockTest.java
@@ -3,8 +3,8 @@ package org.apache.juneau.petstore.test;
 import org.apache.juneau.petstore.App;
 import org.apache.juneau.petstore.dto.*;
 import org.apache.juneau.petstore.rest.PetStoreResource;
-import org.apache.juneau.rest.client2.*;
-import org.apache.juneau.rest.mock2.*;
+import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.mock.*;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -39,8 +39,8 @@ public class MockTest {
 		int petId = petStoreRest
 			.post("/pet", new CreatePet().name("Sunshine").price(100f).species(Species.BIRD).tags("nice"))
 			.run()
-			.assertStatus().code().is(200)
-			.getBody().as(int.class);
+			.assertStatus().asCode().is(200)
+			.getContent().as(int.class);
 
 		return petId;
 	}
@@ -49,7 +49,7 @@ public class MockTest {
 		petStoreRest
 			.delete("/pets")
 			.complete()  // Use complete() because we're not consuming response.
-			.assertStatus().code().is(200);
+			.assertStatus().asCode().is(200);
 	}
 
 	// Delete pet by Id
@@ -60,7 +60,7 @@ public class MockTest {
 		petStoreRest
 			.delete("/pet/" + petId)
 			.complete()
-			.assertStatus().code().is(200);
+			.assertStatus().asCode().is(200);
 	}
 
 	// Getting all pets
@@ -71,8 +71,8 @@ public class MockTest {
 		petStoreRest
 			.get("/pet")
 			.run()
-			.assertStatus().code().is(200)
-			.assertBody().is("[{id:" + petId + ",species:'BIRD',name:'Sunshine',price:100.0,status:'AVAILABLE'}]");
+			.assertStatus().asCode().is(200)
+			.assertContent().is("[{id:" + petId + ",species:'BIRD',name:'Sunshine',price:100.0,status:'AVAILABLE'}]");
 
 		deleteTestPets();
 	}
@@ -84,7 +84,7 @@ public class MockTest {
 		petStoreRest
 			.post("/pet", new CreatePet().name("Sunshine").price(100f).species(Species.BIRD).tags("nice"))
 			.complete()
-			.assertStatus().code().is(200);
+			.assertStatus().asCode().is(200);
 
 		deleteTestPets();
 	}
@@ -98,7 +98,7 @@ public class MockTest {
 			.get("/pet/" + petId)
 			.run()
 			.assertCode().is(200)
-			.assertBody().is("{id:" + petId + ",species:'BIRD',name:'Sunshine',tags:['nice'],price:100.0,status:'AVAILABLE'}");
+			.assertContent().is("{id:" + petId + ",species:'BIRD',name:'Sunshine',tags:['nice'],price:100.0,status:'AVAILABLE'}");
 
 		deleteTestPets();
 
@@ -113,7 +113,7 @@ public class MockTest {
 			.get("/pet/findByStatus?status=AVAILABLE")
 			.run()
 			.assertCode().is(200)
-			.assertBody().is("[{id:" + petId + ",species:'BIRD',name:'Sunshine',tags:['nice'],price:100.0,status:'AVAILABLE'}]");
+			.assertContent().is("[{id:" + petId + ",species:'BIRD',name:'Sunshine',tags:['nice'],price:100.0,status:'AVAILABLE'}]");
 
 		deleteTestPets();
 	}
@@ -210,7 +210,7 @@ public class MockTest {
 			.get("/user")
 			.run()
 			.assertCode().is(200)
-			.assertBody().is("[{username:'doglover',firstName:'Tom',lastName:'Simon',userStatus:'ACTIVE'}]");
+			.assertContent().is("[{username:'doglover',firstName:'Tom',lastName:'Simon',userStatus:'ACTIVE'}]");
 
 		deleteTestUsers();
 	}
@@ -224,7 +224,7 @@ public class MockTest {
 			.get("/user/garfield")
 			.run()
 			.assertCode().is(200)
-			.assertBody().is("{username:'garfield',firstName:'Tom',lastName:'Simon',userStatus:'ACTIVE'}");
+			.assertContent().is("{username:'garfield',firstName:'Tom',lastName:'Simon',userStatus:'ACTIVE'}");
 
 		deleteTestUsers();
 	}
@@ -266,7 +266,7 @@ public class MockTest {
 			)
 			.run()
 			.assertCode().is(200)
-			.getBody().as(int.class);
+			.getContent().as(int.class);
 
 		return orderId;
 	}
@@ -296,7 +296,7 @@ public class MockTest {
 			.get("/store/order")
 			.run()
 			.assertCode().is(200)
-			.assertBody().is("[{id:" + orderId + ",petId:0,status:'PLACED'}]");
+			.assertContent().is("[{id:" + orderId + ",petId:0,status:'PLACED'}]");
 
 		deleteTestOrders();
 
@@ -311,7 +311,7 @@ public class MockTest {
 			.get("/store/order/" + orderId)
 			.run()
 			.assertCode().is(200)
-			.assertBody().is("{id:" + orderId + ",petId:0,status:'PLACED'}");
+			.assertContent().is("{id:" + orderId + ",petId:0,status:'PLACED'}");
 
 		deleteTestOrders();
 	}
diff --git a/pom.xml b/pom.xml
index d99e287..1b6aba9 100755
--- a/pom.xml
+++ b/pom.xml
@@ -36,7 +36,7 @@
 		<maven.compiler.target>18</maven.compiler.target>
 		
 		<httpclient.version>4.5.6</httpclient.version>
-		<juneau.version>8.2.0</juneau.version>
+		<juneau.version>9.0-B1-SNAPSHOT</juneau.version>
 		<derby.version>10.10.2.0</derby.version>
 		<hibernate.version>5.0.9.Final</hibernate.version>
 	</properties>