The plugins for the pizza party application.
The {@link org.cougaar.pizza.plugin.PizzaPrototypePlugin} and {@link org.cougaar.pizza.plugin.KitchenPrototypePlugin}s give Alice, Joes, and Dominoes
access to Asset Prototypes. The KitchenPrototypePlugin also creates
the single Kitchen Asset, with the correct PGs indicating whether that
Pizza Provider serves meat and/or veggie pizzas.
The {@link org.cougaar.pizza.plugin.InvitePlugin} is used at Alice to send an invitation to all her
friends on her buddy list, "FriendsOfMark" -- a Community. Her invitation is an
{@link org.cougaar.pizza.relay.RSVPRelaySource} that asks "Meat or Veggie".
Each member of the Community receives the Relay, and responds using
the {@link org.cougaar.pizza.plugin.RSVPPlugin}. They then use the
{@link org.cougaar.pizza.plugin.util.PizzaPreferenceHelper} to look at the
local self Entity, looking for the
{@link org.cougaar.pizza.Constants.Roles#CARNIVORE} or {@link org.cougaar.pizza.Constants.Roles#VEGETARIAN} Roles, to decide what kind of pizza they
eat. They then set that {@link org.cougaar.pizza.relay.RSVPReply}
Response on the {@link org.cougaar.pizza.relay.RSVPRelayTarget} Relay, which the
infrastructure forwards back to Alice.
At Alice, the infrastructure collects all the RSVPs on a {@link
org.cougaar.pizza.plugin.PizzaPreferences} object, and after waiting
to give everyone a chance to responsd, the InvitePlugin, publishes the PizzaPreferences object summarizing
what pizza Alice wants to order.
At this point, you might use the "/pizza" ({@link
org.cougaar.pizza.servlet.PizzaPreferenceServlet}) servlet to see who
responded and what kinds of pizza Alice needs to order. Keep watching
this servlet to see Alice order her pizza, and whether it succeeds.
There are then 2 options. In the non ServiceDiscovery version, the
{@link org.cougaar.pizza.plugin.PlaceOrderPlugin} at Alice acts next. In the ServiceDiscovery version,
it is the {@link org.cougaar.pizza.plugin.SDPlaceOrderPlugin}, which is a simple extension of the
PlaceOrderPlugin.
The PlaceOrderPlugin sees the PizzaPreferences on its Subscription,
and prepares to order the pizza. First it looks to see if it has a
Relationship on the self Entity to any PizzaProviders. In the SD
version it does not, and must now do ServiceDiscovery. In the non-SD
version, it does. So it then creates an {@link
org.cougaar.pizza.Constants.Verbs#ORDER} Task, ordering {@link org.cougaar.pizza.Constants#PIZZA}. It
then expands that - one for meat pizza (with an appropriate number of
servings depending on RSVPs) and one for veggie. It Allocates those child tasks
to the pizza provider it found on its self Entity (Joes in our example).
In the SD version, the SDPlaceOrderPlugin kicks off ServiceDiscovery by
publishing a {@link org.cougaar.pizza.Constants.Verbs#FIND_PROVIDERS}
Task, with an IndirectObject indicating it wants a PizzaProvider.
The {@link org.cougaar.servicediscovery.plugin.SDClientPlugin} subscribes to those Tasks, and then publishes
an MMQueryRequest, including an MMRoleQuery that specifies it wants a
PizzaProvider, and includes the service scoring function
({@link org.cougaar.pizza.plugin.util.RoleWithBlacklistScorer}) to use in weighing
different possible providers.
The {@link org.cougaar.pizza.plugin.MatchmakerPlugin} picks up the MMQueryRequest, and issues an
asynchronous query to the Yellow Pages, asking it to walk up the
hierarchy of Yellow Pages Communities as necessary, to find providers
matching the query (so it finds Cambridge first, and then MA, as
necessary). On getting a callback with a provider, it publishChanges
the MMQueryRequest.
The {@link org.cougaar.pizza.plugin.SDClientPlugin} picks up the answer to its request, and sends a
ServiceContractRelay to the named provider Agent, asking for a
Relationship. Our example uses the {@link org.cougaar.servicediscovery.plugin.AgreeableProviderPlugin} from the
servicediscovery module, which will immediately say yes
(a more complex plugin might for example check capacity). The
infrastructure then establishes the needed Relationship.
Once the SDClientPlugin sees that it has a Contract for the Role it
was looking for, it marks the FindProviders Task with a confident
Success Disposition. The SDPlaceOrderPlugin sees the change to the
Disposition, and uses that to grab the new PizzaProvider. Then it
continues just like the PlaceOrderPlugin, issuing Order Tasks that it
allocates to the provider.
OK, so now, in both SD and non-SD versions, the PlaceOrderPlugin has
allocated Pizza Order tasks to the Pizza Provider. In both cases, this
should be Joes. The infrastructure copies the Order tasks to Joes
Blackboard (because they were Allocated to the Joes Entity).
At Joes, the {@link org.cougaar.pizza.plugin.ProcessOrderPlugin} sees the new Order Tasks. It matches
the PGs on the Task's Indirect Object Pizza Asset indicating the kind of pizza needed, with
the PGs on its local KitchenAsset, and responds with Success or Fail,
depending on whether it makes the kind of pizza needed. Joes does not
make Veggie pizza, so will Fail that particular Task.
The PlaceOrderPlugin propagates that result up to its root Order
Task, and logs the results. In the non-SD world, this is the end of
the line. Alice only knows about Joes, so can't make her Vegetarian
guests happy. :-(
In the SD version of the application, the SDPlaceOrderPlugin sees the
failure on the order, and decides to find a new provider. It publishes
a new FindProviders task, specifying that the previous provider (Joes)
should be excluded - since Joes cant satisfy the Order. From there, it
continues as before. The SD Plugins look for the next provider that
meets the (stricter) criteria. They walk up from the Cambridge YP
Community and find Dominos in the MA community. The
SDPlaceOrderPlugin issues all new Orders to Dominos, which can meet
Alices needs.
The party is on!
|