Sun公司眼中的UDDI和ebXML
一个XML 注册项是一个使能构建,发布,发现Web服务的基础结构,是一个方便动态的和松散的藕荷B2B交互的中立的第三方.一个注册作为公共资源对组织可用,通常以基于Web服务的形式.
当前有多种XML registries的规范,包括:
ebXML注册和贮存标准,由OASIS等组织管理,代表使用XML的电子商务.
UDDI项目,由供应商联盟负责.
一个registry提供者是一个registry的实现,它遵从XML registries规范.
UDDI注册存储业务信息和它们提供的服务信息, 而一个ebXML registry有一个更广泛的范围.它既作为注册用也做为存储库用,存储库存储任意内容包括元数据.ebXML还给Web服务定义了一个可互操作的企业内容管理API.
对于企业应用和web应用来说,一个ebXML注册和存贮就是一个关系数据库:它为Web服务和 Web应用提供了存储和共享内容和元数据的方法.
Sun的JAXR API
JAXR使java软件程序员使用单个的易于使用的抽象API访问多种XML registries,一个统一的JAXR实现模型描述在XML registries中的内容和元数据.
JAXR给开发者写能使用于多种目标注册的registry客户程序的能力, 还给这些客户程序能跨多种底层registries添加值的能力.
JAXR规范的当前版本包括详尽的在JAXR信息模型和ebXML注册规范之间的绑定描述.通过以下网址可以看到更多资料:
http://java.sun.com/xml/downloads/jaxr.html
Service注册包括一个级别为1能力概要的JAXR提供者,它允许对ebXML注册的完全访问.ebXML规范和JAXR规范并没有很好的适配,因为ebXML规范比JAXR规范高级. 因此,为注册用的JAXR provider包括了一些附加的实现特定的方法,它们实现了ebXML规范,这些扩展可能会包括在JAXR规范的下个版本中.
JAXR 架构
JAXR高级结构由以下部分组成:
JAXR客户端: 这是个使用JAXR API通过JAXR提供者访问一个注册的客户端程序.This is a client program that uses the JAXR API to access a registry through a JAXR provider.
A JAXR provider:这是一个JAXR API的实现,它提供对特定注册提供者的访问或者是对一个基于通用规范的典型注册提供者的访问.
JAXR提供者实现两个包:
javax.xml.registry, 由API接口和定义了注册访问接口的类组成.
javax.xml.registry.infomodel,由定义JAXR信息模型的接口组成,这些接口定义了驻留在注册中的对象的类型和它们怎样彼此相关.这个包中的基本接口是RegistryObject接口.
javax.xml.registry包中最基本的接口是:
Connection. 代表客户到一个注册提供者的会话,为使用注册,客户端必须创建一个到JAXR提供者的连接.
RegistryService. 这是客户端从连接得到的RegistryService对象,通过RegistryService对象,客户端能依次获得对注册的访问接口.
在这个包中,还包括一些基本接口:
QueryManager和BusinessQueryManager,允许客户端搜索注册以获得和javax.xml.registry.infomodel接口一致的信息.
还有一个不错的可选接口,DeclarativeQueryManager,允许客户端使用SQL句法查询.ebXML提供者的注册实现实现了DeclarativeQueryManager.
LifeCycleManager和BusinessLifeCycleManager,允许客户端修改注册信息通过保存更新删除等操作.
在产生错误时,JAXR API方法仍出一个JAXRException或者是它的子类.
在JAXR API中的许多方法使用Collection对象作为参数或是返回值.使用集合对象允许在每次在几个注册上操作.
下图是JAXR架构的图解:对于注册来说,客户端使用兼容级别0和级别1的接口访问JAXR提供者,这是一个ebXML提供者,依次的,JAXR提供者访问特定注册,一个ebXML注册项.
JAXR规范只反映了UDDI版本2,而UDDI3早在2003年9月份已经出来,目前UDDI标准版本是OASIS于今年2月发布的V3.0.2版本,这样在java语言中无法利用UDDI3的最新实现特性了.
使用UDDI发布和查找服务
环境:Eclipse,JWSDP1.6提供的UDDI注册中心。
服务采用文中 http://blog.csdn.net/keepeye/archive/2005/07/25/434513.aspx 的例子。
本例涉及5个文件:
publish.properties,PublishService.java
WsdlDocumentLocater.properties,WsdlDocumentLocater.java
以及包wsidotnet中的IImage_Stub类.
发布:
需要两个文件,一个属性配置文件和一个java类.
publish.properties中的配置:
#Registry Specific properties
#IBM UDDI Test Registry Settings
#query.url=http://uddi.ibm.com/testregistry/inquiryapi
#publish.url=https://uddi.ibm.com/testregistry/protect/publishapi
#MS UDDI Test Registry Settings
#query.url=http://test.uddi.microsoft.com/inquire
#publish.url=https://test.uddi.microsoft.com/publish
#query.url=
#publish.url=
#使用了jwsdp1.6中的注册中心,以下为发布和查询地址.
query.url=http://localhost:8081/soar/registry/soap
publish.url=http://localhost:8081/soar/registry/soap
#Registry Username/Password 这个注册中心不需要用户和口令.
user.name=
user.password=
#如果你处于防火墙之后,需要配置代理
http.proxy.host=
http.proxy.port=
PublishService类创建一个组织SkySoft-BinaryService,添加了一些联系信息和一些分类方案,更重要的是添加了一个一项服务ImageServiceConcept,其代码清单:
package com.skysoft.uddi;
import javax.xml.registry.*;
import javax.xml.registry.infomodel.*;
import org.freebxml.omar.client.xml.registry.util.JAXRUtility;
import java.io.*;
import java.net.*;
import java.util.*;
public class PublishService {
String httpProxyHost = "";
String httpProxyPort = "";
String httpsProxyHost = "";
String httpsProxyPort = "";
String regUrli = "";
String regUrlp = "";
String username = "";
String password = "";
Properties connProps = new Properties();
private static final String QUERY_URL = "query.url";
private static final String PUBLISH_URL = "publish.url";
private static final String USER_NAME = "user.name";
private static final String USER_PASSWORD = "user.password";
private static final String PROXY_HOST = "http.proxy.host";
private static final String PROXY_PORT = "http.proxy.port";
BusinessQueryManager bqm;
BusinessLifeCycleManager blm;
public static void main(String[] args) {
try {
PublishService ps = new PublishService();
// Get publish.properties
Properties properties = new Properties();
properties.load(new FileInputStream("./publish.properties"));
ps.executeTest(properties);
} catch (JAXRException e) {
System.out.println("FAILED" + e.getMessage());
} catch (IOException ioe) {
System.out.println("Can not open properties file");
}
}
public void executeTest(Properties properties) throws JAXRException {
try {
assignUserProperties(properties);
setConnectionProperties();
ConnectionFactory factory = JAXRUtility.getConnectionFactory();
// ConnectionFactory factory = ConnectionFactory.newInstance();
factory.setProperties(connProps);
Connection conn = factory.createConnection();
RegistryService rs = conn.getRegistryService();
bqm = rs.getBusinessQueryManager();
blm = rs.getBusinessLifeCycleManager();
PasswordAuthentication passwdAuth = new PasswordAuthentication(
username, password.toCharArray());
Set creds = new HashSet();
creds.add(passwdAuth);
// conn.setCredentials(creds);
Collection orgs = new ArrayList();
User user = blm.createUser();
PersonName personName = blm.createPersonName("George Washington");
Organization org = blm.createOrganization(blm
.createInternationalString("SkySoft-BinaryService"));
org.setPrimaryContact(user);
TelephoneNumber telephoneNumber = blm.createTelephoneNumber();
telephoneNumber.setNumber("781-333-3333");
telephoneNumber.setType(null);
PostalAddress address = blm.createPostalAddress("546789",
"One USA Place", "Washington", "DC", "USA", "02140", "");
Collection postalAddresses = new ArrayList();
postalAddresses.add(address);
Collection emailAddresses = new ArrayList();
EmailAddress emailAddress = blm
.createEmailAddress("
[email protected]");
emailAddresses.add(emailAddress);
Collection numbers = new ArrayList();
numbers.add(telephoneNumber);
user.setPersonName(personName);
user.setPostalAddresses(postalAddresses);
user.setEmailAddresses(emailAddresses);
user.setTelephoneNumbers(numbers);
// Concepts for NAICS and computer
ClassificationScheme cScheme = blm.createClassificationScheme(blm
.createInternationalString("ntis-gov:naics"), blm
.createInternationalString(""));
javax.xml.registry.infomodel.Key cKey = (javax.xml.registry.infomodel.Key) blm
.createKey("uuid:C0B9FE13-179F-413D-8A5B-5004DB8E5BB2");
cScheme.setKey(cKey);
Classification classification = (Classification) blm
.createClassification(cScheme,
"Computer Systems Design and Related Services",
"5415");
org.addClassification(classification);
ClassificationScheme cScheme1 = blm.createClassificationScheme(blm
.createInternationalString("D-U-N-S"), blm
.createInternationalString(""));
javax.xml.registry.infomodel.Key cKey1 = (javax.xml.registry.infomodel.Key) blm
.createKey("uuid:8609C81E-EE1F-4D5A-B202-3EB13AD01823");
cScheme1.setKey(cKey1);
ExternalIdentifier ei = blm.createExternalIdentifier(cScheme1,
"D-U-N-S number", "08-146-6849");
org.addExternalIdentifier(ei);
createService(org);
orgs.add(org);
BulkResponse br = blm.saveOrganizations(orgs);
if (br.getStatus() == JAXRResponse.STATUS_SUCCESS) {
System.out.println("Organization Saved");
} else {
System.err.println("One or more JAXRExceptions "
+ "occurred during the save operation:");
Collection exceptions = br.getExceptions();
Iterator iter = exceptions.iterator();
while (iter.hasNext()) {
Exception e = (Exception) iter.next();
System.err.println(e.toString());
}
}
} catch (JAXRException e) {
e.printStackTrace();
}
}
//创建服务
private void createService(Organization org) throws JAXRException {
Service service = blm.createService(blm.createInternationalString("Federal Government Service"));
service.setDescription(blm.createInternationalString("Services of the Federal Government"));
Concept specConcept = blm.createConcept(null, "ImageServiceConcept", "");
InternationalString s = blm.createInternationalString("Concept for Hello Service");
specConcept.setDescription(s);
ExternalLink wsdlLink = blm.createExternalLink(
"
http://localhost:8080/netservice/binary?WSDL
",
"Hello WSDL document");
specConcept.addExternalLink(wsdlLink);
String schemeName = "uddi-org:types";
ClassificationScheme uddiOrgTypes = bqm.findClassificationSchemeByName(
null, schemeName);
Classification wsdlSpecClassification = blm.createClassification(
uddiOrgTypes, "wsdlSpec", "wsdlSpec");
specConcept.addClassification(wsdlSpecClassification);
Collection concepts = new ArrayList();
concepts.add(specConcept);
BulkResponse concResponse = blm.saveConcepts(concepts);
String conceptKeyId = null;
Collection concExceptions = concResponse.getExceptions();
javax.xml.registry.infomodel.Key concKey = null;
if (concExceptions == null) {
System.out.println("WSDL Specification Concept saved");
Collection keys = concResponse.getCollection();
Iterator keyIter = keys.iterator();
if (keyIter.hasNext()) {
concKey = (javax.xml.registry.infomodel.Key) keyIter.next();
conceptKeyId = concKey.getId();
System.out.println("Concept key is " + conceptKeyId);
}
}
ServiceBinding binding = blm.createServiceBinding();
s = blm.createInternationalString("My Service Binding Description");
binding.setDescription(s);
binding.setValidateURI(false);
binding.setAccessURI("
http://localhost:8080/netservice/binary
");
Concept specConcept1 = (Concept) bqm.getRegistryObject(conceptKeyId,
LifeCycleManager.CONCEPT);
System.out.println(" Concept key is " +specConcept1.getKey().getId());
SpecificationLink specLink = blm.createSpecificationLink();
specLink.setSpecificationObject(specConcept1);
binding.addSpecificationLink(specLink);
service.addServiceBinding(binding);
org.addService(service);
}
private void assignUserProperties(Properties props) {
String proxyHost = ((String) props.get(PROXY_HOST)).trim();
String proxyPort = ((String) props.get(PROXY_PORT)).trim();
String queryURL = ((String) props.get(QUERY_URL)).trim();
String publishURL = ((String) props.get(PUBLISH_URL)).trim();
String user = ((String) props.get(USER_NAME)).trim();
String pw = ((String) props.get(USER_PASSWORD)).trim();
if (proxyHost != null) {
httpProxyHost = proxyHost;
httpsProxyHost = proxyHost;
}
if (proxyPort != null) {
httpProxyPort = proxyPort;
httpsProxyPort = proxyPort;
}
if (queryURL != null)
regUrli = queryURL;
if (publishURL != null)
regUrlp = publishURL;
if (user != null)
username = user;
if (pw != null)
password = pw;
}
private void setConnectionProperties() {
connProps.setProperty("javax.xml.registry.queryManagerURL", regUrli);
connProps
.setProperty("javax.xml.registry.lifeCycleManagerURL", regUrlp);
connProps.setProperty("javax.xml.registry.factoryClass",
"com.sun.xml.registry.uddi.ConnectionFactoryImpl");
connProps.setProperty("com.sun.xml.registry.http.proxyHost",
httpProxyHost);
connProps.setProperty("com.sun.xml.registry.http.proxyPort",
httpProxyPort);
connProps.setProperty("com.sun.xml.registry.https.proxyHost",
httpsProxyHost);
connProps.setProperty("com.sun.xml.registry.https.proxyPort",
httpsProxyPort);
}
}
查找:
需要一个属性配置文件和一个java类.
WsdlDocumentLocater.properties文件内容:
## 根据需要改变注册中心发布和查询地址,本例使用了jwsdp1.6中的注册中心
query.url=http://localhost:8081/soar/registry/soap
publish.url=http://localhost:8081/soar/registry/soap
## Values for security authentication keystore path is usually
# <home_dir>/omar/3.0-post-alpha2-dev/jaxr-ebxml/security/keystore.jks
security.keystorePath=
# ebxmlrr or 12345678, not sure which
security.storepass=
# alias you specified when you registered with Java UI
security.alias=
# password you specified when you registered with Java UI
security.keypass=
## Values used by publish examples
org.name=The ebXML Coffee Break
org.description=Purveyor of the finest coffees. Established 1905
postal.streetNumber=99
postal.street=Imaginary Ave. Suite 33
postal.city=Imaginary City
postal.state=NY
postal.country=USA
postal.postalCode=00000
postal.type=Type US
phone.countrycode=1
phone.areacode=100
phone.number=100-1000
phone.type=OfficePhone
person.firstname=Jane
person.middlename=M.
person.lastname=Doe
[email protected]
email.type=OfficeEmail
pcphone.countrycode=1
pcphone.areacode=100
pcphone.number=100-1001
pcphone.type=MobilePhone
person.url=http://TheCoffeeBreak.com/JaneMDoe.html
classification.scheme=iso-ch:3166:1999
classification.name=United States
classification.value=US
service.name=Coffee Service Name
service.description=Coffee Service Description
svcbinding.name=Coffee Service Binding Name
svcbinding.description=Coffee Service Binding Description
svcbinding.accessURI=http://TheCoffeeBreak.com:8080/sb/
WsdlDocumentLocater类清单:
package com.skysoft.uddi;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Properties;
import java.util.ResourceBundle;
import javax.xml.registry.BulkResponse;
import javax.xml.registry.Connection;
import javax.xml.registry.ConnectionFactory;
import javax.xml.registry.FindQualifier;
import javax.xml.registry.JAXRException;
import javax.xml.registry.RegistryService;
import javax.xml.registry.infomodel.Concept;
import javax.xml.registry.infomodel.ExternalLink;
import javax.xml.registry.infomodel.Organization;
import javax.xml.registry.infomodel.RegistryObject;
import javax.xml.registry.infomodel.Service;
import javax.xml.registry.infomodel.ServiceBinding;
import javax.xml.registry.infomodel.SpecificationLink;
import org.freebxml.omar.client.xml.registry.BusinessQueryManagerImpl;
import org.freebxml.omar.client.xml.registry.infomodel.RegistryObjectImpl;
import org.freebxml.omar.client.xml.registry.util.JAXRUtility;
import org.oasis.ebxml.registry.bindings.rim.VersionInfoType;
public class WsdlDocumentLocater {
Connection connection = null;
private String wsdlurl;
public WsdlDocumentLocater() {
}
public String getWsdlurl() {
return wsdlurl;
}
public void setWsdlurl(String wsdlurl) {
this.wsdlurl = wsdlurl;
}
public void execQuery(String queryString) {
ResourceBundle registryBundle = ResourceBundle
.getBundle("WsdlDocumentLocater");
String queryURL = registryBundle.getString("query.url");
String publishURL = registryBundle.getString("publish.url");
System.out.println("Name string is " + queryString);
makeConnection(queryURL, publishURL);
executeQuery(queryString);
}
public void makeConnection(String queryUrl, String publishUrl) {
Properties props = new Properties();
props.setProperty("javax.xml.registry.queryManagerURL", queryUrl);
try {
ConnectionFactory factory = JAXRUtility.getConnectionFactory();
factory.setProperties(props);
connection = factory.createConnection();
System.out.println("Created connection to registry");
} catch (Exception e) {
e.printStackTrace();
if (connection != null) {
try {
connection.close();
} catch (JAXRException je) {
}
}
}
}
public void executeQuery(String qString) {
RegistryService rs = null;
BusinessQueryManagerImpl qm = null;
try {
rs = connection.getRegistryService();
qm = (BusinessQueryManagerImpl) rs.getBusinessQueryManager();
System.out.println("Got registry service and " + "query manager");
// Define find qualifiers and name patterns
Collection findQualifiers = new ArrayList();
findQualifiers.add(FindQualifier.SORT_BY_NAME_ASC);
Collection namePatterns = new ArrayList();
namePatterns.add("%" + qString + "%");
// Find objects with name that contains qString
BulkResponse response = qm.findObjects("RegistryObject",
findQualifiers, namePatterns, null, null, null, null);
Collection objects = response.getCollection();
// Display information about the objects found
Iterator objIter = objects.iterator();
if (!(objIter.hasNext())) {
System.out.println("No objects found");
} else {
while (objIter.hasNext()) {
RegistryObject object = (RegistryObject) objIter.next();
Concept objType = object.getObjectType();
System.out.println("Object type is " + objType.getValue());
String objName = getName(object);
System.out.println("Object name: " + objName);
System.out.println("Object description: "
+ getDescription(object));
System.out.println("Object key id: " + getKey(object));
VersionInfoType vInfo = ((RegistryObjectImpl) object)
.getVersionInfo();
if (vInfo != null) {
System.out.println("Object version: "
+ vInfo.getVersionName());
}
if (object instanceof Organization) {
showService(object);
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
try {
connection.close();
} catch (JAXRException je) {
}
}
}
}
private void showService(RegistryObject object) throws JAXRException {
Organization org = (Organization) object;
Collection services = org.getServices();
Iterator iter = services.iterator();
if (!iter.hasNext()) {
System.out.println("No WSDL specification services found");
} else {
while (iter.hasNext()) {
Service service = (Service) iter.next();
System.out.println(service.getName() + " ,"
+ service.getDescription());
// service.getExternalLinks()
Iterator iter1 = service.getServiceBindings().iterator();
if (!iter1.hasNext()) {
System.out.println("No WSDL specification ServiceBinding found");
} else {
while (iter1.hasNext()) {
Object test = iter1.next();
// System.out.println(test.getClass().toString());
ServiceBinding sb = (ServiceBinding) test;
System.out.println(sb.getName() + " ,"
+ sb.getDescription() + ","
+ sb.getAccessURI());
Collection sps = sb.getSpecificationLinks();
Iterator iter2 = sps.iterator();
if (!iter2.hasNext()) {
System.out.println("No WSDL specification SpecificationLinks found");
} else {
while (iter2.hasNext()) {
SpecificationLink sp = (SpecificationLink) iter2
.next();
Concept concept = (Concept) sp
.getSpecificationObject();
showConcept(concept);
System.out.println(sp.getName() + " ,"
+ sp.getDescription());
Iterator iter3 = sp.getExternalLinks()
.iterator();
if (!iter3.hasNext()) {
System.out.println("No WSDL specification ExternalLink found");
} else {
while (iter3.hasNext()) {
ExternalLink el = (ExternalLink) iter2
.next();
System.out.println(el.toString());
}
}
}
}
}
}
}
}
}
private void showConcept(Concept concept) throws JAXRException {
String name = getName(concept);
Collection links = concept.getExternalLinks();
System.out.println("/nSpecification Concept:/n/tName: " + name
+ "/n/tKey: " + getKey(concept) + "/n/tDescription: "
+ getDescription(concept));
if (links.size() > 0) {
ExternalLink link = (ExternalLink) links.iterator().next();
wsdlurl = link.getExternalURI();
System.out.println("/tURL of WSDL document: '" + wsdlurl + "'");
}
}
private String getName(RegistryObject ro) throws JAXRException {
try {
return ro.getName().getValue();
} catch (NullPointerException npe) {
return "No Name";
}
}
private String getDescription(RegistryObject ro) throws JAXRException {
try {
return ro.getDescription().getValue();
} catch (NullPointerException npe) {
return "No Description";
}
}
private String getKey(RegistryObject ro) throws JAXRException {
try {
return ro.getKey().getId();
} catch (NullPointerException npe) {
return "No Key";
}
}
}
客户端要使用类WsdlDocumentLocater 获得WSDL文档的url,然后提供给JAX-RPC环境使用,具体就是修改包wsidotnet中的IImage_Stub类.该类片断:
我们只是简单的修改了该类的构造器:
public IImage_Stub(HandlerChain handlerChain) {
super(handlerChain);
WsdlDocumentLocater servicelocator=new WsdlDocumentLocater();
servicelocator.execQuery("SkySoft-BinaryService");
_setProperty(ENDPOINT_ADDRESS_PROPERTY,servicelocator.getWsdlurl());
}
原来的构造器方法为:
public IImage_Stub(HandlerChain handlerChain) {
super(handlerChain);
_setProperty(ENDPOINT_ADDRESS_PROPERTY, " http://localhost:8080/netservice/binary");
}
修改完成后,测试客户端代码可在
http://blog.csdn.net/keepeye/archive/2005/07/25/434820.aspx 中获得,运行时需要使用SWT Application方式运行。
原文链接: http://blog.csdn.net/keepeye/article/details/434819