From: Mathieu Baudier Date: Mon, 18 Jul 2022 13:59:51 +0000 (+0200) Subject: Clarify CMS initialisation X-Git-Tag: v2.3.10~111 X-Git-Url: https://git.argeo.org/?a=commitdiff_plain;h=bfb5eb067a6796c0ee2a575b1e2431220352513a;p=lgpl%2Fargeo-commons.git Clarify CMS initialisation --- diff --git a/org.argeo.api.cms/src/org/argeo/api/cms/CmsConstants.java b/org.argeo.api.cms/src/org/argeo/api/cms/CmsConstants.java index 7b89813fd..578c82431 100644 --- a/org.argeo.api.cms/src/org/argeo/api/cms/CmsConstants.java +++ b/org.argeo.api.cms/src/org/argeo/api/cms/CmsConstants.java @@ -79,6 +79,11 @@ public interface CmsConstants { */ String NODE_SERVICE = NODE; + /* + * COMPONENT PROPERTIES + */ + String CONTEXT_PATH = "context.path"; + /* * INIT FRAMEWORK PROPERTIES */ diff --git a/org.argeo.cms/OSGI-INF/acrContentRepository.xml b/org.argeo.cms/OSGI-INF/acrContentRepository.xml deleted file mode 100644 index b7a13b4d1..000000000 --- a/org.argeo.cms/OSGI-INF/acrContentRepository.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/org.argeo.cms/OSGI-INF/cmsAcrHttpHandler.xml b/org.argeo.cms/OSGI-INF/cmsAcrHttpHandler.xml index 0a2684a3d..dc45b027e 100644 --- a/org.argeo.cms/OSGI-INF/cmsAcrHttpHandler.xml +++ b/org.argeo.cms/OSGI-INF/cmsAcrHttpHandler.xml @@ -3,6 +3,6 @@ - + diff --git a/org.argeo.cms/OSGI-INF/cmsContentRepository.xml b/org.argeo.cms/OSGI-INF/cmsContentRepository.xml new file mode 100644 index 000000000..b7a13b4d1 --- /dev/null +++ b/org.argeo.cms/OSGI-INF/cmsContentRepository.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/org.argeo.cms/OSGI-INF/cmsDeployment.xml b/org.argeo.cms/OSGI-INF/cmsDeployment.xml index 102ae2adc..b00bc82f3 100644 --- a/org.argeo.cms/OSGI-INF/cmsDeployment.xml +++ b/org.argeo.cms/OSGI-INF/cmsDeployment.xml @@ -2,8 +2,8 @@ - - + + diff --git a/org.argeo.cms/OSGI-INF/cmsOsgiLogger.xml b/org.argeo.cms/OSGI-INF/cmsOsgiLogger.xml new file mode 100644 index 000000000..93fc5c0a4 --- /dev/null +++ b/org.argeo.cms/OSGI-INF/cmsOsgiLogger.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/org.argeo.cms/OSGI-INF/cmsUserAdmin.xml b/org.argeo.cms/OSGI-INF/cmsUserAdmin.xml new file mode 100644 index 000000000..50a9ea6eb --- /dev/null +++ b/org.argeo.cms/OSGI-INF/cmsUserAdmin.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/org.argeo.cms/OSGI-INF/deployConfig.xml b/org.argeo.cms/OSGI-INF/deployConfig.xml deleted file mode 100644 index 55755a920..000000000 --- a/org.argeo.cms/OSGI-INF/deployConfig.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/org.argeo.cms/OSGI-INF/nodeUserAdmin.xml b/org.argeo.cms/OSGI-INF/nodeUserAdmin.xml deleted file mode 100644 index 50a9ea6eb..000000000 --- a/org.argeo.cms/OSGI-INF/nodeUserAdmin.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/org.argeo.cms/OSGI-INF/simpleTransactionManager.xml b/org.argeo.cms/OSGI-INF/simpleTransactionManager.xml deleted file mode 100644 index 81997476e..000000000 --- a/org.argeo.cms/OSGI-INF/simpleTransactionManager.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/org.argeo.cms/OSGI-INF/transactionManager.xml b/org.argeo.cms/OSGI-INF/transactionManager.xml new file mode 100644 index 000000000..81997476e --- /dev/null +++ b/org.argeo.cms/OSGI-INF/transactionManager.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.argeo.cms/bnd.bnd b/org.argeo.cms/bnd.bnd index bb8ed76bf..bddc21f27 100644 --- a/org.argeo.cms/bnd.bnd +++ b/org.argeo.cms/bnd.bnd @@ -7,13 +7,14 @@ org.apache.xerces.jaxp;resolution:=optional,\ * Service-Component:\ +OSGI-INF/cmsOsgiLogger.xml,\ OSGI-INF/cmsState.xml,\ -OSGI-INF/simpleTransactionManager.xml,\ -OSGI-INF/nodeUserAdmin.xml,\ +OSGI-INF/uuidFactory.xml,\ +OSGI-INF/transactionManager.xml,\ +OSGI-INF/cmsUserAdmin.xml,\ OSGI-INF/cmsUserManager.xml,\ OSGI-INF/cmsAuthenticator.xml,\ -OSGI-INF/uuidFactory.xml,\ -OSGI-INF/acrContentRepository.xml,\ +OSGI-INF/cmsContentRepository.xml,\ OSGI-INF/cmsAcrHttpHandler.xml,\ OSGI-INF/cmsDeployment.xml,\ OSGI-INF/cmsContext.xml,\ diff --git a/org.argeo.cms/build.properties b/org.argeo.cms/build.properties index 11ab9e06e..960230a18 100644 --- a/org.argeo.cms/build.properties +++ b/org.argeo.cms/build.properties @@ -1,8 +1,6 @@ -output.. = bin/ bin.includes = META-INF/,\ .,\ bin/,\ - OSGI-INF/,\ - OSGI-INF/cmsAuthenticator.xml,\ - OSGI-INF/cmsAcrHttpHandler.xml + OSGI-INF/ source.. = src/ +output.. = bin/ diff --git a/org.argeo.cms/src/org/argeo/cms/ArgeoLogListener.java b/org.argeo.cms/src/org/argeo/cms/ArgeoLogListener.java deleted file mode 100644 index a01858aa9..000000000 --- a/org.argeo.cms/src/org/argeo/cms/ArgeoLogListener.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.argeo.cms; - -/** Framework agnostic interface for log notifications */ -@Deprecated -public interface ArgeoLogListener { - /** - * Appends a log - * - * @param username - * authentified user, null for anonymous - * @param level - * INFO, DEBUG, WARN, etc. (logging framework specific) - * @param category - * hierarchy (logging framework specific) - * @param thread - * name of the thread which logged this message - * @param msg - * any object as long as its toString() method returns the - * message - * @param exception - * exception in log4j ThrowableStrRep format - */ - public void appendLog(String username, Long timestamp, String level, - String category, String thread, Object msg, String[] exception); -} diff --git a/org.argeo.cms/src/org/argeo/cms/ArgeoLogger.java b/org.argeo.cms/src/org/argeo/cms/ArgeoLogger.java deleted file mode 100644 index 71c503900..000000000 --- a/org.argeo.cms/src/org/argeo/cms/ArgeoLogger.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.argeo.cms; - -/** - * Logging framework agnostic identifying a logging service, to which one can - * register - */ -@Deprecated -public interface ArgeoLogger { - /** - * Register for events by threads with the same authentication (or all - * threads if admin) - */ - public void register(ArgeoLogListener listener, - Integer numberOfPreviousEvents); - - /** - * For admin use only: register for all users - * - * @param listener - * the log listener - * @param numberOfPreviousEvents - * the number of previous events to notify - * @param everything - * if true even anonymous is logged - */ - public void registerForAll(ArgeoLogListener listener, - Integer numberOfPreviousEvents, boolean everything); - - public void unregister(ArgeoLogListener listener); - - public void unregisterForAll(ArgeoLogListener listener); -} diff --git a/org.argeo.cms/src/org/argeo/cms/internal/osgi/CmsActivator.java b/org.argeo.cms/src/org/argeo/cms/internal/osgi/CmsActivator.java index d4b2f4595..5e047d38a 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/osgi/CmsActivator.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/osgi/CmsActivator.java @@ -4,7 +4,6 @@ import java.security.AllPermission; import java.util.Dictionary; import org.argeo.api.cms.CmsLog; -import org.argeo.cms.ArgeoLogger; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; @@ -13,7 +12,6 @@ import org.osgi.service.condpermadmin.ConditionInfo; import org.osgi.service.condpermadmin.ConditionalPermissionAdmin; import org.osgi.service.condpermadmin.ConditionalPermissionInfo; import org.osgi.service.condpermadmin.ConditionalPermissionUpdate; -import org.osgi.service.log.LogReaderService; import org.osgi.service.permissionadmin.PermissionInfo; /** @@ -23,36 +21,22 @@ import org.osgi.service.permissionadmin.PermissionInfo; public class CmsActivator implements BundleActivator { private final static CmsLog log = CmsLog.getLog(CmsActivator.class); -// private static Activator instance; - // TODO make it configurable private boolean hardened = false; private static BundleContext bundleContext; - private LogReaderService logReaderService; - - private CmsOsgiLogger logger; -// private CmsStateImpl nodeState; -// private CmsDeploymentImpl nodeDeployment; -// private CmsContextImpl nodeInstance; - -// private ServiceTracker userAdminSt; - -// static { -// Bundle bundle = FrameworkUtil.getBundle(Activator.class); -// if (bundle != null) { -// bundleContext = bundle.getBundleContext(); -// } -// } +// private LogReaderService logReaderService; +// +// private CmsOsgiLogger logger; void init() { // Runtime.getRuntime().addShutdownHook(new CmsShutdown()); // instance = this; // this.bc = bundleContext; - if (bundleContext != null) - this.logReaderService = getService(LogReaderService.class); - initArgeoLogger(); +// if (bundleContext != null) +// this.logReaderService = getService(LogReaderService.class); +// initArgeoLogger(); // this.internalExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); // // try { @@ -69,21 +53,8 @@ public class CmsActivator implements BundleActivator { void destroy() { try { -// if (nodeInstance != null) -// nodeInstance.shutdown(); -// if (nodeDeployment != null) -// nodeDeployment.shutdown(); -// if (nodeState != null) -// nodeState.shutdown(); -// -// if (userAdminSt != null) -// userAdminSt.close(); - -// internalExecutorService.shutdown(); -// instance = null; bundleContext = null; - this.logReaderService = null; - // this.configurationAdmin = null; +// this.logReaderService = null; } catch (Exception e) { log.error("CMS activator shutdown failed", e); } @@ -127,26 +98,13 @@ public class CmsActivator implements BundleActivator { } - private void initArgeoLogger() { - logger = new CmsOsgiLogger(logReaderService); - if (bundleContext != null) - bundleContext.registerService(ArgeoLogger.class, logger, null); - } - -// private void initNode() throws IOException { -// // Node state -// nodeState = new CmsStateImpl(); -// registerService(CmsState.class, nodeState, null); -// -// // Node deployment -// nodeDeployment = new CmsDeploymentImpl(); -//// registerService(NodeDeployment.class, nodeDeployment, null); -// -// // Node instance -// nodeInstance = new CmsContextImpl(); -// registerService(CmsContext.class, nodeInstance, null); +// private void initArgeoLogger() { +// logger = new CmsOsgiLogger(logReaderService); +// if (bundleContext != null) +// bundleContext.registerService(ArgeoLogger.class, logger, null); // } + public static void registerService(Class clss, T service, Dictionary properties) { if (bundleContext != null) { bundleContext.registerService(clss, service, properties); @@ -169,98 +127,18 @@ public class CmsActivator implements BundleActivator { @Override public void start(BundleContext bc) throws Exception { bundleContext = bc; -// if (!bc.getBundle().equals(bundleContext.getBundle())) -// throw new IllegalStateException( -// "Bundle " + bc.getBundle() + " is not consistent with " + bundleContext.getBundle()); - init(); -// userAdminSt = new ServiceTracker<>(bundleContext, UserAdmin.class, null); -// userAdminSt.open(); -// ServiceTracker httpSt = new ServiceTracker(bc, HttpService.class, null) { -// -// @Override -// public HttpService addingService(ServiceReference sr) { -// Object httpPort = sr.getProperty("http.port"); -// Object httpsPort = sr.getProperty("https.port"); -// log.info(httpPortsMsg(httpPort, httpsPort)); -// close(); -// return super.addingService(sr); -// } -// }; -// httpSt.open(); - } + init(); - private String httpPortsMsg(Object httpPort, Object httpsPort) { - return (httpPort != null ? "HTTP " + httpPort + " " : " ") + (httpsPort != null ? "HTTPS " + httpsPort : ""); } @Override public void stop(BundleContext bc) throws Exception { -// if (!bc.getBundle().equals(bundleContext.getBundle())) -// throw new IllegalStateException( -// "Bundle " + bc.getBundle() + " is not consistent with " + bundleContext.getBundle()); + destroy(); bundleContext = null; } -// private T getService(Class clazz) { -// ServiceReference sr = bundleContext.getServiceReference(clazz); -// if (sr == null) -// throw new IllegalStateException("No service available for " + clazz); -// return bundleContext.getService(sr); -// } - -// public static GSSCredential getAcceptorCredentials() { -// return getNodeUserAdmin().getAcceptorCredentials(); -// } -// -// @Deprecated -// public static boolean isSingleUser() { -// return getNodeUserAdmin().isSingleUser(); -// } -// -// public static UserAdmin getUserAdmin() { -// return (UserAdmin) getNodeUserAdmin(); -// } -// -// public static String getHttpProxySslHeader() { -// return KernelUtils.getFrameworkProp(CmsConstants.HTTP_PROXY_SSL_DN); -// } -// -// private static NodeUserAdmin getNodeUserAdmin() { -// NodeUserAdmin res; -// try { -// res = instance.userAdminSt.waitForService(60000); -// } catch (InterruptedException e) { -// throw new IllegalStateException("Cannot retrieve Node user admin", e); -// } -// if (res == null) -// throw new IllegalStateException("No Node user admin found"); -// -// return res; -// // ServiceReference sr = -// // instance.bc.getServiceReference(UserAdmin.class); -// // NodeUserAdmin userAdmin = (NodeUserAdmin) instance.bc.getService(sr); -// // return userAdmin; -// -// } - -// public static ExecutorService getInternalExecutorService() { -// return instance.internalExecutorService; -// } - - // static CmsSecurity getCmsSecurity() { - // return instance.nodeSecurity; - // } - -// public String[] getLocales() { -// // TODO optimize? -// List locales = CmsStateImpl.getNodeState().getLocales(); -// String[] res = new String[locales.size()]; -// for (int i = 0; i < locales.size(); i++) -// res[i] = locales.get(i).toString(); -// return res; -// } public static BundleContext getBundleContext() { return bundleContext; diff --git a/org.argeo.cms/src/org/argeo/cms/internal/osgi/CmsOsgiLogger.java b/org.argeo.cms/src/org/argeo/cms/internal/osgi/CmsOsgiLogger.java index 2936df28a..3358ed825 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/osgi/CmsOsgiLogger.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/osgi/CmsOsgiLogger.java @@ -1,31 +1,10 @@ package org.argeo.cms.internal.osgi; -import java.io.IOException; -import java.nio.file.FileSystems; -import java.nio.file.Path; -import java.nio.file.StandardWatchEventKinds; -import java.nio.file.WatchEvent; -import java.nio.file.WatchKey; -import java.nio.file.WatchService; import java.security.SignatureException; -import java.util.ArrayList; -import java.util.Collections; import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Properties; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; import org.argeo.api.cms.CmsConstants; import org.argeo.api.cms.CmsLog; -import org.argeo.cms.ArgeoLogListener; -import org.argeo.cms.ArgeoLogger; -import org.argeo.cms.auth.CurrentUser; import org.argeo.util.directory.DirectoryConf; import org.osgi.framework.Bundle; import org.osgi.framework.Constants; @@ -36,51 +15,49 @@ import org.osgi.service.log.LogLevel; import org.osgi.service.log.LogListener; import org.osgi.service.log.LogReaderService; -/** Not meant to be used directly in standard log4j config */ -public class CmsOsgiLogger implements ArgeoLogger, LogListener { +/** Logs OSGi events. */ +public class CmsOsgiLogger implements LogListener { private final static String WHITEBOARD_PATTERN_PROP = "osgi.http.whiteboard.servlet.pattern"; private final static String CONTEXT_NAME_PROP = "contextName"; + + private LogReaderService logReaderService; - /** Internal debug for development purposes. */ - private static Boolean debug = false; +// /** Internal debug for development purposes. */ +// private static Boolean debug = false; - private Boolean disabled = false; - - private String level = null; +// private Boolean disabled = false; +// +// private String level = null; // private Level log4jLevel = null; - private Properties configuration; - - private AppenderImpl appender; +// private Properties configuration; - private final List everythingListeners = Collections - .synchronizedList(new ArrayList()); - private final List allUsersListeners = Collections - .synchronizedList(new ArrayList()); - private final Map> userListeners = Collections - .synchronizedMap(new HashMap>()); +// private AppenderImpl appender; - private BlockingQueue events; - private LogDispatcherThread logDispatcherThread = new LogDispatcherThread(); +// private BlockingQueue events; +// private LogDispatcherThread logDispatcherThread = new LogDispatcherThread(); - private Integer maxLastEventsCount = 10 * 1000; - - /** Marker to prevent stack overflow */ - private ThreadLocal dispatching = new ThreadLocal() { +// private Integer maxLastEventsCount = 10 * 1000; +// +// /** Marker to prevent stack overflow */ +// private ThreadLocal dispatching = new ThreadLocal() { +// +// @Override +// protected Boolean initialValue() { +// return false; +// } +// }; - @Override - protected Boolean initialValue() { - return false; - } - }; +// public CmsOsgiLogger(LogReaderService lrs) { +// } - public CmsOsgiLogger(LogReaderService lrs) { - if (lrs != null) { - Enumeration logEntries = lrs.getLog(); + public void start() { + if (logReaderService != null) { + Enumeration logEntries = logReaderService.getLog(); while (logEntries.hasMoreElements()) logged(logEntries.nextElement()); - lrs.addLogListener(this); + logReaderService.addLogListener(this); // configure log4j watcher // String log4jConfiguration = KernelUtils.getFrameworkProp("log4j.configuration"); @@ -104,43 +81,31 @@ public class CmsOsgiLogger implements ArgeoLogger, LogListener { // } // } } +// try { +//// events = new LinkedBlockingQueue(); +//// +//// // if (layout != null) +//// // setLayout(layout); +//// // else +//// // setLayout(new PatternLayout(pattern)); +////// appender = new AppenderImpl(); +//// reloadConfiguration(); +////// Logger.getRootLogger().addAppender(appender); +//// +//// logDispatcherThread = new LogDispatcherThread(); +//// logDispatcherThread.start(); +// } catch (Exception e) { +// throw new IllegalStateException("Cannot initialize log4j"); +// } } - public void init() { - try { - events = new LinkedBlockingQueue(); - - // if (layout != null) - // setLayout(layout); - // else - // setLayout(new PatternLayout(pattern)); - appender = new AppenderImpl(); - reloadConfiguration(); -// Logger.getRootLogger().addAppender(appender); - - logDispatcherThread = new LogDispatcherThread(); - logDispatcherThread.start(); - } catch (Exception e) { - throw new IllegalStateException("Cannot initialize log4j"); - } - } - - public void destroy() throws Exception { -// Logger.getRootLogger().removeAppender(appender); - allUsersListeners.clear(); - for (List lst : userListeners.values()) - lst.clear(); - userListeners.clear(); - - events.clear(); - events = null; - logDispatcherThread.interrupt(); + public void stop() throws Exception { +// events.clear(); +// events = null; +// logDispatcherThread.interrupt(); + logReaderService.removeLogListener(this); } - // public void setLayout(Layout layout) { - // this.layout = layout; - // } - public String toString() { return "Node Logger"; } @@ -247,295 +212,300 @@ public class CmsOsgiLogger implements ArgeoLogger, LogListener { return false; } + public void setLogReaderService(LogReaderService logReaderService) { + this.logReaderService = logReaderService; + } + + // // ARGEO LOGGER // - public synchronized void register(ArgeoLogListener listener, Integer numberOfPreviousEvents) { - String username = CurrentUser.getUsername(); - if (username == null) - throw new IllegalStateException("Only authenticated users can register a log listener"); - - if (!userListeners.containsKey(username)) { - List lst = Collections.synchronizedList(new ArrayList()); - userListeners.put(username, lst); - } - userListeners.get(username).add(listener); - List lastEvents = logDispatcherThread.getLastEvents(username, numberOfPreviousEvents); - for (LogEvent evt : lastEvents) - dispatchEvent(listener, evt); - } - - public synchronized void registerForAll(ArgeoLogListener listener, Integer numberOfPreviousEvents, - boolean everything) { - if (everything) - everythingListeners.add(listener); - else - allUsersListeners.add(listener); - List lastEvents = logDispatcherThread.getLastEvents(null, numberOfPreviousEvents); - for (LogEvent evt : lastEvents) - if (everything || evt.getUsername() != null) - dispatchEvent(listener, evt); - } - - public synchronized void unregister(ArgeoLogListener listener) { - String username = CurrentUser.getUsername(); - if (username == null)// FIXME - return; - if (!userListeners.containsKey(username)) - throw new IllegalStateException("No user listeners " + listener + " registered for user " + username); - if (!userListeners.get(username).contains(listener)) - throw new IllegalStateException("No user listeners " + listener + " registered for user " + username); - userListeners.get(username).remove(listener); - if (userListeners.get(username).isEmpty()) - userListeners.remove(username); - - } - - public synchronized void unregisterForAll(ArgeoLogListener listener) { - everythingListeners.remove(listener); - allUsersListeners.remove(listener); - } - - /** For development purpose, since using regular logging is not easy here */ - private static void stdOut(Object obj) { - System.out.println(obj); - } - - private static void stdErr(Object obj) { - System.err.println(obj); - } - - private static void debug(Object obj) { - if (debug) - System.out.println(obj); - } - - private static boolean isInternalDebugEnabled() { - return debug; - } +// public synchronized void register(ArgeoLogListener listener, Integer numberOfPreviousEvents) { +// String username = CurrentUser.getUsername(); +// if (username == null) +// throw new IllegalStateException("Only authenticated users can register a log listener"); +// +// if (!userListeners.containsKey(username)) { +// List lst = Collections.synchronizedList(new ArrayList()); +// userListeners.put(username, lst); +// } +// userListeners.get(username).add(listener); +// List lastEvents = logDispatcherThread.getLastEvents(username, numberOfPreviousEvents); +// for (LogEvent evt : lastEvents) +// dispatchEvent(listener, evt); +// } +// +// public synchronized void registerForAll(ArgeoLogListener listener, Integer numberOfPreviousEvents, +// boolean everything) { +// if (everything) +// everythingListeners.add(listener); +// else +// allUsersListeners.add(listener); +// List lastEvents = logDispatcherThread.getLastEvents(null, numberOfPreviousEvents); +// for (LogEvent evt : lastEvents) +// if (everything || evt.getUsername() != null) +// dispatchEvent(listener, evt); +// } +// +// public synchronized void unregister(ArgeoLogListener listener) { +// String username = CurrentUser.getUsername(); +// if (username == null)// FIXME +// return; +// if (!userListeners.containsKey(username)) +// throw new IllegalStateException("No user listeners " + listener + " registered for user " + username); +// if (!userListeners.get(username).contains(listener)) +// throw new IllegalStateException("No user listeners " + listener + " registered for user " + username); +// userListeners.get(username).remove(listener); +// if (userListeners.get(username).isEmpty()) +// userListeners.remove(username); +// +// } +// +// public synchronized void unregisterForAll(ArgeoLogListener listener) { +// everythingListeners.remove(listener); +// allUsersListeners.remove(listener); +// } + +// /** For development purpose, since using regular logging is not easy here */ +// private static void stdOut(Object obj) { +// System.out.println(obj); +// } +// +// private static void stdErr(Object obj) { +// System.err.println(obj); +// } +// +// private static void debug(Object obj) { +// if (debug) +// System.out.println(obj); +// } +// +// private static boolean isInternalDebugEnabled() { +// return debug; +// } // public void setPattern(String pattern) { // this.pattern = pattern; // } - public void setDisabled(Boolean disabled) { - this.disabled = disabled; - } - - public void setLevel(String level) { - this.level = level; - } - - public void setConfiguration(Properties configuration) { - this.configuration = configuration; - } - - public void updateConfiguration(Properties configuration) { - setConfiguration(configuration); - reloadConfiguration(); - } - - public Properties getConfiguration() { - return configuration; - } - - /** - * Reloads configuration (if the configuration {@link Properties} is set) - */ - protected void reloadConfiguration() { - if (configuration != null) { -// LogManager.resetConfiguration(); -// PropertyConfigurator.configure(configuration); - } - } - - protected synchronized void processLoggingEvent(LogEvent event) { - if (disabled) - return; - - if (dispatching.get()) - return; - - if (level != null && !level.trim().equals("")) { -// if (log4jLevel == null || !log4jLevel.toString().equals(level)) -// try { -// log4jLevel = Level.toLevel(level); -// } catch (Exception e) { -// System.err.println("Log4j level could not be set for level '" + level + "', resetting it to null."); -// e.printStackTrace(); -// level = null; -// } +// public void setDisabled(Boolean disabled) { +// this.disabled = disabled; +// } // -// if (log4jLevel != null && !event.getLoggingEvent().getLevel().isGreaterOrEqual(log4jLevel)) { -// return; -// } - } - - try { - // admin listeners - Iterator everythingIt = everythingListeners.iterator(); - while (everythingIt.hasNext()) - dispatchEvent(everythingIt.next(), event); - - if (event.getUsername() != null) { - Iterator allUsersIt = allUsersListeners.iterator(); - while (allUsersIt.hasNext()) - dispatchEvent(allUsersIt.next(), event); - - if (userListeners.containsKey(event.getUsername())) { - Iterator userIt = userListeners.get(event.getUsername()).iterator(); - while (userIt.hasNext()) - dispatchEvent(userIt.next(), event); - } - } - } catch (Exception e) { - stdOut("Cannot process logging event"); - e.printStackTrace(); - } - } - - protected void dispatchEvent(ArgeoLogListener logListener, LogEvent evt) { -// LoggingEvent event = evt.getLoggingEvent(); -// logListener.appendLog(evt.getUsername(), event.getTimeStamp(), event.getLevel().toString(), -// event.getLoggerName(), event.getThreadName(), event.getMessage(), event.getThrowableStrRep()); - } +// public void setLevel(String level) { +// this.level = level; +// } - private class AppenderImpl { // extends AppenderSkeleton { - public boolean requiresLayout() { - return false; - } +// public void setConfiguration(Properties configuration) { +// this.configuration = configuration; +// } +// +// public void updateConfiguration(Properties configuration) { +// setConfiguration(configuration); +// reloadConfiguration(); +// } +// +// public Properties getConfiguration() { +// return configuration; +// } +// +// /** +// * Reloads configuration (if the configuration {@link Properties} is set) +// */ +// protected void reloadConfiguration() { +// if (configuration != null) { +//// LogManager.resetConfiguration(); +//// PropertyConfigurator.configure(configuration); +// } +// } - public void close() { - } +// protected synchronized void processLoggingEvent(LogEvent event) { +// if (disabled) +// return; +// +// if (dispatching.get()) +// return; +// +// if (level != null && !level.trim().equals("")) { +//// if (log4jLevel == null || !log4jLevel.toString().equals(level)) +//// try { +//// log4jLevel = Level.toLevel(level); +//// } catch (Exception e) { +//// System.err.println("Log4j level could not be set for level '" + level + "', resetting it to null."); +//// e.printStackTrace(); +//// level = null; +//// } +//// +//// if (log4jLevel != null && !event.getLoggingEvent().getLevel().isGreaterOrEqual(log4jLevel)) { +//// return; +//// } +// } +// +//// try { +//// // admin listeners +//// Iterator everythingIt = everythingListeners.iterator(); +//// while (everythingIt.hasNext()) +//// dispatchEvent(everythingIt.next(), event); +//// +//// if (event.getUsername() != null) { +//// Iterator allUsersIt = allUsersListeners.iterator(); +//// while (allUsersIt.hasNext()) +//// dispatchEvent(allUsersIt.next(), event); +//// +//// if (userListeners.containsKey(event.getUsername())) { +//// Iterator userIt = userListeners.get(event.getUsername()).iterator(); +//// while (userIt.hasNext()) +//// dispatchEvent(userIt.next(), event); +//// } +//// } +//// } catch (Exception e) { +//// stdOut("Cannot process logging event"); +//// e.printStackTrace(); +//// } +// } + +// protected void dispatchEvent(ArgeoLogListener logListener, LogEvent evt) { +//// LoggingEvent event = evt.getLoggingEvent(); +//// logListener.appendLog(evt.getUsername(), event.getTimeStamp(), event.getLevel().toString(), +//// event.getLoggerName(), event.getThreadName(), event.getMessage(), event.getThrowableStrRep()); +// } + +// private class AppenderImpl { // extends AppenderSkeleton { +// public boolean requiresLayout() { +// return false; +// } +// +// public void close() { +// } +// +//// @Override +//// protected void append(LoggingEvent event) { +//// if (events != null) { +//// try { +//// String username = CurrentUser.getUsername(); +//// events.put(new LogEvent(username, event)); +//// } catch (InterruptedException e) { +//// // silent +//// } +//// } +//// } +// +// } -// @Override -// protected void append(LoggingEvent event) { -// if (events != null) { +// private class LogDispatcherThread extends Thread { +// /** encapsulated in order to simplify concurrency management */ +// private LinkedList lastEvents = new LinkedList(); +// +// public LogDispatcherThread() { +// super("Argeo Logging Dispatcher Thread"); +// } +// +// public void run() { +// while (events != null) { // try { -// String username = CurrentUser.getUsername(); -// events.put(new LogEvent(username, event)); +// LogEvent loggingEvent = events.take(); +// processLoggingEvent(loggingEvent); +// addLastEvent(loggingEvent); // } catch (InterruptedException e) { -// // silent +// if (events == null) +// return; // } // } // } +// +// protected synchronized void addLastEvent(LogEvent loggingEvent) { +// if (lastEvents.size() >= maxLastEventsCount) +// lastEvents.poll(); +// lastEvents.add(loggingEvent); +// } +// +// public synchronized List getLastEvents(String username, Integer maxCount) { +// LinkedList evts = new LinkedList(); +// ListIterator it = lastEvents.listIterator(lastEvents.size()); +// int count = 0; +// while (it.hasPrevious() && (count < maxCount)) { +// LogEvent evt = it.previous(); +// if (username == null || username.equals(evt.getUsername())) { +// evts.push(evt); +// count++; +// } +// } +// return evts; +// } +// } - } - - private class LogDispatcherThread extends Thread { - /** encapsulated in order to simplify concurrency management */ - private LinkedList lastEvents = new LinkedList(); - - public LogDispatcherThread() { - super("Argeo Logging Dispatcher Thread"); - } - - public void run() { - while (events != null) { - try { - LogEvent loggingEvent = events.take(); - processLoggingEvent(loggingEvent); - addLastEvent(loggingEvent); - } catch (InterruptedException e) { - if (events == null) - return; - } - } - } - - protected synchronized void addLastEvent(LogEvent loggingEvent) { - if (lastEvents.size() >= maxLastEventsCount) - lastEvents.poll(); - lastEvents.add(loggingEvent); - } - - public synchronized List getLastEvents(String username, Integer maxCount) { - LinkedList evts = new LinkedList(); - ListIterator it = lastEvents.listIterator(lastEvents.size()); - int count = 0; - while (it.hasPrevious() && (count < maxCount)) { - LogEvent evt = it.previous(); - if (username == null || username.equals(evt.getUsername())) { - evts.push(evt); - count++; - } - } - return evts; - } - } - - private class LogEvent { - private final String username; -// private final LoggingEvent loggingEvent; - - public LogEvent(String username) { - super(); - this.username = username; -// this.loggingEvent = loggingEvent; - } - -// @Override -// public int hashCode() { -// return loggingEvent.hashCode(); +// private class LogEvent { +// private final String username; +//// private final LoggingEvent loggingEvent; +// +// public LogEvent(String username) { +// super(); +// this.username = username; +//// this.loggingEvent = loggingEvent; // } // -// @Override -// public boolean equals(Object obj) { -// return loggingEvent.equals(obj); +//// @Override +//// public int hashCode() { +//// return loggingEvent.hashCode(); +//// } +//// +//// @Override +//// public boolean equals(Object obj) { +//// return loggingEvent.equals(obj); +//// } +//// +//// @Override +//// public String toString() { +//// return username + "@ " + loggingEvent.toString(); +//// } +// +// public String getUsername() { +// return username; // } // -// @Override -// public String toString() { -// return username + "@ " + loggingEvent.toString(); +//// public LoggingEvent getLoggingEvent() { +//// return loggingEvent; +//// } +// +// } +// +// private class Log4jConfWatcherThread extends Thread { +// private Path log4jConfigurationPath; +// +// public Log4jConfWatcherThread(Path log4jConfigurationPath) { +// super("Log4j Configuration Watcher"); +// try { +// this.log4jConfigurationPath = log4jConfigurationPath.toRealPath(); +// } catch (IOException e) { +// this.log4jConfigurationPath = log4jConfigurationPath.toAbsolutePath(); +// stdOut("Cannot determine real path for " + log4jConfigurationPath + ": " + e.getMessage()); +// } // } - - public String getUsername() { - return username; - } - -// public LoggingEvent getLoggingEvent() { -// return loggingEvent; +// +// public void run() { +// Path parentDir = log4jConfigurationPath.getParent(); +// try (final WatchService watchService = FileSystems.getDefault().newWatchService()) { +// parentDir.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY); +// WatchKey wk; +// watching: while ((wk = watchService.take()) != null) { +// for (WatchEvent event : wk.pollEvents()) { +// final Path changed = (Path) event.context(); +// if (log4jConfigurationPath.equals(parentDir.resolve(changed))) { +// if (isInternalDebugEnabled()) +// debug(log4jConfigurationPath + " has changed, reloading."); +//// PropertyConfigurator.configure(log4jConfigurationPath.toUri().toURL()); +// } +// } +// // reset the key +// boolean valid = wk.reset(); +// if (!valid) { +// break watching; +// } +// } +// } catch (IOException | InterruptedException e) { +// stdErr("Log4j configuration watcher failed: " + e.getMessage()); +// } // } - - } - - private class Log4jConfWatcherThread extends Thread { - private Path log4jConfigurationPath; - - public Log4jConfWatcherThread(Path log4jConfigurationPath) { - super("Log4j Configuration Watcher"); - try { - this.log4jConfigurationPath = log4jConfigurationPath.toRealPath(); - } catch (IOException e) { - this.log4jConfigurationPath = log4jConfigurationPath.toAbsolutePath(); - stdOut("Cannot determine real path for " + log4jConfigurationPath + ": " + e.getMessage()); - } - } - - public void run() { - Path parentDir = log4jConfigurationPath.getParent(); - try (final WatchService watchService = FileSystems.getDefault().newWatchService()) { - parentDir.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY); - WatchKey wk; - watching: while ((wk = watchService.take()) != null) { - for (WatchEvent event : wk.pollEvents()) { - final Path changed = (Path) event.context(); - if (log4jConfigurationPath.equals(parentDir.resolve(changed))) { - if (isInternalDebugEnabled()) - debug(log4jConfigurationPath + " has changed, reloading."); -// PropertyConfigurator.configure(log4jConfigurationPath.toUri().toURL()); - } - } - // reset the key - boolean valid = wk.reset(); - if (!valid) { - break watching; - } - } - } catch (IOException | InterruptedException e) { - stdErr("Log4j configuration watcher failed: " + e.getMessage()); - } - } - } +// } } diff --git a/org.argeo.cms/src/org/argeo/cms/internal/osgi/DeployConfig.java b/org.argeo.cms/src/org/argeo/cms/internal/osgi/DeployConfig.java deleted file mode 100644 index 7f8db5a06..000000000 --- a/org.argeo.cms/src/org/argeo/cms/internal/osgi/DeployConfig.java +++ /dev/null @@ -1,450 +0,0 @@ -package org.argeo.cms.internal.osgi; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Writer; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Dictionary; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.SortedMap; -import java.util.TreeMap; - -import javax.naming.InvalidNameException; -import javax.naming.directory.Attribute; -import javax.naming.directory.Attributes; -import javax.naming.directory.BasicAttributes; -import javax.naming.ldap.LdapName; -import javax.naming.ldap.Rdn; - -import org.argeo.api.cms.CmsConstants; -import org.argeo.api.cms.CmsLog; -import org.argeo.util.directory.DirectoryConf; -import org.argeo.util.directory.ldap.AttributesDictionary; -import org.argeo.util.directory.ldap.LdifParser; -import org.argeo.util.directory.ldap.LdifWriter; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.service.cm.Configuration; -import org.osgi.service.cm.ConfigurationAdmin; -import org.osgi.service.cm.ConfigurationEvent; - -/** Manages the LDIF-based deployment configuration. */ -@Deprecated -public class DeployConfig { - - private final CmsLog log = CmsLog.getLog(getClass()); -// private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext(); - - private static Path deployConfigPath;// = KernelUtils.getOsgiInstancePath(KernelConstants.DEPLOY_CONFIG_PATH); - private SortedMap deployConfigs = new TreeMap<>(); -// private final DataModels dataModels; - - private boolean isFirstInit = false; - - private final static String ROLES = "roles"; - - private ConfigurationAdmin configurationAdmin; - - private void firstInit() throws IOException { - log.info("## FIRST INIT ##"); - Files.createDirectories(deployConfigPath.getParent()); - - // FirstInit firstInit = new FirstInit(); - //InitUtils.prepareFirstInitInstanceArea(); - - if (!Files.exists(deployConfigPath)) - deployConfigs = new TreeMap<>(); - else// config file could have juste been copied by preparation - try (InputStream in = Files.newInputStream(deployConfigPath)) { - deployConfigs = new LdifParser().read(in); - } - save(); - } - - private void setFromFrameworkProperties(boolean isFirstInit) { - - // user admin -// List> userDirectoryConfigs = InitUtils.getUserDirectoryConfigs(); -// if (userDirectoryConfigs.size() != 0) { -// List activeCns = new ArrayList<>(); -// for (int i = 0; i < userDirectoryConfigs.size(); i++) { -// Dictionary userDirectoryConfig = userDirectoryConfigs.get(i); -// String baseDn = (String) userDirectoryConfig.get(DirectoryConf.baseDn.name()); -// String cn; -// if (CmsConstants.ROLES_BASEDN.equals(baseDn)) -// cn = ROLES; -// else -// cn = DirectoryConf.baseDnHash(userDirectoryConfig); -// activeCns.add(cn); -// userDirectoryConfig.put(CmsConstants.CN, cn); -// putFactoryDeployConfig(CmsConstants.NODE_USER_ADMIN_PID, userDirectoryConfig); -// } -// // disable others -// LdapName userAdminFactoryName = serviceFactoryDn(CmsConstants.NODE_USER_ADMIN_PID); -// for (LdapName name : deployConfigs.keySet()) { -// if (name.startsWith(userAdminFactoryName) && !name.equals(userAdminFactoryName)) { -//// try { -// Attributes attrs = deployConfigs.get(name); -// String cn = name.getRdn(name.size() - 1).getValue().toString(); -// if (!activeCns.contains(cn)) { -// attrs.put(DirectoryConf.disabled.name(), "true"); -// } -//// } catch (Exception e) { -//// throw new CmsException("Cannot disable user directory " + name, e); -//// } -// } -// } -// } - - // http server -// Dictionary webServerConfig = InitUtils -// .getHttpServerConfig(getProps(KernelConstants.JETTY_FACTORY_PID, CmsConstants.DEFAULT)); -// if (!webServerConfig.isEmpty()) { -// // TODO check for other customizers -// putFactoryDeployConfig(KernelConstants.JETTY_FACTORY_PID, webServerConfig); -// } - - // SAVE - save(); - // - - } - - public void start() { - try { - if (!isInitialized()) { // first init - isFirstInit = true; - firstInit(); - } - - boolean isClean = true; - if (configurationAdmin != null) - try { - Configuration[] confs = configurationAdmin - .listConfigurations("(service.factoryPid=" + CmsConstants.NODE_USER_ADMIN_PID + ")"); - isClean = confs == null || confs.length == 0; - } catch (Exception e) { - throw new IllegalStateException("Cannot analyse clean state", e); - } - - try (InputStream in = Files.newInputStream(deployConfigPath)) { - deployConfigs = new LdifParser().read(in); - } - if (isClean) { - if (log.isDebugEnabled()) - log.debug("Clean state, loading from framework properties..."); - setFromFrameworkProperties(isFirstInit); - if (configurationAdmin != null) - loadConfigs(); - } - // TODO check consistency if not clean - } catch (IOException e) { - throw new RuntimeException("Cannot load deploy configuration", e); - } - } - - public void stop() { - - } - - protected void logAllConfigurations() { - if (!log.isDebugEnabled()) - return; - try { - Configuration[] configurations = configurationAdmin.listConfigurations(null); - if (configurations == null) { - log.debug("No configuration available"); - return; - } - Arrays.sort(configurations, (o1, o2) -> o1.getPid().compareTo(o2.getPid())); - for (Configuration configuration : configurations) { - log.debug(configuration.getFactoryPid() + " - " + configuration.getPid() + " - " - + configuration.getProperties()); - } - } catch (IOException | InvalidSyntaxException e) { - throw new IllegalStateException("Cannot log configurations", e); - } - } - - public void loadConfigs() throws IOException { - // FIXME make it more robust - Configuration systemRolesConf = null; - LdapName systemRolesDn; - try { - // FIXME make it more robust - systemRolesDn = new LdapName("cn=roles,ou=org.argeo.api.userAdmin,ou=deploy,ou=node"); - } catch (InvalidNameException e) { - throw new IllegalArgumentException(e); - } - deployConfigs: for (LdapName dn : deployConfigs.keySet()) { - Attributes deployConfig = deployConfigs.get(dn); - Rdn lastRdn = dn.getRdn(dn.size() - 1); - LdapName prefix = (LdapName) dn.getPrefix(dn.size() - 1); - if (prefix.toString().equals(CmsConstants.DEPLOY_BASEDN)) { - if (lastRdn.getType().equals(CmsConstants.CN)) { - // service - String pid = lastRdn.getValue().toString(); - Configuration conf = configurationAdmin.getConfiguration(pid); - AttributesDictionary dico = new AttributesDictionary(deployConfig); - conf.update(dico); - } else { - // service factory definition - } - } else { - Attribute disabled = deployConfig.get(DirectoryConf.disabled.name()); - if (disabled != null) - continue deployConfigs; - // service factory service - if (!lastRdn.getType().equals(CmsConstants.CN)) - throw new IllegalStateException("Only " + CmsConstants.CN + "= is supported: " + dn); - Rdn beforeLastRdn = dn.getRdn(dn.size() - 2); - assert beforeLastRdn.getType().equals(CmsConstants.OU); - String factoryPid = beforeLastRdn.getValue().toString(); - - String cn = lastRdn.getValue().toString(); - Configuration conf = getSingleServiceConfiguration(factoryPid, cn); - if (conf != null) { - if (systemRolesDn.equals(dn)) - systemRolesConf = conf; - // TODO deal with modifications -// boolean modified = false; -// Dictionary currentProperties = conf.getProperties(); -// -// attrs: for (NamingEnumeration it = deployConfig.getAll(); it -// .hasMoreElements();) { -// Attribute attr = (Attribute) it.next(); -// String key = attr.getID(); -// Object currentValue = currentProperties.get(key); -// if (currentValue == null) { -// modified = true; -// break attrs; -// } -// } - -// AttributesDictionary dico = new AttributesDictionary(deployConfig); -// conf.update(dico); - } else { - - conf = configurationAdmin.createFactoryConfiguration(factoryPid.toString(), null); - if (systemRolesDn.equals(dn)) { - systemRolesConf = configurationAdmin.createFactoryConfiguration(factoryPid.toString(), null); - } else { - AttributesDictionary dico = new AttributesDictionary(deployConfig); - conf.update(dico); - } - } - } - } - - // system roles must be last since it triggers node user admin publication - if (systemRolesConf == null) - throw new IllegalStateException("System roles are not configured."); - systemRolesConf.update(new AttributesDictionary(deployConfigs.get(systemRolesDn))); - -// logAllConfigurations(); - } - - public Set> getUserDirectoryConfigs() { - // not static because class is not supported by Android - final LdapName USER_ADMIN_BASE_DN; - try { - USER_ADMIN_BASE_DN = new LdapName( - CmsConstants.OU + "=" + CmsConstants.NODE_USER_ADMIN_PID + "," + CmsConstants.DEPLOY_BASEDN); - } catch (InvalidNameException e) { - throw new IllegalArgumentException(e); - } - Set> res = new HashSet<>(); - for (LdapName dn : deployConfigs.keySet()) { - if (dn.endsWith(USER_ADMIN_BASE_DN)) { - Attributes attributes = deployConfigs.get(dn); - res.add(new AttributesDictionary(attributes)); - } - } - return res; - } - -// @Override - public void configurationEvent(ConfigurationEvent event) { - try { - if (ConfigurationEvent.CM_UPDATED == event.getType()) { - Configuration conf = configurationAdmin.getConfiguration(event.getPid(), null); - LdapName serviceDn = null; - String factoryPid = conf.getFactoryPid(); - if (factoryPid != null) { - LdapName serviceFactoryDn = serviceFactoryDn(factoryPid); - if (deployConfigs.containsKey(serviceFactoryDn)) { - for (LdapName dn : deployConfigs.keySet()) { - if (dn.startsWith(serviceFactoryDn)) { - Rdn lastRdn = dn.getRdn(dn.size() - 1); - assert lastRdn.getType().equals(CmsConstants.CN); - Object value = conf.getProperties().get(lastRdn.getType()); - assert value != null; - if (value.equals(lastRdn.getValue())) { - serviceDn = dn; - break; - } - } - } - - Object cn = conf.getProperties().get(CmsConstants.CN); - if (cn == null) - throw new IllegalArgumentException("Properties must contain cn"); - if (serviceDn == null) { - putFactoryDeployConfig(factoryPid, conf.getProperties()); - } else { - Attributes attrs = deployConfigs.get(serviceDn); - assert attrs != null; - AttributesDictionary.copy(conf.getProperties(), attrs); - } - save(); - if (log.isDebugEnabled()) - log.debug("Updated deploy config " + serviceDn(factoryPid, cn.toString())); - } else { - // ignore non config-registered service factories - } - } else { - serviceDn = serviceDn(event.getPid()); - if (deployConfigs.containsKey(serviceDn)) { - Attributes attrs = deployConfigs.get(serviceDn); - assert attrs != null; - AttributesDictionary.copy(conf.getProperties(), attrs); - save(); - if (log.isDebugEnabled()) - log.debug("Updated deploy config " + serviceDn); - } else { - // ignore non config-registered services - } - } - } - } catch (Exception e) { - log.error("Could not handle configuration event", e); - } - } - - public void putFactoryDeployConfig(String factoryPid, Dictionary props) { - Object cn = props.get(CmsConstants.CN); - if (cn == null) - throw new IllegalArgumentException("cn must be set in properties"); - LdapName serviceFactoryDn = serviceFactoryDn(factoryPid); - if (!deployConfigs.containsKey(serviceFactoryDn)) - deployConfigs.put(serviceFactoryDn, new BasicAttributes(CmsConstants.OU, factoryPid)); - LdapName serviceDn = serviceDn(factoryPid, cn.toString()); - Attributes attrs = new BasicAttributes(); - AttributesDictionary.copy(props, attrs); - deployConfigs.put(serviceDn, attrs); - } - - void putDeployConfig(String servicePid, Dictionary props) { - LdapName serviceDn = serviceDn(servicePid); - Attributes attrs = new BasicAttributes(CmsConstants.CN, servicePid); - AttributesDictionary.copy(props, attrs); - deployConfigs.put(serviceDn, attrs); - } - - public void save() { - try (Writer writer = Files.newBufferedWriter(deployConfigPath)) { - new LdifWriter(writer).write(deployConfigs); - } catch (IOException e) { - // throw new CmsException("Cannot save deploy configs", e); - log.error("Cannot save deploy configs", e); - } - } - - public void setConfigurationAdmin(ConfigurationAdmin configurationAdmin) { - this.configurationAdmin = configurationAdmin; - } - - public boolean hasDomain() { - // FIXME lookup deploy configs directly - if (configurationAdmin == null) - return false; - - Configuration[] configs = listConfigurationsByFactory(CmsConstants.NODE_USER_ADMIN_PID); - - boolean hasDomain = false; - for (Configuration config : configs) { - Object realm = config.getProperties().get(DirectoryConf.realm.name()); - if (realm != null) { - log.debug("Found realm: " + realm); - hasDomain = true; - } - } - return hasDomain; - } - - private Configuration[] listConfigurationsByFactory(String factoryPid) { - try { - Configuration[] configs = configurationAdmin.listConfigurations("(service.factoryPid=" + factoryPid + ")"); - if (configs == null) - configs = new Configuration[0]; - return configs; - } catch (IOException | InvalidSyntaxException e) { - throw new IllegalStateException("Cannot list configurations with factoryPid " + factoryPid, e); - } - - } - - private Configuration getSingleServiceConfiguration(String factoryPid, String cn) { - Configuration[] configs = listConfigurationsByFactory(factoryPid); - List res = new ArrayList<>(); - for (Configuration config : configs) { - Object currentCn = config.getProperties().get(CmsConstants.CN); - if (currentCn != null && cn.equals(currentCn.toString())) - res.add(config); - } - if (res.size() == 0) - return null; - if (res.size() > 1) - throw new IllegalStateException( - "More than one " + factoryPid + " configuration returned for " + CmsConstants.CN + "=" + cn); - return res.get(0); - } - - /* - * UTILITIES - */ - private LdapName serviceFactoryDn(String factoryPid) { - try { - return new LdapName(CmsConstants.OU + "=" + factoryPid + "," + CmsConstants.DEPLOY_BASEDN); - } catch (InvalidNameException e) { - throw new IllegalArgumentException("Cannot generate DN from " + factoryPid, e); - } - } - - private LdapName serviceDn(String servicePid) { - try { - return new LdapName(CmsConstants.CN + "=" + servicePid + "," + CmsConstants.DEPLOY_BASEDN); - } catch (InvalidNameException e) { - throw new IllegalArgumentException("Cannot generate DN from " + servicePid, e); - } - } - - private LdapName serviceDn(String factoryPid, String cn) { - try { - return (LdapName) serviceFactoryDn(factoryPid).add(new Rdn(CmsConstants.CN, cn)); - } catch (InvalidNameException e) { - throw new IllegalArgumentException("Cannot generate DN from " + factoryPid + " and " + cn, e); - } - } - - public Dictionary getProps(String factoryPid, String cn) { - Attributes attrs = deployConfigs.get(serviceDn(factoryPid, cn)); - if (attrs != null) - return new AttributesDictionary(attrs); - else - return null; - } - - private static boolean isInitialized() { - return Files.exists(deployConfigPath); - } - - public boolean isFirstInit() { - return isFirstInit; - } - -} diff --git a/org.argeo.cms/src/org/argeo/cms/internal/osgi/NodeUserAdmin.java b/org.argeo.cms/src/org/argeo/cms/internal/osgi/NodeUserAdmin.java deleted file mode 100644 index da67c733d..000000000 --- a/org.argeo.cms/src/org/argeo/cms/internal/osgi/NodeUserAdmin.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.argeo.cms.internal.osgi; - -import java.util.Dictionary; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Map; - -import org.argeo.api.cms.CmsConstants; -import org.argeo.api.cms.CmsLog; -import org.argeo.cms.internal.runtime.CmsUserAdmin; -import org.argeo.osgi.useradmin.UserDirectory; -import org.argeo.util.directory.DirectoryConf; -import org.osgi.framework.Constants; -import org.osgi.service.cm.ConfigurationException; -import org.osgi.service.cm.ManagedServiceFactory; -import org.osgi.service.useradmin.UserAdmin; - -/** - * Aggregates multiple {@link UserDirectory} and integrates them with system - * roles. - */ -@Deprecated -public class NodeUserAdmin extends CmsUserAdmin implements ManagedServiceFactory { - private final static CmsLog log = CmsLog.getLog(NodeUserAdmin.class); - - // OSGi - private Map pidToBaseDn = new HashMap<>(); - - @Override - public void updated(String pid, Dictionary properties) throws ConfigurationException { - - String basePath = (String) properties.get(DirectoryConf.baseDn.name()); - - // FIXME make updates more robust - if (pidToBaseDn.containsValue(basePath)) { - if (log.isDebugEnabled()) - log.debug("Ignoring user directory update of " + basePath); - return; - } - - UserDirectory userDirectory = enableUserDirectory(properties); - // OSGi - Hashtable regProps = new Hashtable<>(); - regProps.put(Constants.SERVICE_PID, pid); - if (isSystemRolesBaseDn(basePath)) - regProps.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE); - regProps.put(DirectoryConf.baseDn.name(), basePath); - - CmsActivator.getBundleContext().registerService(UserDirectory.class, userDirectory, regProps); - pidToBaseDn.put(pid, basePath); - - if (isSystemRolesBaseDn(basePath)) { - // publishes itself as user admin only when system roles are available - Dictionary userAdminregProps = new Hashtable<>(); - userAdminregProps.put(CmsConstants.CN, CmsConstants.DEFAULT); - userAdminregProps.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE); - CmsActivator.getBundleContext().registerService(UserAdmin.class, this, userAdminregProps); - } - } - - @Override - public void deleted(String pid) { - // assert pidToServiceRegs.get(pid) != null; - assert pidToBaseDn.get(pid) != null; - // pidToServiceRegs.remove(pid).unregister(); - String basePath = pidToBaseDn.remove(pid); - removeUserDirectory(basePath); - } - - @Override - public String getName() { - return "Node User Admin"; - } - -} diff --git a/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsDeploymentImpl.java b/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsDeploymentImpl.java index 8b0fbbc68..497ed923f 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsDeploymentImpl.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsDeploymentImpl.java @@ -1,7 +1,11 @@ package org.argeo.cms.internal.runtime; +import static org.argeo.api.cms.CmsConstants.CONTEXT_PATH; + import java.util.Map; +import java.util.TreeMap; +import org.argeo.api.cms.CmsConstants; import org.argeo.api.cms.CmsDeployment; import org.argeo.api.cms.CmsLog; import org.argeo.api.cms.CmsState; @@ -15,13 +19,14 @@ public class CmsDeploymentImpl implements CmsDeployment { private final CmsLog log = CmsLog.getLog(getClass()); // Readiness - private boolean httpExpected = false; // private HttpService httpService; private CmsState cmsState; // private DeployConfig deployConfig; + private boolean httpExpected = false; private HttpServer httpServer; + private Map httpHandlers = new TreeMap<>(); public void start() { // httpExpected = deployConfig.getProps(KernelConstants.JETTY_FACTORY_PID, "default") != null; @@ -78,21 +83,35 @@ public class CmsDeploymentImpl implements CmsDeployment { public void setHttpServer(HttpServer httpServer) { this.httpServer = httpServer; + // create contexts whose handles had already been published + for (String contextPath : httpHandlers.keySet()) { + HttpHandler httpHandler = httpHandlers.get(contextPath); + httpServer.createContext(contextPath, httpHandler); + log.debug(() -> "Added handler " + contextPath + " : " + httpHandler.getClass().getName()); + } } public void addHttpHandler(HttpHandler httpHandler, Map properties) { + final String contextPath = properties.get(CONTEXT_PATH); + if (contextPath == null) { + log.warn("Property " + CONTEXT_PATH + " not set on HTTP handler " + properties + ". Ignoring it."); + return; + } + httpHandlers.put(contextPath, httpHandler); if (httpServer == null) return; - final String contextPath = properties.get("contextPath"); httpServer.createContext(contextPath, httpHandler); log.debug(() -> "Added handler " + contextPath + " : " + httpHandler.getClass().getName()); } public void removeHttpHandler(HttpHandler httpHandler, Map properties) { + final String contextPath = properties.get(CmsConstants.CONTEXT_PATH); + if (contextPath == null) + return; // ignore silently + httpHandlers.remove(contextPath); if (httpServer == null) return; - final String contextPath = properties.get("contextPath"); httpServer.removeContext(contextPath); log.debug(() -> "Removed handler " + contextPath + " : " + httpHandler.getClass().getName()); } diff --git a/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsStateImpl.java b/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsStateImpl.java index 7252f425f..d335b48b1 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsStateImpl.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsStateImpl.java @@ -4,9 +4,7 @@ import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.io.Reader; -import java.net.InetAddress; import java.net.URL; -import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -119,7 +117,7 @@ public class CmsStateImpl implements CmsState { } } catch (RuntimeException | IOException e) { - log.error("## FATAL: CMS activator failed", e); + log.error("## FATAL: CMS state failed", e); } }