Java tutorial
/* * Copyright 2001-2011 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.juddi.v3.client.mapping.wsdl; import org.apache.juddi.v3.client.mapping.Common2UDDI; import java.net.MalformedURLException; import java.net.URL; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import javax.wsdl.Binding; import javax.wsdl.Definition; import javax.wsdl.Port; import javax.wsdl.PortType; import javax.wsdl.Service; import javax.wsdl.WSDLException; import javax.xml.namespace.QName; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.juddi.api_v3.AccessPointType; import org.apache.juddi.jaxb.PrintUDDI; import org.apache.juddi.v3.annotations.AnnotationProcessor; import org.apache.juddi.v3.client.config.Property; import org.apache.juddi.v3.client.config.UDDIClerk; import org.apache.juddi.v3.client.config.UDDIKeyConvention; import org.apache.juddi.v3.client.mapping.URLLocalizer; import org.apache.juddi.v3.client.transport.TransportException; import org.uddi.api_v3.AccessPoint; import org.uddi.api_v3.BindingTemplate; import org.uddi.api_v3.BusinessService; import org.uddi.api_v3.CategoryBag; import org.uddi.api_v3.FindBinding; import org.uddi.api_v3.FindTModel; import org.uddi.api_v3.GetTModelDetail; import org.uddi.api_v3.InstanceDetails; import org.uddi.api_v3.KeyedReference; import org.uddi.api_v3.Name; import org.uddi.api_v3.OverviewDoc; import org.uddi.api_v3.OverviewURL; import org.uddi.api_v3.TModel; import org.uddi.api_v3.TModelBag; import org.uddi.api_v3.TModelDetail; import org.uddi.api_v3.TModelInfo; import org.uddi.api_v3.TModelInstanceDetails; import org.uddi.api_v3.TModelInstanceInfo; import org.uddi.api_v3.TModelList; import org.w3c.dom.Element; /** * BPEL4WS abstract processes describe the observable behavior of Web services. They * complement abstract WSDL interfaces (port types and operations) and the UDDI model * by defining dependencies between service operations in the context of a message * exchange. The technical note 'uddi-spec-tc-tn-bpel' describes the relationships * between the three models and suggests how BPEL4WS abstract processes can be used * in a UDDI Registry. This class implements the registrations suggestions as put * forward in the technote. * * * @author Kurt T Stam <kurt.stam@apache.org> * */ public class BPEL2UDDI extends AnnotationProcessor { private Log log = LogFactory.getLog(this.getClass()); private String keyDomainURI; private UDDIClerk clerk; private String lang; private URLLocalizer urlLocalizer; private String businessKey; private Properties properties = new Properties(); private WSDL2UDDI wsdl2UDDI; public BPEL2UDDI(UDDIClerk clerk, URLLocalizer urlLocalizer, Properties properties) throws ConfigurationException { super(); this.clerk = clerk; this.urlLocalizer = urlLocalizer; this.properties = properties; //Obtaining values from the properties this.keyDomainURI = "uddi:" + properties.getProperty("keyDomain") + ":"; this.businessKey = UDDIKeyConvention.getBusinessKey(properties); this.lang = properties.getProperty(Property.LANG, Property.DEFAULT_LANG); this.wsdl2UDDI = new WSDL2UDDI(clerk, urlLocalizer, properties); } public String getKeyDomainURI() { return keyDomainURI; } public void setKeyDomainURI(String keyDomainURI) { this.keyDomainURI = keyDomainURI; } public UDDIClerk getClerk() { return clerk; } public void setClerk(UDDIClerk clerk) { this.clerk = clerk; } public String getLang() { return lang; } public void setLang(String lang) { this.lang = lang; } public URLLocalizer getUrlLocalizer() { return urlLocalizer; } public void setUrlLocalizer(URLLocalizer urlLocalizer) { this.urlLocalizer = urlLocalizer; } /** * 1. Register PortType tModels * 2. Register WSDL BPEL4WS Process * 3. Register WSDL Port * 4. Register Process Service * 5. Register Binding * * @param serviceName - QName of the service * @param portName - portName of the service * @param serviceUrl - URL at which the service can be invoked * @param wsdlDefinition - WSDL Definition of the Web Service * @return a binding template * @throws WSDLException * @throws MalformedURLException * @throws TransportException * @throws ConfigurationException * @throws RemoteException */ @SuppressWarnings("unchecked") public BindingTemplate register(QName serviceName, String portName, URL serviceUrl, Definition wsdlDefinition) throws WSDLException, MalformedURLException, RemoteException, ConfigurationException, TransportException { String targetNamespace = wsdlDefinition.getTargetNamespace(); String genericWSDLURL = wsdlDefinition.getDocumentBaseURI(); //TODO maybe point to repository version String bpelOverviewURL = "http://localhost:8080/bpel-console/"; //TODO maybe point to bpel in console String serviceKey = UDDIKeyConvention.getServiceKey(properties, serviceName.getLocalPart()); BusinessService service = lookupService(serviceKey); if (service == null) { List<TModel> tModels = new ArrayList<TModel>(); // Create the PortType tModels Map<QName, PortType> portTypes = (Map<QName, PortType>) wsdlDefinition.getAllPortTypes(); tModels.addAll(createWSDLPortTypeTModels(genericWSDLURL, portTypes)); // Create the Binding tModels Map<QName, Binding> bindings = (Map<QName, Binding>) wsdlDefinition.getAllBindings(); tModels.addAll(createWSDLBindingTModels(genericWSDLURL, bindings)); // Create the BPEL4WS tModel TModel bpel4WSTModel = createBPEL4WSProcessTModel(serviceName, targetNamespace, portTypes, bpelOverviewURL); tModels.add(bpel4WSTModel); // Register these tModels for (TModel tModel : tModels) { clerk.register(tModel); } // BPEL Service service = createBusinessService(serviceName, wsdlDefinition); // Register this BPEL Service clerk.register(service); } //Add the BindingTemplate to this Service BindingTemplate binding = createBPELBinding(serviceName, portName, serviceUrl, wsdlDefinition); // Register BindingTemplate clerk.register(binding); return binding; } public String unRegister(QName serviceName, String portName, URL serviceUrl) throws RemoteException, ConfigurationException, TransportException { String serviceKey = UDDIKeyConvention.getServiceKey(properties, serviceName.getLocalPart()); BusinessService service = lookupService(serviceKey); boolean isRemoveServiceIfNoTemplates = true; String bindingKey = UDDIKeyConvention.getBindingKey(properties, serviceName, portName, serviceUrl); //check if this bindingKey is in the service's binding templates for (BindingTemplate bindingTemplate : service.getBindingTemplates().getBindingTemplate()) { if (bindingKey.equals(bindingTemplate.getBindingKey())) { clerk.unRegisterBinding(bindingKey); //if this is the last binding for this service, and if (service.getBindingTemplates().getBindingTemplate().size() == 1 && isRemoveServiceIfNoTemplates) { clerk.unRegisterService(serviceKey); FindTModel findTmodelForProcessName = createFindTModelForProcessName(serviceName); TModelList tModelList = clerk.findTModel(findTmodelForProcessName); if (tModelList != null && tModelList.getTModelInfos() != null && tModelList.getTModelInfos().getTModelInfo() != null) { TModelInfo tModelInfo = tModelList.getTModelInfos().getTModelInfo().get(0); String bpel4WSTModelKey = tModelInfo.getTModelKey(); clerk.unRegisterTModel(bpel4WSTModelKey); // now use this key to find the portType TModels GetTModelDetail findAllPortTypesForProcess = createFindAllPortTypesForProcess_1( bpel4WSTModelKey); TModelDetail tModelDetail = clerk.getTModelDetail(findAllPortTypesForProcess); if (tModelDetail != null) { List<TModel> tModelPortTypeList = tModelDetail.getTModel(); if (tModelPortTypeList != null && tModelPortTypeList.size() > 0) { TModel bpel4WSTModel = tModelPortTypeList.get(0); CategoryBag categoryBag = bpel4WSTModel.getCategoryBag(); if (categoryBag != null && categoryBag.getKeyedReference() != null) { List<KeyedReference> portTypeTModelKeys = new ArrayList<KeyedReference>(); KeyedReference namespaceRef = null; for (KeyedReference keyedReference : categoryBag.getKeyedReference()) { if ("uddi:uddi.org:wsdl:porttypereference" .equals(keyedReference.getTModelKey())) { portTypeTModelKeys.add(keyedReference); } if ("uddi:uddi.org:xml:namespace".equals(keyedReference.getTModelKey())) { namespaceRef = keyedReference; } } String namespace = null; if (namespaceRef != null) namespace = namespaceRef.getKeyValue(); //find the bindingTModel for (KeyedReference keyedReference : portTypeTModelKeys) { FindTModel findBindingTModel = WSDL2UDDI.createFindBindingTModelForPortType( keyedReference.getKeyValue(), namespace); TModelList bindingTmodels = clerk.findTModel(findBindingTModel); if (bindingTmodels != null && bindingTmodels.getTModelInfos() != null && bindingTmodels.getTModelInfos().getTModelInfo() != null) { for (TModelInfo bindingTModelInfo : bindingTmodels.getTModelInfos() .getTModelInfo()) { //delete the Binding TModel clerk.unRegisterTModel(bindingTModelInfo.getTModelKey()); } } //delete the PortType TModel clerk.unRegisterTModel(keyedReference.getKeyValue()); } } } } } } break; } } return service.getServiceKey(); } /** * Perform a lookup by serviceKey, and will return null if not found. * @param serviceKey * @return a business service * @throws RemoteException * @throws ConfigurationException * @throws TransportException */ public BusinessService lookupService(String serviceKey) throws RemoteException, ConfigurationException, TransportException { //Checking if this serviceKey already exist BusinessService service = clerk.getServiceDetail(serviceKey); return service; } /** * Registers the Service into UDDI. * * @param serviceName * @param wsdlDefinition * @return a business service */ public BusinessService createBusinessService(QName serviceName, Definition wsdlDefinition) { log.debug("Constructing Service UDDI Information for " + serviceName); BusinessService service = new BusinessService(); // BusinessKey service.setBusinessKey(businessKey); // ServiceKey service.setServiceKey(UDDIKeyConvention.getServiceKey(properties, serviceName.getLocalPart())); // Description String serviceDescription = properties.getProperty(Property.SERVICE_DESCRIPTION, Property.DEFAULT_SERVICE_DESCRIPTION); if (wsdlDefinition.getService(serviceName) != null) { // Override with the service description from the WSDL if present Element docElement = wsdlDefinition.getService(serviceName).getDocumentationElement(); if (docElement != null && docElement.getTextContent() != null) { serviceDescription = docElement.getTextContent(); } } service.getDescription().addAll(Common2UDDI.mapDescription(serviceDescription, lang)); // Service name Name sName = new Name(); sName.setLang(lang); sName.setValue(serviceName.getLocalPart()); service.getName().add(sName); //customization to add KeyedReferences into the categoryBag of the service if (properties.containsKey(Property.SERVICE_CATEGORY_BAG)) { String serviceCategoryBag = properties.getProperty(Property.SERVICE_CATEGORY_BAG); log.debug( "Adding KeyedReferences '" + serviceCategoryBag + "' to service " + serviceName.getLocalPart()); CategoryBag categoryBag = parseCategoryBag(serviceCategoryBag); service.setCategoryBag(categoryBag); } return service; } public Set<TModel> createWSDLPortTypeTModels(String wsdlURL, Map<QName, PortType> portTypes) throws WSDLException { return wsdl2UDDI.createWSDLPortTypeTModels(wsdlURL, portTypes); } public Set<TModel> createWSDLBindingTModels(String wsdlURL, Map<QName, Binding> bindings) throws WSDLException { return wsdl2UDDI.createWSDLBindingTModels(wsdlURL, bindings); } /** * BPEL4WS abstract processes are published as separate UDDI tModels. They are named with the BPEL4WS process * name. They are categorized as BPEL4WS process definitions, using a category system defined in this * technical note. Their overviewDoc references an external BPEL4WS document that contains the process definition. * All WSDL portTypes that are used in the BPEL4WS process definition (via the referenced BPEL4WS partnerLinkTypes) * are published as portType tModels according to [WSDL2UDDI]. The process tModel references all such WSDL portType * tModels, using the WSDL portType Reference tModel defined in [WSDL2UDDI]. Note that it is a characteristic * of the BPEL4WS process that it defines a conversation based on WSDL portTypes. Thus, the relationship * between process tModel and portType tModel is to be published by the process tModel publisher, not by * the portType tModel publisher, which may be a different person. * * In the current implementation it is all registered by the same publisher. * * @param serviceName * @param targetNamespace * @param portTypes * @param bpelOverviewURL * @return tmodels */ public TModel createBPEL4WSProcessTModel(QName serviceName, String targetNamespace, Map<QName, PortType> portTypes, String bpelOverviewURL) { TModel tModel = new TModel(); // Set the Key tModel.setTModelKey(keyDomainURI + serviceName.getLocalPart() + "Process"); // Set the Name Name name = new Name(); name.setLang("en"); name.setValue(serviceName.getLocalPart()); tModel.setName(name); // Set the OverviewURL OverviewURL overviewURL = new OverviewURL(); overviewURL.setValue("http://localhost:8080/bpel-console/"); //should point to the bpel of this process, maybe in guvnor OverviewDoc overviewDoc = new OverviewDoc(); overviewDoc.setOverviewURL(overviewURL); tModel.getOverviewDoc().add(overviewDoc); // Set the categoryBag CategoryBag categoryBag = new CategoryBag(); if (targetNamespace != null) { KeyedReference namespaceReference = WSDL2UDDI.newKeyedReference("uddi:uddi.org:xml:namespace", "uddi-org:xml:namespace", targetNamespace); categoryBag.getKeyedReference().add(namespaceReference); } KeyedReference typesReference = WSDL2UDDI.newKeyedReference("uddi:uddi.org:bpel:types", "uddi-org:bpel:types", "process"); categoryBag.getKeyedReference().add(typesReference); for (QName qName : portTypes.keySet()) { String portTypeKey = keyDomainURI + qName.getLocalPart(); KeyedReference portTypeReference = WSDL2UDDI.newKeyedReference("uddi:uddi.org:wsdl:porttypereference", "uddi-org:wsdl:portTypeReference", portTypeKey); categoryBag.getKeyedReference().add(portTypeReference); } tModel.setCategoryBag(categoryBag); if (log.isDebugEnabled()) { log.debug(new PrintUDDI<TModel>().print(tModel)); } return tModel; } public BindingTemplate createBPELBinding(QName serviceName, String portName, URL serviceUrl, Definition wsdlDefinition) { BindingTemplate bindingTemplate = new BindingTemplate(); // Set BusinessService Key bindingTemplate.setServiceKey(UDDIKeyConvention.getServiceKey(properties, serviceName.getLocalPart())); // Set Binding Key String bindingKey = UDDIKeyConvention.getBindingKey(properties, serviceName, portName, serviceUrl); bindingTemplate.setBindingKey(bindingKey); // Set AccessPoint AccessPoint accessPoint = new AccessPoint(); accessPoint.setUseType(AccessPointType.END_POINT.toString()); accessPoint.setValue(urlLocalizer.rewrite(serviceUrl)); bindingTemplate.setAccessPoint(accessPoint); Service service = wsdlDefinition.getService(serviceName); if (service != null) { TModelInstanceDetails tModelInstanceDetails = new TModelInstanceDetails(); Port port = service.getPort(portName); if (port != null) { Binding binding = port.getBinding(); // Set the Binding Description String bindingDescription = properties.getProperty(Property.BINDING_DESCRIPTION, Property.DEFAULT_BINDING_DESCRIPTION); // Override with the service description from the WSDL if present Element docElement = binding.getDocumentationElement(); if (docElement != null && docElement.getTextContent() != null) { bindingDescription = docElement.getTextContent(); } bindingTemplate.getDescription().addAll(Common2UDDI.mapDescription(bindingDescription, lang)); // reference wsdl:binding tModel TModelInstanceInfo tModelInstanceInfoBinding = new TModelInstanceInfo(); tModelInstanceInfoBinding.setTModelKey(keyDomainURI + binding.getQName().getLocalPart()); InstanceDetails instanceDetails = new InstanceDetails(); instanceDetails.setInstanceParms(portName); tModelInstanceInfoBinding.setInstanceDetails(instanceDetails); tModelInstanceInfoBinding.getDescription() .addAll(Common2UDDI.mapDescription("The wsdl:binding that this wsdl:port implements. " + bindingDescription + " The instanceParms specifies the port local name.", lang)); tModelInstanceDetails.getTModelInstanceInfo().add(tModelInstanceInfoBinding); // reference wsdl:portType tModel PortType portType = binding.getPortType(); TModelInstanceInfo tModelInstanceInfoPortType = new TModelInstanceInfo(); tModelInstanceInfoPortType.setTModelKey(keyDomainURI + portType.getQName().getLocalPart()); String portTypeDescription = ""; docElement = portType.getDocumentationElement(); if (docElement != null && docElement.getTextContent() != null) { portTypeDescription = docElement.getTextContent(); } tModelInstanceInfoPortType.getDescription().addAll(Common2UDDI.mapDescription( "The wsdl:portType that this wsdl:port implements." + portTypeDescription, lang)); tModelInstanceDetails.getTModelInstanceInfo().add(tModelInstanceInfoPortType); //reference bpel:process tModel TModelInstanceInfo tModelInstanceInfoBPEL = new TModelInstanceInfo(); tModelInstanceInfoBPEL.setTModelKey(keyDomainURI + service.getQName().getLocalPart() + "Process"); // Description String serviceDescription = properties.getProperty(Property.SERVICE_DESCRIPTION, Property.DEFAULT_SERVICE_DESCRIPTION); // Override with the service description from the WSDL if present docElement = wsdlDefinition.getService(serviceName).getDocumentationElement(); if (docElement != null && docElement.getTextContent() != null) { serviceDescription = docElement.getTextContent(); } tModelInstanceInfoBPEL.getDescription().addAll(Common2UDDI .mapDescription("The bpel:process this wsdl:port supports." + serviceDescription, lang)); tModelInstanceDetails.getTModelInstanceInfo().add(tModelInstanceInfoBPEL); bindingTemplate.setTModelInstanceDetails(tModelInstanceDetails); } else { log.error("Could not find Port with portName: " + portName); } } else { log.error("Could not find Service with serviceName: " + serviceName.getLocalPart()); } if (log.isDebugEnabled()) { log.debug(new PrintUDDI<BindingTemplate>().print(bindingTemplate)); } return bindingTemplate; } /** Finds and returns ALL the tModels related to the process, so that i.e. they * can be removed on undeployment of the service. * * @param serviceName * @return a tModel if found */ public FindTModel createFindTModelForProcessName(QName serviceName) { FindTModel findTModel = new FindTModel(); Name name = new Name(); //name.setLang(lang); name.setValue(serviceName.getLocalPart()); findTModel.setName(name); CategoryBag categoryBag = new CategoryBag(); String namespace = serviceName.getNamespaceURI(); if (namespace != null && namespace.length() != 0) { KeyedReference namespaceReference = WSDL2UDDI.newKeyedReference("uddi:uddi.org:xml:namespace", "uddi-org:xml:namespace", namespace); categoryBag.getKeyedReference().add(namespaceReference); } KeyedReference typesReference = WSDL2UDDI.newKeyedReference("uddi:uddi.org:bpel:types", "uddi-org:bpel:types", "process"); categoryBag.getKeyedReference().add(typesReference); findTModel.setCategoryBag(categoryBag); if (log.isDebugEnabled()) { log.debug(new PrintUDDI<FindTModel>().print(findTModel)); } return findTModel; } /** * Find all processes that use the given portType. * * @param portTypeKey * @return tmodel info */ public FindTModel createFindProcessesForPortTypes(String portTypeKey) { FindTModel findTModel = new FindTModel(); CategoryBag categoryBag = new CategoryBag(); KeyedReference typesReference = WSDL2UDDI.newKeyedReference("uddi:uddi.org:bpel:types", "uddi-org:bpel:types", "process"); categoryBag.getKeyedReference().add(typesReference); KeyedReference portTypeReference = WSDL2UDDI.newKeyedReference("uddi:uddi.org:wsdl:porttypereference", "uddi-org:wsdl:portTypeReference", portTypeKey); categoryBag.getKeyedReference().add(portTypeReference); findTModel.setCategoryBag(categoryBag); return findTModel; } /** * Find all portTypes used in the given process. This should return the * tModel registration for the process tModel. The tModelKeys for the * portTypes used in the process can be obtained from the process tModels * categoryBag, and passed into the second call. * * @param processKey * @return GetTModelDetail */ public GetTModelDetail createFindAllPortTypesForProcess_1(String processKey) { GetTModelDetail getTModelDetail = new GetTModelDetail(); getTModelDetail.getTModelKey().add(processKey); return getTModelDetail; } /** * Once retrieved, the second call is made to get the tModel registrations * for the portTypes with the keys found in the first step. * * @param portTypeTModelKeys - List of portType tModels found in the first step. * @return GetTModelDetail */ public GetTModelDetail createFindAllPortTypesForProcess_2(List<String> portTypeTModelKeys) { GetTModelDetail getTModelDetail = new GetTModelDetail(); for (String tModelKey : portTypeTModelKeys) { getTModelDetail.getTModelKey().add(tModelKey); } return getTModelDetail; } /** * Find all implementations of the given process. * @param processKey * @return FindBinding */ public FindBinding createFindImplementationsForProcess(String processKey) { FindBinding findBinding = new FindBinding(); TModelBag tModelBag = new TModelBag(); tModelBag.getTModelKey().add(processKey); return findBinding; } }