1/*2 * Copyright 2001-2011 The Apache Software Foundation.3 * 4 * Licensed under the Apache License, Version 2.0 (the "License");5 * you may not use this file except in compliance with the License.6 * You may obtain a copy of the License at7 * http://www.apache.org/licenses/LICENSE-2.08 * 9 * Unless required by applicable law or agreed to in writing, software10 * distributed under the License is distributed on an "AS IS" BASIS,11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12 * See the License for the specific language governing permissions and13 * limitations under the License.14 */15package org.apache.juddi.v3.client.mapping;
1617import java.net.BindException;
18import java.net.URL;
19import java.rmi.RemoteException;
20import java.util.ArrayList;
21import java.util.Properties;
22import java.util.concurrent.ConcurrentHashMap;
2324import javax.xml.namespace.QName;
2526import org.apache.commons.configuration.ConfigurationException;
27import org.apache.commons.logging.Log;
28import org.apache.commons.logging.LogFactory;
29import org.apache.juddi.api_v3.AccessPointType;
30import org.apache.juddi.v3.client.ClassUtil;
31import org.apache.juddi.v3.client.config.UDDIClerk;
32import org.apache.juddi.v3.client.config.UDDIKeyConvention;
33import org.apache.juddi.v3.client.subscription.SubscriptionCallbackListener;
34import org.apache.juddi.v3.client.transport.TransportException;
35import org.uddi.api_v3.AccessPoint;
36import org.uddi.api_v3.BindingTemplate;
37import org.uddi.api_v3.BindingTemplates;
38import org.uddi.api_v3.BusinessService;
3940/**41 * The ServiceLocator contacts the UDDI registry to lookup an Endpoint given a UDDI ServiceKey.<br>42 * This class does NOT chase down WSDL, hosting redirectors or other binding references from43 * access point useType values. See 44 * {@link org.apache.juddi.v3.client.config.UDDIClerk#getEndpoints UDDIClerk.getEndpoints}45 * @see SubscriptionCallbackListener46 * @author <a href="mailto:kstam@apache.org">Kurt T Stam</a>47 */48publicclassServiceLocator {
4950privatestaticfinal Log log = LogFactory.getLog(ServiceLocator.class);
5152privateUDDIClerk clerk;
53private Properties properties = new Properties();
54privateUDDIServiceCache serviceCache = null;
55private String policy = null;
56privateSelectionPolicy selectionPolicy = null;
57privateURLLocalizer urlLocalizer = null;
58private ConcurrentHashMap<String, Topology> simpleCache= null;
59/**60 * Requirement in the config is a clerk with access credentials to the UDDI server61 * you want the locator to do lookups to. When a live cache is used the clerk62 * will register a callback into this UDDI server and the clerk will therefore need63 * inquiry and publish access. The credentials can be set in the uddi-client.xml64 * configuration file.65 * 66 * @param clerk a UDDI Clerk with publish access to the UDDI Server.67 * @throws ConfigurationException68 */69publicServiceLocator(UDDIClerk clerk) {
70super();
71this.clerk = clerk;
72 properties =clerk.getUDDINode().getProperties();
73 }
7475publicServiceLocator(UDDIClerk clerk, URLLocalizer urlLocalizer, Properties properties) throws ConfigurationException {
76super();
77this.clerk = clerk;
78this.urlLocalizer = urlLocalizer;
79this.properties = properties;
80if (properties == null)
81this.properties = clerk.getUDDINode().getProperties();
82 }
8384/**85 * Creates a new UDDIServiceCache, which brings up a new WebService Endpoint. This86 * EndPoint will be called by the UDDI server if any service changes. A callback87 * will result in cleaning the cache. 88 * 89 * @param baseCallbackURL90 * @throws ConfigurationException91 */92publicServiceLocator withCache(URL baseCallbackURL) throws ConfigurationException {
93if (serviceCache == null) {
94 serviceCache = initCache(baseCallbackURL);
95 }
96returnthis;
97 }
9899/**100 * A live cache will receive callbacks from the UDDI server in case there is an update to101 * a service's bindings. All callbacks will clear the UDDIClientCache ensuring that subsequent102 * lookups will contact the UDDI server for the latest binding information.103 * 104 * The baseCallbackURL can be set to solve binding issue. If105 * 106 * @param baseCallbackURL107 * @return a service locator object108 * @throws ConfigurationException109 * @throws BindException110 */111publicServiceLocator withLiveCache(URL baseCallbackURL) throws ConfigurationException, BindException {
112if (serviceCache == null) {
113 serviceCache = initCache(baseCallbackURL);
114 serviceCache.registerAsMBean();
115 }
116if (! serviceCache.hasListener()) {
117 serviceCache.publishAndRegisterHttpCallbackEndpoint();
118 }
119returnthis;
120 }
121122123publicServiceLocator withSimpleCache(){
124if (simpleCache==null){
125 simpleCache= new ConcurrentHashMap<String, Topology>();
126 }
127returnthis;
128 }
129130publicUDDIServiceCache getUDDIServiceCache() {
131return serviceCache;
132 }
133134/**135 * The policy selection can be set as property "juddi.client.selection.policy"136 * or it can be set programmatically using this method. A Policy is a class which 137 * implements the SelectionPolicy interface. Known implementations are138 * org.apache.juddi.v3.client.mapping.PolicyLocalFirst and 139 * org.apache.juddi.v3.client.mapping.PolicyRoundRobin. If the policy is not140 * set the default org.apache.juddi.v3.client.mapping.PolicyLocalFirst is used.141 * 142 * @param policy - the desired policy.143 * @return ServiceLocator144 * @see org.apache.juddi.v3.client.mapping.PolicyLocalFirst145 * @see org.apache.juddi.v3.client.mapping.PolicyRoundRobin146 */147publicServiceLocator setPolicy(String policy) {
148this.policy = policy;
149returnthis;
150 }
151/**152 * Returns the selection policy in use by this instance of the ServiceLocator.153 * 154 * @return SelectionPolicy - the selection policy.155 * @throws ConfigurationException156 */157publicSelectionPolicy getPolicy() throws ConfigurationException {
158try {
159if (selectionPolicy==null) {
160if (policy==null) {
161//TODO update .NET schema file to support this162 policy = properties.getProperty("juddi.client.selection.policy", "org.apache.juddi.v3.client.mapping.PolicyLocalFirst");
163 }
164 @SuppressWarnings("unchecked")
165 Class<? extends SelectionPolicy> selectionPolicyClass = (Class<? extends SelectionPolicy>)
166 ClassUtil.forName(policy, this.getClass());
167 selectionPolicy = selectionPolicyClass.getConstructor(Properties.class).newInstance(properties);
168 }
169return selectionPolicy;
170 } catch (Exception e) {
171thrownew ConfigurationException(e.getMessage(),e);
172 }
173 }
174175/**176 * Creates a new UDDIServiceCache, which brings up a new WebService Endpoint. This177 * EndPoint will be called by the UDDI server if any service changes. A callback178 * will result in cleaning the cache. 179 * 180 * @param baseCallbackURL181 * @throws ConfigurationException182 */183privateUDDIServiceCache initCache(URL baseCallbackURL) throws ConfigurationException {
184if (clerk==null) thrownew ConfigurationException("The UDDIClerk is needed to use the UDDIServiceCache and is null");
185if (urlLocalizer==null) urlLocalizer = new URLLocalizerDefaultImpl(baseCallbackURL);
186if (properties==null) properties = new Properties();
187try {
188 log.info("Creating a UDDICLientCache");
189returnnewUDDIServiceCache(clerk, urlLocalizer, properties);
190 } catch (Exception e) {
191thrownew ConfigurationException(e.getMessage(),e);
192 }
193 }
194195publicvoid clearCaches(){
196if (serviceCache!=null)
197 serviceCache.removeAll();
198if (simpleCache!=null)
199 simpleCache.clear();
200 }
201202/**203 * 204 * @throws RemoteException205 * @throws ConfigurationException206 * @throws TransportException207 */208publicvoid shutdown() throws RemoteException, ConfigurationException, TransportException {
209if (serviceCache!=null)
210 serviceCache.shutdown();
211 }
212/**213 * Looks up the Endpoints for a Service. If the cache is in use it will try to 214 * obtain them from the cache. If no Endpoints are found, or if the cache is not215 * in use, the clerk will do a lookup for this service. After Endpoints are found216 * it will use a policy to pick one Endpoint to return. Returns null if no endpoints217 * are found.218 * 219 * @param serviceKey220 * @return endpoint221 * @throws RemoteException222 * @throws ConfigurationException223 * @throws TransportException224 */225public String lookupEndpoint(String serviceKey) throws RemoteException, ConfigurationException, TransportException {
226 Topology topology = null;
227if (simpleCache != null && simpleCache.containsKey(serviceKey)){
228 topology = simpleCache.get(serviceKey);
229 } elseif (serviceCache==null) { //nocache in use230 topology = lookupEndpointInUDDI(serviceKey);
231 } else { //with cache232//try to get it from the cache first233 topology = serviceCache.lookupService(serviceKey);
234if (topology == null) { //not found in the cache235 topology = lookupEndpointInUDDI(serviceKey);
236 }
237 }
238if (topology!=null && topology.getEprs().size() > 0) {
239if (simpleCache!=null){
240 simpleCache.put(serviceKey,topology);
241 }
242 String epr = getPolicy().select(topology);
243return epr;
244 }
245returnnull;
246 }
247248/** 249 * Looks up the Endpoints for a Service. If the cache is in use it will try to 250 * obtain them from the cache. If no Endpoints are found, or if the cache is not251 * in use, the clerk will do a lookup for this service. After Endpoints are found252 * it will use a policy to pick one Endpoint to return. Returns null if no endpoints253 * are found.254 * 255 * @param serviceQName256 * @param portName257 * @return Returns null if no endpoints258 * are found.259 * @throws TransportException 260 * @throws ConfigurationException 261 * @throws RemoteException 262 */263public String lookupEndpoint(QName serviceQName, String portName) throws RemoteException, ConfigurationException, TransportException {
264 String serviceKey = UDDIKeyConvention.getServiceKey(properties, serviceQName.getLocalPart());
265return lookupEndpoint(serviceKey);
266 }
267268privateTopology lookupEndpointInUDDI(String serviceKey) throws RemoteException, ConfigurationException, TransportException {
269 Topology topology = null;
270271 BusinessService service = clerk.getServiceDetail(serviceKey);
272if (service==null) {
273 log.warn("No Service with key " + serviceKey + " was found in the registry.");
274//TODO find service by tModel275 }
276if (service!=null && service.getBindingTemplates()!=null && service.getBindingTemplates().getBindingTemplate() != null) {
277 ArrayList<String> eprs = new ArrayList<String>();
278 BindingTemplates bindingTemplates = service.getBindingTemplates();
279if (bindingTemplates==null) {
280 log.warn("Found service " + service.getName().get(0).getValue()
281 + " with serviceKey '" + serviceKey + "'"282 + " but no EPRs");
283 } else {
284 log.debug("Found service " + service.getName().get(0).getValue()
285 + " with serviceKey '" + serviceKey + "'"286 + " and " + bindingTemplates.getBindingTemplate().size() + " EPRs");
287//Loop over all bindingTemplates found and get the endpoints.288for (BindingTemplate bindingTemplate : bindingTemplates.getBindingTemplate()) {
289 AccessPoint accessPoint = bindingTemplate.getAccessPoint();
290if (accessPoint!=null){
291if (AccessPointType.END_POINT.toString().equals(accessPoint.getUseType())) {
292 String url = accessPoint.getValue();
293 log.debug("epr= " + url);
294 eprs.add(url);
295 } elseif(AccessPointType.WSDL_DEPLOYMENT.toString().equals(accessPoint.getUseType())) {
296//do something here297//try to open that wsdl, then grab the endpoints298//String url=fetchFromWsdl(accessPoint.getValue());299300 } elseif(AccessPointType.BINDING_TEMPLATE.toString().equals(accessPoint.getUseType())) {
301//do something here302//grab that binding template and use that address303 }
304 }
305 }
306if (eprs.size()>0) {
307 topology = newTopology(eprs);
308 }
309 }
310 }
311if (serviceCache!=null && topology!=null) { //add to cache312 serviceCache.addService(serviceKey, topology);
313 }
314return topology;
315 }
316317318 }