Главная » Java, Web, XML » Реализации UDDI API

0

Функции, входящие в UDDI API, предоставляют все средства для работы клиента с реестром UDDI, но записывать элементы XML, реализующие эти функции — тяжелая и кропотливая работа. Для того чтобы облегчить эту работу, создаются библиотеки классов, автоматически создающих SOAP- послания с запросами к реестру UDDI.

Пакет IBM UDDI4J

Есть уже много библиотек классов и отдельных функций, написанных на различных языках. В технологии Java чаще всего используется пакет классов UDDI4J (UDDI for Java), разработанный фирмой IBM (http://www.uddi4j.org/). Пакет UDDI4J входит в состав IBM WSTK. Классы, входящие в пакет UDDI4J, обеспечивают работу клиента в UDDI-реестре.

Все обращения к реестру UDDI идут через класс-посредник реализованный в пакете UDDI4J. Класс UDDiProxy преобразует эти обращения в функции UDDI API. Методы этого класса называются так же, как и функции UDDI API: save_business (), find_service () И так далее. Они возвращают объекты классов, представляющих SOAP-структуры: ServiceList, BusinessList, BindingDetail, TModelList И Другие классы, собранные В пакет com. ibm.uddi. response.

Аргументами методов класса uddi Proxy, дублирующих функции UDDI API, служат объекты классов, представляющих аргументы функций UDDI API: Authlnfo, FindQualifiers, FindQualifier, IdentifierBag, CategoryBag, TModelBag, BindingKey, BusinessKey, ServiceKey И Другие классы, собранные В пакет com.ibm.uddi.util.

С помощью перечисленных методов и классов можно полностью смоделировать работу UDDI API.

Другой способ использования UDDI API, предлагаемый пакетом UDDI4J, — сначала смоделировать функцию UDDI API объектом одного

ИЗ классов SaveBusiness, SaveService, SaveTModel, FindBusiness, FindService, DeleteBusiness, GetServiceDetail ИЛИ другого класса ИЗ пакета com. ibm. uddi. request. Все эти классы расширяют абстрактный класс UDDIElement.

После того как объект-запрос создан, он посылается реестру методом public org. w3c.dom. Element send (UDDIElement el, boolean inquiry);

Метод возвращает результат запроса в виде дерева элементов XML, которое затем надо разобрать каким-нибудь DOM-парсером.

При создании объекта-запроса полезны классы, моделирующие элементы реестра UDDI: BusinessEntity, Business Services, Business Service, BindingTemplates, BindingTemplate, TModel И множество Других. Они СОбраны в пакет com. ibm. uddi . datatype и его подпакеты.

В листинге 5.7 показано, как можно средствами UDDI4J зарегистрировать Web-службу в том или ином UDDI-реестре.

1 Листинг 5.7. Регистрация Web-службы в UDDI-реестре

import com.ibm.uddi.*;

import com.ibm.uddi.datatype.business.*; import com.ibm.uddi.response.*; import com.ibm.uddi.client.*; import org.w3c.dom.Element; import java.util.Vector;

import java.util.Properties;

public class SaveSomeService{

public static void main (String[] args){

SaveSomeService app = new SaveSomeService(); UDDlProxy proxy = new UDDlProxy();

try{

// Выбираем UDDI-реестр:

// Тестовый реестр IBM proxy.setlnquiryURL("http://www-3.ibm.com/services/" +

"uddi/testregistry/inquiryapi");

proxy.setPublishURL("https://www-3.ibm.com/services/" + "uddi/testregistry/protect/publishapi");

// Официальный реестр IBM // proxy.setlnquiryURL("http://www-3.ibm.com/services/" +

//           "uddi/inquiryapi");

//                             //www-3.ibm.com/services/" +

//

// Тестовый реестр Microsoft

//

//           "http://test.uddi.microsoft.com/inquire");

//

II      "https://test.uddi.microsoft.com/publish");

// Официальный реестр Microsoft

// //

// Реестр Hewlett Packard

// //

// Отладочный локальный реестр из пакета WSTK

// // //

//    "http://localhost:8080/services/uddi/publishapi");

// Заходим на сайт UDDI-реестра. AuthToken token

"userid", "password") ; i’

System.out.println(

"Регистрационный код: " + token.getAuthlnfoString());

System.out.println("Регистрируем Web-службу");

Vector entities = new

// Создаем элемент <businessEntity>. // Первый аргумент — UUID — пока неизвестен. BusinessEntity be = new BusinessEntity("", "SomeService");

entities.addElement(be);

// Регистрируем Web-службу BusinessDetail bd =

entities);

