cpXML: Conversation Policy XML
Version 1.0
e-Commerce and Autonomic Computing Department[1]
IBM T.J. Watson Research Center
Table Of Contents
4.2.1 Send-message
transitions
4.2.3 Child-return transitions
6 Example
2: A CP that uses a child
7 Appendix
A - cpXML XSD Schema
A cpXML document defines a Conversation Policy (CP). A CP is
a set of constraints on schemas
of messages that may be sent, and on the sequencing of messages, in a
conversation between two or more applications. A CP is purely
"passive" structure describing a set of possible message sequences,
without reference to which sequence is actually followed in any given
conversation.
In practice, the conversing applications need not follow the
CP’s constraints. That is, CPs
are non-normative, in the sense that no application is required to follow any
given CP (or any CP at all, for that matter). CPs are intended to be
used as common, conventional, standard protocols, available for use by
applications as an aid to interacting effectively.
CPs confine themselves to constraining just three aspects of
the interaction: the schemas of
messages, the sequencing of
messages, and the timing of messages. A cpXML document does not describe the way in which a CP is
"wired into" (or "bound to") an application. Nor does it
describe the way in which an application executes a conversation.
In
particular, the following types of information are excluded from cpXML:
· How an application chooses
which role to play in a conversation.
· How an application chooses what
action to take (e.g., which message to send), when it has a choice.
· How an application fills in the
message content (i.e., how it constructs messages that conform to a given
schema).
· How an application carries out
the sending and receiving of messages.
A
single CP covers messages from all participants, and is written in a way that
is independent of any particular participant. I.e., a CP is written from the
point of view of a third party overhearing the conversation.
The
essence of a cpXML is a state machine, in which states are labels for “where”
in the conversation the participants are, and transitions between states
correspond to the transmission of a message from one of the participants to the
other(s). Many protocols, though of
course not all of them, can naturally be described using state machines.
A
particularly valuable feature of CPs written in cpXML is the ability for CPs to
be composed with each other; i.e., one CP to load and execute another CP as a
“subconversation” or “child” which takes place in the conversational context
defined by the “parent”. There are at
least two options for defining the way in which conversation policies can be
composed (cf. below).
One analogy that may be useful is to think of a cpXML document
as the script of a play. The script determines the set of characters to be
played, the things each character gets to say, and the order in which they say
it. But it says nothing about the actors, the interpretation an actor gives to
his character, where or how the play is put on, what technology (if any) is
used to reach the audience, and so forth.
A CP consists of:
· a name, which is a string
· a set of 2 or more roles, each
of which is a string
· an initial state, which should
equal one of the states' names
· 1 or more states (which are
described below)
CPs model protocols as state machines. At any point in time, the
conversation is "in" one of the states. It moves from state to state
as the different participants send or receive messages, as detailed in the
states' transitions. States provide a means of identifying "where" in
a conversation the application is. E.g., has it made an offer yet? Is it ready
to send billing information? And so forth.
When two applications begin following a given CP, they sort out
which application plays which of a set of "roles" defined in the CP.
E.g., two applications may agree to start a "BuyStuff" CP, in which
one application plays the "buyer" role and the other application
plays the "seller" role. This assignment of roles lasts for the
duration of the execution of that CP.
E.g.
<conversationPolicy>
<name>Haggle</name>
<roles>
<role>PartyA</role>
<role>PartyB</role>
</roles>
<initialState>NoOffer</initialState>
<!-- [states go here] -->
</conversationPolicy>
As we said above, CPs may be nested or composed in such a way
that one CP describes the loading and execution of another, where the first is
a “parent” and the second is a “child”. Here, we discuss two options for how to
express this relationship:
These two alternative formulations are functionally identical,
but they lead to different XML structures for the states and transitions.
Option 1 has a simpler schema because there is only one kind of state; but it
is more difficult to understand because the state-transition graphs contain
“dangling” transitions to & from states outside the CP, and often contain
multiple disconnected componenets. For this reason, we have chosen to follow
Option 2.
Notionally, there are three kinds of state in a CP:
In addition, normal and load-child states may optionally be given timeouts, which specify the maximum allowed time the conversation might stay in that state.
Transitions between states also come in three varieties:
Clearly, there are constraints on which kinds of transition are required or allowed to connect to and from which kinds of state. These connectivity constraints are described in detail below.
[NOTE:
It is clearly important for the cpXML schema to express these connectivity
constraints, possibly through <key> / <keyref> tags. As of this
writing, I’m not certain of the best way to do this.]
We
can either define these different kinds of state & transition as
first-level things, or as elements inside generic <state> or
<transition> elements. E.g., the list of states can either consist of a
list of elements of type <normal>, <terminal>, and
<in-child>, or else the list of states can consist of elements of type
<state>, each of which consists of a <name>, a state-type
attribute, and transitions of the right type.
A
<state> consists of:
Normal
states are states in which one of the participants is due to send a message.
There must be at least one send-message transition. There may be a
<timeout> element, and, if so, there must be an on-timeout transition.
For
example:
<state StateId=”Querying”>
<!—- optional timeout element & on-timeout transition -->
<!-- 1 or more send-message transitions -->
</state>
In-child
must specify a <load-child> element, which specifies a child CP to load
(cf. below for more details). There may be a <timeout> element, and if
so, there must be an on-timeout transition. There may be 1 or more child-return
transitions.
A
<load-child> element contains the name (i.e., the URI) of the child-CP to
load, and a <rolemap> that determines the roles of the participants will
play in the child CP, based on the roles they play in the parent CP.
E.g.,
<state StateId=”InHaggle”>
<name>InHaggle</name>
<LoadChild>
<policy>”Haggle01.cpml”</policy>
<Rolemap>
<RolemapElement>
<parent>PartyA</parent>
<child>Role1</child>
</RolemapElement>
<RolemapElement>
<parent>PartyB</parent>
<child>Role2</child>
</RolemapElement>
</Rolemap>
</LoadChild>
<!— 0 or more child-terminal transitions go here -->
</state>
Terminal
may not have transitions or timeouts. There must be a <return> element
giving a string identifier to be used by the parent CP in selecting a
child-return transition.
E.g.:
<state StateId=”DealMade”>
<return>DealMade</return>
</state>
[NOTE: the <return> tag and the <StateId> attribute might seem to be redundant; but since they serve different functions, they are defined separately.]
A
<transition> consists of:
A <send-message> element consists of:
--a message encoding name (which may be something like
“xml-document” or “plain-text” or other things we think of later) that
identifies the way in which the message’s format is described
--a message schema name, which identifies an XML document or
other data source that defines the format of the message: what fields in may
contain, and so forth.
--Sender element ,the role that can send message
--TransitionName attribute which is unique in the CP
Note that the sender is specified in the source state.
E.g.,
<SendMessageTransition TransitionName="QueryProduct"> <target>Querying</target>
<Sender>Role1</Sender>
<event>SendMessage</message>
<message>
<encoding>xml-document</encoding>
<schema>ProductQuery</schema>
</message>
</SendMessageTransition >
<transition>
<target>Ready</target>
<event>OnTimeout</event>
</transition>
<transition>
<target>DealMade</target>
<event>ChildReturn</event>
<child-return>Accepted</child-return>
</transition>

