- From: Amelia A. Lewis <alewis@tibco.com>
- Date: Tue, 12 Nov 2002 15:35:28 -0500 (EST)
- To: WS Description List <www-ws-desc@w3.org>
This is an example of a "classic" pub/sub application, with sample/proposed WSDL for illustration. In keeping with a long-standing WSDL tradition, we'll describe a stock service. This one represents a stock trading floor. First, let's describe trading, pre-electronics. On a trading floor, all the traders are equals (apart from the fact that some have more money or more assets, and others have more friends or better reputations). When the day starts, someone starts the ball rolling by bellowing "Sell! Enron! Forty! Ten thousand!" Zero or more traders may bellow back acceptances, and start elbowing their way toward the offer (well, in this case, maybe zero or ... zero). Elsewhere, another trader bellows "Buy! MCI! Ten! Hundred thousand!", and the shouts of acceptance are legion as sellers move in to unload. So it continues until the bell. Another day, another billion ... lost (that's okay, we can write it off as deferred income). Colorful, but not obviously relevant, right? Okay, let's make it electronic. First, each trader can offer a service: OfferToSell, OfferToBuy. Each trader can also respond to a service: AcceptSellOffer, AcceptBuyOffer. The deal closes (in the pit) when they get close enough to personally exchange tokens, although most of the interactions happen broadcast (where 'broadcast' means leather lungs). The information being exchanged is straightforward enough, though. <types> <xs:schema> <xs:complexType name="tradeType"> <xs:sequence> <xs:element name="traderID" type="xs:anyURI" minOccurs="1" /> <xs:element name="symbol" type="xs:string" minOccurs="1" /> <xs:element name="price" type="xs:integer" minOccurs="1" /> <xs:element name="quantity" type="xs:integer" minOccurs="1" /> </xs:sequence> </xs:complexType> <xs:element name="SellOffer" type="tradeType" /> <xs:element name="SellAccept" type="tradeType" /> <xs:element name="BuyOffer" type="tradeType" /> <xs:element name="BuyAccept" type="tradeType" /> <xs:element name="SellConfirm" type="tradeType" /> <xs:element name="BuyConfirm" type="tradeType" /> </xs:schema> </types> I'm going to skip over message definitions, in the interest of brevity (and because they may go away, and because it's clearer if I stick the information into the operations outright). <portType name="trader"> <operation name="Sell"> <output element="SellOffer" /> <input element="SellAccept" /> </operation> <operation name="Buy"> <output element="BuyOffer" /> </input element="BuyAccept" /> </operation> <operation name="ConfirmSale"> <output element="SellConfirm" /> <input element="BuyConfirm" /> </operation> <operation name="ConfirmPurchase"> <output element="BuyConfirm" /> <input element="SellConfirm" /> </operation> </portType> A nice, abstract service defined entirely (and controversially, no doubt) in terms of output-input (solicit-response) operations. There are two reasons for choosing this model, rather than calling it request/response. 1) request/response has some *very* clearly understood semantics: two participants, generally synchronous, service is "always offered." Since the daytrader application is classic pub/sub, each participant can equally be cast as client or as server. But reusing "request/response," with *radically* different semantics (service returns multiple responses from multiple locations, asynchronously, for a limited time only) can only serve to blur what is now a well-understood problem. 2) Conceptually, the traders are *offering* a service, not making a request. It will be easier for folks modelling or reading the description to understand if the service is described as a service, not as a client. Creating perceptual stumbling blocks for service description writers or readers is not a terribly good idea. Now, we're going to bind this to IP multicast. We could just as easily bind it to TIBCO rv or various competitors, but IP multicast is publically documented, so will probably be preferred. Note that we don't need anything else--no subscription, in particular--because we plan on binding this to a service that has built-in subscription/administration (which cannot be modelled in WSDL, as we'll see). <binding name="DayTrader" type="trader"> <protocolBinding uri="http://example.org/ip-multicast" /> <!-- nothing else very interesting; I don't want to do soap:body etc. --> </binding> <service name="DayTraderService"> <port name="DayTraderServicePort" binding="DayTrader"> <ipmulti:address location="227.17.17.17" /> </port> </service> Still with me? Let's do some criticism, then. Since I'm writing and criticizing, these are likely to be rather straw men, but please do look at them. First, from what's in the WSDL one cannot figure out how the trading quite exactly works. This is correct. There's some out of band information that has to be supplied, either by the protocol binding, or by a higher-level language (such as BPEL or WSCI). That information: an offer to buy or offer to sell attracts zero or more responses. A confirmation has precisely one response. Order is important: an offer to buy, for instance, attracts zero or more acceptances to buy; when the service decides not to collect any more acceptances, it initiates a set of (node-to-node, using the traderID to find an address) confirmations. The relationship between operations is not expressed in the WSDL (it can only be expressed in a flow language, I believe; adding flow to WSDL is just *way* out of scope). The multiplicity of respondents is not indicated, except by the identification of the MEP. Again, I think it is out of scope for WSDL, per se, to define these things; they are the province of the MEP and binding specifications. Second, there's no subscription information! That's because it's implicit. In order to use *this* particular service, each trader must have an operating system that supports, and is configured for, multicast. Configuration of IP multicast subscriptions depends on: a) the state of the protocol stack in the host subscribing, and b) the state of the nearest multicast router. The process of subscription is: change the NIC and protocol stack to recognize the multicast address as "me" (and you aren't going to do this with an XML message, in any operating system that I can think of, even if you could figure out how to express the target address). Send an IGMP (this is roughly the same level as IP and ICMP; it isn't going to suddenly grow an XML syntax) to the nearest router letting it know that I have another "identity". Both of these things have to happen. Change IGMP to use an XML syntax, and you can send subscription notices *all* *day* *long* to no effect, if the host protocol stack doesn't recognize the address as its own. Subscription, unsubscription, administration are built into the protocol at a very low level; any processor supporting IP multicast already knows (from the special IP address) what it has to do, and it doesn't need (and *can't* use) an XML message to do it. This, by the way, is not a contrived example. It is more or less how trading works, except that it's using SOAP as the envelope format, instead of custom (lightweight!) stuff. Now, let's turn a quick corner. Having gotten all the traders to use our day trader application, we discover that there are lots of folks out there who want to join the fun, and LOSE MONEY FAST! Only they don't have multicast OSs, or network support staff, or really very many clues at all (well, day traders ... *shrug*). They *do* have email. But we can't do this over email, can we? Well, sure we can. First, we have to define subscription and unsubscription messages. I'm going to give those a quick pass, but I point out that they are application level messages. The application gets to define what they look like. There's no particular reason for WSDL to restrict what they look like. We'll pretend we've added schema elements named "subscribe" and "unsubscribe", okay? I'm using a slightly different style, here, which is a possible future for allowing multiple MEPs to share the same pattern. This allows us to use the classic double-opt-in message exchange pattern for administration of the mailing list. <portType name="admin"> <operation name="subscribe" mep="http://www.tibco.com/xmlns/soap/mep/confirmation/"> <input element="subscribe" /> <output element="challenge" /> <input element="confirm" /> </operation> <operation name="unsubscribe" mep="http://www.tibco.com/xmlns/soap/mep/confirmation/"> <input element="unsubscribe" /> <output element="challenge" /> <input element="confirm" /> </operation> </portType> <binding name="DayTraderAdmin"> <protocolBinding uri="http://www.tibco.com/xmlns/soap/dist-email/" /> <!-- still nothing interesting --> </binding> <service name="DayTraderAdminService"> <port name="DayTraderAdminServicePort" binding="DayTraderAdmin"> <email:address location="day-traders-admin@example.com" /> </port> </service> And we need to revise the service itself, of course. <binding name="DayTrader" type="trader"> <protocolBinding uri="http://www.tibco.com/xmlns/soap/dist-email/" /> <!-- nothing else very interesting; I don't want to do soap:body etc. --> </binding> <service name="DayTraderService"> <port name="DayTraderServicePort" binding="DayTrader"> <email:address location="day-traders@example.com" /> </port> </service> And we're done ... at least in WSDL terms. We're *not* done in terms of explaining how the subscription relates to the list itself. But again, it seems to me that that opens issues of scoping, for WSDL, that ultimately drive it to be a flow language. We can define the operations in WSDL. We can't define the order of operations. We can define services in WSDL. We can't define how those services are related to one another. We do define how services are associated with bindings, and how bindings implement port types. That's enough, that's our scope, and we can't get into the question of order of execution, without enlarging scope to Web Services Description and Process Language. Amy! -- Amelia A. Lewis Architect, TIBCO/Extensibility, Inc. alewis@tibco.com
Received on Tuesday, 12 November 2002 16:00:38 UTC