/******************************************************************************* * Copyright (c) 2008 Cambridge Semantics Incorporated. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * File: $Source$ * Created by: Matthew Roy ( <a href="mailto:mroy@cambridgesemantics.com">mroy@cambridgesemantics.com </a>) * Created on: Jul 2, 2008 * Revision: $Id$ * * Contributors: * Cambridge Semantics Incorporated - initial API and implementation *******************************************************************************/ package org.openanzo.osgi.configuration; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Dictionary; import java.util.Enumeration; import java.util.Map; import java.util.Properties; import org.openanzo.exceptions.ExceptionConstants; import org.openanzo.exceptions.LogUtils; import org.openanzo.exceptions.Messages; import org.openanzo.osgi.GenericObjectClassDef; import org.openanzo.osgi.IStatusProvider; import org.openanzo.osgi.ISystemConfig; import org.openanzo.osgi.OsgiConfigurationUtils; import org.openanzo.osgi.ServiceLifecycleState; import org.openanzo.osgi.attributes.CombusAttributes; import org.openanzo.osgi.attributes.LDAPAttributes; import org.openanzo.osgi.attributes.ServicesAttributes; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ConfigurationPlugin; import org.osgi.service.cm.ManagedService; import org.osgi.service.metatype.AttributeDefinition; import org.osgi.service.metatype.MetaTypeProvider; import org.osgi.service.metatype.ObjectClassDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Matthew Roy ( <a href="mailto:mroy@cambridgesemantics.com">mroy@cambridgesemantics.com</a>) * */ public class SystemConfigurationConfigPlugin implements ConfigurationPlugin, ManagedService, MetaTypeProvider, ISystemConfig { private static final Logger log = LoggerFactory.getLogger(SystemConfigurationConfigPlugin.class); /** Service PID for SystemConfigurationConfigPlugin */ public static final String SERVICE_PID = "org.openanzo.osgi.SystemConfig"; public final static GenericObjectClassDef ocd = new GenericObjectClassDef(SERVICE_PID, "Anzo OSGI Default System Configuration", "Default configuration properties that other bundles use as defaults when they themselves do not have the property locally configured.", new AttributeDefinition[] { CombusAttributes.Host, CombusAttributes.Port, ServicesAttributes.User, ServicesAttributes.Password }, new AttributeDefinition[] { ServicesAttributes.RequireSSL, CombusAttributes.SslHost, CombusAttributes.SslPort, CombusAttributes.UseSsl, LDAPAttributes.Host, LDAPAttributes.Port, LDAPAttributes.LdapServerUser, LDAPAttributes.LdapServerPassword }); private final Properties systemProperties = new Properties(); private final BundleContext context; private ServiceRegistration credentialsReg = null; private ServiceRegistration systemConfig = null; SystemConfigurationConfigPlugin(BundleContext context) { this.context = context; if (credentialsReg == null) { Properties props = new Properties(); props.put(Constants.SERVICE_PID, SystemConfigurationConfigPlugin.SERVICE_PID); props.put(org.osgi.framework.Constants.SERVICE_DESCRIPTION, "SystemConfiguration Config Plugin"); credentialsReg = context.registerService(new String[] { ManagedService.class.getName(), ConfigurationPlugin.class.getName(), MetaTypeProvider.class.getName() }, this, props); } } @SuppressWarnings("unchecked") // implement unchecked interface public void updated(Dictionary config) throws ConfigurationException { if (config != null) { OsgiConfigurationUtils.validateConfiguration(ocd, config); for (Enumeration keys = config.keys(); keys.hasMoreElements();) { Object key = keys.nextElement(); Object value = config.get(key); systemProperties.put(key, value); } if (systemConfig == null) { systemConfig = context.registerService(new String[] { ISystemConfig.class.getName() }, this, null); Thread statusThread = new Thread("StartupStatus Thread") { @Override public void run() { try { while (true) { Thread.sleep(1000); try { ServiceReference refs[] = context.getAllServiceReferences(IStatusProvider.class.getName(), null); if (refs != null) { boolean allOk = true; for (ServiceReference ref : refs) { IStatusProvider service = (IStatusProvider) context.getService(ref); if (service.getState() != ServiceLifecycleState.NOT_ENABLED && service.getState() != ServiceLifecycleState.STARTED) { allOk = false; } } if (allOk) { if (context.getProperty("org.openanzo.regressiontest") != null) { try { String ah = context.getProperty("org.openanzo.regressiontest"); File file = new File(ah != null ? ah : ".", "status.txt"); FileWriter fw = new FileWriter(file); fw.write("ok"); fw.close(); } catch (IOException ioe) { log.error(LogUtils.LIFECYCLE_MARKER, "Error setting status file", ioe); } } System.out.println("All Currently Registered Services started."); return; } } } catch (InvalidSyntaxException ise) { log.error(LogUtils.LIFECYCLE_MARKER, Messages.formatString(ExceptionConstants.OSGI.INVALID_SERVICE_SYNTAX, ise.getFilter()), ise); } } } catch (InterruptedException ie) { log.error(LogUtils.LIFECYCLE_MARKER, "Status thread interrupted", ie); return; } } }; statusThread.setDaemon(true); statusThread.start(); } } } protected void close() { if (credentialsReg != null) { credentialsReg.unregister(); } if (systemConfig != null) { systemConfig.unregister(); } } @SuppressWarnings("unchecked") public void modifyConfiguration(ServiceReference serviceReference, Dictionary config) { String pid = (String) config.get(Constants.SERVICE_PID); if (pid != null && !pid.equals(SERVICE_PID) && (pid.startsWith("org.openanzo.") || pid.startsWith("com.cambridgesemantics."))) { for (Map.Entry<Object, Object> entry : systemProperties.entrySet()) { if (config.get(entry.getKey()) == null) { config.put(entry.getKey(), entry.getValue()); } } Properties props = (Properties) System.getProperties().clone(); for (Map.Entry<Object, Object> entry : props.entrySet()) { String key = entry.getKey().toString(); if (key.startsWith("org.openanzo.") || key.startsWith("com.cambridgesemantics.") && config.get(key) != null) { config.put(entry.getKey(), entry.getValue()); } } } } public String[] getLocales() { return null; } public ObjectClassDefinition getObjectClassDefinition(String pid, String locale) { return ocd; } }