// Для проверки получаем UUID.

Vector businessEntities = bd.getBusinessEntityVector();

BusinessEntity returnedBusinessEntity =

(BusinessEntity)(businessEntities.elementAt(0));

System.out.println("Получили UUID: " +

returnedBusinessEntity.getBusinessKey());

}catch(UDDIException e) {

DispositionReport dr = e.getDispositionReport();

if (dr ! = null) (

System.out.println(

"UDDIException faultCode:" + e.getFaultCode() +

"\n operator:" + dr.getOperator() +

"\n generic:" + dr. getGeneric () +

"\n errno:" + dr.getErrno () +

"\n errCode:" + dr. getErrCode () +

"\n errlnfoText: " + dr. getErrlnfoText () ) ;

}

e.printStackTrace() ;

}catch(Exception e) {

System, err. println ("From proxy: " + e) ;

}

}

}

Программа листинга 5.8 отыскивает Web-службу в том или ином реестре UDDI и получает информацию о зарегистрированных в нем Web-службах.

: Листинг 5.8. Поиск информации в реестре UDDI

import import import import import

import java.util.Vector; import j ava. util. Properties ;

public class SaveSomeService{

public static void main (string [] args) {

SaveSomeService app = new SaveSomeService () ;

UDDIProxy proxy = new UDDIProxyO;

try{

// Выбираем UDDI-реестр:

// Тестовый реестр IBM proxy.setlnquiryURL("http://www-З.ibm.com/services/" +

"uddi/testregistry/inquiryapi");

+

"uddi/testregistry/protect/publishapi");

// Официальный реестр IBM // +

//          "uddi/inquiryapi");

// +

//

// Тестовый реестр Microsoft

//

//           "http://test.uddi.microsoft.com/inquire");

//

//

// Официальный реестр Microsoft

//

/ / proxy.setPublishURL("https://uddi.microsoft.com/publish") ,

/ / Реестр Hewlett Packard

IIproxy.setlnquiryURL("http://uddi.hp.com/inquire"); // proxy.setPublishURL("https://uddi.hp.com/publish");

// Отладочный локальный реестр из пакета WSTK

// proxy.setlnquiryURL(

//

//

//    "http://localhost:8080/services/uddi/publishapi");

// Заходим на сайт UDDI-реестра. AuthToken token = proxy.get_authToken(

"userid", "password");

System.out.println(

"Регистрационный код: " + token.getAuthlnfoString());

System, out. println ("Список Web-служб: " ) ;

// Получаем список зарегистрированных // Web-служб, чьи имена начинаются с буквы "S" . BusinessList Ы = proxy.find_business("S", null, 0) ;

Vector businesslnfoVector =

bl.getBusinessInfos().getBusinessInfoVector();

for (int i = 0; i < businesslnfoVector.size(); i++){

=

(Businesslnfo)businesslnfoVector.elementAt(i); System.out.println(businesslnfo.getNameString());

}

}catch(UDDIException e) {

DispositionReport dr =

if (dr ! = null) {

System.out.println(

"UDDIException faultCode:" + e. getFaultCode () +

"\n operator:" + dr. getOperator () +

"\n generic:" + dr.getGeneric() +

"\n errno:" + dr.getErrno() +

"\n errCode:" + dr.getErrCode() +

"\n errlrifoText:" + dr.getErrlnfoText());

}

e.printStackTrace();

}catch(Exception e) { System, err. println ("From proxy: " + e) ;

}

}

}

