1 package org
.argeo
.cms
.internal
.kernel
;
3 import java
.io
.IOException
;
4 import java
.lang
.management
.ManagementFactory
;
6 import java
.util
.Dictionary
;
8 import org
.apache
.commons
.logging
.Log
;
9 import org
.apache
.commons
.logging
.LogFactory
;
10 import org
.argeo
.api
.NodeConstants
;
11 import org
.argeo
.api
.NodeDeployment
;
12 import org
.argeo
.api
.NodeState
;
13 import org
.argeo
.osgi
.transaction
.WorkTransaction
;
14 import org
.argeo
.osgi
.useradmin
.UserAdminConf
;
15 import org
.eclipse
.equinox
.http
.jetty
.JettyConfigurator
;
16 import org
.osgi
.framework
.BundleContext
;
17 import org
.osgi
.framework
.FrameworkUtil
;
18 import org
.osgi
.framework
.ServiceReference
;
19 import org
.osgi
.service
.cm
.Configuration
;
20 import org
.osgi
.service
.cm
.ConfigurationAdmin
;
21 import org
.osgi
.service
.http
.HttpService
;
22 import org
.osgi
.service
.useradmin
.Group
;
23 import org
.osgi
.service
.useradmin
.Role
;
24 import org
.osgi
.service
.useradmin
.UserAdmin
;
25 import org
.osgi
.util
.tracker
.ServiceTracker
;
27 /** Implementation of a CMS deployment. */
28 public class CmsDeployment
implements NodeDeployment
{
29 private final Log log
= LogFactory
.getLog(getClass());
30 private final BundleContext bc
= FrameworkUtil
.getBundle(getClass()).getBundleContext();
32 private DeployConfig deployConfig
;
34 private Long availableSince
;
37 private boolean nodeAvailable
= false;
38 private boolean userAdminAvailable
= false;
39 private boolean httpExpected
= false;
40 private boolean httpAvailable
= false;
42 public CmsDeployment() {
43 // ServiceReference<NodeState> nodeStateSr = bc.getServiceReference(NodeState.class);
44 // if (nodeStateSr == null)
45 // throw new CmsException("No node state available");
47 // NodeState nodeState = bc.getService(nodeStateSr);
48 // cleanState = nodeState.isClean();
50 // nodeHttp = new NodeHttp();
54 private void initTrackers() {
55 ServiceTracker
<?
, ?
> httpSt
= new ServiceTracker
<HttpService
, HttpService
>(bc
, HttpService
.class, null) {
58 public HttpService
addingService(ServiceReference
<HttpService
> sr
) {
60 Object httpPort
= sr
.getProperty("http.port");
61 Object httpsPort
= sr
.getProperty("https.port");
62 log
.info(httpPortsMsg(httpPort
, httpsPort
));
64 return super.addingService(sr
);
68 KernelUtils
.asyncOpen(httpSt
);
70 ServiceTracker
<?
, ?
> userAdminSt
= new ServiceTracker
<UserAdmin
, UserAdmin
>(bc
, UserAdmin
.class, null) {
72 public UserAdmin
addingService(ServiceReference
<UserAdmin
> reference
) {
73 UserAdmin userAdmin
= super.addingService(reference
);
74 addStandardSystemRoles(userAdmin
);
75 userAdminAvailable
= true;
80 // userAdminSt.open();
81 KernelUtils
.asyncOpen(userAdminSt
);
83 ServiceTracker
<?
, ?
> confAdminSt
= new ServiceTracker
<ConfigurationAdmin
, ConfigurationAdmin
>(bc
,
84 ConfigurationAdmin
.class, null) {
86 public ConfigurationAdmin
addingService(ServiceReference
<ConfigurationAdmin
> reference
) {
87 ConfigurationAdmin configurationAdmin
= bc
.getService(reference
);
90 Configuration
[] confs
= configurationAdmin
91 .listConfigurations("(service.factoryPid=" + NodeConstants
.NODE_USER_ADMIN_PID
+ ")");
92 isClean
= confs
== null || confs
.length
== 0;
93 } catch (Exception e
) {
94 throw new IllegalStateException("Cannot analyse clean state", e
);
96 deployConfig
= new DeployConfig(configurationAdmin
, isClean
);
97 Activator
.registerService(NodeDeployment
.class, CmsDeployment
.this, null);
98 // JcrInitUtils.addToDeployment(CmsDeployment.this);
99 httpExpected
= deployConfig
.getProps(KernelConstants
.JETTY_FACTORY_PID
, "default") != null;
101 Configuration
[] configs
= configurationAdmin
102 .listConfigurations("(service.factoryPid=" + NodeConstants
.NODE_USER_ADMIN_PID
+ ")");
104 boolean hasDomain
= false;
105 for (Configuration config
: configs
) {
106 Object realm
= config
.getProperties().get(UserAdminConf
.realm
.name());
108 log
.debug("Found realm: " + realm
);
113 loadIpaJaasConfiguration();
115 } catch (Exception e
) {
116 throw new IllegalStateException("Cannot initialize config", e
);
118 return super.addingService(reference
);
121 // confAdminSt.open();
122 KernelUtils
.asyncOpen(confAdminSt
);
125 public void addFactoryDeployConfig(String factoryPid
, Dictionary
<String
, Object
> props
) {
126 deployConfig
.putFactoryDeployConfig(factoryPid
, props
);
129 deployConfig
.loadConfigs();
130 } catch (IOException e
) {
131 throw new IllegalStateException(e
);
135 public Dictionary
<String
, Object
> getProps(String factoryPid
, String cn
) {
136 return deployConfig
.getProps(factoryPid
, cn
);
139 private String
httpPortsMsg(Object httpPort
, Object httpsPort
) {
140 return (httpPort
!= null ?
"HTTP " + httpPort
+ " " : " ") + (httpsPort
!= null ?
"HTTPS " + httpsPort
: "");
143 private void addStandardSystemRoles(UserAdmin userAdmin
) {
144 // we assume UserTransaction is already available (TODO make it more robust)
145 WorkTransaction userTransaction
= bc
.getService(bc
.getServiceReference(WorkTransaction
.class));
147 userTransaction
.begin();
148 Role adminRole
= userAdmin
.getRole(NodeConstants
.ROLE_ADMIN
);
149 if (adminRole
== null) {
150 adminRole
= userAdmin
.createRole(NodeConstants
.ROLE_ADMIN
, Role
.GROUP
);
152 if (userAdmin
.getRole(NodeConstants
.ROLE_USER_ADMIN
) == null) {
153 Group userAdminRole
= (Group
) userAdmin
.createRole(NodeConstants
.ROLE_USER_ADMIN
, Role
.GROUP
);
154 userAdminRole
.addMember(adminRole
);
156 userTransaction
.commit();
157 } catch (Exception e
) {
159 userTransaction
.rollback();
160 } catch (Exception e1
) {
163 throw new IllegalStateException("Cannot add standard system roles", e
);
167 private void loadIpaJaasConfiguration() {
168 if (System
.getProperty(KernelConstants
.JAAS_CONFIG_PROP
) == null) {
169 String jaasConfig
= KernelConstants
.JAAS_CONFIG_IPA
;
170 URL url
= getClass().getClassLoader().getResource(jaasConfig
);
171 KernelUtils
.setJaasConfiguration(url
);
172 log
.debug("Set IPA JAAS configuration.");
176 public void shutdown() {
177 // if (nodeHttp != null)
178 // nodeHttp.destroy();
181 JettyConfigurator
.stopServer(KernelConstants
.DEFAULT_JETTY_SERVER
);
182 } catch (Exception e
) {
183 log
.error("Cannot stop default Jetty server.", e
);
186 if (deployConfig
!= null) {
187 new Thread(() -> deployConfig
.save(), "Save Argeo Deploy Config").start();
192 * Checks whether the deployment is available according to expectations, and
193 * mark it as available.
195 private synchronized void checkReadiness() {
198 if (nodeAvailable
&& userAdminAvailable
&& (httpExpected ? httpAvailable
: true)) {
199 String data
= KernelUtils
.getFrameworkProp(KernelUtils
.OSGI_INSTANCE_AREA
);
200 String state
= KernelUtils
.getFrameworkProp(KernelUtils
.OSGI_CONFIGURATION_AREA
);
201 availableSince
= System
.currentTimeMillis();
202 long jvmUptime
= ManagementFactory
.getRuntimeMXBean().getUptime();
203 String jvmUptimeStr
= " in " + (jvmUptime
/ 1000) + "." + (jvmUptime
% 1000) + "s";
204 log
.info("## ARGEO NODE AVAILABLE" + (log
.isDebugEnabled() ? jvmUptimeStr
: "") + " ##");
205 if (log
.isDebugEnabled()) {
206 log
.debug("## state: " + state
);
208 log
.debug("## data: " + data
);
210 long begin
= bc
.getService(bc
.getServiceReference(NodeState
.class)).getAvailableSince();
211 long initDuration
= System
.currentTimeMillis() - begin
;
212 if (log
.isTraceEnabled())
213 log
.trace("Kernel initialization took " + initDuration
+ "ms");
214 tributeToFreeSoftware(initDuration
);
218 final private void tributeToFreeSoftware(long initDuration
) {
219 if (log
.isTraceEnabled()) {
220 long ms
= initDuration
/ 100;
221 log
.trace("Spend " + ms
+ "ms" + " reflecting on the progress brought to mankind" + " by Free Software...");
222 long beginNano
= System
.nanoTime();
225 } catch (InterruptedException e
) {
228 long durationNano
= System
.nanoTime() - beginNano
;
229 final double M
= 1000d
* 1000d
;
230 double sleepAccuracy
= ((double) durationNano
) / (ms
* M
);
231 log
.trace("Sleep accuracy: " + String
.format("%.2f", 100 - (sleepAccuracy
* 100 - 100)) + " %");
236 public synchronized Long
getAvailableSince() {
237 return availableSince
;
240 public synchronized boolean isAvailable() {
241 return availableSince
!= null;