001: /*
002: * Copyright 2005-2006 The Kuali Foundation.
003: *
004: *
005: * Licensed under the Educational Community License, Version 1.0 (the "License");
006: * you may not use this file except in compliance with the License.
007: * You may obtain a copy of the License at
008: *
009: * http://www.opensource.org/licenses/ecl1.php
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package edu.iu.uis.eden.messaging.config;
018:
019: import java.util.ArrayList;
020: import java.util.LinkedList;
021: import java.util.List;
022:
023: import javax.sql.DataSource;
024:
025: import org.apache.commons.lang.StringUtils;
026: import org.apache.log4j.Logger;
027: import org.kuali.bus.auth.AuthorizationService;
028: import org.kuali.bus.ojb.OjbConfigurer;
029: import org.kuali.bus.services.KSBServiceLocator;
030: import org.kuali.rice.RiceConstants;
031: import org.kuali.rice.config.Config;
032: import org.kuali.rice.config.ConfigurationException;
033: import org.kuali.rice.config.ModuleConfigurer;
034: import org.kuali.rice.core.Core;
035: import org.kuali.rice.lifecycle.Lifecycle;
036: import org.kuali.rice.lifecycle.ServiceDelegatingLifecycle;
037: import org.kuali.rice.resourceloader.GlobalResourceLoader;
038: import org.kuali.rice.util.ClassLoaderUtils;
039: import org.quartz.Scheduler;
040:
041: import edu.iu.uis.eden.cache.RiceCacheAdministrator;
042: import edu.iu.uis.eden.messaging.ServiceDefinition;
043: import edu.iu.uis.eden.messaging.resourceloading.KSBResourceLoaderFactory;
044:
045: /**
046: * Used to configure the embedded workflow. This could be used to configure embedded workflow programmatically
047: * but mostly this is a base class by which to hang specific configuration behavior off of through
048: * subclassing
049: *
050: * @author Kuali Rice Team (kuali-rice@googlegroups.com)
051: *
052: */
053: public class KSBConfigurer extends ModuleConfigurer {
054:
055: private static final Logger LOG = Logger
056: .getLogger(KSBConfigurer.class);
057:
058: private List<ServiceHolder> overrideServices;
059: private List<ServiceDefinition> services = new ArrayList<ServiceDefinition>();
060:
061: private String serviceServletUrl;
062: private String keystoreAlias;
063: private String keystorePassword;
064: private String keystoreFile;
065: private String webservicesUrl;
066: private String webserviceRetry;
067: private RiceCacheAdministrator cache;
068:
069: private DataSource registryDataSource;
070: private DataSource messageDataSource;
071: private String registryDataSourceJndiName;
072: private String messageDataSourceJndiName;
073: private Scheduler exceptionMessagingScheduler;
074:
075: private AuthorizationService authorizationService;
076:
077: private boolean isStarted = false;
078:
079: public Config loadConfig(Config parentConfig) throws Exception {
080: LOG.info("Starting configuration of KEW for message entity "
081: + getMessageEntity(parentConfig));
082: Config currentConfig = Core.getCurrentContextConfig();
083: configureDataSource(currentConfig);
084: configureBus(currentConfig);
085: configureKeystore(currentConfig);
086: configureScheduler(currentConfig);
087: configureAuthorization(currentConfig);
088: if (getServiceServletUrl() != null) {
089: currentConfig.overrideProperty("http.service.url",
090: getServiceServletUrl());
091: }
092: return currentConfig;
093: }
094:
095: @Override
096: protected List<Lifecycle> loadLifecycles() throws Exception {
097: List<Lifecycle> lifecycles = new LinkedList<Lifecycle>();
098:
099: //this validation of our service list needs to happen after we've loaded our configs so it's a lifecycle
100: lifecycles.add(new Lifecycle() {
101: boolean started = false;
102:
103: public boolean isStarted() {
104: return this .started;
105: }
106:
107: public void start() throws Exception {
108: for (final ServiceDefinition serviceDef : KSBConfigurer.this .services) {
109: serviceDef.validate();
110: }
111: this .started = true;
112: }
113:
114: public void stop() throws Exception {
115: this .started = false;
116: }
117: });
118: lifecycles.add(new OjbConfigurer());
119: lifecycles.add(KSBResourceLoaderFactory
120: .createRootKSBResourceLoader());
121: lifecycles.add(new ServicesOverrideLifecycle(this
122: .getOverrideServices()));
123: lifecycles.add(new ServiceDelegatingLifecycle(
124: KSBServiceLocator.THREAD_POOL_SERVICE));
125: lifecycles.add(new ServiceDelegatingLifecycle(
126: KSBServiceLocator.SCHEDULED_THREAD_POOL_SERVICE));
127: lifecycles.add(new ServiceDelegatingLifecycle(
128: KSBServiceLocator.REPEAT_TOPIC_INVOKING_QUEUE));
129: lifecycles.add(new ServiceDelegatingLifecycle(
130: KSBServiceLocator.OBJECT_REMOTER));
131: lifecycles.add(new ServiceDelegatingLifecycle(
132: KSBServiceLocator.BUS_ADMIN_SERVICE));
133: if (getCache() != null) {
134: lifecycles.add(getCache());
135: }
136: lifecycles.add(new ServiceDelegatingLifecycle(
137: KSBServiceLocator.REMOTED_SERVICE_REGISTRY));
138: return lifecycles;
139: }
140:
141: protected String getMessageEntity(Config config) {
142: if (StringUtils.isBlank(config.getMessageEntity())) {
143: throw new ConfigurationException(
144: "The 'message.entity' property was not properly configured.");
145: }
146: return config.getMessageEntity();
147: }
148:
149: @SuppressWarnings("unchecked")
150: protected void configureBus(Config config) throws Exception {
151: LOG.debug("Configuring services for Message Entity "
152: + Core.getCurrentContextConfig().getMessageEntity()
153: + " using config for classloader "
154: + ClassLoaderUtils.getDefaultClassLoader());
155: configureServiceList(config, Config.BUS_DEPLOYED_SERVICES,
156: getServices());
157: }
158:
159: @SuppressWarnings("unchecked")
160: protected void configureServiceList(Config config, String key,
161: List services) throws Exception {
162: LOG.debug("Configuring services for Message Entity "
163: + Core.getCurrentContextConfig().getMessageEntity()
164: + " using config for classloader "
165: + ClassLoaderUtils.getDefaultClassLoader());
166: List<ServiceDefinition> serviceDefinitions = (List<ServiceDefinition>) config
167: .getObject(key);
168: if (serviceDefinitions == null) {
169: config.getObjects().put(key, services);
170: } else if (services != null) {
171: LOG
172: .debug("Services already exist. Adding additional services");
173: serviceDefinitions.addAll(services);
174: }
175:
176: // if it's empty, then we want to be able to inherit it from the parent configuration
177: if (!StringUtils.isEmpty(this .serviceServletUrl)) {
178: config.getObjects().put(Config.SERVICE_SERVLET_URL,
179: this .serviceServletUrl);
180: config.overrideProperty(Config.SERVICE_SERVLET_URL,
181: this .serviceServletUrl);
182: }
183: }
184:
185: protected void configureScheduler(Config config) {
186: if (this .getExceptionMessagingScheduler() != null) {
187: LOG
188: .info("Configuring injected exception messaging Scheduler");
189: config
190: .getObjects()
191: .put(
192: RiceConstants.INJECTED_EXCEPTION_MESSAGE_SCHEDULER_KEY,
193: this .getExceptionMessagingScheduler());
194: }
195: }
196:
197: protected void configureAuthorization(Config config) {
198: if (this .getAuthorizationService() != null) {
199: LOG.info("Configuring injected AuthorizationService: "
200: + getAuthorizationService().getClass().getName());
201: config.getObjects().put(RiceConstants.KSB_AUTH_SERVICE,
202: this .getAuthorizationService());
203: }
204: }
205:
206: protected void configureKeystore(Config config) {
207: if (!StringUtils.isEmpty(this .keystoreAlias)) {
208: config.getProperties().put(Config.KEYSTORE_ALIAS,
209: this .keystoreAlias);
210: }
211: if (!StringUtils.isEmpty(this .keystorePassword)) {
212: config.getProperties().put(Config.KEYSTORE_PASSWORD,
213: this .keystorePassword);
214: }
215: if (!StringUtils.isEmpty(this .keystoreFile)) {
216: config.getProperties().put(Config.KEYSTORE_FILE,
217: this .keystoreFile);
218: }
219: }
220:
221: protected void configureDataSource(Config config) {
222: if (getMessageDataSource() != null
223: && getRegistryDataSource() == null) {
224: throw new ConfigurationException(
225: "A message data source was defined but a registry data source was not defined. Both must be specified.");
226: }
227: if (getMessageDataSource() == null
228: && getRegistryDataSource() != null) {
229: throw new ConfigurationException(
230: "A registry data source was defined but a message data source was not defined. Both must be specified.");
231: }
232:
233: if (getMessageDataSource() != null) {
234: config.getObjects().put(
235: RiceConstants.KSB_MESSAGE_DATASOURCE,
236: getMessageDataSource());
237: } else if (!StringUtils.isBlank(getMessageDataSourceJndiName())) {
238: config.getProperties().put(
239: RiceConstants.KSB_MESSAGE_DATASOURCE_JNDI,
240: getMessageDataSourceJndiName());
241: }
242: if (getRegistryDataSource() != null) {
243: config.getObjects().put(
244: RiceConstants.KSB_REGISTRY_DATASOURCE,
245: getRegistryDataSource());
246: } else if (!StringUtils
247: .isBlank(getRegistryDataSourceJndiName())) {
248: config.getProperties().put(
249: RiceConstants.KSB_REGISTRY_DATASOURCE_JNDI,
250: getRegistryDataSourceJndiName());
251: }
252: }
253:
254: public void stop() throws Exception {
255: try {
256: GlobalResourceLoader.stop();
257: } finally {
258: this .isStarted = false;
259: }
260: }
261:
262: public boolean isStarted() {
263: return this .isStarted;
264: }
265:
266: protected void setStarted(boolean isStarted) {
267: this .isStarted = isStarted;
268: }
269:
270: public List<ServiceDefinition> getServices() {
271: return this .services;
272: }
273:
274: public void setServices(List<ServiceDefinition> javaServices) {
275: this .services = javaServices;
276: }
277:
278: public String getKeystoreAlias() {
279: return this .keystoreAlias;
280: }
281:
282: public void setKeystoreAlias(String keystoreAlias) {
283: this .keystoreAlias = keystoreAlias;
284: }
285:
286: public String getKeystoreFile() {
287: return this .keystoreFile;
288: }
289:
290: public void setKeystoreFile(String keystoreFile) {
291: this .keystoreFile = keystoreFile;
292: }
293:
294: public String getKeystorePassword() {
295: return this .keystorePassword;
296: }
297:
298: public void setKeystorePassword(String keystorePassword) {
299: this .keystorePassword = keystorePassword;
300: }
301:
302: public String getWebserviceRetry() {
303: return this .webserviceRetry;
304: }
305:
306: public void setWebserviceRetry(String webserviceRetry) {
307: this .webserviceRetry = webserviceRetry;
308: }
309:
310: public String getWebservicesUrl() {
311: return this .webservicesUrl;
312: }
313:
314: public void setWebservicesUrl(String webservicesUrl) {
315: this .webservicesUrl = webservicesUrl;
316: }
317:
318: public String getServiceServletUrl() {
319: return this .serviceServletUrl;
320: }
321:
322: public void setServiceServletUrl(String serviceServletUrl) {
323: if (!StringUtils.isEmpty(serviceServletUrl)
324: && !serviceServletUrl.endsWith("/")) {
325: serviceServletUrl += "/";
326: }
327: this .serviceServletUrl = serviceServletUrl;
328: }
329:
330: public DataSource getMessageDataSource() {
331: return this .messageDataSource;
332: }
333:
334: public void setMessageDataSource(DataSource messageDataSource) {
335: this .messageDataSource = messageDataSource;
336: }
337:
338: public String getMessageDataSourceJndiName() {
339: return this .messageDataSourceJndiName;
340: }
341:
342: public void setMessageDataSourceJndiName(
343: String messageDataSourceJndiName) {
344: this .messageDataSourceJndiName = messageDataSourceJndiName;
345: }
346:
347: public DataSource getRegistryDataSource() {
348: return this .registryDataSource;
349: }
350:
351: public void setRegistryDataSource(DataSource registryDataSource) {
352: this .registryDataSource = registryDataSource;
353: }
354:
355: public String getRegistryDataSourceJndiName() {
356: return this .registryDataSourceJndiName;
357: }
358:
359: public void setRegistryDataSourceJndiName(
360: String registryDataSourceJndiName) {
361: this .registryDataSourceJndiName = registryDataSourceJndiName;
362: }
363:
364: public List<ServiceHolder> getOverrideServices() {
365: return this .overrideServices;
366: }
367:
368: public void setOverrideServices(List<ServiceHolder> overrideServices) {
369: this .overrideServices = overrideServices;
370: }
371:
372: public RiceCacheAdministrator getCache() {
373: return this .cache;
374: }
375:
376: public void setCache(RiceCacheAdministrator cache) {
377: this .cache = cache;
378: }
379:
380: public Scheduler getExceptionMessagingScheduler() {
381: return this .exceptionMessagingScheduler;
382: }
383:
384: public void setExceptionMessagingScheduler(
385: Scheduler exceptionMessagingScheduler) {
386: this .exceptionMessagingScheduler = exceptionMessagingScheduler;
387: }
388:
389: public AuthorizationService getAuthorizationService() {
390: return this .authorizationService;
391: }
392:
393: public void setAuthorizationService(
394: AuthorizationService authorizationService) {
395: this.authorizationService = authorizationService;
396: }
397:
398: }
|