Пакет JAXR

В главе 2 и в этой главе мы говорили о нескольких различных системах регистрации и поиска Web-служб: UDDI, ebXML, WS-Inspection. Есть и другие системы, не рассматриваемые в этой книге. Все эти системы требуют разных методов доступа к реестру и работы с ним. Для каждой системы приходится создавать своего клиента, работающего с реестром по правилам данной системы поиска Web-служб.

Как уже говорилось в главе 2, фирма Sun Microsystems решила разработать единую методику доступа к реестрам разных типов и создала набор интерфейсов JAXR. Этот набор реализован в пакете Sun WSDP и будет включен в состав J2EE, предположительно начиная с версии 1.4. В пакет Sun WSDP включен пример клиента реестра, созданного средствами JAXR. Это графическая утилита просмотра реестров Registry Browser. Она вызывается из командной строки просто набором имени командного файла.

$ jaxr-browser

Как мы уже говорили в главе 2, в составе WSDP есть и простой тренировочный реестр, реализованный в виде сервлета RegistryServerServlet. Реестр работает в Web-контейнере Tomcat и хранит информацию в небольшой базе данных Xindice (произносится, как говорят авторы, "Зин-ди-чи" — с итальянским акцентом), созданной сообществом Apache Software Foundation и тоже входящей в состав WSDP. Для запуска реестра надо запустить Tomcat и стартовать базу данных: $ cd $WSDP_HOME/bin

$ startup $ xindice-start

Для проверки работы реестра и для посылки ему сообщений применяется специальная утилита, работающая из командной строки. Для входа в реестр надо набрать следующую командную строку:

$ registry-server-test run-cli-request -Dxml/GetAuthToken.xml

Для работы с реестром прямо через базу данных Xindice в составе WSDP есть графическая утилита Indri. Она запускается из командной строки:

$ registry-server-test run-indri

Поскольку набор JAXR рассчитан на работу с реестрами самых разных типов, он содержит только интерфейсы, которые должен реализовать поставщик услуг (service provider) конкретного реестра. Интерфейсы будут по- разному реализованы поставщиком услуг реестра UDDI и поставщиком услуг реестра ebXML, но клиент этого не замечает, он просто связывается с поставщиком услуг и пользуется интерфейсами пакета JAXR. Схема обращения клиента к реестру через поставщика услуг показана на рис 2.4.

Состав пакета JAXR

Набор JAXR состоит из двух Java-пакетов j avax. xml. registry и

Интерфейсы первого пакета применяются клиентом для работы с реестром, интерфейсы второго пакета — поставщиком услуг для преобразования информации к виду, пригодному для хранения в базе данных реестра.

Для связи с поставщиком услуг клиент пользуется интерфейсом connection. Экземпляр этого класса клиент получает с помощью класса-фабрики ConnectionFactory. Сначала статическим методом                         () создается

объект этого класса, затем методом setProperties () в него заносятся характеристики реестра, после этого методом            создается объект типа Connection. Вот примерная схема соединения:

Properties props = new Properties () ;

props. setProperty (" j avax. xml. registry. queryManagerURL",

queryURL);

ConnectionFactory fact = ConnectionFactory.newInstance() ; fact.setProperties(props);

Connection conn = factory.createConnection();

После того как связь с поставщиком услуг установлена, методом getRegistryService () интерфейса Connection получаем объект типа RegistryService:

RegistryService rs = conn.getRegistryService () ;

Интерфейс RegistryService — это центральный интерфейс в пакете JAXR. Своими методами        он предоставляет основные объекты, содержа

щие методы работы с реестром.

Так, методом getBusinessQueryManager() получаем объект типа

BusinessQueryManager:

BusinessQueryManager bqm = rs.getBusinessQueryManager() ;

Поиск в реестре

В интерфейсе BusinessQueryManager собран                         десяток методов

получения информации из реестра. Конечно, их сигнатуры не совпадают с сигнатурами функций     API, поскольку пакет JAXR рас

