PageRenderTime 37ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/service-manager/trunk/src/main/java/com/unitt/servicemanager/websocket/MessagingWebSocket.java

http://unitt.googlecode.com/
Java | 280 lines | 220 code | 44 blank | 16 comment | 23 complexity | 91fb28e9fd64b837376dcf05643a9abb MD5 | raw file
  1. package com.unitt.servicemanager.websocket;
  2. import java.io.ByteArrayOutputStream;
  3. import java.io.IOException;
  4. import java.util.UUID;
  5. import java.util.concurrent.BlockingQueue;
  6. import java.util.concurrent.ConcurrentMap;
  7. import java.util.concurrent.TimeUnit;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10. import com.unitt.commons.foundation.lifecycle.Destructable;
  11. import com.unitt.commons.foundation.lifecycle.Initializable;
  12. import com.unitt.servicemanager.util.ByteUtil;
  13. import com.unitt.servicemanager.util.ValidationUtil;
  14. public abstract class MessagingWebSocket implements Initializable, Destructable
  15. {
  16. private static Logger logger = LoggerFactory.getLogger( MessagingWebSocket.class );
  17. private ServerWebSocket serverWebSocket;
  18. private boolean isInitialized;
  19. private String socketId;
  20. private String serverId;
  21. private MessageSerializerRegistry serializers;
  22. private long queueTimeoutInMillis;
  23. // constructors
  24. // ---------------------------------------------------------------------------
  25. public MessagingWebSocket()
  26. {
  27. this( null, null, 30000, null );
  28. }
  29. public MessagingWebSocket( String aServerId, MessageSerializerRegistry aSerializers, long aQueueTimeoutInMillis, ServerWebSocket aServerWebSocket )
  30. {
  31. this( aServerId, aSerializers, aQueueTimeoutInMillis, aServerWebSocket, null );
  32. }
  33. public MessagingWebSocket( String aServerId, MessageSerializerRegistry aSerializers, long aQueueTimeoutInMillis, ServerWebSocket aServerWebSocket, String aSocketId )
  34. {
  35. setServerId(aServerId);
  36. setSerializerRegistry( aSerializers );
  37. setQueueTimeoutInMillis( aQueueTimeoutInMillis );
  38. setServerWebSocket( aServerWebSocket );
  39. setSocketId( aSocketId );
  40. }
  41. // lifecycle logic
  42. // ---------------------------------------------------------------------------
  43. public void destroy()
  44. {
  45. setServerId(null);
  46. setSerializerRegistry( null );
  47. setServerWebSocket( null );
  48. setSocketId( null );
  49. setQueueTimeoutInMillis( 0 );
  50. }
  51. public boolean isInitialized()
  52. {
  53. return isInitialized;
  54. }
  55. public void initialize()
  56. {
  57. // init
  58. if ( getSocketId() == null )
  59. {
  60. setSocketId( UUID.randomUUID().toString() );
  61. }
  62. if ( getQueueTimeoutInMillis() == 0 )
  63. {
  64. setQueueTimeoutInMillis( 30000 );
  65. }
  66. String missing = null;
  67. // validate we have all properties
  68. if ( getSerializerRegistry() == null )
  69. {
  70. missing = ValidationUtil.appendMessage( missing, "Missing serializer registry. " );
  71. }
  72. if ( getServerWebSocket() == null )
  73. {
  74. missing = ValidationUtil.appendMessage( missing, "Missing server web socket. " );
  75. }
  76. if ( getServerId() == null )
  77. {
  78. missing = ValidationUtil.appendMessage( missing, "Missing server id. " );
  79. }
  80. // fail out with appropriate message if missing anything
  81. if ( missing != null )
  82. {
  83. logger.error( missing );
  84. throw new IllegalStateException( missing );
  85. }
  86. setInitialized( true );
  87. }
  88. protected void setInitialized( boolean aIsInitialized )
  89. {
  90. isInitialized = aIsInitialized;
  91. }
  92. // getters & setters
  93. // ---------------------------------------------------------------------------
  94. public String getSocketId()
  95. {
  96. return socketId;
  97. }
  98. public void setSocketId( String aSocketId )
  99. {
  100. socketId = aSocketId;
  101. }
  102. public String getServerId()
  103. {
  104. return serverId;
  105. }
  106. public void setServerId( String aServerId )
  107. {
  108. serverId = aServerId;
  109. }
  110. public MessageSerializerRegistry getSerializers()
  111. {
  112. return serializers;
  113. }
  114. public void setSerializers( MessageSerializerRegistry aSerializers )
  115. {
  116. serializers = aSerializers;
  117. }
  118. public MessageSerializerRegistry getSerializerRegistry()
  119. {
  120. return serializers;
  121. }
  122. public void setSerializerRegistry( MessageSerializerRegistry aSerializers )
  123. {
  124. serializers = aSerializers;
  125. }
  126. public long getQueueTimeoutInMillis()
  127. {
  128. return queueTimeoutInMillis;
  129. }
  130. public void setQueueTimeoutInMillis( long aQueueTimeoutInMillis )
  131. {
  132. queueTimeoutInMillis = aQueueTimeoutInMillis;
  133. }
  134. public ServerWebSocket getServerWebSocket()
  135. {
  136. return serverWebSocket;
  137. }
  138. public void setServerWebSocket( ServerWebSocket aServerWebSocket )
  139. {
  140. serverWebSocket = aServerWebSocket;
  141. }
  142. // web socket logic
  143. // ---------------------------------------------------------------------------
  144. public void send( MessageResponse aResponse )
  145. {
  146. ByteArrayOutputStream output = new ByteArrayOutputStream();
  147. try
  148. {
  149. MessageSerializer serializer = getSerializerRegistry().getSerializer( aResponse.getHeader().getSerializerType() );
  150. byte[] headerBytes = serializer.serializeHeader( aResponse.getHeader() );
  151. byte[] bodyBytes = aResponse.getBodyBytes();
  152. if (bodyBytes == null && aResponse.getBody() != null)
  153. {
  154. bodyBytes = serializer.serializeBody( aResponse.getBody() );
  155. }
  156. System.out.println("Sending serialized body: " + new String(bodyBytes));
  157. output.write( ByteUtil.convertShortToBytes( new Integer( headerBytes.length ).shortValue() ) );
  158. output.write( ByteUtil.convertShortToBytes( aResponse.getHeader().getSerializerType() ) );
  159. output.write( headerBytes );
  160. output.write( bodyBytes );
  161. byte[] bytesOut = output.toByteArray();
  162. getServerWebSocket().sendMessage( bytesOut );
  163. }
  164. catch ( Exception e )
  165. {
  166. logger.error( "An error occurred sending the message response: " + aResponse, e );
  167. }
  168. finally
  169. {
  170. try
  171. {
  172. output.close();
  173. }
  174. catch ( IOException e )
  175. {
  176. // do nothing
  177. }
  178. }
  179. }
  180. public void onMessage( byte[] aData )
  181. {
  182. short headerLength = ByteUtil.convertBytesToShort( aData, 0 );
  183. short serializerType = ByteUtil.convertBytesToShort( aData, 2 );
  184. int bodyLength = aData.length - headerLength - 4;
  185. if ( bodyLength > 0 && headerLength > 0 && aData.length > bodyLength && aData.length > headerLength )
  186. {
  187. // assemble message parts
  188. byte[] headerBytes = new byte[headerLength];
  189. System.arraycopy( aData, 4, headerBytes, 0, headerLength );
  190. byte[] bodyBytes = new byte[bodyLength];
  191. System.arraycopy( aData, 4 + headerLength, bodyBytes, 0, bodyLength );
  192. // create message objects
  193. MessageSerializer serializer = getSerializerRegistry().getSerializer( serializerType );
  194. if (serializer == null)
  195. {
  196. logger.debug("Could not find serializer: " + serializerType);
  197. }
  198. MessageRoutingInfo header = serializer.deserializeHeader( headerBytes );
  199. header.setSerializerType( serializerType );
  200. header.setWebSocketId( getSocketId() );
  201. header.setServerId( getServerId() );
  202. SerializedMessageBody body = new SerializedMessageBody( bodyBytes );
  203. // put body bytes in map
  204. pushBody( header.getUid(), body );
  205. // push message header into routing queue
  206. if ( !pushHeader( header ) )
  207. {
  208. removeBody( header.getUid() );
  209. }
  210. }
  211. }
  212. public boolean pushHeader( MessageRoutingInfo aHeader )
  213. {
  214. try
  215. {
  216. logger.debug( "Pushing header: " + aHeader );
  217. return getHeaderQueue().offer( aHeader, getQueueTimeoutInMillis(), TimeUnit.MILLISECONDS );
  218. }
  219. catch ( Exception e )
  220. {
  221. logger.error( "Could not push header to be routed: " + aHeader, e );
  222. return false;
  223. }
  224. }
  225. public void pushBody( String aUid, SerializedMessageBody aBody )
  226. {
  227. logger.info( "Pushing body to map for key: " + aUid );
  228. getBodyMap().put( aUid, aBody );
  229. }
  230. public void removeBody( String aUid )
  231. {
  232. getBodyMap().remove( aUid );
  233. }
  234. public abstract ConcurrentMap<String, SerializedMessageBody> getBodyMap();
  235. public abstract BlockingQueue<MessageRoutingInfo> getHeaderQueue();
  236. }