Scripting Groove Web Services
I first saw Groove in the spring of 2000, when Tim O'Reilly invited me to join him on a visit to Groove Networks. Our mission was to learn what Ray Ozzie and a surprisingly large team of crack developers had been secretly inventing in a Brobdingnagian former shoe factory in Beverly, Massachusetts. When version 1.0 shipped in the fall of that year, I interviewed Ray for the O'Reilly Network. Two years later, peer-to-peer isn't the rage that it was (and will be again), but Ray's concluding remarks still resonate powerfully:
Groove isn't an indirect marketing play. It's about enhancing the value of the pipe that is connected between us, in a way that gives you control and respects your privacy. It's a way for you to share and do things with the people who are important to you. It's about value, and trust.
Groove enhances the value of the pipe by supplying a set of services, including always-on security, reliable messaging, store-and-forward delivery, firewall/NAT transparency, ad hoc group formation, and change notification. The problem, for me, was that I couldn't see how to build on the platform. If you're looking for a definition of software development goodness, you can't do better than Larry Wall's dictum: easy things should be easy, hard things should be possible. The Groove Developer's Kit (GDK) met the second requirement, but not the first. To create a tool that can be injected into a Groove shared space, and that displays in the transceiver, you had to master some pretty esoteric skills. There are brilliant practioners of that art, but I'll never become one of them. More importantly, neither will a great many scripters who would otherwise love to reach into Groove's basket of services. Why couldn't we just write a few lines of Perl, or Python, or Ruby, or C#, in order to do easy things easily? In the next version of Groove, due out in early 2003, we can, thanks to Groove Web Services (GWS).
I've written elsewhere about the architecture of GWS. Now that I've had a chance to try out a preview of the software, I'm even more excited. I've written a proof-of-concept application--in Perl and C#--that reads the messages in a Groove forum (Discussion tool), notices URLs mentioned there, fetches the pages referenced by those URLs, and stores them in a repository (Files tool). It's brain-dead simple. If the forum were a newsgroup or a discussion board, and the repository were a Web-based or local filesystem, these little scripts would be utterly boring. But Groove forums and Groove repositories have interesting properties.
Suppose I mention the URL of this very article in a Groove discussion. It's kind of nice to know that I'll be able to read it anytime, anywhere, because the article will be stored on my laptop, on my desktop PC, and on any other Groove device I use. From a team perspective--and this, of course, is the essence of Groove--it's also nice to know that the same will hold true for all members of the shared space in which I made this reference to the article. More goodness: the change notification system will automatically flag the newly added article, on all devices and for all users in the space.
Example 1 illustrates this idea using Perl, and Example 2 does the same thing in C#. I chose these languages purely for convenience. The beta GWS kit includes Perl wrappers for the GWS WSDL interfaces, which handle things like generating the schema-defined SOAP headers, and doing doc/literal serialization. I stole some of these idioms from the sample program, although I'm not enough of a SOAP or SOAP::Lite expert to fully grok the details. Suffice it to say that somebody inside Groove created these wrappers, and that once GWS ships as part of Groove 2.5, people outside Groove will refine and extend them. I'm particularly looking forward to PyGroove which, if history repeats itself, Mark Pilgrim will probably knock off in short order.
For me, C# was easier in one way and harder in another. It was easier because Visual Studio .NET made consumption of the WSDL APIs frictionless. No support libraries were needed. It was harder because, well, C# really isn't a scripting language. Regular expression hacks that Perl does in a single statement take several lines of C# code. And life's too short to waste time converting strings to byte arrays. The early promise of .NET was that dynamic languages would be first-class citizens of the environment. That hasn't happened yet, but I'm still hoping that it will.
Two features stand out prominently in both examples. First, there's the Groove "nonce"--a value fetched from the Windows registry and stashed into the header of every SOAP message. This value, which changes each time Groove starts, is the token that your scripts use to authenticate to the SOAP listener on localhost. Local access is all that's supported in the current beta; I wasn't able to try a forthcoming mechanism for remote invocation. In the local case, the security rationale is that if you've got control of your registry, you're OK, and if not, you've got worse problems than just a Groove breach. It's a reasonable stance.
Script Locally, Publish Globally
It's fascinating to see how powerful the seemingly restrictive localhost-only setup can be. In these examples, I make local SOAP calls to update a single instance of a shared space, and yet can affect a whole population of devices and users. Script locally, publish globally. Here's a thought experiment that underscores where this could go. Let's say I'm running GWS, and you are too, and we agree on a protocol whereby some tool in a shared space we inhabit serves as a blackboard. On that blackboard, we post queries: "find documents that mention x;" "find contacts at organization y." When we execute a query and post the results back to the blackboard, we will have performed a union of two disjoint sets of shared spaces. We obviously have at least one space in common, but you're not a member of all of mine, nor I of yours. The notion that a few lines of Perl can create this wormhole effect will undoubtedly cause eyebrows to be raised in certain quarters. But I hope it will be clear that nothing fundamental to the Groove security model has changed. Shared-space membership is always based on trust that can be violated. It was always true that I could take one of your confidential, ultra-encrypted documents and pop it into an email to anyone in the world. My guess is that, Palladium fantasies notwithstanding, that always will be true.
Admittedly, our thought experiment is not completely innocuous. My asking you for information to which I do not have direct access is not quite the same as my asking your software agent for information to which I do not have direct access. Before we agree to install these agents, then, we'll need to convince ourselves that they will exercise the right kind of judgment. Since judgment is exactly what software agents lack, that'll be a hard sell in some environments. Fine. Don't use GWS, then. People who lack judgment are already enough to worry about. You can, and in these situations should, use the managed-identity features in the enterprise flavor of Groove to keep track of where they go and what they do. In other cases, though, you'll care more to promote the flow of information across shared spaces than to keep it locked within them. Imagine a federated blogspace that's a network of weakly linked teams, each with a view of data that's guaranteed to be consistent. I honestly don't know quite what that would mean, but I'm intensely curious to find out.
Links and URLs
The other noteworthy feature of the two examples is the way in which they embed some long, nasty-looking URLs. These identify SOAP endpoints, and belong to a Weblike namespace that can be traversed like so:
After I created these spaces interactively in the Groove transceiver, I discovered their URLs by traversing my Groove account using a WinForms-based explorer (included in the beta kit) that walks the account and dumps everything into a tree control. Each of the SOAP endpoint URLs that it reveals is, in effect, a bookmark that you can use to revisit a location in Groovespace.
account -> identities -> spaces -> tools -> data.
It's tempting to push the analogy further. If I can bookmark a file in a Groove repository, can I link to it as well? Yes and no. Interactively, using the transceiver, I can create a link to a file in the Files tool, then switch to the Discussion tool and paste it into a message. My original plan was to add a groove: link alongside the http: link so that an offline user could go directly to the stored file. The internal linking mechanism isn't exposed yet through GWS, however, so I resorted to decorating the URL with a name (its HTML doctitle) that corresponds to the name of the stored file.
The relationship between Groove and the Web, with respect to URLs and linking, has always been a bit problematic. The RESTful style of GWS makes it easier to join these realms, but the relationship still isn't seamless, and perhaps cannot be. A Groove URL has facets--account, identity--that a Web URL does not. Nevertheless, interesting results are bound to emerge. Consider, for example, the curious property exhibited by URLs in a local, Web-server-based product like Radio UserLand. A single URL, posted on a public site, behaves differently for different people. A document that explains how to adjust the number of items shown in the news aggregator, for example, can describe the process step by step:
Prefs -> News Aggregator -> How Many Items?
But it can also include a link that resolves uniquely for each Radio user who clicks on it. In similar fashion, a GWS endpoint has a user-specific piece (account -> identity) and a canonical piece (space -> tool -> data). I'm quite certain that useful effects will be achieved by breaking apart and recombining these pieces.
The point of all this, in any case, is not to make Groove just like the Web. It's different in ways that define its mission: to support ad hoc, secure, robust, and multimodal team communication. Until now, you've had to climb a wall in order to integrate that communication with email and the Web. GWS is about to tear down that wall, and when it does Groove will become useful to many more people than it already is.