This
is a simple CP called “Haggle01”. Here’s a state-transition diagram. Start state is “NoOffer”. Return states are double ellipses.
Here’s
the cpXML. Note the reuse of the “Offer” message on transitions from different
states.
<conversationpolicy>
<name>Haggle01</name>
<roles>
<role>Role1</role>
<role>Role2</role>
</roles>
<initialstate>NoOffer</initialstate>
<state StateId=”NoOffer”>
<SendMessageTransition TransitionName=”OfferOpen“>
<target>OfferOpen</target>
<Sender>Role1</Sender>
<event>SendMessage</event>
<message>
<encoding>xml-document</encoding>
<schema>Offer</schema>
</message>
</SendMessageTransition >
</state>
<state StateId=”OfferOpen”>
<timeout>P5M</timeout>
<TimeoutTransition>
<event>OnTimeout</event>
<target>Cancelled</target>
</ TimeoutTransition >
<SendMessageTransition TransitionName=”Cancel”>
<target>Cancelled</target>
<Sender>Role2</Sender>
<event>SendMessage</event>
<message>
<encoding>xml-document</encoding>
<schema>Cancel</schema>
</message>
</ SendMessageTransition >
< SendMessageTransition TransitionName=”Accept” >
<target>Accepted</target>
<Sender>Role2</Sender>
<event>SendMessage</event>
<message>
<encoding>xml-document</encoding>
<schema>Accept</schema>
</message>
</ SendMessageTransition >
< SendMessageTransition TransitionName=”Offer”>
<target>CounterOfferOpen</target>
<Sender>Role2</Sender>
<event>SendMessage</event>
<message>
<encoding>xml-document</encoding>
<schema>Offer</schema>
</message>
</ SendMessageTransition >
</state>
<state StateId=”CounterOfferOpen”>
<timeout>P5M</timeout>
<TimeoutTransition>
<event>on-timeout</event>
<target>Cancelled</target>
</TimeoutTransition>
<SendMessageTransition TransitionName=”Role1Cancel”>
<event>SendMessage</event>
<Sender>Role1</Sender>
<target>Cancelled</target>
<message>
<encoding>xml-document</encoding>
<schema>Cancel</schema>
</message>
</ SendMessageTransition >
< SendMessageTransition TransitionName=”Role1Accept”>
<target>Accepted</target>
<Sender>Role1</Sender>
<event>send-message</event>
<message>
<encoding>xml-document</encoding>
<schema>Accept</schema>
</message>
</ SendMessageTransition >
< SendMessageTransition TransitionName=”Role1Offer”>
<target>OfferOpen</target>
<Sender>Role1</Sender>
<event>SendMessage</event>
<message>
<encoding>xml-document</encoding>
<schema>Offer</schema>
</message>
</ SendMessageTransition >
</state>
<state StateId=”Cancelled”>
<return>Cancelled</return>
</state>
<state StateId=”Accepted”>
<return>Accepted</return>
</state>
</conversationpolicy>
Here’s
a CP that uses the Haggle01 CP as a child as part of a commercial transaction.
There are two roles, “buyer” (B) and “seller” (S). By putting the haggling
process in a child CP, the creators and
users of the BuyStuff CP do not need to concern themselves with most of the
details of the haggling protocol. All that is needed is to know the name of the
child CP, the set of roles, and the set of termination states.
Additionally,
by factoring the overall conversation in this way, it becomes immensely easier
to change the haggling portion to use a different CP, for example by upgrading
to a new and improved version of the Haggle CP. All that needs changing is the
child policy’s name and, perhaps, the transitions for the child’s terminal
states.