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   *  U.S. Government, Department of the Army
15   *  Army Materiel Command
16   *  Research Development Engineering Command
17   *  Communications Electronics Research Development and Engineering Center
18   *  ---------------------------------------------------------------------------
19   */
20  package org.miloss.fgsms.uddipub;
21  
22  import java.net.MalformedURLException;
23  import java.net.URL;
24  import java.sql.PreparedStatement;
25  import java.sql.ResultSet;
26  import java.util.ArrayList;
27  import java.util.Collections;
28  import java.util.HashSet;
29  import java.util.List;
30  import java.util.Map;
31  import java.util.Set;
32  import java.util.concurrent.atomic.AtomicReference;
33  import javax.net.ssl.HostnameVerifier;
34  import javax.net.ssl.HttpsURLConnection;
35  import javax.net.ssl.SSLContext;
36  import javax.net.ssl.SSLSession;
37  import javax.net.ssl.TrustManager;
38  import javax.net.ssl.X509TrustManager;
39  import javax.xml.ws.BindingProvider;
40  import org.apache.juddi.v3.client.UDDIService;
41  import org.miloss.fgsms.common.DBSettingsLoader;
42  import org.miloss.fgsms.common.Utility;
43  import org.miloss.fgsms.plugins.sla.AlertContainer;
44  import org.miloss.fgsms.services.interfaces.policyconfiguration.FederationPolicy;
45  import org.miloss.fgsms.services.interfaces.policyconfiguration.KeyNameValueEnc;
46  import org.miloss.fgsms.services.interfaces.policyconfiguration.ServicePolicy;
47  import org.miloss.fgsms.sla.SLACommon;
48  import org.apache.log4j.Level;
49  import org.miloss.fgsms.common.DBUtils;
50  import org.miloss.fgsms.common.Logger;
51  import org.miloss.fgsms.services.interfaces.common.NameValuePair;
52  import org.miloss.fgsms.services.interfaces.common.PolicyType;
53  import org.uddi.api_v3.AuthToken;
54  import org.uddi.api_v3.GetAuthToken;
55  import org.uddi.v3_service.UDDIInquiryPortType;
56  import org.uddi.v3_service.UDDIPublicationPortType;
57  import org.uddi.v3_service.UDDISecurityPortType;
58  
59  /**
60   * This SLA Plugin will register and unregister in UDDI when a web service when
61   * its status changes
62   *
63   *
64   * This is incomplete
65   *
66   * @author AO
67   */
68  public class UpdateUddiRegistration implements org.miloss.fgsms.plugins.sla.SLAActionInterface {
69  
70      private static final Logger log = Logger.getLogger("fgsms.UDDIStatusUpdater");
71      static boolean configuredForUddi = false;
72      static long lastRefresh = 0;
73      static boolean isPooled = false;
74      private UDDIService uddi = null;
75      private UDDIInquiryPortType inquiry = null;
76      private UDDISecurityPortType security = null;
77      private UDDIPublicationPortType publication = null;
78      private boolean ClientCertRequired = false;
79      private String inquiryurl = "";
80      private String publishurl = "";
81      private String securityurl = "";
82  
83      @Override
84      public List<NameValuePair> GetRequiredParameters() {
85          List<NameValuePair> ret = new ArrayList<NameValuePair>();
86          ret.add(Utility.newNameValuePair(UddiPublisher.OPTION_BINDING_KEY, null, false, false));
87          return ret;
88      }
89  
90      @Override
91      public List<NameValuePair> GetOptionalParameters() {
92          return new ArrayList<NameValuePair>();
93      }
94  
95      @Override
96      public boolean ValidateConfiguration(List<NameValuePair> params, AtomicReference<String> outError) {
97          throw new UnsupportedOperationException("Not supported yet.");
98      }
99  
100     @Override
101     public String GetHtmlFormattedHelp() {
102         return "This plugin will either register or unregister a UDDI binding template registration based on the current status indicator. This is designed to work"
103                 + " in hand with the Rule: Change in Status<br><br>"
104                 + "<ul>"
105                 + "<li>" + UddiPublisher.OPTION_BINDING_KEY + " - Required. This is the key of the binding template in UDDI from which data will be attached</li>"
106                 + "</ul>";
107     }
108 
109     @Override
110     public String GetDisplayName() {
111         return "Update UDDI Registration";
112     }
113 
114     @Override
115     public void ProcessAction(AlertContainer alert, List<NameValuePair> params) {
116         AtomicReference<Boolean> status = new AtomicReference<Boolean>();
117         SLACommon.GetCurrentStatus(alert.isPooled(), null, status, null, null);
118         if (status != null && status.get() != null && status.get() == true) {
119             Register(alert.isPooled(), alert.getServicePolicy());
120         } else {
121             Unregister(alert.isPooled(), alert.getServicePolicy());
122         }
123     }
124 
125     @Override
126     public List<PolicyType> GetAppliesTo() {
127         List<PolicyType> ret = new ArrayList<PolicyType>();
128         ret.add(PolicyType.STATUS);
129         ret.add(PolicyType.TRANSACTIONAL);
130         return ret;
131     }
132 
133     private enum AuthMode {
134 
135         Uddi, Http
136     }
137     private AuthMode uddiauth = AuthMode.Http;
138     /// 
139     /// Checks to see if the open esm tmodels have been registered with the uddi registry.
140     /// if they haven't been, they are published
141     /// 
142     public boolean State = false;
143     protected String username = "";
144     protected String password = "";
145 
146     /*
147      * protected URL pcsURL; private PCS client;
148      */
149 
150     private String LoginWrapper() {
151 
152         return Login(username, password);
153     }
154 
155     private String Login(String username, String password) {
156         if (Utility.stringIsNullOrEmpty(username) || Utility.stringIsNullOrEmpty(password)) {
157             return "";
158         }
159         if (uddiauth != AuthMode.Uddi) {
160             return "";
161         }
162 
163         //return "";/*
164         GetAuthToken request = new GetAuthToken();
165         request.setUserID(username);
166         request.setCred(Utility.DE(password));
167         try {
168             AuthToken response = security.getAuthToken(request);
169             return response.getAuthInfo();
170         } catch (Exception ex) {
171             log.log(Level.ERROR, "Error authenticating to the UDDI server: ", ex);
172             throw new IllegalArgumentException("can't authenticate to UDDI with the provided credentials");
173             //return "";
174         }
175     }
176 
177     private void Register(boolean pooled, ServicePolicy servicePolicy) {
178         Init(pooled);
179         if (!State) {
180             return;
181         }
182         FederationPolicyExt fp = new FederationPolicyExt(GetUddiFedPol(servicePolicy));
183         if (fp == null || fp.getBindingKey() == null) {
184             return;
185         }
186         //TODO
187     }
188 
189     private void Unregister(boolean pooled, ServicePolicy servicePolicy) {
190         Init(pooled);
191         if (!State) {
192             return;
193         }
194         FederationPolicyExt fp = new FederationPolicyExt(GetUddiFedPol(servicePolicy));
195         if (fp == null || fp.getBindingKey() == null) {
196             return;
197         }
198         //TODO
199     }
200 
201     private FederationPolicy GetUddiFedPol(ServicePolicy p) {
202         if (p == null) {
203             return null;
204         }
205         if (p.getFederationPolicyCollection() == null) {
206             return null;
207         }
208         for (int i = 0; i < p.getFederationPolicyCollection().getFederationPolicy().size(); i++) {
209             if (p.getFederationPolicyCollection().getFederationPolicy().get(i).getImplementingClassName().equalsIgnoreCase("org.miloss.fgsms.uddipub.UddiPublisher")) {
210                 return p.getFederationPolicyCollection().getFederationPolicy().get(i);
211             }
212         }
213         return null;
214     }
215 
216     private void Init(boolean pooled) {
217         if (System.currentTimeMillis() - 5 * 60 * 1000 > lastRefresh) {
218             isPooled = pooled;
219             try {
220                 String t = "";
221                 KeyNameValueEnc p = DBSettingsLoader.GetPropertiesFromDB(isPooled, "UddiPublisher", "Username");
222                 if (p != null && p.getKeyNameValue() != null) {
223                     username = p.getKeyNameValue().getPropertyValue();
224                 }
225                 p = DBSettingsLoader.GetPropertiesFromDB(isPooled, "UddiPublisher", "password");
226                 if (p != null && p.getKeyNameValue() != null) {
227                     password = p.getKeyNameValue().getPropertyValue();
228                 }
229                 p = DBSettingsLoader.GetPropertiesFromDB(isPooled, "UddiPublisher", "ClientCertRequired");
230                 if (p != null && p.getKeyNameValue() != null) {
231                     try {
232                         ClientCertRequired = Boolean.parseBoolean(p.getKeyNameValue().getPropertyValue());
233                     } catch (Exception ex) {
234                         ClientCertRequired = false;
235                     }
236                 }
237                 p = DBSettingsLoader.GetPropertiesFromDB(isPooled, "UddiPublisher", "AuthMode");
238                 if (p != null && p.getKeyNameValue() != null) {
239                     t = p.getKeyNameValue().getPropertyValue();
240                     try {
241                         uddiauth = AuthMode.valueOf(t);
242                     } catch (Exception ex) {
243                         log.log(Level.WARN, "Unable to parse the value of UddiPublisher.AuthMode!", ex);
244                         throw ex;
245                     }
246                 }
247 
248                 inquiryurl = "";
249                 publishurl = "";
250                 securityurl = "";
251 
252                 p = DBSettingsLoader.GetPropertiesFromDB(isPooled, "UddiPublisher", "InquiryURL");
253                 if (p != null && p.getKeyNameValue() != null) {
254                     inquiryurl = p.getKeyNameValue().getPropertyValue();
255                 }
256                 p = DBSettingsLoader.GetPropertiesFromDB(isPooled, "UddiPublisher", "PublishURL");
257                 if (p != null && p.getKeyNameValue() != null) {
258                     publishurl = p.getKeyNameValue().getPropertyValue();
259                 }
260                 p = DBSettingsLoader.GetPropertiesFromDB(isPooled, "UddiPublisher", "SecurityURL");
261                 if (p != null && p.getKeyNameValue() != null) {
262                     securityurl = p.getKeyNameValue().getPropertyValue();
263                 }
264 
265                 String jbossconfigpath = "";
266                 if (!Utility.stringIsNullOrEmpty(System.getProperty("jboss.server.config.url"))) {
267                     jbossconfigpath = System.getProperty("jboss.server.config.url");
268                 }
269 
270                 String truststore = null;
271                 String truststorepass = null;
272                 String keystore = null;
273                 String keystorepass = null;
274                 p = DBSettingsLoader.GetPropertiesFromDB(isPooled, "defaults", "keystore");
275                 if (p != null && p.getKeyNameValue() != null) {
276                     keystore = jbossconfigpath + p.getKeyNameValue().getPropertyValue();
277                 }
278                 p = DBSettingsLoader.GetPropertiesFromDB(isPooled, "defaults", "keystorepass");
279                 if (p != null && p.getKeyNameValue() != null) {
280                     keystorepass = p.getKeyNameValue().getPropertyValue();
281                 }
282                 p = DBSettingsLoader.GetPropertiesFromDB(isPooled, "defaults", "truststore");
283                 if (p != null && p.getKeyNameValue() != null) {
284                     truststore = jbossconfigpath + p.getKeyNameValue().getPropertyValue();
285                 }
286                 p = DBSettingsLoader.GetPropertiesFromDB(isPooled, "defaults", "truststorepass");
287                 if (p != null && p.getKeyNameValue() != null) {
288                     truststorepass = p.getKeyNameValue().getPropertyValue();
289                 }
290                 p = DBSettingsLoader.GetPropertiesFromDB(isPooled, "UddiPublisher", "keystore");
291                 if (p != null && p.getKeyNameValue() != null) {
292                     keystore = jbossconfigpath + p.getKeyNameValue().getPropertyValue();
293                 }
294                 p = DBSettingsLoader.GetPropertiesFromDB(isPooled, "UddiPublisher", "keystorepass");
295                 if (p != null && p.getKeyNameValue() != null) {
296                     keystorepass = p.getKeyNameValue().getPropertyValue();
297                 }
298 
299                 //get SSL trust store
300                 boolean ignoresslerrors = false;
301                 p = DBSettingsLoader.GetPropertiesFromDB(isPooled, "UddiPublisher", "IgnoreSSLErrors");
302                 if (p != null && p.getKeyNameValue() != null) {
303                     try {
304                         ignoresslerrors = Boolean.parseBoolean(p.getKeyNameValue().getPropertyValue());
305                     } catch (Exception ex) {
306                         ignoresslerrors = false;
307                     }
308                 }
309                 if (ignoresslerrors) {
310                     HostnameVerifier ignoreHostName = new HostnameVerifier() {
311                         public boolean verify(String string, SSLSession ssls) {
312                             return true;
313                         }
314                     };
315                     TrustManager[] trustAllCerts = new TrustManager[]{
316                         new X509TrustManager() {
317                             public java.security.cert.X509Certificate[] getAcceptedIssuers() {
318                                 return null;
319                             }
320 
321                             public void checkClientTrusted(
322                                     java.security.cert.X509Certificate[] certs, String authType) {
323                             }
324 
325                             public void checkServerTrusted(
326                                     java.security.cert.X509Certificate[] certs, String authType) {
327                             }
328                         }
329                     };
330 
331                     SSLContext sc = SSLContext.getInstance("SSL");
332                     sc.init(null, trustAllCerts, new java.security.SecureRandom());
333                     HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
334                     HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostName);
335                     SSLContext.setDefault(sc);
336                 }
337 
338                 if (Utility.stringIsNullOrEmpty(inquiryurl)) {
339                     State = false;
340                     log.log(Level.FATAL, "inquiry url is not set, see the how to guide for configuration Uddi Publication.");
341                     return;
342                 }
343                 if (Utility.stringIsNullOrEmpty(publishurl)) {
344                     State = false;
345                     log.log(Level.FATAL, "publishurl url is not set, see the how to guide for configuration Uddi Publication.");
346                     return;
347                 }
348                 if (Utility.stringIsNullOrEmpty(securityurl) && uddiauth == AuthMode.Uddi) {
349                     State = false;
350                     log.log(Level.FATAL, "auth mode is UDDI and the security url is not set, see the how to guide for configuration Uddi Publication.");
351                     return;
352                 }
353 
354 //inquiry endpoint
355                 uddi = new UDDIService();
356                 inquiry = uddi.getUDDIInquiryPort();
357                 BindingProvider bpPCS = (BindingProvider) inquiry;
358                 Map<String, Object> contextPCS = bpPCS.getRequestContext();
359                 contextPCS.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, inquiryurl.trim());
360 
361                 if (uddiauth == AuthMode.Http && !Utility.stringIsNullOrEmpty(password) && !Utility.stringIsNullOrEmpty(username)) {
362                     contextPCS.put(BindingProvider.PASSWORD_PROPERTY, Utility.DE(password));
363                     contextPCS.put(BindingProvider.USERNAME_PROPERTY, username);
364                 }
365                 if (inquiryurl.toLowerCase().startsWith("https")) {
366                     if (!Utility.stringIsNullOrEmpty(truststore) && !Utility.stringIsNullOrEmpty(truststorepass)) {
367                         log.log(Level.INFO, "Inquiry Endpoint: Loading truststore from " + truststore);
368                         contextPCS.put("javax.net.ssl.trustStorePassword", Utility.DE(truststorepass));
369                         contextPCS.put("javax.net.ssl.trustStore", truststore);
370                     }
371                 }
372                 if (ClientCertRequired && Utility.stringIsNullOrEmpty(keystore) && Utility.stringIsNullOrEmpty(keystorepass)) {
373                     contextPCS.put("javax.net.ssl.keyStorePassword", Utility.DE(keystorepass));
374                     contextPCS.put("javax.net.ssl.keyStore", keystore);
375                     log.log(Level.INFO, "Inquiry Endpoint: Loading keystore from " + keystore);
376                 }
377 
378 //publish endpoint
379                 publication = uddi.getUDDIPublicationPort();
380                 bpPCS = (BindingProvider) publication;
381 
382                 contextPCS = bpPCS.getRequestContext();
383 
384                 contextPCS.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, publishurl.trim());
385                 if (uddiauth == AuthMode.Http && !Utility.stringIsNullOrEmpty(password) && !Utility.stringIsNullOrEmpty(username)) {
386                     contextPCS.put(BindingProvider.PASSWORD_PROPERTY, Utility.DE(password));
387                     contextPCS.put(BindingProvider.USERNAME_PROPERTY, username);
388                 }
389                 if (publishurl.toLowerCase().startsWith("https")) {
390                     if (!Utility.stringIsNullOrEmpty(truststore) && !Utility.stringIsNullOrEmpty(truststorepass)) {
391                         contextPCS.put("javax.net.ssl.trustStorePassword", Utility.DE(truststorepass));
392                         contextPCS.put("javax.net.ssl.trustStore", truststore);
393                         log.log(Level.INFO, "Publish Endpoint: Loading truststore from " + truststore);
394                     }
395                 }
396                 if (ClientCertRequired && Utility.stringIsNullOrEmpty(keystore) && Utility.stringIsNullOrEmpty(keystorepass)) {
397                     contextPCS.put("javax.net.ssl.keyStorePassword", Utility.DE(keystorepass));
398                     contextPCS.put("javax.net.ssl.keyStore", keystore);
399                     log.log(Level.INFO, "Publish Endpoint: Loading keystore from " + truststore);
400                 }
401 
402                 if (uddiauth == AuthMode.Uddi) {
403                     //sercurity endpoint
404                     security = uddi.getUDDISecurityPort();
405                     bpPCS = (BindingProvider) security;
406                     contextPCS = bpPCS.getRequestContext();
407                     contextPCS.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, securityurl.trim());
408                     if (securityurl.toLowerCase().startsWith("https")) {
409                         if (!Utility.stringIsNullOrEmpty(truststore) && !Utility.stringIsNullOrEmpty(truststorepass)) {
410                             contextPCS.put("javax.net.ssl.trustStorePassword", Utility.DE(truststorepass));
411                             contextPCS.put("javax.net.ssl.trustStore", truststore);
412                             log.log(Level.INFO, "Security Endpoint: Loading truststore from " + truststore);
413                         }
414                     }
415                     if (ClientCertRequired && Utility.stringIsNullOrEmpty(keystore) && Utility.stringIsNullOrEmpty(keystorepass)) {
416                         contextPCS.put("javax.net.ssl.keyStorePassword", Utility.DE(keystorepass));
417                         contextPCS.put("javax.net.ssl.keyStore", keystore);
418                         log.log(Level.INFO, "Security Endpoint: Loading truststore from " + keystore);
419                     }
420                 }
421 
422             } catch (Exception ex) {
423                 State = false;
424                 log.warn("check for configuration file, uddi.properties", ex);
425                 return;
426             }
427             State = true;
428         }
429     }
430 
431     /**
432      * Alternate URLs, basically multiple hostnames, FQDN, host file entries,
433      * etc can map to the same service. Sometimes a particular url is firewalled
434      * or only listens on a specific hostname. By default bueller will first
435      * attempt a connection using the modified url, i.e. the URL displayed in
436      * fgsms which usually uses the hostname of the machine hosting the service
437      * If another url was observed by an agent at some point in time, then this
438      * will fetch all other urls for
439      *
440      * @param url
441      * @param perf
442      * @return
443      */
444     protected static Set<String> GetAlternateUrls(String url, java.sql.Connection perf) throws MalformedURLException {
445         Set<String> alts = new HashSet<String>();
446         PreparedStatement com = null;
447         ResultSet rs = null;
448         try {
449 
450             //dec 10-2011 PreparedStatement com = perf.prepareStatement("select  originalurl from rawdata where uri=? group by originalurl;");
451             com = perf.prepareStatement("select  alturi from alternateurls where uri=?;");
452             com.setString(1, url);
453             rs = com.executeQuery();
454             while (rs.next()) {
455                 String t = rs.getString(1);
456                 if (!Utility.stringIsNullOrEmpty(t)) {
457                     t = t.trim();
458                     if (!Utility.stringIsNullOrEmpty(t)) {
459                         if (!t.equals(url)) {
460                             if (!url.equals(t)) {
461                                 try {
462                                     URL turl = new URL(t);
463                                     if (turl.getHost().toLowerCase().equalsIgnoreCase("localhost")) {
464                                         alts.add(t);
465                                     }
466                                 } catch (Exception ex) {
467                                     log.log(Level.DEBUG, null, ex);
468                                 }
469                             }
470                         }
471                     }
472                 }
473                 //TODO future optimization but not required, this might be a good spot to filter out localhost/127.0.0.1 records, but only if this machine is different that the machine hosting the service
474             }
475         } catch (Exception ex) {
476             log.log(Level.DEBUG, null, ex);
477         } finally {
478             DBUtils.safeClose(rs);
479             DBUtils.safeClose(com);
480 
481         }
482         return alts;
483 
484     }
485 
486     /**
487      * provides a wrapper for getting alternate urls without passing a db
488      * connection
489      *
490      * @param url
491      * @param pooled
492      * @return
493      */
494     static Set<String> GetAlternateUrls(String url, boolean pooled) {
495 
496         java.sql.Connection perf = null;
497         if (pooled) {
498             perf = Utility.getPerformanceDBConnection();
499         } else {
500             perf = Utility.getPerformanceDB_NONPOOLED_Connection();
501         }
502         Set<String> ret = Collections.EMPTY_SET;
503         try {
504             ret = GetAlternateUrls(url, perf);
505         } catch (Exception ex) {
506             log.log(Level.WARN, null, ex);
507         } finally {
508             DBUtils.safeClose(perf);
509         }
510         return ret;
511     }
512 }