считан на разные реестры, не только UDDI. Вот заголовок одного из этих методов:

public BulkResponse                              orgKey,

Collection findQualifiers, Collection namePatterns, Collection classifications, Collection

Первый аргумент этого метода orgKey содержит идентификатор отыскиваемой Web-службы, которым может быть ключ UDDI.

Во втором аргументе findQualifiers, аналогичном аргументу функций UDDI, в метод передается набор условий поиска. Условия поиска записаны строковыми константами интерфейса FindQualifier. Например, условие сортировки результата поиска по имени записывается константой

FindQualifier.SORT_BY_NAME_ASC.

Третий аргумент namePatterns содержит набор шаблонов имен для поиска. Каждый шаблон — строка символов, содержащая метасимволы в духе SQL.

Четвертый аргумент classifications передает в метод набор объектов типа classification, классифицирующих искомую Web-службу. Этот аргумент аналогичен аргументу <categoryBag> UDDI API.

Наконец, пятый аргумент, specifications, содержит набор технических деталей, аналогично аргументу <tModelBag> UDDI API. Тип каждого элемента ЕЛСИ коллекции RegistryObject. Интерфейс RegistryObject — ЕГО суперинтерфейс большинства объектов реестра. Среди них service,

ServiceBinding, User, Organization.

Как видите, аргументы метода findservices() весьма сложны, что отражает сложность поиска в реестре.

Метод findservices о возвращает объект типа BulkResponse, содержащий сведения о найденных Web-службах в виде коллекции типа collection. Прежде чем воспользоваться результатом, следует проверить успешность запроса. Проверка выполняется методом getstatus (), возвращающим одну из четырех констант STATUS JJNAVAILABLE.

Итак, искать Web-службу надо примерно так:

BulkResponse resp = bqrn. findService (key, null, null, null, null);

if (resp.getStatus() = BulkResponse.STATUS^SUCCESS){ Collection coll =

}

Полученная коллекция должна содержать объекты типа Service, аналогичные элементу <businessService> реестра UDDI. Выделив из коллекции один такой объект:

Service serv = {Service)coll.iterator().next ();

извлекаем из него информацию многочисленными методами интерфейса Service И его Предка — интерфейса RegistryObject: getKeyO, getDescription() , getName(),getSubmittingOrganization() И другими.

Остальные методы findXxx() интерфейса BusinessQueryManager ОТЫСКИв^ ют сведения о фирме, фирмы, связанные с фирмой, указанной в запросе, способы классификации, принятые в реестре, и другую информацию о реестре. Наиболее полезен из них метод findServiceBindings о с теми же аргументами и возвращаемым значением, что и метод findservices(). По информации, возвращаемой методом findServiceBindings () можно узнать способы доступа к реестру. Метод                                      возвращает самую

обширную информацию о всей фирме.

В листинге 5.9 показано, как можно связаться с реестром и получить из него различную информацию о фирме с помощью JAXR.

public class JAXRClient {

public static void main (String [ ] args) (

// Несколько адресов реестров на выбор. String queryURL =

"http://www-3.ibm.com/services/uddi/inquiryapi"; //"http://uddi.rte.microsoft.com/inquire";

//"http://localhost:8080/registry-server/RegistryServerServlet";

if {args.length< 1) {

System, out.println ("Usage: java JAXRClient <name>") ; System.exit(1) ;

}

JAXRClient jq = new JAXRClient();

String httpProxyHost = "localhost"; String httpProxyPort = "8080";

Properties props = new

props.setProperty("javax.xml.registry.queryManagerURL",

queryURL);

props.setProperty("com.sun.xml.registry.http.proxyHost",

httpProxyHost); props.setProperty("com.sun.xml.registry.http.proxyPort",

httpProxyPort);

Connection conn = null; try{

ConnectionFactory fact =

ConnectionFactory.newlnstance();

fact.setProperties(props);

conn =

System, out .println ("Связь с реестром установлена") ;

Registry-Service rs = conn.getRegistryService(); BusinessQueryManager bqm = rs.getBusinessQueryManager();

Collection findQualif iers = new ArrayList(); findQualif iers. add (FindQualif ier. SORT_BY__NAME__DESC) ;

Collection namePatterns = new ArrayList(); namePatterns.add("%" +args[0] +"%");

// Поиск фирмы ПО имени. response = bqm.findOrganizations(findQualifiers,

namePatterns, null, null, null, null);

Collection orgs =

// Сведения о фирме. Iterator while

Organization org = (Organization)orglter.next();

" +

org.getName().getValue());

" +

org.getDescription().getValue());

