View Javadoc
1   /**
2    * This Source Code Form is subject to the terms of the Mozilla Public
3    * License, v. 2.0. If a copy of the MPL was not distributed with this
4    * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5    *
6    * If it is not possible or desirable to put the notice in a particular
7    * file, then You may include the notice in a location (such as a LICENSE
8    * file in a relevant directory) where a recipient would be likely to look
9    * for such a notice.
10  
11   * 
12   */
13   
14  /*  ---------------------------------------------------------------------------
15   *  U.S. Government, Department of the Army
16   *  Army Materiel Command
17   *  Research Development Engineering Command
18   *  Communications Electronics Research Development and Engineering Center
19   *  ---------------------------------------------------------------------------
20   */
21  
22  package org.miloss.fgsms.discovery;
23  
24  import java.util.ArrayList;
25  import java.util.HashSet;
26  import java.util.List;
27  import java.util.Map;
28  import java.util.Properties;
29  import java.util.Set;
30  import javax.xml.ws.BindingProvider;
31  import org.apache.juddi.v3.client.UDDIConstants;
32  import org.apache.juddi.v3.client.UDDIService;
33  import org.apache.log4j.Level;
34  import org.miloss.fgsms.common.Logger;;
35  import org.miloss.fgsms.common.Utility;
36  import org.miloss.fgsms.plugins.agents.IEndpointDiscovery;
37  
38  import org.uddi.api_v3.*;
39  import org.uddi.v3_service.UDDIInquiryPortType;
40  import org.uddi.v3_service.UDDISecurityPortType;
41  
42  /**
43   * Provides UDDI discovery services for use with agents
44   *
45   * @author AO
46   */
47  public class UDDIDiscovery implements IEndpointDiscovery {
48  
49      private static final Logger log = Logger.getLogger("fgsms.Discovery.UDDI");
50      private UDDIService uddi = null;
51      private UDDIInquiryPortType inquiry = uddi.getUDDIInquiryPort();
52      
53      private UDDISecurityPortType security = uddi.getUDDISecurityPort();
54      private boolean LoginRequired = false;
55      private String PCSlookupkey = "";
56      private String DCSlookupkey = "";
57      private String SSlookupkey = "";
58  
59      boolean uddiauth = true;
60      /// 
61      /// Checks to see if the open esm tmodels have been registered with the uddi registry.
62      /// if they haven't been, they are published
63      /// 
64      boolean good;
65      protected String username = "";
66      protected String encryptedpassword = "";
67      long lastlookup = 0;
68      boolean UddiEnabled = true;
69      private findType currentFind = findType.EndpointBindingKey;
70      public UDDIDiscovery() {
71      }
72  
73      private List<String> DiscoveryServiceEndpoints(String lookupkey, findType findType) {
74          List<String> list = new ArrayList<String>();
75          switch (currentFind) {
76              case EndpointBindingKey:
77                  list.addAll(DiscoverEndpointBindingKey(lookupkey, null));
78                  break;
79              case EndpointKeyWord:
80                  list.addAll(DiscoverEndpointKeyWord(lookupkey, null));
81                  break;
82              case ServiceEntityKey:
83                  list.addAll(DiscoverByServiceKey(lookupkey, null));
84                  break;
85          }
86          return new ArrayList<String>(new HashSet(list));
87      }
88  
89      private List<String> DiscoverEndpointBindingKey(String key, String token) {
90          if (Utility.stringIsNullOrEmpty(key)) {
91              throw new IllegalArgumentException("bindingKey");
92          }
93  
94          if (LoginRequired && uddiauth && Utility.stringIsNullOrEmpty(token)) {
95              token = LoginWrapper();
96          }
97          GetBindingDetail req = new GetBindingDetail();
98  
99          req.setAuthInfo(token);
100         req.getBindingKey().add(key);
101         BindingDetail response = null;
102         try {
103             response = inquiry.getBindingDetail(req);
104         } catch (Exception ex) {
105             log.log(Level.ERROR, "error caught uddi agent endpoints", ex);
106         }
107 //        HashMap endpoints = new HashMap();
108         List<String> ret = new ArrayList<String>();
109         if (response != null && !response.getBindingTemplate().isEmpty()) {
110             for (int i = 0; i < response.getBindingTemplate().size(); i++) {
111                 if (response.getBindingTemplate().get(i).getAccessPoint() != null) {
112                     ret.addAll(parseResults(response.getBindingTemplate().get(i).getAccessPoint(), token));
113                 }
114                 if (response.getBindingTemplate().get(i).getHostingRedirector() != null) {
115                     ret.addAll(DiscoverEndpointBindingKey(response.getBindingTemplate().get(i).getHostingRedirector().getBindingKey(), token));
116                 }
117             }
118         }
119         return ret;
120     }
121 
122     private List<String> DiscoverByServiceKey(String key, String token) {
123         if (key == null) {
124             throw new IllegalArgumentException("keycol");
125         }
126 
127         if (this.LoginRequired && uddiauth && Utility.stringIsNullOrEmpty(token)) {
128             token = LoginWrapper();
129         }
130         GetServiceDetail req = new GetServiceDetail();
131         req.getServiceKey().add(key);
132         req.setAuthInfo(token);
133         ServiceDetail response = null;
134         try {
135             response = inquiry.getServiceDetail(req);
136 
137         } catch (Exception ex) {
138             log.log(Level.ERROR, "error caught discovering agent endpoints from uddi", ex);
139         }
140 
141         List<String> ret = new ArrayList<String>();
142         if (response == null || response == null || response.getBusinessService() == null || response.getBusinessService().isEmpty()) {
143             return ret;
144         }
145         for (int i = 0; i < response.getBusinessService().size(); i++) {
146             if (response.getBusinessService().get(i).getBindingTemplates() != null) {
147                 for (int k = 0; k < response.getBusinessService().get(i).getBindingTemplates().getBindingTemplate().size(); k++) {
148                     if (response.getBusinessService().get(i).getBindingTemplates().getBindingTemplate().get(k).getAccessPoint() != null) {
149                         ret.addAll(parseResults(response.getBusinessService().get(i).getBindingTemplates().getBindingTemplate().get(k).getAccessPoint(), token));
150                     }
151                 }
152             }
153         }
154 
155         return ret;
156     }
157 
158     /**
159      * find service by name
160      *
161      * @param key
162      * @param token
163      * @return
164      */
165     private List<String> DiscoverEndpointKeyWord(String key, String token) {
166 
167         if (key == null) {
168             throw new IllegalArgumentException("keywords");
169         }
170 
171 
172 
173         if (LoginRequired && uddiauth && Utility.stringIsNullOrEmpty((token))) {
174             token = LoginWrapper();
175         }
176 
177         FindService req = new FindService();
178         Name n = new Name();
179         n.setValue(key);
180         req.getName().add(n);
181         req.setFindQualifiers(new FindQualifiers());
182         req.getFindQualifiers().getFindQualifier().add(UDDIConstants.APPROXIMATE_MATCH);
183         req.getFindQualifiers().getFindQualifier().add(UDDIConstants.CASE_INSENSITIVE_MATCH);
184         req.setAuthInfo(token);
185 
186         ServiceList response = null;
187 
188         List<String> ret = new ArrayList<String>();
189         try {
190             response = inquiry.findService(req);
191         } catch (Exception ex) {
192             log.log(Level.ERROR, "error discoverying agent endpoints", ex);
193             return ret;
194         }
195 
196         if (response == null || response.getServiceInfos() == null || response.getServiceInfos().getServiceInfo().isEmpty()) {
197             log.log(Level.INFO, "Discovery from service name search in UDDI yielded no results.");
198             return ret;
199         }
200 
201         GetServiceDetail sreq = new GetServiceDetail();
202         sreq.setAuthInfo(token);
203 
204 
205         for (int k = 0; k < response.getServiceInfos().getServiceInfo().size(); k++) {
206             sreq.getServiceKey().add(response.getServiceInfos().getServiceInfo().get(k).getServiceKey());
207         }
208         ServiceDetail sresponse = null;
209 
210         try {
211             sresponse = inquiry.getServiceDetail(sreq);
212         } catch (Exception ex) {
213             log.log(Level.ERROR, "error discoverying agent endpoints", ex);
214             return ret;
215         }
216 
217         if (sresponse != null && !sresponse.getBusinessService().isEmpty()) {
218             log.log(Level.INFO, "Discovery from service name search in UDDI yielded " + sresponse.getBusinessService().size() + " results.");
219             for (int i = 0; i < sresponse.getBusinessService().size(); i++) {
220                 if (sresponse.getBusinessService().get(i).getBindingTemplates() != null) {
221                     for (int k = 0; k < sresponse.getBusinessService().get(i).getBindingTemplates().getBindingTemplate().size(); k++) {
222                         if (sresponse.getBusinessService().get(i).getBindingTemplates().getBindingTemplate().get(k).getAccessPoint() != null) {
223                             ret.addAll(parseResults(sresponse.getBusinessService().get(i).getBindingTemplates().getBindingTemplate().get(k).getAccessPoint(), token));
224                         }
225                     }
226                 }
227             }
228         } else {
229             log.log(Level.INFO, "Discovery from service name search in UDDI yielded no results");
230         }
231         return ret;
232     }
233 /// 
234     /// helper class to try and dicipher the complicated arrangements of the uddi type accessPoint
235     /// 
236     /// <param name="ap"></param>
237     /// <param name="username"></param>
238     /// <param name="password"></param>
239     /// <param name="discoveryEndpointAddress"></param>
240     /// <returns></returns>
241 
242     private List<String> parseResults(AccessPoint ap, String authtoken) {
243         List<String> ret = new ArrayList<String>();
244         boolean ok = false;
245         if (!Utility.stringIsNullOrEmpty(ap.getUseType())) {
246             //useType is defined, now what?
247             //lets try and figure out what it is
248             if (ap.getUseType().equalsIgnoreCase("endpoint")) {
249                 //for systinet servers, they tend to have endpoints with the value
250                 //equal to some java class file, why? who the hell knows, but it's against the 
251                 //uddi spec and thus not really expected.
252                 if (ap.getValue().toLowerCase().startsWith("http")) {
253                     ret.add(ap.getValue());
254                 }
255                 //if (ap.Value.StartsWith("ftp", StringComparison.CurrentCultureIgnoreCase))
256                 //ret.Add(ap.Value);
257                 //if (ap.Value.StartsWith("smtp", StringComparison.CurrentCultureIgnoreCase))
258                 //ret.Add(ap.Value);
259                 // ret.Add(ap.Value);
260                 ok = true;
261             } else if (ap.getUseType().equalsIgnoreCase("bindingtemplate") || ap.getUseType().equalsIgnoreCase("hostingredirector")) {
262 
263                 //bindingKey
264                 //another call out to the same registry
265                 try {
266                     ret.addAll(DiscoverEndpointBindingKey(ap.getValue(), authtoken));
267                 } catch (Exception ex) {
268                     log.log(Level.WARN, "trouble discoverying endpoint from UDDI." + ex);
269                 }
270                 ok = true;
271             } else /* case "hostingredirector":
272              //another call out to a different registry
273              try
274              {
275              //remote auth not supported
276              string[] r2 = this.DiscoverEndpointKeyWord(keywords, ap.Value);
277              for (int k = 0; k < r2.Length; k++)
278              ret.Add(r2[k]);
279              }
280              catch (Exception ex)
281              {
282             
283              }
284             
285              break;*/ if (ap.getUseType().equalsIgnoreCase("bindingtemplate") || ap.getUseType().equalsIgnoreCase("hostingredirector")) {
286 
287                 ret.addAll(DiscoverEndpointByWSDL(ap.getValue()));
288 
289 
290                 ok = true;
291             }
292 
293 
294             if (!ok) {
295                 //this means it's an unknown useType OR
296                 //this means the useType is not defined. lets try to guess if the value is actually a url
297                 if (ap.getValue().toLowerCase().startsWith("http")) {
298                     ret.add(ap.getValue());
299                 }
300                 //if (ap.Value.StartsWith("ftp", StringComparison.CurrentCultureIgnoreCase))
301                 //ret.Add(ap.Value);
302                 //if (ap.Value.StartsWith("smtp", StringComparison.CurrentCultureIgnoreCase))
303                 //ret.Add(ap.Value);
304                 //else ignore it, log unknown type as warning
305             }
306 
307         }
308         return ret;
309     }
310 
311     private List<String> DiscoverEndpointByWSDL(String value) {
312         //TODO maybe all commons.httpclient to fetch the wsdl
313         return new ArrayList<String>();
314     }
315 
316     @Override
317     public List<String> GetRSURLs() {
318         throw new UnsupportedOperationException("Not supported yet.");
319     }
320 
321     @Override
322     public List<String> GetARSURLs() {
323         throw new UnsupportedOperationException("Not supported yet.");
324     }
325 
326     @Override
327     public List<String> GetURLs(String lookupkey) {
328         return DiscoveryServiceEndpoints(lookupkey, currentFind);
329     }
330 
331     @Override
332     public List<String> GetDASURLs() {
333         throw new UnsupportedOperationException("Not supported yet.");
334     }
335 
336     @Override
337     public void SetLastLookup(long timeinms) {
338         lastlookup = timeinms;
339     }
340 
341     @Override
342     public long GetLastLookup() {
343         return lastlookup;
344     }
345 
346     @Override
347     public void LoadConfig(Properties props) {
348         try {
349             if (props == null) {
350                 throw new IllegalArgumentException("check for configuration file, uddi.properties");
351             }
352 
353             try {
354                 UddiEnabled = Boolean.parseBoolean(props.getProperty("discovery.uddi.enabled").trim());
355             } catch (Exception ex) {
356                 UddiEnabled = false;
357                 log.log(Level.WARN, null, ex);
358             }
359 
360             
361             inquiry = uddi.getUDDIInquiryPort();
362             BindingProvider bpPCS = (BindingProvider) inquiry;
363             Map<String, Object> contextPCS = bpPCS.getRequestContext();
364             if (!Utility.stringIsNullOrEmpty(props.getProperty("discovery.uddi.inquiry.url"))) {
365                 contextPCS.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, props.getProperty("discovery.uddi.inquiry.url"));
366             }
367 
368             if (Utility.stringIsNullOrEmpty(props.getProperty("discovery.uddi.lookup.dcs.servicename"))) {
369                 DCSlookupkey = "fgsms.DCS";
370                 log.log(Level.WARN, "fgsms discovery.uddi.lookup.dcs.servicename lookup key is not defined. defaulting to fgsms.DCS");
371             } else {
372                 DCSlookupkey = props.getProperty("discovery.uddi.lookup.dcs.servicename");
373             }
374 
375             if (Utility.stringIsNullOrEmpty(props.getProperty("discovery.uddi.lookup.ss.servicename"))) {
376                 DCSlookupkey = "fgsms.SS";
377                 log.log(Level.WARN, "fgsms discovery.uddi.lookup.ss.servicename lookup key is not defined. defaulting to fgsms.SS");
378             } else {
379                 SSlookupkey = props.getProperty("discovery.uddi.lookup.ss.servicename");
380             }
381 
382             if (Utility.stringIsNullOrEmpty(props.getProperty("discovery.uddi.lookup.pcs.servicename"))) {
383                 PCSlookupkey = "fgsms.PCS";
384                 log.log(Level.WARN, "fgsms discovery.uddi.lookup.pcs.servicename lookup key is not defined. defaulting to fgsms.PCS");
385             } else {
386                 PCSlookupkey = props.getProperty("discovery.uddi.lookup.pcs.servicename");
387             }
388 
389 
390             if (Utility.stringIsNullOrEmpty(props.getProperty("discovery.uddi.inquiry.authrequired"))) {
391                 LoginRequired = false;
392                 log.log(Level.WARN, "fgsms discovery.uddi.lookup.dcs.servicename lookup key is not defined. defaulting to fgsms.DCS");
393             } else {
394                 LoginRequired = Boolean.parseBoolean(props.getProperty("discovery.uddi.inquiry.authrequired"));
395             }
396 
397 
398             try {
399                 currentFind = findType.valueOf(props.getProperty("discovery.uddi.lookup.findType"));
400             } catch (Exception ex) {
401             }
402 
403             if (LoginRequired) {
404                 String t = props.getProperty("discovery.uddi.inquiry.authmode");
405                 if (t.equalsIgnoreCase("http")) {
406                     uddiauth = false;
407                 } else {
408                     uddiauth = true;
409                 }
410 
411                 if (uddiauth) {
412                     try {
413     
414                         security = uddi.getUDDISecurityPort();
415                         bpPCS = (BindingProvider) security;
416                         contextPCS = bpPCS.getRequestContext();
417                         if (!Utility.stringIsNullOrEmpty(props.getProperty("discovery.uddi.security.url"))) {
418                             contextPCS.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, props.getProperty("discovery.uddi.security.url"));
419                         }
420 
421                         username = (String) props.get("discovery.uddi.security.username");
422                         if (Utility.stringIsNullOrEmpty(username)) {
423                             throw new IllegalArgumentException("username is empty");
424                         }
425                         encryptedpassword = (String) props.get("discovery.uddi.security.password");
426 
427 
428                     } catch (Exception e) {
429                         throw new IllegalArgumentException("UDDI Login required, but the security service could not be initialized.", e);
430                     }
431                 } else {
432                     contextPCS.put(BindingProvider.USERNAME_PROPERTY, props.getProperty("discovery.uddi.security.username"));
433                     contextPCS.put(BindingProvider.PASSWORD_PROPERTY, Utility.DE(props.getProperty("discovery.uddi.security.password")));
434                 }
435             }
436             good = true;
437         } catch (Exception ex) {
438             log.log(Level.WARN, "Unable to initialize uddi inquiry parameters for rollover or load balancing. check the agent configuration file, " + ex);
439             good = false;
440         }
441     }
442 
443     @Override
444     public boolean IsEnabled() {
445         return this.UddiEnabled;
446     }
447 
448 
449     private String LoginWrapper() {
450 
451         return Login(username, encryptedpassword);
452     }
453 
454     private String Login(String username, String encryptedpassword) {
455         if (Utility.stringIsNullOrEmpty(username) || Utility.stringIsNullOrEmpty(encryptedpassword)) {
456             return "";
457         }
458 
459         //return "";/*
460         GetAuthToken request = new GetAuthToken();
461         request.setUserID(username);
462         request.setCred(Utility.DE(encryptedpassword));
463         try {
464             AuthToken response = security.getAuthToken(request);
465             return response.getAuthInfo();
466         } catch (Exception ex) {
467             log.log(Level.ERROR, "Error authenticating to the UDDI server: ", ex);
468             good = false;
469             return "";
470         }
471     }
472 
473     public List<String> GetPCSURLs() {
474 
475         return DiscoveryServiceEndpoints(PCSlookupkey, currentFind);
476     }
477 
478     public List<String> GetDCSURLs() {
479         return DiscoveryServiceEndpoints(DCSlookupkey, currentFind);
480     }
481 
482     public List<String> GetSSURLs() {
483         return DiscoveryServiceEndpoints(SSlookupkey, currentFind);
484     }
485     public enum findType {
486         
487         EndpointBindingKey,
488         EndpointKeyWord,
489         ServiceEntityKey
490     }
491    
492 }