]> git.argeo.org Git - lgpl/argeo-commons.git/blob - cms/internal/kernel/Kernel.java
Prepare next development cycle
[lgpl/argeo-commons.git] / cms / internal / kernel / Kernel.java
1 package org.argeo.cms.internal.kernel;
2
3 import java.lang.management.ManagementFactory;
4
5 import javax.jcr.Repository;
6 import javax.jcr.RepositoryFactory;
7
8 import org.apache.commons.logging.Log;
9 import org.apache.commons.logging.LogFactory;
10 import org.apache.jackrabbit.util.TransientFileFactory;
11 import org.argeo.ArgeoException;
12 import org.argeo.cms.CmsException;
13 import org.argeo.jackrabbit.OsgiJackrabbitRepositoryFactory;
14 import org.argeo.jcr.ArgeoJcrConstants;
15 import org.argeo.security.core.InternalAuthentication;
16 import org.eclipse.equinox.http.servlet.ExtendedHttpService;
17 import org.osgi.framework.BundleContext;
18 import org.osgi.framework.ServiceEvent;
19 import org.osgi.framework.ServiceListener;
20 import org.osgi.framework.ServiceReference;
21 import org.osgi.util.tracker.ServiceTracker;
22 import org.springframework.security.core.context.SecurityContextHolder;
23
24 /**
25 * Argeo CMS Kernel. Responsible for :
26 * <ul>
27 * <li>security</li>
28 * <li>provisioning</li>
29 * <li>transaction</li>
30 * <li>logging</li>
31 * <li>local and remote file systems access</li>
32 * <li>OS access</li>
33 * </ul>
34 */
35 final class Kernel implements ServiceListener {
36 private final static Log log = LogFactory.getLog(Kernel.class);
37
38 private final BundleContext bundleContext;
39 // private final ThreadGroup threadGroup = new
40 // ThreadGroup("Argeo CMS Kernel");
41
42 private JackrabbitNode node;
43 private RepositoryFactory repositoryFactory;
44 private NodeSecurity nodeSecurity;
45 private NodeHttp nodeHttp;
46
47 Kernel(BundleContext bundleContext) {
48 this.bundleContext = bundleContext;
49 }
50
51 void init() {
52 // new Thread(threadGroup, "init") {
53 // @Override
54 // public void run() {
55 // // CMS bundle classloader used during initialisation
56 // Thread.currentThread().setContextClassLoader(
57 // Kernel.class.getClassLoader());
58 doInit();
59 // }
60 // }.start();
61 }
62
63 protected void doInit() {
64 ClassLoader currentContextCl = Thread.currentThread()
65 .getContextClassLoader();
66 Thread.currentThread().setContextClassLoader(
67 Kernel.class.getClassLoader());
68 long begin = System.currentTimeMillis();
69 InternalAuthentication initAuth = new InternalAuthentication(
70 KernelConstants.DEFAULT_SECURITY_KEY);
71 SecurityContextHolder.getContext().setAuthentication(initAuth);
72
73 try {
74 node = new JackrabbitNode(bundleContext);
75 repositoryFactory = new OsgiJackrabbitRepositoryFactory();
76 nodeSecurity = new NodeSecurity(bundleContext, node);
77
78 // Equinox dependency
79 ExtendedHttpService httpService = waitForHttpService();
80 nodeHttp = new NodeHttp(httpService, node, nodeSecurity);
81
82 // Publish services to OSGi
83 nodeSecurity.publish();
84 node.publish();
85 bundleContext.registerService(RepositoryFactory.class,
86 repositoryFactory, null);
87
88 bundleContext.addServiceListener(Kernel.this);
89 } catch (Exception e) {
90 log.error("Cannot initialize Argeo CMS", e);
91 throw new ArgeoException("Cannot initialize", e);
92 } finally {
93 Thread.currentThread().setContextClassLoader(currentContextCl);
94 }
95
96 long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime();
97 log.info("## ARGEO CMS UP in " + (jvmUptime / 1000) + "."
98 + (jvmUptime % 1000) + "s ##");
99 long initDuration = System.currentTimeMillis() - begin;
100 if (log.isTraceEnabled())
101 log.trace("Kernel initialization took " + initDuration + "ms");
102 directorsCut(initDuration);
103 }
104
105 void destroy() {
106 long begin = System.currentTimeMillis();
107
108 if (nodeHttp != null)
109 nodeHttp.destroy();
110 if (nodeSecurity != null)
111 nodeSecurity.destroy();
112 if (node != null)
113 node.destroy();
114
115 bundleContext.removeServiceListener(this);
116
117 // Clean hanging threads from Jackrabbit
118 TransientFileFactory.shutdown();
119
120 long duration = System.currentTimeMillis() - begin;
121 log.info("## ARGEO CMS DOWN in " + (duration / 1000) + "."
122 + (duration % 1000) + "s ##");
123 }
124
125 @Override
126 public void serviceChanged(ServiceEvent event) {
127 ServiceReference<?> sr = event.getServiceReference();
128 Object jcrRepoAlias = sr
129 .getProperty(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS);
130 if (jcrRepoAlias != null) {// JCR repository
131 String alias = jcrRepoAlias.toString();
132 Repository repository = (Repository) bundleContext.getService(sr);
133 if (ServiceEvent.REGISTERED == event.getType()) {
134 try {
135 nodeHttp.registerWebdavServlet(alias, repository, true);
136 nodeHttp.registerWebdavServlet(alias, repository, false);
137 nodeHttp.registerRemotingServlet(alias, repository, true);
138 nodeHttp.registerRemotingServlet(alias, repository, false);
139 } catch (Exception e) {
140 throw new CmsException("Could not publish JCR repository "
141 + alias, e);
142 }
143 } else if (ServiceEvent.UNREGISTERING == event.getType()) {
144 }
145 }
146
147 }
148
149 final private static void directorsCut(long initDuration) {
150 // final long ms = 128l + (long) (Math.random() * 128d);
151 long ms = initDuration / 10;
152 log.info("Spend " + ms + "ms"
153 + " reflecting on the progress brought to mankind"
154 + " by Free Software...");
155 long beginNano = System.nanoTime();
156 try {
157 Thread.sleep(ms, 0);
158 } catch (InterruptedException e) {
159 // silent
160 }
161 long durationNano = System.nanoTime() - beginNano;
162 final double M = 1000d * 1000d;
163 double sleepAccuracy = ((double) durationNano) / (ms * M);
164 if (log.isTraceEnabled())
165 log.trace("Sleep accuracy: "
166 + String.format("%.2f", sleepAccuracy * 100) + " %");
167 }
168
169 private ExtendedHttpService waitForHttpService() {
170 final ServiceTracker<ExtendedHttpService, ExtendedHttpService> st = new ServiceTracker<ExtendedHttpService, ExtendedHttpService>(
171 bundleContext, ExtendedHttpService.class, null);
172 st.open();
173 ExtendedHttpService httpService;
174 try {
175 httpService = st.waitForService(1000);
176 } catch (InterruptedException e) {
177 httpService = null;
178 }
179
180 if (httpService == null)
181 throw new CmsException("Could not find "
182 + ExtendedHttpService.class + " service.");
183 return httpService;
184 }
185 }