" +

org.getKey().getld());

// Контактная информация User =

if (pc != null) {

PersonName pcName = pc.getPersonName ();

" +

pcName.getFullName() ) ;

Collection phNums =

pc.getTelephoneNumbers(null); Iterator phlter = phNums.iterator(); while (phlter.hasNextO ) {

TelephoneNumber num =

(TelephoneNumberJphlter.next();

System.out.println("Номер телефона: " + num.getNumber());

}

Collection eAddrs = pc.getEmailAddresses(); Iterator ealter = eAddrs.iterator();

while (ealter.hasNext())(

EmailAddress eAd =

(EmailAddress) ealter.next();

System.out.println("E-mail: " + eAd.getAddress());

}

}

// Услуги и доступ к ним Collection services = org.getServices();

Iterator      =

while

Service svc = (Service)

System.out.println("Название услуги: " + svc. getName () . getValue () ) ;

System.out.println("Описание услуги: " + svc.getDescription().getValue());

Collection serviceBindings =

svc.getServiceBindings();

Iterator                  =

while (sblter.hasNext ()) {

ServiceBlnding sb =

(ServiceBinding)sblter.next();

System.out.println("Адрес URI: " + sb.getAccessURI());

}

}

System, out.println ("——- ");

}

}catch(Exception e) {

e.printStackTrace() ; }finally}

if (ccnnecticn != null) try{

connection.close(); } catch (JAXRException je) {}

}

}

Изменением информации в реестре занимаются методы интерфейса

BusinessLifeCycleManager.

Изменение записей реестра

В интерфейсе BusinessLifeCycleManager собраны методы и удаляющие или изменяющие информацию, хранящуюся в рее

стре. Кроме того, поскольку этот интерфейс расширяет интерфейс можно воспользоваться многочисленными методами последнего интерфейса, создающими записи в реестре.

Объект интерфейса BusinessLifeCycleManager получаем с помощью объекта типа RegistryService следующим методом:

BusinessLifeCycieManager blcm = rs.getBusinessLifeCycleManager();

Около сорока унаследованных методов полученного объекта создают различные записи В реестре: createClassification(), createEmailAddress(), createKeyO, createPostalAddress(), createService(), createUser() И

другие.

Шесть методов удаляют записи разных типов, например, метод deleteServices<). Их аргументами служат коллекции ключей удаляемых записей.

Шесть методов заносят новые сведения, например, метод saveservices (). Аргументами этих методов служат коллекции объектов соответствующего типа.

В листинге 5.10 показано создание записи о фирме в реестре. Листинг 5.10. Создание записи в реестре

import javax.xml.registry. *;

import j avax.xml.registry.infomodel.*;

import j ava. net. *;

import

import

public class JAXRPublishf

Connection connection = null; public

