@Override
 public void run() {
   final SessionID sessionID;
   try {
     try {
       sessionID = statefulSessionComponent.createSession();
     } catch (Throwable t) {
       SessionOpenRequestHandler.this.writeException(
           channelAssociation,
           SessionOpenRequestHandler.this.marshallerFactory,
           invocationId,
           t,
           null);
       return;
     }
     // get the affinity of the component
     final Affinity hardAffinity = statefulSessionComponent.getCache().getStrictAffinity();
     SessionOpenRequestHandler.this.writeSessionId(
         channelAssociation, invocationId, sessionID, hardAffinity);
   } catch (IOException ioe) {
     EjbLogger.ROOT_LOGGER.exceptionGeneratingSessionId(
         ioe, invocationId, channelAssociation.getChannel());
     // close the channel
     IoUtils.safeClose(this.channelAssociation.getChannel());
     return;
   }
 }
 private void sendModuleUnAvailability(DeploymentModuleIdentifier[] availableModules)
     throws IOException {
   final DataOutputStream outputStream;
   final MessageOutputStream messageOutputStream;
   try {
     messageOutputStream = channelAssociation.acquireChannelMessageOutputStream();
   } catch (Exception e) {
     throw EjbLogger.ROOT_LOGGER.failedToOpenMessageOutputStream(e);
   }
   outputStream = new DataOutputStream(messageOutputStream);
   final ModuleAvailabilityWriter moduleAvailabilityWriter = new ModuleAvailabilityWriter();
   try {
     moduleAvailabilityWriter.writeModuleUnAvailability(outputStream, availableModules);
   } finally {
     channelAssociation.releaseChannelMessageOutputStream(messageOutputStream);
     outputStream.close();
   }
 }
 @Override
 public void deploymentRemoved(DeploymentModuleIdentifier deploymentModuleIdentifier) {
   try {
     this.sendModuleUnAvailability(new DeploymentModuleIdentifier[] {deploymentModuleIdentifier});
   } catch (IOException e) {
     EjbLogger.ROOT_LOGGER.failedToSendModuleUnavailabilityMessageToClient(
         e, deploymentModuleIdentifier, channelAssociation.getChannel());
   }
 }
 /**
  * Sends out a cluster removal message for the passed cluster, over the remoting channel
  *
  * @param registry The cluster which was removed
  * @throws IOException If any exception occurs while sending the message over the channel
  */
 private void sendClusterRemovedMessage(final Registry<String, List<ClientMapping>> registry)
     throws IOException {
   final DataOutputStream outputStream;
   final MessageOutputStream messageOutputStream;
   try {
     messageOutputStream = channelAssociation.acquireChannelMessageOutputStream();
   } catch (Exception e) {
     throw EjbLogger.ROOT_LOGGER.failedToOpenMessageOutputStream(e);
   }
   outputStream = new DataOutputStream(messageOutputStream);
   final ClusterTopologyWriter clusterTopologyWriter = new ClusterTopologyWriter();
   try {
     EjbLogger.ROOT_LOGGER.debug(
         "Cluster "
             + registry.getGroup().getName()
             + " removed, writing cluster removal message to channel "
             + this.channelAssociation.getChannel());
     clusterTopologyWriter.writeClusterRemoved(outputStream, Collections.singleton(registry));
   } finally {
     channelAssociation.releaseChannelMessageOutputStream(messageOutputStream);
     outputStream.close();
   }
 }
  private void writeSessionId(
      final ChannelAssociation channelAssociation,
      final short invocationId,
      final SessionID sessionID,
      final Affinity hardAffinity)
      throws IOException {
    final byte[] sessionIdBytes = sessionID.getEncodedForm();
    final DataOutputStream dataOutputStream;
    final MessageOutputStream messageOutputStream;
    try {
      messageOutputStream = channelAssociation.acquireChannelMessageOutputStream();
    } catch (Exception e) {
      throw EjbMessages.MESSAGES.failedToOpenMessageOutputStream(e);
    }
    dataOutputStream = new DataOutputStream(messageOutputStream);
    try {
      // write out header
      dataOutputStream.writeByte(HEADER_SESSION_OPEN_RESPONSE);
      // write out invocation id
      dataOutputStream.writeShort(invocationId);
      // session id byte length
      PackedInteger.writePackedInteger(dataOutputStream, sessionIdBytes.length);
      // write out the session id bytes
      dataOutputStream.write(sessionIdBytes);
      // now marshal the hard affinity associated with this session
      final Marshaller marshaller =
          this.prepareForMarshalling(this.marshallerFactory, dataOutputStream);
      marshaller.writeObject(hardAffinity);

      // finish marshalling
      marshaller.finish();

    } finally {
      channelAssociation.releaseChannelMessageOutputStream(messageOutputStream);
      dataOutputStream.close();
    }
  }
 /**
  * Sends a cluster formation message for the passed clusters, over the remoting channel
  *
  * @param clientMappingRegistries The new clusters
  * @throws IOException If any exception occurs while sending the message over the channel
  */
 private void sendNewClusterFormedMessage(
     final Collection<Registry<String, List<ClientMapping>>> clientMappingRegistries)
     throws IOException {
   final DataOutputStream outputStream;
   final MessageOutputStream messageOutputStream;
   try {
     messageOutputStream = channelAssociation.acquireChannelMessageOutputStream();
   } catch (Exception e) {
     throw EjbLogger.ROOT_LOGGER.failedToOpenMessageOutputStream(e);
   }
   outputStream = new DataOutputStream(messageOutputStream);
   final ClusterTopologyWriter clusterTopologyWriter = new ClusterTopologyWriter();
   try {
     EjbLogger.ROOT_LOGGER.debug(
         "Writing out cluster formation message for "
             + clientMappingRegistries.size()
             + " clusters, to channel "
             + this.channelAssociation.getChannel());
     clusterTopologyWriter.writeCompleteClusterTopology(outputStream, clientMappingRegistries);
   } finally {
     channelAssociation.releaseChannelMessageOutputStream(messageOutputStream);
     outputStream.close();
   }
 }
 @Override
 public void registryAdded(Registry<String, List<ClientMapping>> cluster) {
   try {
     EjbLogger.ROOT_LOGGER.debug(
         "Received new cluster formation notification for cluster "
             + cluster.getGroup().getName());
     this.sendNewClusterFormedMessage(Collections.singleton(cluster));
   } catch (IOException ioe) {
     EjbLogger.ROOT_LOGGER.failedToSendClusterFormationMessageToClient(
         ioe, cluster.getGroup().getName(), channelAssociation.getChannel());
   } finally {
     // add a listener for receiving node(s) addition/removal from the cluster
     final ClusterTopologyUpdateListener clusterTopologyUpdateListener =
         new ClusterTopologyUpdateListener(cluster, this);
     cluster.addListener(clusterTopologyUpdateListener);
     // keep track of this update listener so that we cleanup properly
     this.clusterTopologyUpdateListeners.add(clusterTopologyUpdateListener);
   }
 }