001: /*
002: * <copyright>
003: *
004: * Copyright 2002-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.servicediscovery.service;
028:
029: import java.util.Collection;
030: import java.util.HashMap;
031: import java.util.Iterator;
032: import java.util.Vector;
033:
034: import org.cougaar.core.service.LoggingService;
035: import org.cougaar.core.service.ThreadService;
036: import org.cougaar.yp.OneShotMachine;
037: import org.cougaar.yp.YPFuture;
038: import org.cougaar.yp.YPProxy;
039: import org.cougaar.yp.YPService;
040: import org.uddi4j.datatype.binding.AccessPoint;
041: import org.uddi4j.datatype.binding.BindingTemplate;
042: import org.uddi4j.datatype.binding.BindingTemplates;
043: import org.uddi4j.datatype.binding.InstanceDetails;
044: import org.uddi4j.datatype.binding.InstanceParms;
045: import org.uddi4j.datatype.binding.TModelInstanceDetails;
046: import org.uddi4j.datatype.binding.TModelInstanceInfo;
047: import org.uddi4j.datatype.tmodel.TModel;
048: import org.uddi4j.response.AuthToken;
049: import org.uddi4j.response.TModelDetail;
050: import org.uddi4j.response.TModelInfo;
051: import org.uddi4j.response.TModelInfos;
052: import org.uddi4j.response.TModelList;
053: import org.uddi4j.util.CategoryBag;
054: import org.uddi4j.util.DiscoveryURLs;
055: import org.uddi4j.util.FindQualifiers;
056: import org.uddi4j.util.IdentifierBag;
057: import org.uddi4j.util.KeyedReference;
058: import org.uddi4j.util.TModelBag;
059:
060: /**
061: * Utility class for holding common functions of YP/UDDI4J SD interations,
062: **/
063: public class UDDI4JUtility implements YPServiceAdapter // import Callback
064: {
065: protected final LoggingService log;
066: protected final YPService ypService;
067: protected final ThreadService threads;
068: protected boolean cacheEnabled;
069:
070: public UDDI4JUtility(LoggingService log, YPService ypService,
071: ThreadService threads) {
072: this .log = log;
073: this .ypService = ypService;
074: this .threads = threads;
075: this .cacheEnabled = !(Boolean
076: .getBoolean("org.cougaar.servicediscovery.service.tModelCacheDisabled"));
077: }
078:
079: /** Override to pre/post-fix log strings **/
080: protected String logString(String s) {
081: return s;
082: }
083:
084: protected BindingTemplates createBindingTemplates(String uri,
085: TModelInstanceDetails tModelInstanceDetails) {
086: BindingTemplates bindings = new BindingTemplates();
087: BindingTemplate binding = new BindingTemplate("",
088: tModelInstanceDetails);
089: AccessPoint accessPoint = new AccessPoint(uri, "http");
090: binding.setAccessPoint(accessPoint);
091: bindings.getBindingTemplateVector().add(binding);
092: return bindings;
093: }
094:
095: // doesn't require a machine - single invocation with quick completion
096: // callback.invoke(TModelInstanceDetails)
097: // callback.handle(NoSuchTModelKeyException)
098: protected void createTModelInstance(YPProxy proxy,
099: String tModelName, final String messageAddress,
100: final Callback callback) {
101: String suffix = ":Binding";
102: Callback chain = new Callback() {
103: public void invoke(Object o) {
104: String tModelKey = (String) o;
105: TModelInstanceDetails tModelInstanceDetails = null;
106: Vector tModelInstanceInfoVector = new Vector();
107: TModelInstanceInfo tModelInstanceInfo = new TModelInstanceInfo(
108: tModelKey);
109: InstanceDetails id = new InstanceDetails();
110: id.setInstanceParms(new InstanceParms(messageAddress));
111: tModelInstanceInfo.setInstanceDetails(id);
112: tModelInstanceInfoVector.add(tModelInstanceInfo);
113: tModelInstanceDetails = new TModelInstanceDetails();
114: tModelInstanceDetails
115: .setTModelInstanceInfoVector(tModelInstanceInfoVector);
116: callback.invoke(tModelInstanceDetails);
117: }
118:
119: public void handle(Exception e) {
120: callback.handle(e);
121: }
122: };
123: findTModelKey(proxy, tModelName + suffix, chain);
124: }
125:
126: // doesn't require a machine - single invocation with quick completion
127: // callback.invoke(KeyedReference)
128: // callback.handle(NoSuchTModelKeyException)
129: protected void getKeyedReference(YPProxy proxy,
130: final String tModelName, final String attribute,
131: final String value, final Callback callback) {
132: if (log.isInfoEnabled()) {
133: log.info(logString("enter getKeyedReference(" + tModelName
134: + ", " + attribute + ", " + value + ")"));
135: }
136:
137: Callback chain = new Callback() {
138: public void invoke(Object o) {
139: String key = (String) o;
140: KeyedReference kr = new KeyedReference(attribute, value);
141: kr.setTModelKey(key);
142: if (log.isInfoEnabled()) {
143: log.info(logString("exit getKeyedReference("
144: + tModelName + ", " + attribute + ", "
145: + value + ")=" + key));
146: }
147: callback.invoke(kr);
148: }
149:
150: public void handle(Exception e) {
151: if (log.isInfoEnabled()) {
152: log.info(logString("exception getKeyedReference("
153: + tModelName + ", " + attribute + ", "
154: + value + ")"), e);
155: }
156: callback.handle(e);
157: }
158: };
159:
160: findTModelKey(proxy, tModelName, chain);
161: }
162:
163: /** cache for findTModelKey, tModelName to tModelKey. Access should be synchronized on schemeKeys
164: *
165: * Caching currently disabled. Current single hash table implementation does
166: * not work with distributed yp servers. Key/Name pair is different for each
167: * server. Resolution to a specific yp server occurs in the yp module after
168: * servicediscovery has formulated the UDDI4J call.
169: *
170: * @note HashMap<String,String>
171: **/
172:
173: private final HashMap cachedKeys = new HashMap(11);
174:
175: protected String getCachedKey(String name) {
176: /* Disable for distributed YP - see RFE
177: */
178: if (cacheEnabled) {
179: synchronized (cachedKeys) {
180: return (String) cachedKeys.get(name);
181: }
182: } else {
183: return null;
184: }
185: }
186:
187: protected void setCachedKey(String name, String key) {
188: if (cacheEnabled) {
189: synchronized (cachedKeys) {
190: cachedKeys.put(name, key);
191: }
192: }
193: }
194:
195: private final HashMap cachedNames = new HashMap(11);
196:
197: protected String getCachedName(String key) {
198: if (cacheEnabled) {
199: synchronized (cachedNames) {
200: return (String) cachedNames.get(key);
201: }
202: } else {
203: return null;
204: }
205: }
206:
207: protected void setCachedName(String key, String name) {
208: if (cacheEnabled) {
209: synchronized (cachedNames) {
210: cachedNames.put(key, name);
211: }
212: }
213: }
214:
215: protected void setCache(String key, String name) {
216: setCachedKey(name, key);
217: setCachedName(key, name);
218: }
219:
220: /** get the TModel key from YP, possibly using a previous value.
221: * returns the value via the callback. On success, Callback.invoke
222: * will pass in a String;
223: **/
224: protected void findTModelKey(YPProxy proxy,
225: final String tModelName, final Callback callback) {
226: {
227: String k = getCachedKey(tModelName);
228: if (k != null) {
229: callback.invoke(k);
230: return;
231: }
232: }
233:
234: if (log.isInfoEnabled()) {
235: log.info(logString("enter findTModelKey(" + tModelName
236: + ")"));
237: }
238:
239: YPFuture fut = proxy.find_tModel(tModelName, null, null, null,
240: 1);
241: Callback smc = new CallbackDelegate(callback) {
242: public void invoke(Object result) {
243: TModelList tlist = (TModelList) result;
244:
245: if (log.isInfoEnabled()) {
246: if (tlist == null) {
247: log
248: .info(logString("findTModelKey: unable to find "
249: + tModelName));
250: } else if (log.isInfoEnabled()) {
251: log.info(logString("findTModelKey: found "
252: + tModelName));
253: }
254: }
255:
256: if (tlist == null) {
257: callback.handle(new NoSuchTModelKeyException(
258: "Unable to find tModel for " + tModelName));
259: return;
260: }
261:
262: TModelInfos infos = tlist.getTModelInfos();
263: Vector tms = infos.getTModelInfoVector();
264:
265: if (tms.size() == 0) {
266: callback.handle(new NoSuchTModelKeyException(
267: "Unable to find tModel for " + tModelName));
268: return;
269: }
270: String key = ((TModelInfo) tms.elementAt(0))
271: .getTModelKey();
272:
273: setCache(key, tModelName);
274: if (log.isInfoEnabled()) {
275: log.info(logString("exit findTModelKey("
276: + tModelName + ")=" + key));
277: }
278: super .invoke(key);
279: }
280: };
281:
282: launch(fut, smc);
283: }
284:
285: protected void findTModelName(YPProxy proxy,
286: final String tModelKey, final Callback callback) {
287: {
288: String n = getCachedName(tModelKey);
289: if (n != null) {
290: callback.invoke(n);
291: return;
292: }
293: }
294:
295: YPFuture fut = proxy.get_tModelDetail(tModelKey);
296: Callback smc = new CallbackDelegate(callback) {
297: public void invoke(Object result) {
298: TModelDetail tDetail = (TModelDetail) result;
299: Vector tList = tDetail.getTModelVector();
300: if (tList.size() > 0) {
301: TModel tm = (TModel) tList.elementAt(0);
302: String name = tm.getNameString();
303: setCache(tModelKey, name);
304: super .invoke(name);
305: } else {
306: log
307: .info("Requested TModel was not found in registry "
308: + tModelKey);
309: super .invoke(null);
310: }
311: }
312: };
313: launch(fut, smc);
314: }
315:
316: protected void launch(YPFuture fut, Callback callback) {
317: (new OneShotMachine(fut, callback, ypService, threads)).start();
318: }
319:
320: /** @note Callback.invoke(ServiceDetail) **/
321: protected void getServiceDetail(YPProxy proxy, Vector serviceKeys,
322: Callback callback) {
323: YPFuture fut = proxy.get_serviceDetail(serviceKeys);
324: launch(fut, callback);
325: }
326:
327: /** @note Callback.invoke(ServiceDetail) **/
328: protected void getServiceDetail(YPProxy proxy, String serviceKey,
329: Callback callback) {
330: YPFuture fut = proxy.get_serviceDetail(serviceKey);
331: launch(fut, callback);
332: }
333:
334: protected void findService(YPProxy proxy, String businessKey,
335: Vector names, CategoryBag categoryBag, TModelBag tModelBag,
336: FindQualifiers findQualifiers, int maxRows,
337: Callback callback) {
338: YPFuture fut = proxy.find_service(businessKey, names,
339: categoryBag, tModelBag, findQualifiers, maxRows);
340: launch(fut, callback);
341: }
342:
343: protected void findBusiness(YPProxy proxy, Vector names,
344: DiscoveryURLs discoveryURLs, IdentifierBag identifierBag,
345: CategoryBag categoryBag, TModelBag tModelBag,
346: FindQualifiers findQualifiers, int maxRows,
347: Callback callback) {
348: YPFuture fut = proxy.find_business(names, discoveryURLs,
349: identifierBag, categoryBag, tModelBag, findQualifiers,
350: maxRows);
351: launch(fut, callback);
352: }
353:
354: protected void saveBusiness(YPProxy proxy, AuthToken token,
355: Vector entities, Callback callback) {
356: YPFuture fut = proxy.save_business(token.getAuthInfoString(),
357: entities);
358: launch(fut, callback);
359: }
360:
361: /** @note Callback.invoke(BusinessDetail) **/
362: protected void getBusinessDetail(YPProxy proxy, String key,
363: Callback callback) {
364: YPFuture fut = proxy.get_businessDetail(key);
365: launch(fut, callback);
366: }
367:
368: /** @note Callback.invoke(BusinessDetail) **/
369: protected void getBusinessDetail(YPProxy proxy, Vector keys,
370: Callback callback) {
371: YPFuture fut = proxy.get_businessDetail(keys);
372: launch(fut, callback);
373: }
374:
375: public void getAuthToken(YPProxy proxy, String username,
376: String password, Callback callback) {
377: YPFuture fut = proxy.get_authToken(username, password);
378: launch(fut, callback);
379: }
380:
381: public void discardAuthToken(YPProxy proxy, AuthToken token,
382: Callback callback) {
383: YPFuture fut = proxy.discard_authToken(token
384: .getAuthInfoString());
385: launch(fut, callback);
386: }
387:
388: public static abstract class CallbackDelegate implements Callback {
389: private final Callback delegate;
390:
391: public CallbackDelegate(Callback delegate) {
392: this .delegate = delegate;
393: }
394:
395: public void invoke(Object result) {
396: delegate.invoke(result);
397: }
398:
399: public void handle(Exception e) {
400: delegate.handle(e);
401: }
402: }
403:
404: /** Loop over the collection, calling sub.invoke(element) and finally calling next.invoke(sub)
405: * @note Callback.invoke(sub)
406: **/
407: protected void loop(Collection collection, final Callback sub,
408: Callback next) {
409: class State {
410: Iterator it;
411: Callback chain;
412: }
413: ;
414: final State state = new State();
415:
416: state.it = collection.iterator();
417: state.chain = new CallbackDelegate(next) {
418: public void invoke(Object result) {
419: if (state.it.hasNext()) {
420: sub.invoke(new Object[] { state.it.next(),
421: state.chain });
422: } else {
423: super.invoke(sub);
424: }
425: }
426: };
427: state.chain.invoke(null);
428: }
429: }
|