log4j.logger.org.argeo=DEBUG
log4j.logger.org.argeo.cms.internal.kernel=TRACE
-#log4j.logger.org.apache.jackrabbit.core.RepositoryImpl=DEBUG
-#log4j.logger.argeo.stats=DEBUG
-#log4j.logger.org.eclipse.jetty.server.Server=DEBUG
## Appenders
log4j.appender.console=org.apache.log4j.ConsoleAppender
package org.argeo.node;
public interface NodeDeployment {
- long getAvailableSince();
+ Long getAvailableSince();
}
String getHostname();
boolean isClean();
+
+ Long getAvailableSince();
+
}
import java.io.IOException;
import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.Dictionary;
-import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import org.argeo.node.ArgeoLogger;
import org.argeo.node.NodeConstants;
import org.argeo.node.NodeDeployment;
+import org.argeo.node.NodeInstance;
import org.argeo.node.NodeState;
import org.argeo.util.LangUtils;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.osgi.service.cm.ManagedService;
import org.osgi.service.condpermadmin.ConditionalPermissionAdmin;
import org.osgi.service.log.LogReaderService;
* access to kernel information for the rest of the bundle (and only it)
*/
public class Activator implements BundleActivator {
- // public final static String SYSTEM_KEY_PROPERTY =
- // "argeo.security.systemKey";
private final Log log = LogFactory.getLog(Activator.class);
- // private final static String systemKey;
- // static {
- // System.setProperty(SYSTEM_KEY_PROPERTY, systemKey);
- // }
-
- // private static Kernel kernel;
private static Activator instance;
private BundleContext bc;
private ConditionalPermissionAdmin permissionAdmin;
private LogReaderService logReaderService;
- private ConfigurationAdmin configurationAdmin;
+ // private ConfigurationAdmin configurationAdmin;
private NodeLogger logger;
private CmsState nodeState;
private CmsDeployment nodeDeployment;
+ private CmsInstance nodeInstance;
@Override
public void start(BundleContext bundleContext) throws Exception {
- // try {
- // kernel = new Kernel();
- // kernel.init();
- // } catch (Exception e) {
- // log.error("Cannot boot kernel", e);
- // }
-
instance = this;
this.bc = bundleContext;
this.permissionAdmin = getService(ConditionalPermissionAdmin.class);
this.logReaderService = getService(LogReaderService.class);
- this.configurationAdmin = getService(ConfigurationAdmin.class);
+ // this.configurationAdmin = getService(ConfigurationAdmin.class);
initSecurity();// must be first
initArgeoLogger();
- initNodeState();
+ try {
+ initNode();
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new CmsException("Cannot initialize node", e);
+ }
}
private void initSecurity() {
private void initArgeoLogger() {
logger = new NodeLogger(logReaderService);
-
- // register
bc.registerService(ArgeoLogger.class, logger, null);
}
- private void initNodeState() throws IOException {
- nodeState = new CmsState();
-
- Object cn;
- Configuration nodeConf = configurationAdmin.getConfiguration(NodeConstants.NODE_STATE_PID);
- Dictionary<String, Object> props = nodeConf.getProperties();
- if (props == null) {
- if (log.isDebugEnabled())
- log.debug("Clean node state");
- Dictionary<String, Object> envProps = new Hashtable<>();
- // Use the UUID of the first framework run as state UUID
- cn = bc.getProperty(Constants.FRAMEWORK_UUID);
- envProps.put(NodeConstants.CN, cn);
- nodeConf.update(envProps);
+ private void initNode() throws IOException {
+ // Node state
+ Path stateUuidPath = bc.getDataFile("stateUuid").toPath();
+ String stateUuid;
+ if (Files.exists(stateUuidPath)) {
+ stateUuid = Files.readAllLines(stateUuidPath).get(0);
} else {
- // Check if state is in line with environment
- // Dictionary<String, Object> envProps = new Hashtable<>();
- // for (String key : LangUtils.keys(envProps)) {
- // Object envValue = envProps.get(key);
- // Object storedValue = props.get(key);
- // if (storedValue == null)
- // throw new CmsException("No state value for env " + key + "=" +
- // envValue
- // + ", please clean the OSGi configuration.");
- // if (!storedValue.equals(envValue))
- // throw new CmsException("State value for " + key + "=" +
- // storedValue
- // + " is different from env value =" + envValue + ", please clean
- // the OSGi configuration.");
- // }
- cn = props.get(NodeConstants.CN);
- if (cn == null)
- throw new CmsException("No state UUID available");
+ stateUuid = bc.getProperty(Constants.FRAMEWORK_UUID);
+ Files.write(stateUuidPath, stateUuid.getBytes());
}
-
+ nodeState = new CmsState(stateUuid);
+ // Object cn;
+ // Configuration nodeConf =
+ // configurationAdmin.getConfiguration(NodeConstants.NODE_STATE_PID);
+ // Dictionary<String, Object> props = nodeConf.getProperties();
+ // if (props == null) {
+ // if (log.isDebugEnabled())
+ // log.debug("Clean node state");
+ // Dictionary<String, Object> envProps = new Hashtable<>();
+ // // Use the UUID of the first framework run as state UUID
+ // cn = bc.getProperty(Constants.FRAMEWORK_UUID);
+ // envProps.put(NodeConstants.CN, cn);
+ // nodeConf.update(envProps);
+ // } else {
+ // cn = props.get(NodeConstants.CN);
+ // if (cn == null)
+ // throw new CmsException("No state UUID available");
+ // }
Dictionary<String, Object> regProps = LangUtils.init(Constants.SERVICE_PID, NodeConstants.NODE_STATE_PID);
- regProps.put(NodeConstants.CN, cn);
- bc.registerService(LangUtils.names(NodeState.class, ManagedService.class), nodeState, regProps);
+ regProps.put(NodeConstants.CN, stateUuid);
+ bc.registerService(NodeState.class, nodeState, regProps);
- try {
- nodeDeployment = new CmsDeployment();
- bc.registerService(LangUtils.names(NodeDeployment.class), nodeDeployment, null);
- } catch (RuntimeException e) {
- e.printStackTrace();
- throw e;
- }
+ // Node deployment
+ nodeDeployment = new CmsDeployment();
+ bc.registerService(NodeDeployment.class, nodeDeployment, null);
+
+ // Node instance
+ nodeInstance = new CmsInstance();
+ bc.registerService(NodeInstance.class, nodeInstance, null);
}
@Override
public void stop(BundleContext bundleContext) throws Exception {
+ nodeInstance.shutdown();
+ nodeDeployment.shutdown();
nodeState.shutdown();
instance = null;
this.bc = null;
this.permissionAdmin = null;
this.logReaderService = null;
- this.configurationAdmin = null;
-
- // if (kernel != null) {
- // kernel.destroy();
- // kernel = null;
- // }
-
+ // this.configurationAdmin = null;
}
private <T> T getService(Class<T> clazz) {
import static org.argeo.node.DataModelNamespace.CMS_DATA_MODEL_NAMESPACE;
-import java.io.IOException;
-import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
-import java.io.Writer;
+import java.lang.management.ManagementFactory;
import java.net.URL;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
import javax.jcr.Repository;
import javax.jcr.Session;
-import javax.naming.InvalidNameException;
-import javax.naming.directory.Attributes;
-import javax.naming.directory.BasicAttributes;
-import javax.naming.ldap.LdapName;
-import javax.naming.ldap.Rdn;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.node.NodeConstants;
import org.argeo.node.NodeDeployment;
import org.argeo.node.NodeState;
-import org.argeo.util.naming.AttributesDictionary;
-import org.argeo.util.naming.LdifParser;
-import org.argeo.util.naming.LdifWriter;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleWire;
import org.osgi.framework.wiring.BundleWiring;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.osgi.service.cm.ConfigurationEvent;
-import org.osgi.service.cm.SynchronousConfigurationListener;
+import org.osgi.service.http.HttpService;
+import org.osgi.service.useradmin.UserAdmin;
import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
public class CmsDeployment implements NodeDeployment {
private final Log log = LogFactory.getLog(getClass());
private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
private final DeployConfig deployConfig;
- // private Repository deployedNodeRepository;
private HomeRepository homeRepository;
private Long availableSince;
+ // Readiness
+ private boolean nodeAvailable = false;
+ private boolean userAdminAvailable = false;
+ private boolean httpExpected = false;
+ private boolean httpAvailable = false;
+
public CmsDeployment() {
- // FIXME no guarantee this is already available
- NodeState nodeState = bc.getService(bc.getServiceReference(NodeState.class));
+ ServiceReference<NodeState> nodeStateSr = bc.getServiceReference(NodeState.class);
+ if (nodeStateSr == null)
+ throw new CmsException("No node state available");
+
+ NodeState nodeState = bc.getService(nodeStateSr);
deployConfig = new DeployConfig(nodeState.isClean());
+ httpExpected = deployConfig.getProps(KernelConstants.JETTY_FACTORY_PID, "default") != null;
+
+ initTrackers();
+ }
+
+ private void initTrackers() {
+ new PrepareHttpStc().open();
+ new RepositoryContextStc().open();
+ new ServiceTracker<UserAdmin, UserAdmin>(bc, UserAdmin.class, null) {
+ @Override
+ public UserAdmin addingService(ServiceReference<UserAdmin> reference) {
+ userAdminAvailable = true;
+ checkReadiness();
+ return super.addingService(reference);
+ }
+ }.open();
+ }
+
+ public void shutdown() {
+ deployConfig.save();
+ }
- new ServiceTracker<>(bc, RepositoryContext.class, new RepositoryContextStc()).open();
+ private void checkReadiness() {
+ if (nodeAvailable && userAdminAvailable && (httpExpected ? httpAvailable : true)) {
+ availableSince = System.currentTimeMillis();
+ long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime();
+ log.info("## ARGEO CMS AVAILABLE in " + (jvmUptime / 1000) + "." + (jvmUptime % 1000) + "s ##");
+ long begin = bc.getService(bc.getServiceReference(NodeState.class)).getAvailableSince();
+ long initDuration = System.currentTimeMillis() - begin;
+ if (log.isTraceEnabled())
+ log.trace("Kernel initialization took " + initDuration + "ms");
+ directorsCut(initDuration);
+ }
+ }
+
+ final private void directorsCut(long initDuration) {
+ // final long ms = 128l + (long) (Math.random() * 128d);
+ long ms = initDuration / 100;
+ log.info("Spend " + ms + "ms" + " reflecting on the progress brought to mankind" + " by Free Software...");
+ long beginNano = System.nanoTime();
+ try {
+ Thread.sleep(ms, 0);
+ } catch (InterruptedException e) {
+ // silent
+ }
+ long durationNano = System.nanoTime() - beginNano;
+ final double M = 1000d * 1000d;
+ double sleepAccuracy = ((double) durationNano) / (ms * M);
+ if (log.isDebugEnabled())
+ log.debug("Sleep accuracy: " + String.format("%.2f", 100 - (sleepAccuracy * 100 - 100)) + " %");
}
private void prepareNodeRepository(Repository deployedNodeRepository) {
throw new CmsException("Deployment is already available");
}
- availableSince = System.currentTimeMillis();
-
prepareDataModel(KernelUtils.openAdminSession(deployedNodeRepository));
Hashtable<String, String> regProps = new Hashtable<String, String>();
regProps.put(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS, ArgeoJcrConstants.ALIAS_HOME);
Hashtable<String, Object> properties = new Hashtable<>();
properties.put(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS, name);
+ properties.put(NodeConstants.CN, name);
bc.registerService(Repository.class, adminSession.getRepository(), properties);
if (log.isDebugEnabled())
log.debug("Published data model " + name);
}
- // public void setDeployedNodeRepository(Repository deployedNodeRepository)
- // {
- // this.deployedNodeRepository = deployedNodeRepository;
- // }
-
@Override
- public long getAvailableSince() {
+ public Long getAvailableSince() {
return availableSince;
}
- private class RepositoryContextStc implements ServiceTrackerCustomizer<RepositoryContext, RepositoryContext> {
+ private class RepositoryContextStc extends ServiceTracker<RepositoryContext, RepositoryContext> {
+
+ public RepositoryContextStc() {
+ super(bc, RepositoryContext.class, null);
+ }
@Override
public RepositoryContext addingService(ServiceReference<RepositoryContext> reference) {
Object cn = reference.getProperty(NodeConstants.CN);
if (cn != null && cn.equals(ArgeoJcrConstants.ALIAS_NODE)) {
prepareNodeRepository(nodeRepo.getRepository());
- // nodeDeployment.setDeployedNodeRepository(nodeRepo.getRepository());
- // Dictionary<String, Object> props =
- // LangUtils.init(Constants.SERVICE_PID,
- // NodeConstants.NODE_DEPLOYMENT_PID);
- // props.put(NodeConstants.CN,
- // nodeRepo.getRootNodeId().toString());
- // register
- // bc.registerService(LangUtils.names(NodeDeployment.class,
- // ManagedService.class), nodeDeployment, props);
+ nodeAvailable = true;
+ checkReadiness();
}
-
return nodeRepo;
}
}
+ private class PrepareHttpStc extends ServiceTracker<HttpService, HttpService> {
+ private DataHttp dataHttp;
+ private NodeHttp nodeHttp;
+
+ public PrepareHttpStc() {
+ super(bc, HttpService.class, null);
+ }
+
+ @Override
+ public HttpService addingService(ServiceReference<HttpService> reference) {
+ HttpService httpService = addHttpService(reference);
+ return httpService;
+ }
+
+ @Override
+ public void removedService(ServiceReference<HttpService> reference, HttpService service) {
+ if (dataHttp != null)
+ dataHttp.destroy();
+ dataHttp = null;
+ if (nodeHttp != null)
+ nodeHttp.destroy();
+ nodeHttp = null;
+ }
+
+ private HttpService addHttpService(ServiceReference<HttpService> sr) {
+ HttpService httpService = bc.getService(sr);
+ // TODO find constants
+ Object httpPort = sr.getProperty("http.port");
+ Object httpsPort = sr.getProperty("https.port");
+ dataHttp = new DataHttp(httpService);
+ nodeHttp = new NodeHttp(httpService, bc);
+ log.info(httpPortsMsg(httpPort, httpsPort));
+ httpAvailable = true;
+ checkReadiness();
+ return httpService;
+ }
+
+ private String httpPortsMsg(Object httpPort, Object httpsPort) {
+ return "HTTP " + httpPort + (httpsPort != null ? " - HTTPS " + httpsPort : "");
+ }
+ }
+
}
--- /dev/null
+package org.argeo.cms.internal.kernel;
+
+import javax.jcr.Repository;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.ArgeoJcrConstants;
+import org.argeo.node.NodeConstants;
+import org.argeo.node.NodeInstance;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class CmsInstance implements NodeInstance {
+ private final Log log = LogFactory.getLog(getClass());
+ private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
+
+
+ public CmsInstance() {
+ initTrackers();
+ }
+
+ private void initTrackers() {
+ // node repository
+ new ServiceTracker<Repository, Repository>(bc, Repository.class, null) {
+ @Override
+ public Repository addingService(ServiceReference<Repository> reference) {
+ Object cn = reference.getProperty(NodeConstants.CN);
+ if (cn != null && cn.equals(ArgeoJcrConstants.ALIAS_NODE)) {
+ if (log.isDebugEnabled())
+ log.debug("Node repository is available");
+ }
+ return super.addingService(reference);
+ }
+ }.open();
+ }
+
+ public void shutdown() {
+
+ }
+
+}
import static bitronix.tm.TransactionManagerServices.getTransactionSynchronizationRegistry;
import static java.util.Locale.ENGLISH;
import static org.argeo.cms.internal.auth.LocaleChoice.asLocaleList;
-import static org.argeo.cms.internal.kernel.KernelUtils.getFrameworkProp;
import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
import java.net.InetAddress;
-import java.net.URI;
import java.net.UnknownHostException;
-import java.nio.file.Files;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Dictionary;
-import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
-import java.util.SortedMap;
import java.util.UUID;
import javax.jcr.RepositoryFactory;
-import javax.naming.InvalidNameException;
-import javax.naming.directory.Attributes;
-import javax.naming.ldap.LdapName;
-import javax.naming.ldap.Rdn;
import javax.transaction.TransactionManager;
import javax.transaction.TransactionSynchronizationRegistry;
import javax.transaction.UserTransaction;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.core.RepositoryContext;
-import org.argeo.cms.CmsException;
import org.argeo.cms.maintenance.MaintenanceUi;
-import org.argeo.jcr.ArgeoJcrConstants;
import org.argeo.node.NodeConstants;
-import org.argeo.node.NodeDeployment;
import org.argeo.node.NodeState;
-import org.argeo.node.RepoConf;
import org.argeo.util.LangUtils;
-import org.argeo.util.naming.AttributesDictionary;
-import org.argeo.util.naming.LdifParser;
-import org.eclipse.equinox.http.jetty.JettyConfigurator;
-import org.eclipse.equinox.http.jetty.JettyConstants;
import org.eclipse.rap.rwt.application.ApplicationConfiguration;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.osgi.service.cm.ConfigurationException;
-import org.osgi.service.cm.ManagedService;
import org.osgi.service.cm.ManagedServiceFactory;
-import org.osgi.service.http.HttpService;
-import org.osgi.service.metatype.MetaTypeProvider;
import org.osgi.service.useradmin.UserAdmin;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
import bitronix.tm.BitronixTransactionManager;
import bitronix.tm.BitronixTransactionSynchronizationRegistry;
import bitronix.tm.TransactionManagerServices;
-public class CmsState implements NodeState, ManagedService {
+public class CmsState implements NodeState {
private final Log log = LogFactory.getLog(CmsState.class);
private final BundleContext bc = FrameworkUtil.getBundle(CmsState.class).getBundleContext();
- // avoid dependency to RWT OSGi
- private final static String PROPERTY_CONTEXT_NAME = "contextName";
-
// REFERENCES
- private ConfigurationAdmin configurationAdmin;
+ private Long availableSince;
// i18n
private Locale defaultLocale;
private List<Locale> locales = null;
- // private BitronixTransactionManager transactionManager;
- // private BitronixTransactionSynchronizationRegistry
- // transactionSynchronizationRegistry;
- // private NodeRepositoryFactory repositoryFactory;
- // private NodeUserAdmin userAdmin;
- // private RepositoryServiceFactory repositoryServiceFactory;
- // private RepositoryService repositoryService;
-
- // Deployment
- // private final CmsDeployment nodeDeployment = new CmsDeployment();
-
- private boolean cleanState = false;
- private URI nodeRepoUri = null;
-
private ThreadGroup threadGroup = new ThreadGroup("CMS");
private KernelThread kernelThread;
private List<Runnable> shutdownHooks = new ArrayList<>();
+ private final String stateUuid;
+ private final boolean cleanState;
private String hostname;
- public CmsState() {
+ public CmsState(String stateUuid) {
+ this.stateUuid = stateUuid;
+ String frameworkUuid = KernelUtils.getFrameworkProp(Constants.FRAMEWORK_UUID);
+ this.cleanState = stateUuid.equals(frameworkUuid);
try {
this.hostname = InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
log.error("Cannot set hostname", e);
}
- }
- @Override
- public void updated(Dictionary<String, ?> properties) throws ConfigurationException {
- if (properties == null) {
- // // TODO this should not happen anymore
- // this.cleanState = true;
- // if (log.isTraceEnabled())
- // log.trace("Clean state");
- return;
- }
- String stateUuid = properties.get(NodeConstants.CN).toString();
- String frameworkUuid = KernelUtils.getFrameworkProp(Constants.FRAMEWORK_UUID);
- this.cleanState = stateUuid.equals(frameworkUuid);
+ availableSince = System.currentTimeMillis();
+ if (log.isDebugEnabled())
+ log.debug("## CMS STARTED " + this.stateUuid + (cleanState ? " (clean state) " : " "));
- try {
- if (log.isDebugEnabled())
- log.debug("## CMS STARTED " + stateUuid + (cleanState ? " (clean state) " : " ")
- + LangUtils.toJson(properties, true));
- configurationAdmin = bc.getService(bc.getServiceReference(ConfigurationAdmin.class));
-
- nodeRepoUri = KernelUtils.getOsgiInstanceUri("repos/node");
-
- initI18n();
- initServices();
-// initDeployConfigs();
- // initWebServer();
- // initNodeDeployment();
-
- // kernel thread
- kernelThread = new KernelThread(threadGroup, "Kernel Thread");
- kernelThread.setContextClassLoader(getClass().getClassLoader());
- kernelThread.start();
- } catch (Exception e) {
- throw new CmsException("Cannot get configuration", e);
- }
+ initI18n();
+ initServices();
+
+ // kernel thread
+ kernelThread = new KernelThread(threadGroup, "Kernel Thread");
+ kernelThread.setContextClassLoader(getClass().getClassLoader());
+ kernelThread.start();
}
private void initI18n() {
}
private void initServices() {
- // trackers
- new ServiceTracker<HttpService, HttpService>(bc, HttpService.class, new PrepareHttpStc()).open();
-
initTransactionManager();
// JCR
NodeRepositoryFactory repositoryFactory = new NodeRepositoryFactory();
bc.registerService(RepositoryFactory.class, repositoryFactory, null);
- // RepositoryService repositoryService = new RepositoryService();
- // shutdownHooks.add(() -> repositoryService.shutdown());
- // bc.registerService(LangUtils.names(ManagedService.class,
- // MetaTypeProvider.class), repositoryService,
- // LangUtils.init(Constants.SERVICE_PID, NodeConstants.NODE_REPO_PID));
-
// Security
NodeUserAdmin userAdmin = new NodeUserAdmin();
shutdownHooks.add(() -> userAdmin.destroy());
// UI
bc.registerService(ApplicationConfiguration.class, new MaintenanceUi(),
- LangUtils.init(PROPERTY_CONTEXT_NAME, "system"));
- bc.registerService(ApplicationConfiguration.class, new UserUi(), LangUtils.init(PROPERTY_CONTEXT_NAME, "user"));
+ LangUtils.init(KernelConstants.CONTEXT_NAME_PROP, "system"));
+ bc.registerService(ApplicationConfiguration.class, new UserUi(), LangUtils.init(KernelConstants.CONTEXT_NAME_PROP, "user"));
}
- // private void initUserAdmin() {
- // userAdmin = new NodeUserAdmin();
- // // register
- // Dictionary<String, Object> props = userAdmin.currentState();
- // props.put(Constants.SERVICE_PID, NodeConstants.NODE_USER_ADMIN_PID);
- // // TODO use ManagedService
- // bc.registerService(UserAdmin.class, userAdmin, props);
- // }
private void initTransactionManager() {
// TODO manage it in a managed service, as startup could be long
log.debug("Initialised default Bitronix transaction manager");
}
- // private void initRepositoryFactory() {
- // // TODO rationalise RepositoryFactory
- // repositoryFactory = new NodeRepositoryFactory();
- // // register
- // bc.registerService(RepositoryFactory.class, repositoryFactory, null);
- // }
-
- // private void initUi() {
- // bc.registerService(ApplicationConfiguration.class, new MaintenanceUi(),
- // LangUtils.init(PROPERTY_CONTEXT_NAME, "system"));
- // bc.registerService(ApplicationConfiguration.class, new UserUi(),
- // LangUtils.init(PROPERTY_CONTEXT_NAME, "user"));
- // }
-
- // private void initRepositories(Dictionary<String, ?> stateProps) throws
- // IOException {
- // // register
- // repositoryServiceFactory = new RepositoryServiceFactory();
- // bc.registerService(ManagedServiceFactory.class, repositoryServiceFactory,
- // LangUtils.init(Constants.SERVICE_PID,
- // NodeConstants.JACKRABBIT_FACTORY_PID));
- //
- // repositoryService = new RepositoryService();
- // Dictionary<String, Object> regProps =
- // LangUtils.init(Constants.SERVICE_PID, NodeConstants.NODE_REPO_PID);
- // bc.registerService(LangUtils.names(ManagedService.class,
- // MetaTypeProvider.class), repositoryService, regProps);
- // }
-
- // private void initNodeDeployment() throws IOException {
- // Configuration nodeDeploymentConf =
- // configurationAdmin.getConfiguration(NodeConstants.NODE_DEPLOYMENT_PID);
- // nodeDeploymentConf.update(new Hashtable<>());
- // }
-
void shutdown() {
- // if (transactionManager != null)
- // transactionManager.shutdown();
- // if (userAdmin != null)
- // userAdmin.destroy();
- // if (repositoryServiceFactory != null)
- // repositoryServiceFactory.shutdown();
-
applyShutdownHooks();
if (kernelThread != null)
private void applyShutdownHooks() {
for (int i = shutdownHooks.size() - 1; i >= 0; i--) {
try {
- // new Thread(shutdownHooks.get(i), "CMS Shutdown Hook #" +
- // i).start();
shutdownHooks.get(i).run();
} catch (Exception e) {
log.error("Could not run shutdown hook #" + i);
new GogoShellKiller().start();
}
- private class PrepareHttpStc implements ServiceTrackerCustomizer<HttpService, HttpService> {
- private DataHttp dataHttp;
- private NodeHttp nodeHttp;
-
- @Override
- public HttpService addingService(ServiceReference<HttpService> reference) {
- HttpService httpService = addHttpService(reference);
- return httpService;
- }
-
- @Override
- public void modifiedService(ServiceReference<HttpService> reference, HttpService service) {
- }
-
- @Override
- public void removedService(ServiceReference<HttpService> reference, HttpService service) {
- if (dataHttp != null)
- dataHttp.destroy();
- dataHttp = null;
- if (nodeHttp != null)
- nodeHttp.destroy();
- nodeHttp = null;
- }
-
- private HttpService addHttpService(ServiceReference<HttpService> sr) {
- HttpService httpService = bc.getService(sr);
- // TODO find constants
- Object httpPort = sr.getProperty("http.port");
- Object httpsPort = sr.getProperty("https.port");
- dataHttp = new DataHttp(httpService);
- nodeHttp = new NodeHttp(httpService, bc);
- if (log.isDebugEnabled())
- log.debug(httpPortsMsg(httpPort, httpsPort));
- return httpService;
- }
-
- }
-
@Override
public boolean isClean() {
return cleanState;
}
+ @Override
+ public Long getAvailableSince() {
+ return availableSince;
+ }
+
/*
* ACCESSORS
*/
return hostname;
}
- /*
- * STATIC
- */
- private static String httpPortsMsg(Object httpPort, Object httpsPort) {
- return "HTTP " + httpPort + (httpsPort != null ? " - HTTPS " + httpsPort : "");
- }
-
/** Workaround for blocking Gogo shell by system shutdown. */
private class GogoShellKiller extends Thread {
import org.argeo.cms.CmsException;
import org.argeo.jcr.ArgeoJcrConstants;
import org.argeo.node.NodeConstants;
-import org.argeo.node.NodeState;
import org.argeo.util.naming.AttributesDictionary;
import org.argeo.util.naming.LdifParser;
import org.argeo.util.naming.LdifWriter;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.cm.ConfigurationEvent;
-import org.osgi.service.cm.SynchronousConfigurationListener;
+import org.osgi.service.cm.ConfigurationListener;
-class DeployConfig implements SynchronousConfigurationListener {
+class DeployConfig implements ConfigurationListener {
private final Log log = LogFactory.getLog(getClass());
private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
} catch (IOException e) {
throw new CmsException("Could not init deploy configs", e);
}
- bc.registerService(SynchronousConfigurationListener.class, this, null);
+ // FIXME check race conditions during initialization
+ // bc.registerService(ConfigurationListener.class, this, null);
}
private void firstInit() throws IOException {
if (!webServerConfig.isEmpty())
putFactoryDeployConfig(KernelConstants.JETTY_FACTORY_PID, webServerConfig);
- saveDeployedConfigs();
+ save();
}
private void init(ConfigurationAdmin configurationAdmin, boolean isClean) throws IOException {
assert attrs != null;
AttributesDictionary.copy(conf.getProperties(), attrs);
}
- saveDeployedConfigs();
+ save();
if (log.isDebugEnabled())
log.debug("Updated deploy config " + serviceDn(factoryPid, cn.toString()));
} else {
Attributes attrs = deployConfigs.get(serviceDn);
assert attrs != null;
AttributesDictionary.copy(conf.getProperties(), attrs);
- saveDeployedConfigs();
+ save();
if (log.isDebugEnabled())
log.debug("Updated deploy config " + serviceDn);
} else {
deployConfigs.put(serviceDn, attrs);
}
- void saveDeployedConfigs() throws IOException {
+ void save() {
try (Writer writer = Files.newBufferedWriter(deployConfigPath)) {
new LdifWriter(writer).write(deployConfigs);
+ } catch (IOException e) {
+ throw new CmsException("Cannot save deploy configs", e);
}
}
}
}
- private Dictionary<String, Object> getProps(String factoryPid, String cn) {
+ Dictionary<String, Object> getProps(String factoryPid, String cn) {
Attributes attrs = deployConfigs.get(serviceDn(factoryPid, cn));
if (attrs != null)
return new AttributesDictionary(attrs);
import org.argeo.node.NodeConstants;
public interface KernelConstants {
-
-
- //final static String TRANSACTIONS_HOME = "argeo.node.transactions.home";
-
- final static String[] DEFAULT_CNDS = { "/org/argeo/jcr/argeo.cnd", "/org/argeo/cms/cms.cnd" };
+ String[] DEFAULT_CNDS = { "/org/argeo/jcr/argeo.cnd", "/org/argeo/cms/cms.cnd" };
// Directories
- final static String DIR_NODE = "node";
- final static String DIR_REPOS = "repos";
-// final static String DIR_DEPLOY = "deploy";
- final static String DIR_TRANSACTIONS = "transactions";
- final static String DIR_PKI = "pki";
- final static String DIR_PKI_PRIVATE = DIR_PKI + "/private";
+ String DIR_NODE = "node";
+ String DIR_REPOS = "repos";
+ String DIR_TRANSACTIONS = "transactions";
+ String DIR_PKI = "pki";
+ String DIR_PKI_PRIVATE = DIR_PKI + "/private";
// Files
String DEPLOY_CONFIG_PATH = KernelConstants.DIR_NODE + '/' + NodeConstants.DEPLOY_BASEDN + ".ldif";
-
+
// Security
- final static String DEFAULT_SECURITY_KEY = "argeo";
- final static String JAAS_CONFIG = "/org/argeo/cms/internal/kernel/jaas.cfg";
- final static String LOGIN_CONTEXT_KERNEL = "KERNEL";
- final static String LOGIN_CONTEXT_HARDENED_KERNEL = "HARDENED_KERNEL";
+ String DEFAULT_SECURITY_KEY = "argeo";
+ String JAAS_CONFIG = "/org/argeo/cms/internal/kernel/jaas.cfg";
+ String LOGIN_CONTEXT_KERNEL = "KERNEL";
+ String LOGIN_CONTEXT_HARDENED_KERNEL = "HARDENED_KERNEL";
// DAV
- final static String WEBDAV_CONFIG = "/org/argeo/cms/internal/kernel/webdav-config.xml";
- final static String PATH_DATA = "/data";
- final static String WEBDAV_PUBLIC = PATH_DATA + "/public";
- final static String WEBDAV_PRIVATE = PATH_DATA + "/files";
- final static String REMOTING_PUBLIC = PATH_DATA + "/pub";
- final static String REMOTING_PRIVATE = PATH_DATA + "/jcr";
+ String WEBDAV_CONFIG = "/org/argeo/cms/internal/kernel/webdav-config.xml";
+ String PATH_DATA = "/data";
+ String WEBDAV_PUBLIC = PATH_DATA + "/public";
+ String WEBDAV_PRIVATE = PATH_DATA + "/files";
+ String REMOTING_PUBLIC = PATH_DATA + "/pub";
+ String REMOTING_PRIVATE = PATH_DATA + "/jcr";
// RWT / RAP
- final static String PATH_WORKBENCH = "/ui";
- final static String PATH_WORKBENCH_PUBLIC = PATH_WORKBENCH + "/public";
+ String PATH_WORKBENCH = "/ui";
+ String PATH_WORKBENCH_PUBLIC = PATH_WORKBENCH + "/public";
- final static String JETTY_FACTORY_PID = "org.eclipse.equinox.http.jetty.config"; //$NON-NLS-1$
+ String JETTY_FACTORY_PID = "org.eclipse.equinox.http.jetty.config";
+ String WHITEBOARD_PATTERN_PROP = "osgi.http.whiteboard.servlet.pattern";
+ // avoid dependency to RWT OSGi
+ String CONTEXT_NAME_PROP = "contextName";
}
import org.argeo.cms.auth.CurrentUser;
import org.argeo.node.ArgeoLogListener;
import org.argeo.node.ArgeoLogger;
+import org.argeo.node.NodeConstants;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.log.LogEntry;
import org.osgi.service.log.LogListener;
import org.osgi.service.log.LogReaderService;
// FIXME Fix Argeo TP
if (status.getException() instanceof SignatureException)
return;
- pluginLog.error(status.getMessage(), status.getException());
+ pluginLog.error(msg(status), status.getException());
} else if (severity == LogService.LOG_WARNING)
- pluginLog.warn(status.getMessage(), status.getException());
+ pluginLog.warn(msg(status), status.getException());
else if (severity == LogService.LOG_INFO && pluginLog.isDebugEnabled())
- pluginLog.debug(
- status.getMessage() + (status.getServiceReference() != null ?" "+ status.getServiceReference() : ""),
- status.getException());
+ pluginLog.debug(msg(status), status.getException());
else if (severity == LogService.LOG_DEBUG && pluginLog.isTraceEnabled())
- pluginLog.trace(status.getMessage(), status.getException());
+ pluginLog.trace(msg(status), status.getException());
+ }
+
+ private String msg(LogEntry status) {
+ StringBuilder sb = new StringBuilder(status.getMessage());
+ ServiceReference<?> sr = status.getServiceReference();
+ if (sr != null) {
+ sb.append(' ');
+ String[] objectClasses = (String[]) sr.getProperty(Constants.OBJECTCLASS);
+ sb.append(arrayToString(objectClasses));
+ Object cn = sr.getProperty(NodeConstants.CN);
+ if (cn != null)
+ sb.append(" " + NodeConstants.CN + ": " + cn);
+ Object factoryPid = sr.getProperty(ConfigurationAdmin.SERVICE_FACTORYPID);
+ if (factoryPid != null)
+ sb.append(" " + ConfigurationAdmin.SERVICE_FACTORYPID + ": " + factoryPid);
+ else {
+ Object servicePid = sr.getProperty(Constants.SERVICE_PID);
+ if (servicePid != null)
+ sb.append(" " + Constants.SERVICE_PID + ": " + servicePid);
+ }
+ // servlets
+ Object whiteBoardPattern = sr.getProperty(KernelConstants.WHITEBOARD_PATTERN_PROP);
+ if (whiteBoardPattern != null)
+ sb.append(" " + KernelConstants.WHITEBOARD_PATTERN_PROP + ": "
+ + arrayToString((String[]) whiteBoardPattern));
+ // RWT
+ Object contextName = sr.getProperty(KernelConstants.CONTEXT_NAME_PROP);
+ if (contextName != null)
+ sb.append(" " + KernelConstants.CONTEXT_NAME_PROP + ": " + contextName);
+ }
+ return sb.toString();
+ }
+
+ private String arrayToString(Object[] arr) {
+ StringBuilder sb = new StringBuilder();
+ sb.append('{');
+ for (int i = 0; i < arr.length; i++) {
+ if (i != 0)
+ sb.append(',');
+ sb.append(arr[i]);
+ }
+ sb.append('}');
+ return sb.toString();
}
//