public static void min (String [ ] args){

String queryURL =

"http://www-3.ibm.com/services/uddi/v2beta/inquiryapi" ; //"http://uddi.rte.microsoft.com/inquire";

//"http://localhost:8080/registry-server/RegistryServerServlet";

String publishURL =

"https://www-3.ibm.com/services/uddi/v2beta/protect/publishapi";

//"https://uddi.rte.microsoft.com/publish"; //"http://localhost:8080/registry-server/RegistryServerServlet";

String username = "testuser"; String password = "testuser";

String httpProxyHost = "localhost"; String httpProxyPort ="8080";

Properties props = new Properties () ;

props. setProperty (" j avax. xml. registry. queryManagerURL", queryURL);

props.setProperty("javax.xml.registry.lifeCycleManagerURL", publishURL);

props.setProperty("com.sun.xml.registry.http.proxyHost",

httpPtoxyHost); props.setProperty("com.sun.xml.registry.http.proxyPort",

httpProxyPort) ; props.setProperty("com.sun.xml.registry.https.proxyHost",

httpsEtoxyHost); props.setProperty("com.sun.xml.registry.https.proxyPort", httpsProxyPort);

try{

ConnectionFactory fact =

ConnectionFactory.newlnstance(); fact.setProperties(props); conn = factory.createConnection();

System, out .println ("Соединение установлено. ") ;

RegistryServ^ice rs = connection.getRegistryService();

BusinessLifeCycleManager blcm =

rs.getBusinessLifeCycleManager();

=

PasswordAuthentication passwdAuth =

new PasswordAuthentication(username, password.toCharArrayO);

Set creds = new HashSet () ; creds.add(passwdAuth); conn.setCredentials(creds);

// Создание фирмы. Organization org =

blcm.createOrganization("Рога и копыта") ; InternationalString s =

blcm.createlnternationalString( "Прием круглосуточно."); org.setDescription(s);

// Контактная информация. User primaryContact = blcm.createUser();

PersonName pName = blcm.createPersonName ("О. И. Бендер" );

primaryContact.setPersonName(pName);

=

tNum.setNumber("333-44-55");

Collection phoneNums = new ArrayList(); phoneNums. ad^^um) ;

primaryContact.setTelephoneNumbers(phoneNums);

=

blcm.createEmailAddress("bender@hornhoof.com");

Collection emailAddresses = new ArrayList(); emailAddresses.add(emailAddress) ;

primaryContact.setEmailAddresses(emailAddresses);

org.setPrimaryContact(primaryContact);

ClassificationScheme cScheme =

bqm.findClassificationSchemeByName(

null, "ntis-gov:naics");

Classification classification = (Classification)

Ысш. createClassification(cScheme,

"Snack and Nonalcoholic Beverage Bars", "722213") ; Collection classifications = new ArrayList(); classifications.add(classification); org.addClassifications(classifications);

Collection services = new Service service =

blcm.createService("Прием рогов"); InternationalString is =

blcm.createlnternationalString ("Высшее качество") ; service.setDescription(is);

Collection serviceBindings = new ArrayList();

ServiceBinding binding = blcm.createServiceBinding();

is =                                Service Binding " +

"Description"); binding.setDescription (is) ;

// allow us to publish a bogus URL without an error binding.setValidateURI(false);

binding.setAccessURI("http://TheCoffeeBreak.com:8080/sb/"); serviceBindings.add(binding);

// Add service bindings to service service.addServiceBindings(serviceBindings);

// Add service to services, then add services to organization services.add(service); org.addServices(services);

// Add organization and submit to registry // Retrieve key if successful Collection orgs = new orgs.add(org);

BulkResponse response = blcm.saveOrganizations(orgs);

Collection exceptions = if (exceptions == null){

saved") ;

Collection keys = response.getCollection(); Iterator keylter = keys.iterator(); if (keylter.hasNext ()) {

javax.xml.registry.infomodel.Key orgKey =

(javax.xml.registry.infomodel.Key)keylter.next(); String id = orgKey.getldO ;

System, out. println ("Organization key is " + id) ;

}

}else{

Iterator exciter = exceptions.iterator(); Exception exception = null; while (exciter.hasNext()){

exception = (Exception) exciter.next () ; System.err.println("Exception on save: " + exception.toString());

}

}

}catch(Exception e) {

e.printStackTrace(); }finally!

if (connection != null){ try{

connection.close(); }catch(JAXRException je) {}

}

}

}

}

Литература:

Хабибуллин И. Ш. Разработка Web-служб средствами Java. — СПб.: БХВ-Петербург, 2003. — 400 с: ил.

По теме:

  • Комментарии