]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.launcher/src/main/java/org/argeo/slc/cli/SlcMain.java
32c3ce90660f3c8ffc87a745e5b9eb153e1a7c0c
[gpl/argeo-slc.git] / runtime / org.argeo.slc.launcher / src / main / java / org / argeo / slc / cli / SlcMain.java
1 package org.argeo.slc.cli;
2
3 import java.io.FileInputStream;
4 import java.util.Properties;
5
6 import org.apache.commons.cli.CommandLine;
7 import org.apache.commons.cli.CommandLineParser;
8 import org.apache.commons.cli.GnuParser;
9 import org.apache.commons.cli.HelpFormatter;
10 import org.apache.commons.cli.Option;
11 import org.apache.commons.cli.OptionBuilder;
12 import org.apache.commons.cli.Options;
13 import org.apache.commons.cli.ParseException;
14 import org.apache.commons.io.IOUtils;
15 import org.apache.commons.logging.Log;
16 import org.apache.commons.logging.LogFactory;
17 import org.argeo.slc.SlcException;
18 import org.argeo.slc.logging.Log4jUtils;
19 import org.argeo.slc.runtime.SlcExecutionContext;
20 import org.argeo.slc.runtime.SlcRuntime;
21 import org.springframework.context.ApplicationContext;
22 import org.springframework.context.ConfigurableApplicationContext;
23 import org.springframework.context.support.FileSystemXmlApplicationContext;
24
25 public class SlcMain {
26 public enum Mode {
27 single, agent
28 }
29
30 private static Log log = null;
31
32 private final static String BOOTSTRAP_LOG4J_CONFIG = "org/argeo/slc/cli/bootstrapLog4j.properties";
33
34 private final static Option modeOpt = OptionBuilder.withLongOpt("mode")
35 .withArgName("mode").hasArg().withDescription(
36 "SLC execution mode, one of: " + listModeValues()).create(
37 'm');
38
39 private final static Option propertyOpt = OptionBuilder.withLongOpt(
40 "property").withArgName("prop1=val1,prop2=val2").hasArgs()
41 .withValueSeparator(',').withDescription(
42 "use value for given property").create('p');
43
44 private final static Option propertiesOpt = OptionBuilder.withLongOpt(
45 "properties").withArgName("properties file").hasArgs()
46 .withValueSeparator(',').withDescription(
47 "load properties from file (-p has priority)").create('P');
48
49 private final static Option scriptOpt = OptionBuilder.withLongOpt("script")
50 .withArgName("script").hasArg().withDescription(
51 "SLC script to execute").create('s');
52
53 private final static Option targetsOpt = OptionBuilder.withLongOpt(
54 "targets").withArgName("targets").hasArg().withDescription(
55 "Targets to execute").create('t');
56
57 private final static Option runtimeOpt = OptionBuilder.withLongOpt(
58 "runtime").withArgName("runtime").hasArg().withDescription(
59 "Runtime to use, either a full path or relative to slc app conf dir: "
60 + "<conf dir>/runtime/<runtime>/.xml").create('r');
61
62 private final static Options options;
63
64 private final static String commandName = "slc";
65
66 static {
67 options = new Options();
68 options.addOption(modeOpt);
69 options.addOption(scriptOpt);
70 options.addOption(targetsOpt);
71 options.addOption(propertyOpt);
72 options.addOption(propertiesOpt);
73 options.addOption(runtimeOpt);
74 }
75
76 public static void main(String[] args) {
77 Mode mode = null;
78 Properties properties = new Properties();
79 String script = null;
80 String targets = null;
81 String runtimeStr = null;
82
83 try {
84
85 CommandLineParser clParser = new GnuParser();
86 CommandLine cl = clParser.parse(options, args);
87
88 // Mode
89 String modeStr = cl.getOptionValue(modeOpt.getOpt());
90 if (modeStr == null) {
91 mode = Mode.single;
92 } else {
93 try {
94 mode = Mode.valueOf(modeStr);
95 } catch (IllegalArgumentException e) {
96 throw new SlcException("Unrecognized mode '" + modeStr
97 + "'", e);
98 }
99 }
100
101 // Script
102 if (mode.equals(Mode.single)) {
103 if (!cl.hasOption(scriptOpt.getOpt()))
104 throw new SlcException("Mode " + Mode.single
105 + " requires option '" + scriptOpt.getLongOpt()
106 + "'");
107 script = cl.getOptionValue(scriptOpt.getOpt());
108
109 // Targets
110 if (cl.hasOption(targetsOpt.getOpt()))
111 targets = cl.getOptionValue(targetsOpt.getOpt());
112 }
113
114 // Properties
115 if (cl.hasOption(propertiesOpt.getOpt())) {
116 for (String propertyFile : cl.getOptionValues(propertiesOpt
117 .getOpt())) {
118 loadPropertyFile(properties, propertyFile);
119 }
120 }
121 if (cl.hasOption(propertyOpt.getOpt())) {
122 for (String property : cl.getOptionValues(propertyOpt.getOpt())) {
123 addProperty(properties, property);
124 }
125 }
126
127 // Runtime
128 if (cl.hasOption(runtimeOpt.getOpt())) {
129 runtimeStr = cl.getOptionValue(runtimeOpt.getOpt());
130 }
131 } catch (ParseException e) {
132 System.err.println("Problem with command line arguments. "
133 + e.getMessage());
134 badExit();
135 } catch (SlcException e) {
136 System.err.println(e.getMessage());
137 badExit();
138 } catch (Exception e) {
139 System.err.println("Unexpected exception when bootstrapping.");
140 e.printStackTrace();
141 badExit();
142 }
143
144 // Initializes logging and log arguments
145 initLogging(properties);
146 if (log.isDebugEnabled()) {
147 log.debug("Mode: " + mode);
148 if (runtimeStr != null)
149 log.debug("Runtime: " + runtimeStr);
150 log.debug("User properties: " + properties);
151 if (script != null)
152 log.debug("Script: " + script);
153 if (targets != null)
154 log.debug("Targets: " + targets);
155 }
156
157 // Execution
158 if (mode.equals(Mode.single)) {
159 try {
160 // DefaultSlcRuntime runtime = new DefaultSlcRuntime();
161 // FIXME: inject this more cleanly
162 ClassLoader cl = Thread.currentThread().getContextClassLoader();
163 Class clss = cl.loadClass("org.argeo.slc.ant.AntSlcRuntime");
164 SlcRuntime<? extends SlcExecutionContext> runtime = (SlcRuntime<? extends SlcExecutionContext>) clss
165 .newInstance();
166 runtime.executeScript(runtimeStr, script, targets, properties,
167 null, null);
168 // System.exit(0);
169 } catch (Exception e) {
170 log.error("SLC client terminated with an error: ", e);
171 System.exit(1);
172 }
173 }
174 // Agent
175 else if (mode.equals(Mode.agent)) {
176 if (runtimeStr == null)
177 runtimeStr = "agent.xml";
178 final ConfigurableApplicationContext applicationContext = new FileSystemXmlApplicationContext(
179 "agent.xml");
180 applicationContext.start();
181 log.info("SLC Agent context started.");
182
183 Thread shutdownHook = new Thread("SLC agent shutdown hook") {
184 public void run() {
185 applicationContext.stop();
186 applicationContext.close();
187 log.info("Closed agent application context.");
188 }
189 };
190 Runtime.getRuntime().addShutdownHook(shutdownHook);
191
192 while (applicationContext.isActive()) {
193 try {
194 Thread.sleep(1000);
195 } catch (InterruptedException e) {
196 // silent
197 }
198 }
199 }
200 }
201
202 public static void printUsage() {
203 new HelpFormatter().printHelp(commandName, options, true);
204 }
205
206 private static String listModeValues() {
207 StringBuffer buf = new StringBuffer("");
208 for (Mode mode : Mode.values()) {
209 buf.append(mode).append(", ");
210 }
211 String str = buf.toString();
212 // unsafe, but there will be at least one value in the enum
213 return str.substring(0, str.length() - 2);
214 }
215
216 protected static void addProperty(Properties properties, String property) {
217 int eqIndex = property.indexOf('=');
218 if (eqIndex == 0)
219 throw new SlcException("Badly formatted property " + property);
220
221 if (eqIndex > 0) {
222 String key = property.substring(0, eqIndex);
223 String value = property.substring(eqIndex + 1);
224 properties.setProperty(key, value);
225
226 } else {
227 properties.setProperty(property, "true");
228 }
229 }
230
231 protected static void loadPropertyFile(Properties properties,
232 String propertyFile) {
233 FileInputStream in = null;
234 try {
235 in = new FileInputStream(propertyFile);
236 properties.load(in);
237 } catch (Exception e) {
238 throw new SlcException("Could not load proeprty file "
239 + propertyFile);
240 } finally {
241 IOUtils.closeQuietly(in);
242 }
243 }
244
245 private static void initLogging(Properties userProperties) {
246 System.setProperty("log4j.defaultInitOverride", "true");
247
248 // Add log4j user properties to System properties
249 for (Object obj : userProperties.keySet()) {
250 String key = obj.toString();
251 if (key.startsWith("log4j.")) {
252 System.setProperty(key, userProperties.getProperty(key));
253 }
254 }
255 Log4jUtils.initLog4j(System.getProperty("log4j.configuration",
256 "classpath:" + BOOTSTRAP_LOG4J_CONFIG));
257 log = LogFactory.getLog(SlcMain.class);
258
259 }
260
261 private static void badExit() {
262 printUsage();
263 System.exit(1);
264 }
265 }