/src/main/java/org/chililog/server/engine/RepositoryService.java

https://github.com/lightningdb/chililog-server · Java · 362 lines · 158 code · 33 blank · 171 comment · 44 complexity · a58ef698e4dfd62757f5ba8b8740cae1 MD5 · raw file

  1. //
  2. // Copyright 2010 Cinch Logic Pty Ltd.
  3. //
  4. // http://www.chililog.com
  5. //
  6. // Licensed under the Apache License, Version 2.0 (the "License");
  7. // you may not use this file except in compliance with the License.
  8. // You may obtain a copy of the License at
  9. //
  10. // http://www.apache.org/licenses/LICENSE-2.0
  11. //
  12. // Unless required by applicable law or agreed to in writing, software
  13. // distributed under the License is distributed on an "AS IS" BASIS,
  14. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. // See the License for the specific language governing permissions and
  16. // limitations under the License.
  17. //
  18. package org.chililog.server.engine;
  19. import java.util.ArrayList;
  20. import org.bson.types.ObjectId;
  21. import org.chililog.server.common.ChiliLogException;
  22. import org.chililog.server.common.Log4JLogger;
  23. import org.chililog.server.data.MongoConnection;
  24. import org.chililog.server.data.RepositoryConfigBO;
  25. import org.chililog.server.data.RepositoryConfigController;
  26. import org.chililog.server.data.RepositoryConfigListCriteria;
  27. import org.chililog.server.data.RepositoryConfigBO.Status;
  28. import com.mongodb.DB;
  29. /**
  30. * <p>
  31. * The RepositoryService is responsible managing for start/stop/reload all repositories.
  32. * </p>
  33. *
  34. * <pre>
  35. * // Start all repositories
  36. * RepositoryManager.getInstance().start();
  37. *
  38. * // Stop all repositories
  39. * RepositoryManager.getInstance().stop();
  40. * </pre>
  41. *
  42. * <p>
  43. * It is assumed that mongoDB and HornetQ (via {@link MqService}) has been started.
  44. * </p>
  45. *
  46. * @author vibul
  47. *
  48. */
  49. public class RepositoryService {
  50. static Log4JLogger _logger = Log4JLogger.getLogger(RepositoryService.class);
  51. /**
  52. * List of repositories that are readonly or online
  53. */
  54. private ArrayList<Repository> _activeRepositories = new ArrayList<Repository>();
  55. /**
  56. * Returns the singleton instance for this class
  57. */
  58. public static RepositoryService getInstance() {
  59. return SingletonHolder.INSTANCE;
  60. }
  61. /**
  62. * SingletonHolder is loaded on the first execution of Singleton.getInstance() or the first access to
  63. * SingletonHolder.INSTANCE, not before.
  64. *
  65. * @see http://en.wikipedia.org/wiki/Singleton_pattern
  66. */
  67. private static class SingletonHolder {
  68. public static final RepositoryService INSTANCE = new RepositoryService();
  69. }
  70. /**
  71. * <p>
  72. * Singleton constructor
  73. * </p>
  74. */
  75. private RepositoryService() {
  76. return;
  77. }
  78. /**
  79. * <p>
  80. * Starts this service by starting all repositories where the startup status is ONLINE
  81. * </p>
  82. * <p>
  83. * Should be called once at the start of the application
  84. * </p>
  85. */
  86. public synchronized void start() throws ChiliLogException {
  87. ArrayList<RepositoryConfigBO> repoConfigList = this.getRepositoryConfigList();
  88. for (RepositoryConfigBO repoConfig : repoConfigList) {
  89. if (repoConfig.getStartupStatus() == Status.ONLINE) {
  90. bringRepositoryOnline(repoConfig);
  91. } else if (repoConfig.getStartupStatus() == Status.READONLY) {
  92. makeRepositoryReadOnly(repoConfig);
  93. }
  94. }
  95. return;
  96. }
  97. /**
  98. * Stops this service
  99. *
  100. * @throws Exception
  101. */
  102. public synchronized void stop() throws Exception {
  103. takeAllRepositoriesOffline();
  104. return;
  105. }
  106. /**
  107. * <p>
  108. * Brings all repositories online
  109. * </p>
  110. */
  111. public synchronized void bringAllRepositoriesOnline() throws ChiliLogException {
  112. ArrayList<RepositoryConfigBO> repoList = this.getRepositoryConfigList();
  113. for (RepositoryConfigBO repoConfig : repoList) {
  114. // If offline or readonly, enable it
  115. Repository repo = getActiveRepository(repoConfig.getDocumentID());
  116. if (repo == null) {
  117. bringRepositoryOnline(repoConfig);
  118. } else if (repo.getStatus() == Status.READONLY) {
  119. // Reload readonly repositories so that it gets the latest definition
  120. takeRepositoryOffline(repo);
  121. makeRepositoryReadOnly(repoConfig);
  122. }
  123. }
  124. return;
  125. }
  126. /**
  127. * <p>
  128. * Make all repositories read only
  129. * </p>
  130. */
  131. public synchronized void makeAllRepositoriesReadonly() throws ChiliLogException {
  132. ArrayList<RepositoryConfigBO> repoList = this.getRepositoryConfigList();
  133. for (RepositoryConfigBO repoConfig : repoList) {
  134. // If offline or readonly, enable it
  135. Repository repo = getActiveRepository(repoConfig.getDocumentID());
  136. if (repo == null) {
  137. makeRepositoryReadOnly(repoConfig);
  138. } else if (repo.getStatus() == Status.ONLINE) {
  139. repo.makeReadonly();
  140. }
  141. }
  142. return;
  143. }
  144. /**
  145. * <p>
  146. * Take all repositories offline
  147. * </p>
  148. */
  149. public synchronized void takeAllRepositoriesOffline() throws ChiliLogException {
  150. for (Repository repo : _activeRepositories) {
  151. repo.takeOffline();
  152. }
  153. _activeRepositories.clear();
  154. return;
  155. }
  156. /**
  157. * Starts the specified repository. Once started, a repository becomes "online". Log entries will be streamed and
  158. * saved (if configured to do so).
  159. *
  160. * @param repositoryInfoDocumentID
  161. * Document ID of the repository info to start
  162. * @return Repository runtime information
  163. * @throws ChiliLogException
  164. */
  165. public synchronized Repository bringRepositoryOnline(ObjectId repositoryInfoDocumentID) throws ChiliLogException {
  166. Repository repo = this.getActiveRepository(repositoryInfoDocumentID);
  167. if (repo != null) {
  168. if (repo.getStatus() == Status.ONLINE) {
  169. // Repository is already online
  170. return repo;
  171. } else if (repo.getStatus() == Status.READONLY) {
  172. // Remove the repository so we can bring online with the latest definition
  173. _activeRepositories.remove(repo);
  174. }
  175. }
  176. DB db = MongoConnection.getInstance().getConnection();
  177. RepositoryConfigBO repoInfo = RepositoryConfigController.getInstance().get(db, repositoryInfoDocumentID);
  178. return bringRepositoryOnline(repoInfo);
  179. }
  180. /**
  181. * Creates the specified repository and brings it online
  182. *
  183. * @param repoConfig
  184. * Meta data of repository to bring online
  185. * @return Repository runtime information
  186. * @throws ChiliLogException
  187. */
  188. private Repository bringRepositoryOnline(RepositoryConfigBO repoConfig) throws ChiliLogException {
  189. Repository repo = new Repository(repoConfig);
  190. repo.bringOnline();
  191. _activeRepositories.add(repo);
  192. return repo;
  193. }
  194. /**
  195. * Creates a repository and make it readonly
  196. *
  197. * @param repositoryInfoDocumentID
  198. * Document ID of the repository to stop
  199. * @return Repository runtime information
  200. * @throws ChiliLogException
  201. */
  202. public synchronized Repository makeRepositoryReadOnly(ObjectId repositoryInfoDocumentID) throws ChiliLogException {
  203. Repository repo = this.getActiveRepository(repositoryInfoDocumentID);
  204. if (repo != null) {
  205. if (repo.getStatus() == Status.ONLINE) {
  206. // Make repository readonly
  207. repo.makeReadonly();
  208. return repo;
  209. } else if (repo.getStatus() == Status.READONLY) {
  210. // Repo already readonly so just return it
  211. return repo;
  212. }
  213. }
  214. DB db = MongoConnection.getInstance().getConnection();
  215. RepositoryConfigBO repoInfo = RepositoryConfigController.getInstance().get(db, repositoryInfoDocumentID);
  216. return makeRepositoryReadOnly(repoInfo);
  217. }
  218. /**
  219. * Creates a repository and make it readonly
  220. *
  221. * @param repoConfig
  222. * Runtime information of repository to make readonly
  223. * @return Repository runtime information
  224. * @throws ChiliLogException
  225. */
  226. private synchronized Repository makeRepositoryReadOnly(RepositoryConfigBO repoConfig) throws ChiliLogException {
  227. Repository repo = new Repository(repoConfig);
  228. repo.makeReadonly();
  229. _activeRepositories.add(repo);
  230. return repo;
  231. }
  232. /**
  233. * Take the specified repository offline. Streaming of log entries will be disabled and new log entries will not be
  234. * stored. Also, searching is prohibited on the workbench.
  235. *
  236. * @param repositoryInfoDocumentID
  237. * Document ID of the repository to stop
  238. * @throws ChiliLogException
  239. */
  240. public synchronized void takeRepositoryOffline(ObjectId repositoryInfoDocumentID) throws ChiliLogException {
  241. Repository repo = getActiveRepository(repositoryInfoDocumentID);
  242. if (repo != null) {
  243. takeRepositoryOffline(repo);
  244. }
  245. }
  246. /**
  247. * Take the specified repository off line. Streaming of log entries will be disabled and new log entries will not be
  248. * stored. Also, searching is prohibited on the workbench.
  249. *
  250. * @param repo
  251. * Runtime information of repository to stop
  252. * @throws ChiliLogException
  253. */
  254. private synchronized void takeRepositoryOffline(Repository repo) throws ChiliLogException {
  255. repo.takeOffline();
  256. _activeRepositories.remove(repo);
  257. return;
  258. }
  259. /**
  260. * Finds an online repository with a matching repository configuration document id
  261. *
  262. * @param repositoryConfigDocumentID
  263. * ID of repository configuration document of repository to find
  264. * @return Matching repository. <code>null</code> if not found
  265. */
  266. private Repository getActiveRepository(ObjectId repositoryConfigDocumentID) {
  267. for (Repository repo : _activeRepositories) {
  268. if (repo.getRepoConfig().getDocumentID().equals(repositoryConfigDocumentID)) {
  269. return repo;
  270. }
  271. }
  272. return null;
  273. }
  274. /**
  275. * <p>
  276. * Returns a list of repository configuration
  277. * </p>
  278. *
  279. * @throws ChiliLogException
  280. */
  281. private ArrayList<RepositoryConfigBO> getRepositoryConfigList() throws ChiliLogException {
  282. // Get count connections
  283. DB db = MongoConnection.getInstance().getConnection();
  284. // Get list of repositories
  285. RepositoryConfigListCriteria criteria = new RepositoryConfigListCriteria();
  286. ArrayList<RepositoryConfigBO> list = RepositoryConfigController.getInstance().getList(db, criteria);
  287. return list;
  288. }
  289. /**
  290. * Returns the latest runtime information for the specified repository info id.
  291. *
  292. * @param id
  293. * Repository config document id of the repository to retrieve
  294. * @return Matching repository.
  295. * @throws ChiliLogException
  296. * - if error or not found
  297. */
  298. public synchronized Repository getRepository(ObjectId id) throws ChiliLogException {
  299. // Check it see if repository is online
  300. for (Repository repo : _activeRepositories) {
  301. if (repo.getRepoConfig().getDocumentID().equals(id)) {
  302. return repo;
  303. }
  304. }
  305. // Get count connections
  306. DB db = MongoConnection.getInstance().getConnection();
  307. RepositoryConfigBO repoConfig = RepositoryConfigController.getInstance().get(db, id);
  308. return repoConfig == null ? null : new Repository(repoConfig);
  309. }
  310. /**
  311. * Returns the latest runtime information for all repositories
  312. *
  313. * @throws ChiliLogException
  314. */
  315. public synchronized Repository[] getRepositories() throws ChiliLogException {
  316. ArrayList<Repository> list = new ArrayList<Repository>();
  317. ArrayList<RepositoryConfigBO> repoConfigList = this.getRepositoryConfigList();
  318. for (RepositoryConfigBO repoConfig : repoConfigList) {
  319. Repository repo = getActiveRepository(repoConfig.getDocumentID());
  320. if (repo == null) {
  321. list.add(new Repository(repoConfig));
  322. } else {
  323. // Online so send that one
  324. list.add(repo);
  325. }
  326. }
  327. return list.toArray(new Repository[] {});
  328. }
  329. }