2 * Copyright (C) 2007-2012 Argeo GmbH
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org
.argeo
.slc
.cli
;
19 import java
.io
.FileOutputStream
;
20 import java
.io
.IOException
;
21 import java
.io
.InputStream
;
22 import java
.lang
.reflect
.Method
;
23 import java
.security
.AccessController
;
24 import java
.security
.PrivilegedAction
;
25 import java
.util
.ArrayList
;
26 import java
.util
.Date
;
27 import java
.util
.HashMap
;
28 import java
.util
.List
;
30 import java
.util
.ServiceLoader
;
31 import java
.util
.UUID
;
33 import javax
.security
.auth
.Subject
;
34 import javax
.security
.auth
.login
.LoginContext
;
36 import org
.argeo
.osgi
.boot
.OsgiBoot
;
37 import org
.osgi
.framework
.BundleContext
;
38 import org
.osgi
.framework
.BundleException
;
39 import org
.osgi
.framework
.ServiceReference
;
40 import org
.osgi
.framework
.launch
.Framework
;
41 import org
.osgi
.framework
.launch
.FrameworkFactory
;
43 /** Configures an SLC runtime and runs a process. */
44 public class SlcMain
implements PrivilegedAction
<String
> {
45 public final static String NIX
= "NIX";
46 public final static String WINDOWS
= "WINDOWS";
47 public final static String SOLARIS
= "SOLARIS";
49 public final static String os
;
50 public final static String slcDirName
= ".slc";
51 final static File homeDir
= new File(System
.getProperty("user.home"));
54 String osName
= System
.getProperty("os.name");
55 if (osName
.startsWith("Win"))
57 else if (osName
.startsWith("Solaris"))
63 private Long timeout
= 30 * 1000l;
64 private final String
[] args
;
65 private final File confDir
;
66 private final File dataDir
;
67 private final File modulesDir
;
69 private final List
<String
> bundlesToStart
= new ArrayList
<String
>();
71 public SlcMain(String
[] args
, File confDir
, File dataDir
, File modulesDir
) {
73 this.confDir
= confDir
;
74 this.dataDir
= dataDir
;
75 this.modulesDir
= modulesDir
;
76 bundlesToStart
.add("org.springframework.osgi.extender");
77 bundlesToStart
.add("org.argeo.node.repo.jackrabbit");
78 bundlesToStart
.add("org.argeo.security.dao.os");
79 bundlesToStart
.add("org.argeo.slc.node.jackrabbit");
80 bundlesToStart
.add("org.argeo.slc.agent");
81 bundlesToStart
.add("org.argeo.slc.agent.jcr");
83 bundlesToStart
.add("org.argeo.slc.support.equinox");
84 // bundlesToStart.add("org.argeo.slc.agent.cli");
88 long begin
= System
.currentTimeMillis();
90 Framework framework
= null;
92 info("## Date : " + new Date());
93 info("## Data : " + dataDir
.getCanonicalPath());
96 ServiceLoader
<FrameworkFactory
> ff
= ServiceLoader
97 .load(FrameworkFactory
.class);
98 FrameworkFactory frameworkFactory
= ff
.iterator().next();
99 Map
<String
, String
> configuration
= new HashMap
<String
, String
>();
100 configuration
.put("osgi.configuration.area",
101 confDir
.getCanonicalPath());
102 configuration
.put("osgi.instance.area", dataDir
.getCanonicalPath());
103 if (args
.length
== 0) {
104 // configuration.put("osgi.clean", "true");
105 configuration
.put("osgi.console", "");
108 // Spring configs currently require System properties
109 System
.getProperties().putAll(configuration
);
111 framework
= frameworkFactory
.newFramework(configuration
);
113 BundleContext bundleContext
= framework
.getBundleContext();
116 OsgiBoot osgiBoot
= new OsgiBoot(bundleContext
);
118 // working copy modules
119 if (modulesDir
.exists())
120 osgiBoot
.installUrls(osgiBoot
.getBundlesUrls(modulesDir
121 .getCanonicalPath() + ";in=*;ex=.gitignore"));
124 if (System
.getProperty(OsgiBoot
.PROP_ARGEO_OSGI_BUNDLES
) != null)
125 osgiBoot
.installUrls(osgiBoot
.getBundlesUrls(System
126 .getProperty(OsgiBoot
.PROP_ARGEO_OSGI_BUNDLES
)));
128 osgiBoot
.installUrls(osgiBoot
.getBundlesUrls(System
129 .getProperty("user.home") + "/.slc/modules/;in=**"));
132 osgiBoot
.startBundles(bundlesToStart
);
135 ServiceReference sr
= null;
138 .getServiceReference("org.argeo.slc.execution.SlcAgentCli");
139 if (System
.currentTimeMillis() - begin
> timeout
)
140 throw new RuntimeException("Cannot find SLC agent CLI");
143 Object agentCli
= bundleContext
.getService(sr
);
145 // Initialization completed
146 long duration
= System
.currentTimeMillis() - begin
;
147 info("[[ Initialized in " + (duration
/ 1000) + "s "
148 + (duration
% 1000) + "ms ]]");
150 if (args
.length
== 0)
151 return null;// console mode
153 // Subject.doAs(Subject.getSubject(AccessController.getContext()),
154 // new AgentCliCall(agentCli));
155 Class
<?
>[] parameterTypes
= { String
[].class };
156 Method method
= agentCli
.getClass().getMethod("process",
158 Object
[] methodArgs
= { args
};
159 Object ret
= method
.invoke(agentCli
, methodArgs
);
161 // Shutdown OSGi runtime
163 framework
.waitForStop(60 * 1000);
165 return ret
.toString();
166 } catch (Exception e
) {
167 // Shutdown OSGi runtime
168 if (framework
!= null)
171 framework
.waitForStop(15 * 1000);
172 } catch (Exception silent
) {
174 throw new RuntimeException("Cannot run SLC command line", e
);
180 public static void main(String
[] args
) {
182 // Prepare directories
183 File executionDir
= new File(System
.getProperty("user.dir"));
185 Boolean isTransient
= false;
187 File tempDir
= new File(System
.getProperty("java.io.tmpdir")
188 + "/" + System
.getProperty("user.name"));
189 slcDir
= new File(tempDir
, "slc-"
190 + UUID
.randomUUID().toString());
192 System
.setProperty("argeo.node.repo.configuration",
193 "osgibundle:repository-memory.xml");
195 slcDir
= findSlcDir(executionDir
);
196 if (slcDir
== null) {
197 slcDir
= new File(executionDir
, slcDirName
);
199 info("## Creating an SLC node at " + slcDir
+ " ...");
203 File dataDir
= new File(slcDir
, "data");
204 if (!dataDir
.exists())
207 File confDir
= new File(slcDir
, "conf");
208 if (!confDir
.exists())
211 File modulesDir
= new File(slcDir
, "modules");
214 File jaasFile
= new File(confDir
, "jaas.config");
215 if (!jaasFile
.exists())
216 copyResource("/org/argeo/slc/cli/jaas.config", jaasFile
);
217 System
.setProperty("java.security.auth.login.config",
218 jaasFile
.getCanonicalPath());
221 File log4jFile
= new File(confDir
, "log4j.properties");
222 if (!log4jFile
.exists())
223 copyResource("/org/argeo/slc/cli/log4j.properties", log4jFile
);
224 System
.setProperty("log4j.configuration",
225 "file://" + log4jFile
.getCanonicalPath());
226 // Run as a privileged action
227 LoginContext lc
= new LoginContext(os
);
230 Subject subject
= Subject
.getSubject(AccessController
.getContext());
231 Subject
.doAs(subject
, new SlcMain(args
, confDir
, dataDir
,
234 if (args
.length
!= 0)
236 } catch (Exception e
) {
243 * Recursively look in parent directories for a directory named
244 * {@link #slcDirName}
246 protected static File
findSlcDir(File currentDir
) {
247 File slcDir
= new File(currentDir
, slcDirName
);
248 if (slcDir
.exists() && slcDir
.isDirectory())
250 File parentDir
= currentDir
.getParentFile();
251 if (parentDir
== null)
254 // ~/.slc reserved for agent
255 if (parentDir
.getCanonicalPath().equals(homeDir
.getCanonicalPath()))
257 } catch (IOException e
) {
258 throw new RuntimeException("Cannot check home directory", e
);
260 return findSlcDir(parentDir
);
263 protected static void copyResource(String resource
, File targetFile
) {
264 InputStream input
= null;
265 FileOutputStream output
= null;
267 input
= SlcMain
.class.getResourceAsStream(resource
);
268 output
= new FileOutputStream(targetFile
);
269 byte[] buf
= new byte[8192];
271 int length
= input
.read(buf
);
274 output
.write(buf
, 0, length
);
276 } catch (Exception e
) {
277 throw new RuntimeException("Cannot write " + resource
+ " file to "
282 } catch (Exception ignore
) {
286 } catch (Exception ignore
) {
292 protected static void info(Object msg
) {
293 System
.out
.println(msg
);
296 protected static void err(Object msg
) {
297 System
.err
.println(msg
);
300 protected static void debug(Object msg
) {
301 System
.out
.println(msg
);
306 // private String bundlesToInstall = System.getProperty("user.home")
308 // "/dev/src/slc/dep/org.argeo.slc.dep.minimal/target/dependency;in=*.jar,"
309 // + System.getProperty("user.home")
310 // + "/dev/src/slc/demo/modules;in=*;ex=pom.xml;ex=.svn";
312 // ServiceTracker agentTracker = new ServiceTracker(bundleContext,
313 // "org.argeo.slc.execution.SlcAgentCli", null);
314 // agentTracker.open();
315 // final Object agentCli = agentTracker.waitForService(30 * 1000);
316 // if (agentCli == null)
317 // throw new RuntimeException("Cannot find SLC agent CLI");
319 // protected class AgentCliCall implements PrivilegedAction<String> {
320 // private final Object agentCli;
322 // public AgentCliCall(Object agentCli) {
324 // this.agentCli = agentCli;
327 // public String run() {
329 // Class<?>[] parameterTypes = { String[].class };
330 // Method method = agentCli.getClass().getMethod("process",
332 // Object[] methodArgs = { args };
333 // Object ret = method.invoke(agentCli, methodArgs);
334 // return ret.toString();
335 // } catch (Exception e) {
336 // throw new RuntimeException("Cannot run "
337 // + Arrays.toString(args) + " on " + agentCli, e);