]> git.argeo.org Git - lgpl/argeo-commons.git/blob - CmsState.java
b794d088e619392088fd179043aa1d3690030631
[lgpl/argeo-commons.git] / CmsState.java
1 package org.argeo.cms.internal.kernel;
2
3 import static java.util.Locale.ENGLISH;
4
5 import java.net.InetAddress;
6 import java.net.UnknownHostException;
7 import java.nio.file.spi.FileSystemProvider;
8 import java.util.ArrayList;
9 import java.util.List;
10 import java.util.Locale;
11
12 import javax.jcr.RepositoryFactory;
13 import javax.transaction.TransactionManager;
14 import javax.transaction.UserTransaction;
15
16 import org.apache.commons.logging.Log;
17 import org.apache.commons.logging.LogFactory;
18 import org.argeo.api.NodeConstants;
19 import org.argeo.api.NodeState;
20 import org.argeo.cms.LocaleUtils;
21 import org.argeo.transaction.simple.SimpleTransactionManager;
22 import org.argeo.util.LangUtils;
23 import org.osgi.framework.Constants;
24 import org.osgi.service.cm.ManagedServiceFactory;
25
26 /**
27 * Implementation of a {@link NodeState}, initialising the required services.
28 */
29 public class CmsState implements NodeState {
30 private final static Log log = LogFactory.getLog(CmsState.class);
31 // private final BundleContext bc = FrameworkUtil.getBundle(CmsState.class).getBundleContext();
32
33 // REFERENCES
34 private Long availableSince;
35
36 // i18n
37 private Locale defaultLocale;
38 private List<Locale> locales = null;
39
40 private ThreadGroup threadGroup = new ThreadGroup("CMS");
41 private KernelThread kernelThread;
42 private List<Runnable> stopHooks = new ArrayList<>();
43
44 private final String stateUuid;
45 // private final boolean cleanState;
46 private String hostname;
47
48 public CmsState() {
49 // this.stateUuid = stateUuid;
50 this.stateUuid = KernelUtils.getFrameworkProp(Constants.FRAMEWORK_UUID);
51 // this.cleanState = stateUuid.equals(frameworkUuid);
52 try {
53 this.hostname = InetAddress.getLocalHost().getHostName();
54 } catch (UnknownHostException e) {
55 log.error("Cannot set hostname: " + e);
56 }
57
58 availableSince = System.currentTimeMillis();
59 if (log.isDebugEnabled())
60 // log.debug("## CMS starting... stateUuid=" + this.stateUuid + (cleanState ? "
61 // (clean state) " : " "));
62 log.debug("## CMS starting... (" + stateUuid + ")");
63
64 initI18n();
65 initServices();
66
67 // kernel thread
68 kernelThread = new KernelThread(threadGroup, "Kernel Thread");
69 kernelThread.setContextClassLoader(getClass().getClassLoader());
70 kernelThread.start();
71 }
72
73 private void initI18n() {
74 Object defaultLocaleValue = KernelUtils.getFrameworkProp(NodeConstants.I18N_DEFAULT_LOCALE);
75 defaultLocale = defaultLocaleValue != null ? new Locale(defaultLocaleValue.toString())
76 : new Locale(ENGLISH.getLanguage());
77 locales = LocaleUtils.asLocaleList(KernelUtils.getFrameworkProp(NodeConstants.I18N_LOCALES));
78 }
79
80 private void initServices() {
81 // JTA
82 String tmType = KernelUtils.getFrameworkProp(NodeConstants.TRANSACTION_MANAGER,
83 NodeConstants.TRANSACTION_MANAGER_SIMPLE);
84 if (NodeConstants.TRANSACTION_MANAGER_SIMPLE.equals(tmType)) {
85 initSimpleTransactionManager();
86 } else if (NodeConstants.TRANSACTION_MANAGER_BITRONIX.equals(tmType)) {
87 // initBitronixTransactionManager();
88 throw new UnsupportedOperationException(
89 "Bitronix is not supported anymore, but could be again if there is enough interest.");
90 } else {
91 throw new IllegalArgumentException("Usupported transaction manager type " + tmType);
92 }
93
94 // POI
95 // POIXMLTypeLoader.setClassLoader(CTConnection.class.getClassLoader());
96
97 // Tika
98 // OpenDocumentParser odfParser = new OpenDocumentParser();
99 // bc.registerService(Parser.class, odfParser, new Hashtable());
100 // PDFParser pdfParser = new PDFParser();
101 // bc.registerService(Parser.class, pdfParser, new Hashtable());
102 // OOXMLParser ooxmlParser = new OOXMLParser();
103 // bc.registerService(Parser.class, ooxmlParser, new Hashtable());
104 // TesseractOCRParser ocrParser = new TesseractOCRParser();
105 // ocrParser.setLanguage("ara");
106 // bc.registerService(Parser.class, ocrParser, new Hashtable());
107
108 // JCR
109 RepositoryServiceFactory repositoryServiceFactory = new RepositoryServiceFactory();
110 stopHooks.add(() -> repositoryServiceFactory.shutdown());
111 Activator.registerService(ManagedServiceFactory.class, repositoryServiceFactory,
112 LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_REPOS_FACTORY_PID));
113
114 NodeRepositoryFactory repositoryFactory = new NodeRepositoryFactory();
115 Activator.registerService(RepositoryFactory.class, repositoryFactory, null);
116
117 // Security
118 NodeUserAdmin userAdmin = new NodeUserAdmin(NodeConstants.ROLES_BASEDN, NodeConstants.TOKENS_BASEDN);
119 stopHooks.add(() -> userAdmin.destroy());
120 Activator.registerService(ManagedServiceFactory.class, userAdmin,
121 LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_USER_ADMIN_PID));
122
123 // File System
124 CmsFsProvider cmsFsProvider = new CmsFsProvider();
125 // ServiceLoader<FileSystemProvider> fspSl = ServiceLoader.load(FileSystemProvider.class);
126 // for (FileSystemProvider fsp : fspSl) {
127 // log.debug("FileSystemProvider " + fsp);
128 // if (fsp instanceof CmsFsProvider) {
129 // cmsFsProvider = (CmsFsProvider) fsp;
130 // }
131 // }
132 // for (FileSystemProvider fsp : FileSystemProvider.installedProviders()) {
133 // log.debug("Installed FileSystemProvider " + fsp);
134 // }
135 Activator.registerService(FileSystemProvider.class, cmsFsProvider,
136 LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_FS_PROVIDER_PID));
137 }
138
139 private void initSimpleTransactionManager() {
140 SimpleTransactionManager transactionManager = new SimpleTransactionManager();
141 Activator.registerService(TransactionManager.class, transactionManager, null);
142 Activator.registerService(UserTransaction.class, transactionManager, null);
143 // TODO TransactionSynchronizationRegistry
144 }
145
146 // private void initBitronixTransactionManager() {
147 // // TODO manage it in a managed service, as startup could be long
148 // ServiceReference<TransactionManager> existingTm = bc.getServiceReference(TransactionManager.class);
149 // if (existingTm != null) {
150 // if (log.isDebugEnabled())
151 // log.debug("Using provided transaction manager " + existingTm);
152 // return;
153 // }
154 //
155 // if (!TransactionManagerServices.isTransactionManagerRunning()) {
156 // bitronix.tm.Configuration tmConf = TransactionManagerServices.getConfiguration();
157 // tmConf.setServerId(UUID.randomUUID().toString());
158 //
159 // Bundle bitronixBundle = FrameworkUtil.getBundle(bitronix.tm.Configuration.class);
160 // File tmBaseDir = bitronixBundle.getDataFile(KernelConstants.DIR_TRANSACTIONS);
161 // File tmDir1 = new File(tmBaseDir, "btm1");
162 // tmDir1.mkdirs();
163 // tmConf.setLogPart1Filename(new File(tmDir1, tmDir1.getName() + ".tlog").getAbsolutePath());
164 // File tmDir2 = new File(tmBaseDir, "btm2");
165 // tmDir2.mkdirs();
166 // tmConf.setLogPart2Filename(new File(tmDir2, tmDir2.getName() + ".tlog").getAbsolutePath());
167 // }
168 // BitronixTransactionManager transactionManager = getTransactionManager();
169 // stopHooks.add(() -> transactionManager.shutdown());
170 // BitronixTransactionSynchronizationRegistry transactionSynchronizationRegistry = getTransactionSynchronizationRegistry();
171 // // register
172 // bc.registerService(TransactionManager.class, transactionManager, null);
173 // bc.registerService(UserTransaction.class, transactionManager, null);
174 // bc.registerService(TransactionSynchronizationRegistry.class, transactionSynchronizationRegistry, null);
175 // if (log.isDebugEnabled())
176 // log.debug("Initialised default Bitronix transaction manager");
177 // }
178
179 void shutdown() {
180 if (log.isDebugEnabled())
181 log.debug("CMS stopping... (" + this.stateUuid + ")");
182
183 if (kernelThread != null)
184 kernelThread.destroyAndJoin();
185 // In a different thread in order to avoid interruptions
186 Thread stopHookThread = new Thread(() -> applyStopHooks(), "Apply Argeo Stop Hooks");
187 stopHookThread.start();
188 try {
189 stopHookThread.join(10 * 60 * 1000);
190 } catch (InterruptedException e) {
191 // silent
192 }
193
194 long duration = ((System.currentTimeMillis() - availableSince) / 1000) / 60;
195 log.info("## ARGEO CMS STOPPED after " + (duration / 60) + "h " + (duration % 60) + "min uptime ##");
196 }
197
198 /** Apply shutdown hoos in reverse order. */
199 private void applyStopHooks() {
200 for (int i = stopHooks.size() - 1; i >= 0; i--) {
201 try {
202 stopHooks.get(i).run();
203 } catch (Exception e) {
204 log.error("Could not run shutdown hook #" + i);
205 }
206 }
207 // Clean hanging Gogo shell thread
208 new GogoShellKiller().start();
209 }
210
211 // @Override
212 // public boolean isClean() {
213 // return cleanState;
214 // }
215
216 @Override
217 public Long getAvailableSince() {
218 return availableSince;
219 }
220
221 /*
222 * ACCESSORS
223 */
224 public Locale getDefaultLocale() {
225 return defaultLocale;
226 }
227
228 public List<Locale> getLocales() {
229 return locales;
230 }
231
232 public String getHostname() {
233 return hostname;
234 }
235 }