PageRenderTime 2988ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/jWebSocket/shared/J2SE/jWebSocketServer/org/jwebsocket/plugins/channels/ChannelManager.java

http://jwebsocket.googlecode.com/
Java | 367 lines | 185 code | 29 blank | 153 comment | 31 complexity | 4a7afad2f18f330e38df60db0c623c0f MD5 | raw file
Possible License(s): Apache-2.0
  1. // ---------------------------------------------------------------------------
  2. // Copyright (c) 2010 Innotrade GmbH, jWebSocket.org
  3. // ---------------------------------------------------------------------------
  4. // This program is free software; you can redistribute it and/or modify it
  5. // under the terms of the GNU Lesser General Public License as published by the
  6. // Free Software Foundation; either version 3 of the License, or (at your
  7. // option) any later version.
  8. // This program is distributed in the hope that it will be useful, but WITHOUT
  9. // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
  11. // more details.
  12. // You should have received a copy of the GNU Lesser General Public License along
  13. // with this program; if not, see <http://www.gnu.org/licenses/lgpl.html>.
  14. // ---------------------------------------------------------------------------
  15. package org.jwebsocket.plugins.channels;
  16. import java.util.Collections;
  17. import java.util.Map;
  18. import java.util.concurrent.ConcurrentHashMap;
  19. import org.jwebsocket.api.WebSocketConnector;
  20. import org.jwebsocket.config.JWebSocketCommonConstants;
  21. import org.jwebsocket.config.JWebSocketConfig;
  22. import org.jwebsocket.config.JWebSocketServerConstants;
  23. import org.jwebsocket.config.xml.ChannelConfig;
  24. import org.jwebsocket.security.SecurityFactory;
  25. import org.jwebsocket.security.User;
  26. import org.jwebsocket.token.Token;
  27. import org.jwebsocket.token.TokenFactory;
  28. /**
  29. * Manager class responsible for all the channel operations within the
  30. * jWebSocket server system.
  31. *
  32. * @author puran
  33. * @version $Id: ChannelManager.java 1425 2011-01-04 18:56:34Z fivefeetfurther $
  34. */
  35. public class ChannelManager {
  36. /** id for the logger channel */
  37. private static final String LOGGER_CHANNEL_ID = "jws.logger.channel";
  38. /** id for the admin channel */
  39. private static final String ADMIN_CHANNEL_ID = "jws.admin.channel";
  40. /** settings key strings */
  41. private static final String USE_PERSISTENT_STORE = "use_persistent_store";
  42. private static final String ALLOW_NEW_CHANNELS = "allow_new_channels";
  43. /** persistent storage objects */
  44. private final ChannelStore mChannelStore = new BaseChannelStore();
  45. private final SubscriberStore mSubscriberStore = new BaseSubscriberStore();
  46. private final PublisherStore mPublisherStore = new BasePublisherStore();
  47. /** in-memory store maps */
  48. private final Map<String, Channel> mSystemChannels = new ConcurrentHashMap<String, Channel>();
  49. private final Map<String, Channel> mPrivateChannels = new ConcurrentHashMap<String, Channel>();
  50. private final Map<String, Channel> mPublicChannels = new ConcurrentHashMap<String, Channel>();
  51. private Map<String, String> mChannelPluginSettings = null;
  52. /**
  53. * Logger channel that publish all the logs in jWebSocket system
  54. */
  55. private static Channel mLoggerChannel = null;
  56. /**
  57. * admin channel to monitor channel plugin activity
  58. */
  59. private static Channel mAdminChannel = null;
  60. /** setting to check for persistent storage or not */
  61. public static boolean usePersistentStore;
  62. /** setting to check if new channel creation or registration is allowed */
  63. public static boolean allowNewChannels;
  64. private ChannelManager(Map<String, String> aSettings) {
  65. this.mChannelPluginSettings = new ConcurrentHashMap<String, String>(aSettings);
  66. String lUsePersisentStore = mChannelPluginSettings.get(USE_PERSISTENT_STORE);
  67. if (lUsePersisentStore != null && lUsePersisentStore.equals("true")) {
  68. usePersistentStore = true;
  69. }
  70. String lAllowNewChannels = mChannelPluginSettings.get(ALLOW_NEW_CHANNELS);
  71. if (lAllowNewChannels != null && lAllowNewChannels.equals("true")) {
  72. allowNewChannels = true;
  73. }
  74. }
  75. /**
  76. * @return the static manager instance
  77. */
  78. public static ChannelManager getChannelManager(Map<String, String> aSettings) {
  79. return new ChannelManager(aSettings);
  80. }
  81. /**
  82. * Starts the system channels within the jWebSocket system configured via
  83. * jWebSocket.xml, Note that it doesn't insert the system channels to the
  84. * channel store.
  85. *
  86. * @throws ChannelLifeCycleException
  87. * if exception starting the system channels
  88. */
  89. public void startSystemChannels() throws ChannelLifeCycleException {
  90. User lRoot = SecurityFactory.getRootUser();
  91. // TODO: Process if no root user could be found!
  92. JWebSocketConfig lConfig = JWebSocketConfig.getConfig();
  93. for (ChannelConfig lCfg : lConfig.getChannels()) {
  94. if (lCfg.isSystemChannel()) {
  95. lCfg.validate();
  96. if (LOGGER_CHANNEL_ID.equals(lCfg.getId())) {
  97. mLoggerChannel = new Channel(lCfg);
  98. mLoggerChannel.start(lRoot.getLoginname());
  99. } else if (ADMIN_CHANNEL_ID.equals(lCfg.getId())) {
  100. mAdminChannel = new Channel(lCfg);
  101. mAdminChannel.start(lRoot.getLoginname());
  102. } else {
  103. Channel lChannel = new Channel(lCfg);
  104. lChannel.start(lRoot.getLoginname());
  105. // put in system channels map
  106. mSystemChannels.put(lChannel.getId(), lChannel);
  107. }
  108. }
  109. }
  110. }
  111. /**
  112. * Stops all the system channels running in the system and clears the system
  113. * channels map
  114. */
  115. public void stopSystemChannels() throws ChannelLifeCycleException {
  116. User root = SecurityFactory.getRootUser();
  117. for (Map.Entry<String, Channel> entry : mSystemChannels.entrySet()) {
  118. Channel channel = entry.getValue();
  119. channel.stop(root.getLoginname());
  120. }
  121. mSystemChannels.clear();
  122. if (mLoggerChannel != null) {
  123. mLoggerChannel.stop(root.getLoginname());
  124. }
  125. if (mAdminChannel != null) {
  126. mAdminChannel.stop(root.getLoginname());
  127. }
  128. }
  129. /**
  130. * Returns the channel registered in the jWebSocket system based on channel
  131. * id it does a various lookup and then if it doesn't find anywhere from the
  132. * memory it loads the channel from the database. If it doesn' find anything
  133. * then it returns the null object
  134. *
  135. * @param aChannelId
  136. * @return channel object, null if not found
  137. */
  138. public Channel getChannel(String aChannelId) {
  139. if (mSystemChannels.containsKey(aChannelId)) {
  140. return mSystemChannels.get(aChannelId);
  141. }
  142. if (mPrivateChannels.containsKey(aChannelId)) {
  143. return mPrivateChannels.get(aChannelId);
  144. }
  145. if (mPublicChannels.containsKey(aChannelId)) {
  146. return mPublicChannels.get(aChannelId);
  147. }
  148. if (usePersistentStore) {
  149. // if not anywhere then look in the channel store
  150. Channel channel = mChannelStore.getChannel(aChannelId);
  151. if (channel != null) {
  152. mPublicChannels.put(aChannelId, channel);
  153. }
  154. return channel;
  155. }
  156. return null;
  157. }
  158. /**
  159. * Register the given channel to the list of channels maintained by the
  160. * jWebSocket system.
  161. *
  162. * @param aChannel
  163. * the channel to store.
  164. */
  165. public void registerChannel(Channel aChannel) {
  166. if (aChannel.isSystemChannel()) {
  167. mSystemChannels.put(aChannel.getId(), aChannel);
  168. } else if (aChannel.isPrivateChannel()) {
  169. mPrivateChannels.put(aChannel.getId(), aChannel);
  170. } else {
  171. mPublicChannels.put(aChannel.getId(), aChannel);
  172. }
  173. if (usePersistentStore) {
  174. mChannelStore.storeChannel(aChannel);
  175. }
  176. }
  177. /**
  178. * Returns the registered subscriber object for the given subscriber id
  179. *
  180. * @param aSubscriberId
  181. * the subscriber id
  182. * @return the subscriber object
  183. */
  184. public Subscriber getSubscriber(String aSubscriberId) {
  185. return mSubscriberStore.getSubscriber(aSubscriberId);
  186. }
  187. /**
  188. * Stores the registered subscriber information in the channel store
  189. *
  190. * @param aSubscriber
  191. * the subscriber to register
  192. */
  193. public void storeSubscriber(Subscriber aSubscriber) {
  194. mSubscriberStore.storeSubscriber(aSubscriber);
  195. }
  196. /**
  197. * Removes the given subscriber information from channel store
  198. *
  199. * @param aSubscriber
  200. * the subscriber object
  201. */
  202. public void removeSubscriber(Subscriber aSubscriber) {
  203. mSubscriberStore.removeSubscriber(aSubscriber.getId());
  204. }
  205. /**
  206. * Returns the registered publisher for the given publisher id
  207. *
  208. * @param aPublisherId
  209. * the publisher id
  210. * @return the publisher object
  211. */
  212. public Publisher getPublisher(String aPublisherId) {
  213. return mPublisherStore.getPublisher(aPublisherId);
  214. }
  215. /**
  216. * Stores the given publisher to the channel store
  217. *
  218. * @param publisher
  219. * the publisher object to store
  220. */
  221. public void storePublisher(Publisher aPublisher) {
  222. mPublisherStore.storePublisher(aPublisher);
  223. }
  224. /**
  225. * Removes the publisher from the channel store permanently
  226. *
  227. * @param aPublisher
  228. * the publisher to remove
  229. */
  230. public void removePublisher(Publisher aPublisher) {
  231. mPublisherStore.removePublisher(aPublisher.getId());
  232. }
  233. /**
  234. * Returns the instance of the logger channel.If not initialized for some
  235. * reason returns null.
  236. *
  237. * @return the logger channel
  238. */
  239. public static Channel getLoggerChannel() {
  240. return mLoggerChannel;
  241. }
  242. /**
  243. * Returns the instance of the admin channel. If not initialized for some
  244. * reasons returns null.
  245. *
  246. * @return the admin channel
  247. */
  248. public static Channel getAdminChannel() {
  249. return mAdminChannel;
  250. }
  251. public void publishToLoggerChannel(Token aToken) {
  252. Channel lLoggerChannel = getLoggerChannel();
  253. // Added by Alex:
  254. if (lLoggerChannel != null) {
  255. lLoggerChannel.broadcastToken(aToken);
  256. }
  257. }
  258. /**
  259. * Returns the error token
  260. *
  261. * @param aConnector
  262. * the target connector object
  263. * @param aChannelId
  264. * the channelId
  265. * @param aMessage
  266. * the error message
  267. * @return the error token
  268. */
  269. public Token getErrorToken(WebSocketConnector aConnector, String aChannelId, String aMessage) {
  270. Token logToken = getBaseChannelResponse(aConnector, aChannelId);
  271. logToken.setString("event", "error");
  272. logToken.setString("error", aMessage);
  273. return logToken;
  274. }
  275. /**
  276. * Returns the basic response token for a channel
  277. *
  278. * @param aConnector
  279. * the target connector object
  280. * @param aChannel
  281. * the target channel
  282. * @return the base token of type channel
  283. */
  284. public Token getBaseChannelResponse(WebSocketConnector aConnector, String aChannel) {
  285. Token channelToken = TokenFactory.createToken("channel");
  286. // TODO: In clusters, especially for service nodes we will post these fields on a lower level!
  287. // check! Commented out by Alex
  288. // channelToken.setString("vendor", JWebSocketCommonConstants.VENDOR);
  289. // channelToken.setString("version", JWebSocketServerConstants.VERSION_STR);
  290. // Alex: These fields are mandatory
  291. channelToken.setString("sourceId", aConnector.getId());
  292. channelToken.setString("channelId", aChannel);
  293. return channelToken;
  294. }
  295. public Token getChannelSuccessToken(WebSocketConnector aConnector, String aChannel, ChannelEventEnum aEventType) {
  296. Token lToken = getBaseChannelResponse(aConnector, aChannel);
  297. String lEvent = "";
  298. switch (aEventType) {
  299. case LOGIN:
  300. lEvent = "login";
  301. break;
  302. case AUTHORIZE:
  303. lEvent = "authorize";
  304. break;
  305. case PUBLISH:
  306. lEvent = "publish";
  307. break;
  308. case SUSCRIBE:
  309. lEvent = "subscribe";
  310. case UNSUSCRIBE:
  311. lEvent = "unsuscribe";
  312. break;
  313. default:
  314. break;
  315. }
  316. lToken.setString("event", lEvent);
  317. lToken.setString("status", "ok");
  318. return lToken;
  319. }
  320. /**
  321. * @return the system channels
  322. */
  323. public Map<String, Channel> getSystemChannels() {
  324. return Collections.unmodifiableMap(mSystemChannels);
  325. }
  326. /**
  327. * @return the private channels
  328. */
  329. public Map<String, Channel> getPrivateChannels() {
  330. return Collections.unmodifiableMap(mPrivateChannels);
  331. }
  332. /**
  333. * @return the public channels
  334. */
  335. public Map<String, Channel> getPublicChannels() {
  336. return Collections.unmodifiableMap(mPublicChannels);
  337. }
  338. }