UDDI::HalfDecent - a half-decent implementation of UDDI


 use UDDI::HalfDecent;
 $endpoint = "";
 $uddi = new UDDI::HalfDecent($endpoint);
 $rs = $uddi->find_business(name => 'frog');
 $n = $rs->count();
 foreach $i (0 .. $n-1) {
     $rec = $rs->record($i);
     $key = $rec->xpath('@businessKey');
     $rs2 = $uddi->find_service(businessKey => $key);


I have tried to use and love UDDI::Lite, honestly I have. I have tried to use the underlying SOAP::Lite, which package UDDI::Lite is part of, and ploughed countless futile man-hours into the effort. There is no doubt that that suite of modules is a tour de force of intellectual effort, startling in its strange, crystalline beauty and innovative to a degree one hardly thought possible. All of this is, however, marred by the one tiny flaw that it doesn't work. And worse, it doesn't diagnose its failures: error-handling callbacks don't get invoked, global error-indication objects don't get set, and SOAP faults perfectly visible in the protocol XML go unreported.

So the obvious thing to do is go into that code and fix it, right? Except you can't because the code is so obviously a work of genius that no mortal being can understand it. (I am not just being feeble here: this is the overwhelming feeling of the broader community). The SOAP::Lite code, including UDDI::Lite, is a fantastic illustration of Kernighan and Pike's observation: "Everyone knows that debugging is twice as hard at writing a program in the first place. So if you're as clever as you can be be when you write it, how will you ever debug it?" (from The Elements of Programming Style, 1978 - very nearly thirty years old as I write this, but as fresh and relevant as ever. And very funny, which is not something you can say about most programming books.)

So the SOAP::Lite package is a write-off, and my attempts to interact with its community underline that: the email address of the package maintainer no longer works, and the mailing list consists entirely of forlorn souls such as myself asking "has anyone got x to work?" and never receiving replies.

And the only other UDDI package on CPAN is one just called UDDI, the most recent release of which is 0.03 from the year 2000, and which fails its test-suite.

So that leaves only one option, which is to start from the ground and roll my own. At least that way I'll be ablet to debug it.

The number one design principle with this module (and anyone who's used SOAP::Lite will understand why I make a big deal of this) is that all errors are reported immediately, through the throwing of a Exception::Class::UDDI object. If something goes wrong, you will know it; and you will know it immediately; and you will know what went wrong. Just imagine!

On the downside, this module has no pretention to the flexibility and generality that SOAP::Lite and UDDI::Lite would offer, if only they worked. Those modules set out to encompass RPC-style and document-style SOAP, XML-RPC, UDDI versions 1, 2 and 3 (although not really 3) and of course a hundred different ways of expressing everything. This module will offer only those facilities required to access actual UDDI servers - and, more precisely, those facilities needed by z2uddi.



 $uddi = new UDDI::HalfDecent($endpoint);

Creates and returns a new UDDI object for communicating with the specified endpoint.


 $val = $uddi->option($key);
 $oldval = $uddi->option($key, $newval);
 $uddi->option($key, $oldval);

Gets and gets the values of named options in the UDDI object. When called with a single argument, the current value of the specified option is returned; when called with two arguments the option named by the first is set to the value specified by the second, and the old value of the named option is returned.

Options affect the functioning of the UDDI object as follows:


Specifies the version of HTTP to use. Valid values are 1.0 and 1.1; if not specified, HTTP 1.1 is used.


Specifies the version of UDDI to use. Valid values are 1, 2 and 3; if not specified, UDDI version 3 is used. Note that some servers are arses when it comes to this: for example, if you send a v3 request to, it will send a v2 response whose fault information will therefore not be readable. So if you get funny results from a server, try playing with this.


If this is set then it is the URL of a proxy which will be used for all HTTP transactions. Not set by default.


If set to a true value, the all log messages emitted will have a .prefix of the form _log(level) and the messages themselves will be enclosed in square brackets. This makes the logging more explicit, and in particular makes it possible to see zero-length log messages such as empty responses. Not set by default.


 $uddi->loglevel(qw(-- request response));

Sets the logging level of the UDDI object, controlling what logging information is emitted on the standard error stream. Zero or more levels may be specified, each as a separate argument: each specified level is added to the current set unless it is prefixed with a minus sign in which case it is removed from the current set. The special option -- clears all currently set levels.

Supported logging levels include:


The XML of UDDI requests is emitted.


The XML of UDDI responses is emitted.


The headers associated with the requests sent


The headers associated with the requests sent

find_business(), find_service(), find_binding(), find_tModel()

 $rs = $uddi->find_business(name => 'frog');
 $rs = $uddi->find_business(name => 'fish',
     qualifiers => [ qw(sortByNameAsc caseSensitiveMatch) ]);
 $rs = $uddi->find_service(businessKey => "0123456789abcdef");
 $rs = $uddi->find_binding(serviceKey => "0123456789abcdef");
 $rs = $uddi->find_tModel(name => 'uddi');

These four similar methods search in the UDDI repository indicated by $uddi for businesses, services, bindings and tModels matching the specified criteria. These criteria consist of key-value pairs, in which the key may be any of the following (though not all keys are valid for all four kinds of search):


The name, or partial name, of the business or businesses to search for. It exactly interpretation is specified by the qualifiers. By default, the name is searched for case-sensitively and for an exact match.


A set of zero or more qualifier tokens which modify the interpretation of name, separated by spaces or commas. The acceptable qualifiers are: andAllKeys, approximateMatch, binarySort, bindingSubset, caseInsensitiveSort, caseInsensitiveMatch, caseSensitiveSort, caseSensitiveMatch, combineCategoryBags, diacriticInsensitiveMatch, diacriticSensitiveMatch, exactMatch, signaturePresent, orAllKeys, orLikeKeys, serviceSubset, sortByNameAsc, sortByNameDesc, sortByDateAsc, sortByDateDesc, suppressProjectedServices and UTS-10. The meanings of these are defined in section of the UDDI specification.


The unique key of a business whose services are sought. This may be obtained from the result of an earlier find_business() call using $record->xpath('@businessKey').


The unique key of a service whose bindings are sought. This may be obtained from the result of an earlier find_service() call using $record->xpath('@serviceKey').


A bag of tModels, separated by spaces or commas.


A bag of identifiers, separated by spaces or commas.


A bag of categories, separated by spaces or commas.

On success, these methods return a UDDI::HalfDecent::ResultSet object which may be further interrogated. On failure, they throw an exception of type UDDIException describing what went wrong.


The functioning of this module is affected by several environment variables, all of having names beginning with UDDI_:


If this is set, then it is a comma- or space-separated list of levels to be be included in the logging output on standard error. See the description of the loglevel() method for details.


If this is set to a true value, then when uncaught exceptions are displayed, a full stack-trace will be included. That is helpful for debugging, but a bit ugly for production.


Exception::Class provides the exception objects thrown by this package.

Net::Z3950::UDDI is the module that uses this, and for which it was written.

z2uddi is the gateway program, built on Net::Z3950::UDDI, that is the raison d'etre of this code.

UDDI::Lite is supposedly a UDDI library that is part of the SOAP::Lite distribution, although I can't testify to that since I have never seen it actually do any UDDI.


As for Net::Z3950::UDDI.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 223:

=back doesn't take any parameters, but you said =back 4