This versioned example app for VMware Tanzu GemFire is a Spring Boot app that can be used with a Tanzu GemFire service instance. That service instance may be configured either with or without TLS encryption enabled.
The app uses Spring Boot Data Geode (SBDG) to talk to the Tanzu GemFire service instance. The app provides a REST interface that lets a user view pizzas, place orders, and view an order. The app leverages Spring Web MVC controllers to expose data access operations.
Pizzas are stored in the Tanzu GemFire servers running within
the Tanzu GemFire service instance.
The app uses Spring Data Repositories to store,
access, and query data stored on the servers.
The app stores data in two repositories Pizza
and Name
(repositories are referred to as regions in Tanzu GemFire).
See GemFire Basics for the briefest of introductions to Tanzu GemFire,
and see Region Design for a quick tour of Tanzu GemFire regions.
This app performs operations on two regions:
- The
Pizza
region represents the pizzas on order. Each pizza has a unique name used as the key for the region entry. The value portion of the key/value entry is the specification of a sauce and any toppings on a single pizza. - The
Name
region is populated by the unique name associated with the pizzas with pesto as a sauce. A Tanzu GemFire continuous query triggers a put to theName
region whenever a pizza with pesto sauce is added. See Continuous Querying for an extensive explanation of Tanzu GemFire continuous queries.
Pizza sauces are one of:
- ALFREDO
- BARBECUE
- HUMMUS
- MARINARA
- PESTO
- TAPENADE
- TOMATO
Pizza toppings are any of:
- ARUGULA
- BACON
- BANANA_PEPPERS
- BLACK_OLIVES
- CHEESE
- CHERRY_TOMATOES
- CHICKEN
- GREEN_OLIVES
- GREEN_PEPPERS
- JALAPENO
- MUSHROOM
- ONIONS
- PARMESAN
- PEPPERONI
- SAUSAGE
The app runs with a Tanzu GemFire service instance.
This app is versioned, and branches of this git repository correspond to
the Tanzu GemFire version that this app will work with.
Check out and run the app from the branch that matches your Tanzu GemFire
tile version.
For example, if your Tanzu GemFire service instance is version 1.11,
check out this repository's release/1.11
branch.
This is important because the procedure to run the app differs slightly,
based on whether TLS encryption is enabled or not.
Follow the appropriate setup procedure.
- You should be logged in to your cf environment. Please see cf login
- The CF environment should have a Tanzu Gemfire Tile installed.
-
Create the Tanzu GemFire service instance with TLS enabled:
$ cf create-service p-cloudcache PLAN_NAME SERVICE_INSTANCE -c '{"tls":true}'
Note the name of your
SERVICE_INSTANCE
, as it will be used in themanifest.yml
file. -
Create the regions required by the app using
gfsh
:Connect to the cluster via
gfsh
. Please see Accessing a Service Instance for detailed instructions on connecting to your service instance.gfsh>create region --name=Pizza --type=REPLICATE gfsh>create region --name=Name --type=REPLICATE
-
Configure the app to use SSL by adding this property to
src/main/resources/application.properties
:spring.data.gemfire.security.ssl.use-default-context=true
-
Modify the
manifest.yml
file such that the service instance is no longer commented out and has the name of your Tanzu GemFire service instance. If your service instance had the namedev-instance-1
, then theservices
portion of themanifest.yml
file would be:services: - dev-instance-1
The Spring Boot framework detects whether the service instance has TLS enabled or not, so the same manifest is used when pushing the app as is shown above.
-
Create a Tanzu GemFire service instance without enabling TLS encryption:
cf create-service p-cloudcache PLAN_NAME SERVICE_INSTANCE
Note the name of your
SERVICE_INSTANCE
, as it will be used in themanifest.yml
file. -
Create the regions required by the app using
gfsh
:Connect to the cluster. See Accessing a Service Instance for detailed instructions on connecting to your service instance.
gfsh>create region --name=Pizza --type=REPLICATE gfsh>create region --name=Name --type=REPLICATE
-
Modify the
manifest.yml
file such that the service instance is no longer commented out and has the name of your Tanzu GemFire service instance. If your service instance had the namedev-instance-1
, then theservices
portion of themanifest.yml
file would be:services: - dev-instance-1
Build and cf push the app. With current working directory of
PCC-Sample-App-PizzaStore
:
$ ./mvnw clean install
$ cf push
All REST API endpoints are accessible using HTTP GET. This is not very RESTful, but is convenient when accessing this app from your web browser.
Run the command:
$ cf apps
to acquire your app's APP-URL. Use the APP-URL with the following endpoints:
-
GET /ping
Responds with an HTTP status code of
200 - OK
and an HTTP message body of "PONG!" if the app is running correctly.$ curl -k https://APP-URL/ping
-
GET /preheatOven
Loads the
Pizza
region with three pre-defined pizzas. This REST API endpoint callsRepository.save()
for each pizza and verifies the pizzas with theRepository.findById(..)
on thePizza
region to verify that everything was set up properly. It creates these pizzas:- tomato sauce and a cheese topping
- Alfredo sauce, and chicken and arugula toppings
- pesto sauce, and chicken, cherry tomatoes and parmesan cheese toppings
Responds with an HTTP message body of "OVEN HEATED!".
$ curl -k https://APP-URL/preheatOven
-
GET /pizzas
Lists the current contents of the
Pizza
region, formatted as a JSON array containingPizza
objects. Returns "No Pizzas Found" if the region is empty.$ curl -k https://APP-URL/pizzas
-
GET /pizzas/{name}
Returns the pizza with the specified name. Returned pizza is in JSON form. Returns "Pizza [name] Not Found" if no pizza with the given name exists.
curl -k https://APP-URL/pizzas/plain
-
GET /pizzas/order/{name}\[?sauce=<sauce>\[&toppings=\<topping-1>,\<topping-2>,...,\<topping-N>]]
Adds a pizza order for the specified name, with an optional
sauce
(defaults toTOMATO
) and optionaltoppings
(defaults toCHEESE
). Changes the pizza order if the name is already present in the pizzas on order.curl -k https://APP-URL/pizzas/order/myCustomPizza?sauce=MARINARA&toppings=CHEESE,PEPPERONI,MUSHROOM
-
GET /pizzas/pestoOrder/{name}
Bakes a pesto sauce pizza with chicken, cherry tomatoes, and parmesan cheese toppings.
curl -k https://APP-URL/pizzas/pestoOrder/myPestoPizza
-
GET /cleanSlate
Removes all data from the
Pizza
andName
regions.$ curl -k https://APP-URL/cleanSlate
A Tanzu GemFire Continuous Query allows an app to register interest in events. Interest is expressed with an OQL query on regions containing the data interests. This is ideal, since a developer can specify complex criteria in an OQL query predicate for the exact data the app is interested in receiving notifications for. Thus, when a data event occurs matching the conditions expressed in the query predicate, an event will be returned with the data.
This Spring Boot app registers two continuous queries
on the Pizza
region.
-
Whenever any pizza is ordered, the event is logged to
System.err
. -
When any pesto pizza is ordered, the event triggers putting the name of the pizza in the
Name
region.
For more details, see the Tanzu GemFire documentation section on Continuous Querying.
For more details on how to use continuous queries in your Spring Boot apps see Configuring Continuous Queries.