]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.init/src/org/argeo/init/RuntimeManagerMain.java
Simplify multi-runtime
[lgpl/argeo-commons.git] / org.argeo.init / src / org / argeo / init / RuntimeManagerMain.java
1 package org.argeo.init;
2
3 import static org.argeo.api.init.InitConstants.SYMBOLIC_NAME_INIT;
4
5 import java.lang.System.Logger;
6 import java.lang.System.Logger.Level;
7 import java.nio.file.Path;
8 import java.nio.file.Paths;
9 import java.util.HashMap;
10 import java.util.HashSet;
11 import java.util.Hashtable;
12 import java.util.Map;
13 import java.util.TreeMap;
14 import java.util.function.Consumer;
15
16 import org.argeo.api.init.InitConstants;
17 import org.argeo.api.init.RuntimeContext;
18 import org.argeo.api.init.RuntimeManager;
19 import org.argeo.init.logging.ThinLoggerFinder;
20 import org.argeo.init.osgi.OsgiBoot;
21 import org.argeo.init.osgi.OsgiRuntimeContext;
22 import org.argeo.internal.init.InternalState;
23 import org.osgi.framework.BundleContext;
24 import org.osgi.framework.FrameworkEvent;
25 import org.osgi.framework.launch.Framework;
26
27 /**
28 * Dynamically configures and launches multiple runtimes, coordinated by a main
29 * one.
30 */
31 public class RuntimeManagerMain {
32 private final static Logger logger = System.getLogger(RuntimeManagerMain.class.getName());
33
34 private final static String ENV_STATE_DIRECTORY = "STATE_DIRECTORY";
35 // private final static String ENV_CONFIGURATION_DIRECTORY = "CONFIGURATION_DIRECTORY";
36 // private final static String ENV_CACHE_DIRECTORY = "CACHE_DIRECTORY";
37
38 private final static long RUNTIME_SHUTDOWN_TIMEOUT = 60 * 1000;
39
40 private Path baseConfigArea;
41 private Path baseWritableArea;
42 private Map<String, String> configuration = new HashMap<>();
43
44 RuntimeManagerMain(Path configArea, Path stateArea) {
45 RuntimeManager.loadConfig(configArea, configuration);
46
47 // integration with OSGi runtime; this will be read by the init bundle
48 configuration.put(ServiceMain.PROP_ARGEO_INIT_MAIN, "true");
49 configuration.put(InitConstants.PROP_OSGI_SHARED_CONFIGURATION_AREA, configArea.toUri().toString());
50
51 configuration.put(InitConstants.PROP_OSGI_CONFIGURATION_AREA, stateArea.resolve(RuntimeManager.STATE).toUri().toString());
52 // use config area if instance area is not set
53 if (!configuration.containsKey(InitConstants.PROP_OSGI_INSTANCE_AREA))
54 configuration.put(InitConstants.PROP_OSGI_INSTANCE_AREA, stateArea.resolve(RuntimeManager.DATA).toUri().toString());
55 this.baseConfigArea = configArea.getParent();
56 this.baseWritableArea = stateArea.getParent();
57
58 logger.log(Level.TRACE, () -> "Runtime manager configuration: " + configuration);
59
60 // System.out.println("java.library.path=" + System.getProperty("java.library.path"));
61 }
62
63 public void run() {
64 OsgiRuntimeContext managerRuntimeContext = new OsgiRuntimeContext(configuration);
65 try {
66 managerRuntimeContext.run();
67 InternalState.setMainRuntimeContext(managerRuntimeContext);
68
69 // shutdown on exit
70 Runtime.getRuntime().addShutdownHook(new Thread(() -> shutdown(), "Runtime shutdown"));
71
72 // BundleContext bc = managerRuntimeContext.getFramework().getBundleContext();
73 // // uninstall init as a bundle since it will be available via OSGi system
74 // OsgiBoot.uninstallBundles(bc, SYMBOLIC_NAME_INIT);
75 // bc.registerService(RuntimeManager.class, this, new Hashtable<>(configuration));
76 logger.log(Level.DEBUG, "Registered runtime manager");
77
78 managerRuntimeContext.waitForStop(0);
79 } catch (InterruptedException e) {
80 e.printStackTrace();
81 System.exit(1);
82 }
83
84 }
85
86 protected void shutdown() {
87 // shutdown manager runtime
88 try {
89 InternalState.getMainRuntimeContext().close();
90 InternalState.getMainRuntimeContext().waitForStop(RUNTIME_SHUTDOWN_TIMEOUT);
91 // logger.log(Logger.Level.INFO, "Argeo Init stopped with PID " + ProcessHandle.current().pid());
92 System.out.flush();
93 } catch (Exception e) {
94 e.printStackTrace();
95 Runtime.getRuntime().halt(1);
96 }
97 }
98
99 public static void main(String[] args) {
100 ThinLoggerFinder.reloadConfiguration();
101 logger.log(Logger.Level.DEBUG, () -> "Argeo Init starting with PID " + ProcessHandle.current().pid());
102 Map<String, String> env = System.getenv();
103 // for (String envName : new TreeSet<>(env.keySet())) {
104 // System.out.format("%s=%s%n", envName, env.get(envName));
105 // }
106 if (args.length < 1)
107 throw new IllegalArgumentException("A relative configuration directory must be specified");
108 Path configArea = Paths.get(System.getProperty("user.dir"), args[0]);
109
110 // System.out.println("## Start with PID " + ProcessHandle.current().pid());
111 // System.out.println("user.dir=" + System.getProperty("user.dir"));
112
113 Path stateArea = Paths.get(env.get(ENV_STATE_DIRECTORY));
114
115 RuntimeManagerMain runtimeManager = new RuntimeManagerMain(configArea, stateArea);
116 runtimeManager.run();
117 }
118
119 }