Coverage Report - org.kuali.rice.ksb.messaging.config.KSBConfigurer
 
Classes in this File Line Coverage Branch Coverage Complexity
KSBConfigurer
0%
0/164
0%
0/50
1.571
KSBConfigurer$1
0%
0/11
0%
0/4
1.571
 
 1  
 /*
 2  
  * Copyright 2005-2007 The Kuali Foundation
 3  
  *
 4  
  *
 5  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  * http://www.opensource.org/licenses/ecl2.php
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.kuali.rice.ksb.messaging.config;
 18  
 
 19  
 import java.util.ArrayList;
 20  
 import java.util.LinkedList;
 21  
 import java.util.List;
 22  
 
 23  
 import javax.sql.DataSource;
 24  
 
 25  
 import org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory;
 26  
 import org.apache.commons.httpclient.protocol.Protocol;
 27  
 import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
 28  
 import org.apache.commons.lang.StringUtils;
 29  
 import org.kuali.rice.core.config.Config;
 30  
 import org.kuali.rice.core.config.ConfigContext;
 31  
 import org.kuali.rice.core.config.ConfigurationException;
 32  
 import org.kuali.rice.core.config.ModuleConfigurer;
 33  
 import org.kuali.rice.core.config.event.AfterStartEvent;
 34  
 import org.kuali.rice.core.config.event.RiceConfigEvent;
 35  
 import org.kuali.rice.core.lifecycle.Lifecycle;
 36  
 import org.kuali.rice.core.lifecycle.ServiceDelegatingLifecycle;
 37  
 import org.kuali.rice.core.resourceloader.ResourceLoader;
 38  
 import org.kuali.rice.core.resourceloader.SpringLoader;
 39  
 import org.kuali.rice.core.util.ClassLoaderUtils;
 40  
 import org.kuali.rice.core.util.OrmUtils;
 41  
 import org.kuali.rice.core.util.RiceConstants;
 42  
 import org.kuali.rice.ksb.messaging.AlternateEndpoint;
 43  
 import org.kuali.rice.ksb.messaging.AlternateEndpointLocation;
 44  
 import org.kuali.rice.ksb.messaging.ServiceDefinition;
 45  
 import org.kuali.rice.ksb.messaging.resourceloader.KSBResourceLoaderFactory;
 46  
 import org.kuali.rice.ksb.messaging.serviceconnectors.HttpInvokerConnector;
 47  
 import org.kuali.rice.ksb.service.KSBServiceLocator;
 48  
 import org.kuali.rice.ksb.util.KSBConstants;
 49  
 import org.quartz.Scheduler;
 50  
 import org.springframework.transaction.PlatformTransactionManager;
 51  
 
 52  
 
 53  
 /**
 54  
  * Used to configure the embedded workflow. This could be used to configure
 55  
  * embedded workflow programmatically but mostly this is a base class by which
 56  
  * to hang specific configuration behavior off of through subclassing
 57  
  * 
 58  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 59  
  * 
 60  
  */
 61  0
 public class KSBConfigurer extends ModuleConfigurer {
 62  
 
 63  0
         private List<ServiceDefinition> services = new ArrayList<ServiceDefinition>();
 64  
         
 65  0
     private List<AlternateEndpointLocation> alternateEndpointLocations = new ArrayList<AlternateEndpointLocation>();
 66  
 
 67  0
         private List<AlternateEndpoint> alternateEndpoints = new ArrayList<AlternateEndpoint>();
 68  
 
 69  
         private String serviceServletUrl;
 70  
 
 71  
         private String keystoreAlias;
 72  
 
 73  
         private String keystorePassword;
 74  
 
 75  
         private String keystoreFile;
 76  
 
 77  
         private String webservicesUrl;
 78  
 
 79  
         private String webserviceRetry;
 80  
 
 81  
         private DataSource registryDataSource;
 82  
 
 83  
         private DataSource messageDataSource;
 84  
         
 85  
         private DataSource nonTransactionalMessageDataSource;
 86  
 
 87  
         private String registryDataSourceJndiName;
 88  
 
 89  
     private String messageDataSourceJndiName;
 90  
 
 91  
     private String nonTransactionalMessageDataSourceJndiName;
 92  
 
 93  
         private Scheduler exceptionMessagingScheduler;
 94  
 
 95  
         private PlatformTransactionManager platformTransactionManager;
 96  
 
 97  0
         private boolean isStarted = false;
 98  
 
 99  
         public KSBConfigurer() {
 100  0
         super();
 101  0
         setModuleName( "KSB" );
 102  0
         setHasWebInterface(true);
 103  0
         VALID_RUN_MODES.remove(EMBEDDED_RUN_MODE);
 104  0
         VALID_RUN_MODES.remove( REMOTE_RUN_MODE );
 105  0
         VALID_RUN_MODES.remove( THIN_RUN_MODE );
 106  0
     }
 107  
         
 108  
         public Config loadConfig(Config parentConfig) throws Exception {
 109  0
                 Config currentConfig = super.loadConfig(parentConfig);
 110  0
                 configureDataSource(currentConfig);
 111  0
                 configureBus(currentConfig);
 112  0
                 configureKeystore(currentConfig);
 113  0
                 configureScheduler(currentConfig);
 114  0
                 configurePlatformTransactionManager(currentConfig);
 115  0
                 if (getServiceServletUrl() != null) {
 116  0
                         currentConfig.putProperty("http.service.url", getServiceServletUrl());
 117  
                 }
 118  0
                 configureAlternateEndpoints(currentConfig);
 119  0
                 return currentConfig;
 120  
         }
 121  
 
 122  
         @Override
 123  
         public String getSpringFileLocations(){
 124  0
             String files = "classpath:org/kuali/rice/ksb/config/KSBSpringBeans.xml" + SpringLoader.SPRING_SEPARATOR_CHARACTER;
 125  
         
 126  0
         if (OrmUtils.isJpaEnabled("rice.ksb")) {
 127  0
             files += "classpath:org/kuali/rice/ksb/config/KSBJPASpringBeans.xml";
 128  
         }
 129  
         else {
 130  0
             files += "classpath:org/kuali/rice/ksb/config/KSBOJBSpringBeans.xml";
 131  
         }
 132  
         
 133  0
         if (Boolean.valueOf(ConfigContext.getCurrentContextConfig().getProperty(KSBConstants.LOAD_KNS_MODULE_CONFIGURATION))) {
 134  0
                 files += SpringLoader.SPRING_SEPARATOR_CHARACTER + "classpath:org/kuali/rice/ksb/config/KSBModuleConfigurationSpringBeans.xml";
 135  
         }
 136  
         
 137  0
         return files;
 138  
         }
 139  
         
 140  
         /**
 141  
          * Returns true - KSB UI should always be included.
 142  
          * 
 143  
          * @see org.kuali.rice.core.config.ModuleConfigurer#shouldRenderWebInterface()
 144  
          */
 145  
         @Override
 146  
         public boolean shouldRenderWebInterface() {
 147  0
                 return true;
 148  
         }
 149  
         
 150  
         @Override
 151  
         public ResourceLoader getResourceLoaderToRegister() throws Exception{
 152  0
                 ResourceLoader ksbRemoteResourceLoader = KSBResourceLoaderFactory.createRootKSBRemoteResourceLoader();
 153  0
                 ksbRemoteResourceLoader.start();
 154  0
                 return ksbRemoteResourceLoader;
 155  
         }
 156  
         
 157  
         @Override
 158  
         protected List<Lifecycle> loadLifecycles() throws Exception {
 159  0
                 List<Lifecycle> lifecycles = new LinkedList<Lifecycle>();
 160  
 
 161  
                 // this validation of our service list needs to happen after we've
 162  
                 // loaded our configs so it's a lifecycle
 163  0
                 lifecycles.add(new Lifecycle() {
 164  0
                         boolean started = false;
 165  
 
 166  
                         public boolean isStarted() {
 167  0
                                 return this.started;
 168  
                         }
 169  
 
 170  
                         public void start() throws Exception {
 171  
                                 // first check if we want to allow self-signed certificates for SSL communication
 172  0
                                 if (new Boolean(ConfigContext.getCurrentContextConfig().getProperty(KSBConstants.KSB_ALLOW_SELF_SIGNED_SSL))) {
 173  0
                                     Protocol.registerProtocol("https", new Protocol("https",
 174  
                                             (ProtocolSocketFactory) new EasySSLProtocolSocketFactory(), 443));
 175  
                                 }
 176  
         
 177  0
                                 for (final ServiceDefinition serviceDef : KSBConfigurer.this.services) {
 178  0
                                         serviceDef.validate();
 179  
                                 }
 180  0
                                 this.started = true;
 181  0
                         }
 182  
 
 183  
                         public void stop() throws Exception {
 184  0
                                 this.started = false;
 185  0
                         }
 186  
                 });
 187  0
                 lifecycles.add(new ServiceDelegatingLifecycle(KSBServiceLocator.THREAD_POOL_SERVICE));
 188  0
                 lifecycles.add(new ServiceDelegatingLifecycle(KSBServiceLocator.SCHEDULED_THREAD_POOL_SERVICE));
 189  0
                 lifecycles.add(new ServiceDelegatingLifecycle(KSBServiceLocator.REPEAT_TOPIC_INVOKING_QUEUE));
 190  0
                 lifecycles.add(new ServiceDelegatingLifecycle(KSBServiceLocator.OBJECT_REMOTER));
 191  0
                 lifecycles.add(new ServiceDelegatingLifecycle(KSBServiceLocator.BUS_ADMIN_SERVICE));
 192  0
                 lifecycles.add(new ServiceDelegatingLifecycle(KSBServiceLocator.REMOTED_SERVICE_REGISTRY));
 193  0
                 return lifecycles;
 194  
         }
 195  
         
 196  
         
 197  
 
 198  
         /**
 199  
      * Used to refresh the service registry after the Application Context is initialized.  This way any services that were exported on startup
 200  
      * will be available in the service registry once startup is complete.
 201  
      */
 202  
     @Override
 203  
     public void onEvent(RiceConfigEvent event) throws Exception {
 204  0
         if (event instanceof AfterStartEvent) {
 205  0
             LOG.info("Refreshing Service Registry to export services to the bus.");
 206  0
             KSBServiceLocator.getServiceDeployer().refresh();
 207  
         }
 208  0
     }
 209  
 
 210  
     protected String getServiceNamespace(Config config) {
 211  0
                 if (StringUtils.isBlank(config.getServiceNamespace())) {
 212  0
                         throw new ConfigurationException("The 'service.namespace' property was not properly configured.");
 213  
                 }
 214  0
                 return config.getServiceNamespace();
 215  
         }
 216  
 
 217  
         @SuppressWarnings("unchecked")
 218  
         protected void configureBus(Config config) throws Exception {
 219  0
                 LOG.debug("Configuring services for Service Namespace " + ConfigContext.getCurrentContextConfig().getServiceNamespace() + " using config for classloader " + ClassLoaderUtils.getDefaultClassLoader());
 220  0
                 configureServiceList(config, Config.BUS_DEPLOYED_SERVICES, getServices());
 221  0
         }
 222  
 
 223  
         @SuppressWarnings("unchecked")
 224  
         protected void configureServiceList(Config config, String key, List services) throws Exception {
 225  0
                 LOG.debug("Configuring services for Service Namespace " + ConfigContext.getCurrentContextConfig().getServiceNamespace() + " using config for classloader " + ClassLoaderUtils.getDefaultClassLoader());
 226  0
                 List<ServiceDefinition> serviceDefinitions = (List<ServiceDefinition>) config.getObject(key);
 227  0
                 if (serviceDefinitions == null) {
 228  0
                         config.putObject(key, services);
 229  0
                 } else if (services != null) {
 230  0
                         LOG.debug("Services already exist.  Adding additional services");
 231  0
                         serviceDefinitions.addAll(services);
 232  
                 }
 233  
 
 234  
                 // if it's empty, then we want to be able to inherit it from the parent
 235  
                 // configuration
 236  0
                 if (!StringUtils.isEmpty(this.serviceServletUrl)) {
 237  0
                         config.putObject(Config.SERVICE_SERVLET_URL, this.serviceServletUrl);
 238  0
                         config.putProperty(Config.SERVICE_SERVLET_URL, this.serviceServletUrl);
 239  
                 }
 240  0
         }
 241  
 
 242  
         protected void configureScheduler(Config config) {
 243  0
                 if (this.getExceptionMessagingScheduler() != null) {
 244  0
                         LOG.info("Configuring injected exception messaging Scheduler");
 245  0
                         config.putObject(KSBConstants.INJECTED_EXCEPTION_MESSAGE_SCHEDULER_KEY, this.getExceptionMessagingScheduler());
 246  
                 }
 247  0
         }
 248  
 
 249  
         protected void configureKeystore(Config config) {
 250  0
                 if (!StringUtils.isEmpty(this.keystoreAlias)) {
 251  0
                         config.putProperty(Config.KEYSTORE_ALIAS, this.keystoreAlias);
 252  
                 }
 253  0
                 if (!StringUtils.isEmpty(this.keystorePassword)) {
 254  0
                         config.putProperty(Config.KEYSTORE_PASSWORD, this.keystorePassword);
 255  
                 }
 256  0
                 if (!StringUtils.isEmpty(this.keystoreFile)) {
 257  0
                         config.putProperty(Config.KEYSTORE_FILE, this.keystoreFile);
 258  
                 }
 259  0
         }
 260  
 
 261  
         protected void configureDataSource(Config config) {
 262  0
         if (getMessageDataSource() != null && getRegistryDataSource() == null) {
 263  0
             throw new ConfigurationException("A message data source was defined but a registry data source was not defined.  Both must be specified.");
 264  
         }
 265  0
         if (getMessageDataSource() == null && getRegistryDataSource() != null) {
 266  0
             throw new ConfigurationException("A registry data source was defined but a message data source was not defined.  Both must be specified.");
 267  
         }
 268  
 
 269  0
         if (getMessageDataSource() != null) {
 270  0
             config.putObject(KSBConstants.KSB_MESSAGE_DATASOURCE, getMessageDataSource());
 271  0
         } else if (!StringUtils.isBlank(getMessageDataSourceJndiName())) {
 272  0
             config.putProperty(KSBConstants.KSB_MESSAGE_DATASOURCE_JNDI, getMessageDataSourceJndiName());
 273  
         }
 274  0
         if (getNonTransactionalMessageDataSource() != null) {
 275  0
             config.putObject(KSBConstants.KSB_MESSAGE_NON_TRANSACTIONAL_DATASOURCE, getNonTransactionalMessageDataSource());
 276  0
         } else if (!StringUtils.isBlank(getMessageDataSourceJndiName())) {
 277  0
             config.putProperty(KSBConstants.KSB_MESSAGE_NON_TRANSACTIONAL_DATASOURCE_JNDI, getNonTransactionalMessageDataSourceJndiName());
 278  
         }
 279  0
         if (getRegistryDataSource() != null) {
 280  0
             config.putObject(KSBConstants.KSB_REGISTRY_DATASOURCE, getRegistryDataSource());
 281  0
         } else if (!StringUtils.isBlank(getRegistryDataSourceJndiName())) {
 282  0
             config.putProperty(KSBConstants.KSB_REGISTRY_DATASOURCE_JNDI, getRegistryDataSourceJndiName());
 283  
         }
 284  0
     }
 285  
 
 286  
         protected void configurePlatformTransactionManager(Config config) {
 287  0
                 if (getPlatformTransactionManager() == null) {
 288  0
                         return;
 289  
                 }
 290  0
                 config.putObject(RiceConstants.SPRING_TRANSACTION_MANAGER, getPlatformTransactionManager());
 291  0
         }
 292  
         
 293  
         protected void configureAlternateEndpoints(Config config) {
 294  0
                 config.putObject(KSBConstants.KSB_ALTERNATE_ENDPOINT_LOCATIONS, getAlternateEndpointLocations());
 295  0
                 config.putObject(KSBConstants.KSB_ALTERNATE_ENDPOINTS, getAlternateEndpoints());
 296  0
         }
 297  
         
 298  
         public void stop() throws Exception {
 299  
                 try {
 300  0
                         HttpInvokerConnector.shutdownIdleConnectionTimeout();
 301  0
                 } catch (Exception e) {
 302  0
                         LOG.error("Failed to shutdown idle connection timeout evictor thread.", e);
 303  0
                 }
 304  0
             super.stop();
 305  0
             cleanUpConfiguration();
 306  0
         }
 307  
         
 308  
         /**
 309  
      * Because our configuration is global, shutting down Rice does not get rid of objects stored there.  For that reason
 310  
      * we need to manually clean these up.  This is most important in the case of the service bus because the configuration
 311  
      * is used to store services to be exported.  If we don't clean this up then a shutdown/startup within the same
 312  
      * class loading context causes the service list to be doubled and results in "multiple endpoint" error messages.
 313  
      *
 314  
      */
 315  
     protected void cleanUpConfiguration() {
 316  0
         ConfigContext.getCurrentContextConfig().removeObject(Config.BUS_DEPLOYED_SERVICES);
 317  0
         ConfigContext.getCurrentContextConfig().removeObject(KSBConstants.KSB_ALTERNATE_ENDPOINTS);
 318  0
     }
 319  
 
 320  
         public boolean isStarted() {
 321  0
                 return this.isStarted;
 322  
         }
 323  
 
 324  
         protected void setStarted(boolean isStarted) {
 325  0
                 this.isStarted = isStarted;
 326  0
         }
 327  
 
 328  
         public List<ServiceDefinition> getServices() {
 329  0
                 return this.services;
 330  
         }
 331  
 
 332  
         public void setServices(List<ServiceDefinition> javaServices) {
 333  0
                 this.services = javaServices;
 334  0
         }
 335  
 
 336  
         public String getKeystoreAlias() {
 337  0
                 return this.keystoreAlias;
 338  
         }
 339  
 
 340  
         public void setKeystoreAlias(String keystoreAlias) {
 341  0
                 this.keystoreAlias = keystoreAlias;
 342  0
         }
 343  
 
 344  
         public String getKeystoreFile() {
 345  0
                 return this.keystoreFile;
 346  
         }
 347  
 
 348  
         public void setKeystoreFile(String keystoreFile) {
 349  0
                 this.keystoreFile = keystoreFile;
 350  0
         }
 351  
 
 352  
         public String getKeystorePassword() {
 353  0
                 return this.keystorePassword;
 354  
         }
 355  
 
 356  
         public void setKeystorePassword(String keystorePassword) {
 357  0
                 this.keystorePassword = keystorePassword;
 358  0
         }
 359  
 
 360  
         public String getWebserviceRetry() {
 361  0
                 return this.webserviceRetry;
 362  
         }
 363  
 
 364  
         public void setWebserviceRetry(String webserviceRetry) {
 365  0
                 this.webserviceRetry = webserviceRetry;
 366  0
         }
 367  
 
 368  
         public String getWebservicesUrl() {
 369  0
                 return this.webservicesUrl;
 370  
         }
 371  
 
 372  
         public void setWebservicesUrl(String webservicesUrl) {
 373  0
                 this.webservicesUrl = webservicesUrl;
 374  0
         }
 375  
 
 376  
         public String getServiceServletUrl() {
 377  0
                 return this.serviceServletUrl;
 378  
         }
 379  
 
 380  
         public void setServiceServletUrl(String serviceServletUrl) {
 381  0
                 if (!StringUtils.isEmpty(serviceServletUrl) && !serviceServletUrl.endsWith("/")) {
 382  0
                         serviceServletUrl += "/";
 383  
                 }
 384  0
                 this.serviceServletUrl = serviceServletUrl;
 385  0
         }
 386  
 
 387  
         public DataSource getMessageDataSource() {
 388  0
                 return this.messageDataSource;
 389  
         }
 390  
 
 391  
         public void setMessageDataSource(DataSource messageDataSource) {
 392  0
                 this.messageDataSource = messageDataSource;
 393  0
         }
 394  
 
 395  
     public DataSource getNonTransactionalMessageDataSource() {
 396  0
         return this.nonTransactionalMessageDataSource;
 397  
     }
 398  
 
 399  
     public void setNonTransactionalMessageDataSource(DataSource nonTransactionalMessageDataSource) {
 400  0
         this.nonTransactionalMessageDataSource = nonTransactionalMessageDataSource;
 401  0
     }
 402  
 
 403  
     public String getMessageDataSourceJndiName() {
 404  0
                 return this.messageDataSourceJndiName;
 405  
         }
 406  
 
 407  
         public void setMessageDataSourceJndiName(String messageDataSourceJndiName) {
 408  0
                 this.messageDataSourceJndiName = messageDataSourceJndiName;
 409  0
         }
 410  
 
 411  
     public String getNonTransactionalMessageDataSourceJndiName() {
 412  0
         return this.nonTransactionalMessageDataSourceJndiName;
 413  
     }
 414  
 
 415  
     public void setNonTransactionalMessageDataSourceJndiName(String nonTransactionalMessageDataSourceJndiName) {
 416  0
         this.nonTransactionalMessageDataSourceJndiName = nonTransactionalMessageDataSourceJndiName;
 417  0
     }
 418  
 
 419  
     public DataSource getRegistryDataSource() {
 420  0
                 return this.registryDataSource;
 421  
         }
 422  
 
 423  
         public void setRegistryDataSource(DataSource registryDataSource) {
 424  0
                 this.registryDataSource = registryDataSource;
 425  0
         }
 426  
 
 427  
         public String getRegistryDataSourceJndiName() {
 428  0
                 return this.registryDataSourceJndiName;
 429  
         }
 430  
 
 431  
         public void setRegistryDataSourceJndiName(String registryDataSourceJndiName) {
 432  0
                 this.registryDataSourceJndiName = registryDataSourceJndiName;
 433  0
         }
 434  
 
 435  
         public Scheduler getExceptionMessagingScheduler() {
 436  0
                 return this.exceptionMessagingScheduler;
 437  
         }
 438  
 
 439  
         public void setExceptionMessagingScheduler(Scheduler exceptionMessagingScheduler) {
 440  0
                 this.exceptionMessagingScheduler = exceptionMessagingScheduler;
 441  0
         }
 442  
 
 443  
         public PlatformTransactionManager getPlatformTransactionManager() {
 444  0
                 return platformTransactionManager;
 445  
         }
 446  
 
 447  
         public void setPlatformTransactionManager(PlatformTransactionManager springTransactionManager) {
 448  0
                 this.platformTransactionManager = springTransactionManager;
 449  0
         }
 450  
 
 451  
     public List<AlternateEndpointLocation> getAlternateEndpointLocations() {
 452  0
         return this.alternateEndpointLocations;
 453  
     }
 454  
 
 455  
     public void setAlternateEndpointLocations(List<AlternateEndpointLocation> alternateEndpointLocations) {
 456  0
         this.alternateEndpointLocations = alternateEndpointLocations;
 457  0
         }
 458  
 
 459  
     public List<AlternateEndpoint> getAlternateEndpoints() {
 460  0
         return this.alternateEndpoints;
 461  
     }
 462  
 
 463  
     public void setAlternateEndpoints(List<AlternateEndpoint> alternateEndpoints) {
 464  0
         this.alternateEndpoints = alternateEndpoints;
 465  0
     }
 466  
     
 467  
 }