protected void processDispatch(Command command) throws IOException {
   MessageDispatch messageDispatch =
       (MessageDispatch) (command.isMessageDispatch() ? command : null);
   try {
     if (!stopping.get()) {
       if (messageDispatch != null) {
         protocolManager.preProcessDispatch(messageDispatch);
       }
       dispatch(command);
     }
   } catch (IOException e) {
     if (messageDispatch != null) {
       TransmitCallback sub = messageDispatch.getTransmitCallback();
       protocolManager.postProcessDispatch(messageDispatch);
       if (sub != null) {
         sub.onFailure();
       }
       messageDispatch = null;
       throw e;
     }
   } finally {
     if (messageDispatch != null) {
       TransmitCallback sub = messageDispatch.getTransmitCallback();
       protocolManager.postProcessDispatch(messageDispatch);
       if (sub != null) {
         sub.onSuccess();
       }
     }
   }
 }
 private AMQProducerBrokerExchange getProducerBrokerExchange(ProducerId id) throws IOException {
   AMQProducerBrokerExchange result = producerExchanges.get(id);
   if (result == null) {
     synchronized (producerExchanges) {
       result = new AMQProducerBrokerExchange();
       result.setConnectionContext(context);
       // todo implement reconnect https://issues.apache.org/jira/browse/ARTEMIS-194
       if (context.isReconnect()
           || (context.isNetworkConnection() && this.acceptorUsed.isAuditNetworkProducers())) {
         if (protocolManager.getPersistenceAdapter() != null) {
           result.setLastStoredSequenceId(
               protocolManager.getPersistenceAdapter().getLastProducerSequenceId(id));
         }
       }
       SessionState ss = state.getSessionState(id.getParentId());
       if (ss != null) {
         result.setProducerState(ss.getProducerState(id));
         ProducerState producerState = ss.getProducerState(id);
         if (producerState != null && producerState.getInfo() != null) {
           ProducerInfo info = producerState.getInfo();
           result.setMutable(info.getDestination() == null || info.getDestination().isComposite());
         }
       }
       producerExchanges.put(id, result);
     }
   }
   return result;
 }
 @Override
 public Response processAddSession(SessionInfo info) throws Exception {
   // Avoid replaying dup commands
   if (!state.getSessionIds().contains(info.getSessionId())) {
     protocolManager.addSession(this, info);
     try {
       state.addSession(info);
     } catch (IllegalStateException e) {
       e.printStackTrace();
       protocolManager.removeSession(context, info);
     }
   }
   return null;
 }
  protected void doStop() throws Exception {
    this.acceptorUsed.onStopped(this);
    /*
     * What's a duplex bridge? try { synchronized (this) { if (duplexBridge !=
     * null) { duplexBridge.stop(); } } } catch (Exception ignore) {
     * LOG.trace("Exception caught stopping. This exception is ignored.",
     * ignore); }
     */
    try {
      getTransportConnection().close();
    } catch (Exception e) {
      // log
    }

    if (taskRunner != null) {
      taskRunner.shutdown(1);
      taskRunner = null;
    }

    active = false;
    // Run the MessageDispatch callbacks so that message references get
    // cleaned up.
    synchronized (dispatchQueue) {
      for (Iterator<Command> iter = dispatchQueue.iterator(); iter.hasNext(); ) {
        Command command = iter.next();
        if (command.isMessageDispatch()) {
          MessageDispatch md = (MessageDispatch) command;
          TransmitCallback sub = md.getTransmitCallback();
          protocolManager.postProcessDispatch(md);
          if (sub != null) {
            sub.onFailure();
          }
        }
      }
      dispatchQueue.clear();
    }
    //
    // Remove all logical connection associated with this connection
    // from the broker.
    if (!protocolManager.isStopped()) {
      context.getStopping().set(true);
      try {
        processRemoveConnection(state.getInfo().getConnectionId(), 0L);
      } catch (Throwable ignore) {
        ignore.printStackTrace();
      }
    }
  }
 @Override
 public Response processRollbackTransaction(TransactionInfo info) throws Exception {
   protocolManager.rollbackTransaction(info);
   TransactionId txId = info.getTransactionId();
   txMap.remove(txId);
   return null;
 }
 public void dispatchAsync(Command message) {
   if (!stopping.get()) {
     if (taskRunner == null) {
       dispatchSync(message);
     } else {
       synchronized (dispatchQueue) {
         dispatchQueue.add(message);
       }
       try {
         taskRunner.wakeup();
       } catch (InterruptedException e) {
         Thread.currentThread().interrupt();
       }
     }
   } else {
     if (message.isMessageDispatch()) {
       MessageDispatch md = (MessageDispatch) message;
       TransmitCallback sub = md.getTransmitCallback();
       protocolManager.postProcessDispatch(md);
       if (sub != null) {
         sub.onFailure();
       }
     }
   }
 }
 @Override
 public Response processRemoveSession(SessionId id, long lastDeliveredSequenceId)
     throws Exception {
   SessionState session = state.getSessionState(id);
   if (session == null) {
     throw new IllegalStateException("Cannot remove session that had not been registered: " + id);
   }
   // Don't let new consumers or producers get added while we are closing
   // this down.
   session.shutdown();
   // Cascade the connection stop to the consumers and producers.
   for (ConsumerId consumerId : session.getConsumerIds()) {
     try {
       processRemoveConsumer(consumerId, lastDeliveredSequenceId);
     } catch (Throwable e) {
       // LOG.warn("Failed to remove consumer: {}", consumerId, e);
     }
   }
   for (ProducerId producerId : session.getProducerIds()) {
     try {
       processRemoveProducer(producerId);
     } catch (Throwable e) {
       // LOG.warn("Failed to remove producer: {}", producerId, e);
     }
   }
   state.removeSession(id);
   protocolManager.removeSession(context, session.getInfo());
   return null;
 }
 private void deleteTempQueues() throws Exception {
   Iterator<String> queueNames = tempQueues.iterator();
   while (queueNames.hasNext()) {
     String q = queueNames.next();
     protocolManager.deleteQueue(q);
   }
 }
  @Override
  public Response processCommitTransactionTwoPhase(TransactionInfo info) throws Exception {
    protocolManager.commitTransactionTwoPhase(info);
    TransactionId txId = info.getTransactionId();
    txMap.remove(txId);

    return null;
  }
  @Override
  public Response processForgetTransaction(TransactionInfo info) throws Exception {
    TransactionId txId = info.getTransactionId();
    txMap.remove(txId);

    protocolManager.forgetTransaction(info.getTransactionId());
    return null;
  }
  public void deliverMessage(MessageDispatch dispatch) {
    Message m = dispatch.getMessage();
    if (m != null) {
      long endTime = System.currentTimeMillis();
      m.setBrokerOutTime(endTime);
    }

    protocolManager.send(this, dispatch);
  }
 @Override
 public Response processRemoveDestination(DestinationInfo info) throws Exception {
   ActiveMQDestination dest = info.getDestination();
   if (dest.isQueue()) {
     String qName = "jms.queue." + dest.getPhysicalName();
     protocolManager.deleteQueue(qName);
   }
   return null;
 }
  @Override
  public Response processEndTransaction(TransactionInfo info) throws Exception {
    protocolManager.endTransaction(info);
    TransactionId txId = info.getTransactionId();

    if (!txMap.containsKey(txId)) {
      txMap.put(txId, info);
    }
    return null;
  }
  @Override
  public Response processMessage(Message messageSend) {
    Response resp = null;
    try {
      ProducerId producerId = messageSend.getProducerId();
      AMQProducerBrokerExchange producerExchange = getProducerBrokerExchange(producerId);
      final AMQConnectionContext pcontext = producerExchange.getConnectionContext();
      final ProducerInfo producerInfo = producerExchange.getProducerState().getInfo();
      boolean sendProducerAck =
          !messageSend.isResponseRequired()
              && producerInfo.getWindowSize() > 0
              && !pcontext.isInRecoveryMode();

      AMQSession session = protocolManager.getSession(producerId.getParentId());

      if (producerExchange.canDispatch(messageSend)) {
        SendingResult result = session.send(producerExchange, messageSend, sendProducerAck);
        if (result.isBlockNextSend()) {
          if (!context.isNetworkConnection() && result.isSendFailIfNoSpace()) {
            throw new ResourceAllocationException(
                "Usage Manager Memory Limit reached. Stopping producer ("
                    + producerId
                    + ") to prevent flooding "
                    + result.getBlockingAddress()
                    + "."
                    + " See http://activemq.apache.org/producer-flow-control.html for more info");
          }

          if (producerInfo.getWindowSize() > 0 || messageSend.isResponseRequired()) {
            // in that case don't send the response
            // this will force the client to wait until
            // the response is got.
            context.setDontSendReponse(true);
          } else {
            // hang the connection until the space is available
            session.blockingWaitForSpace(producerExchange, result);
          }
        } else if (sendProducerAck) {
          ProducerAck ack = new ProducerAck(producerInfo.getProducerId(), messageSend.getSize());
          this.dispatchAsync(ack);
        }
      }
    } catch (Throwable e) {
      if (e instanceof ActiveMQSecurityException) {
        resp = new ExceptionResponse(new JMSSecurityException(e.getMessage()));
      } else {
        resp = new ExceptionResponse(e);
      }
    }
    return resp;
  }
 @Override
 public Response processAddDestination(DestinationInfo dest) throws Exception {
   Response resp = null;
   try {
     protocolManager.addDestination(this, dest);
   } catch (Exception e) {
     if (e instanceof ActiveMQSecurityException) {
       resp = new ExceptionResponse(new JMSSecurityException(e.getMessage()));
     } else {
       resp = new ExceptionResponse(e);
     }
   }
   return resp;
 }
 @Override
 public Response processAddConsumer(ConsumerInfo info) {
   Response resp = null;
   try {
     protocolManager.addConsumer(this, info);
   } catch (Exception e) {
     if (e instanceof ActiveMQSecurityException) {
       resp = new ExceptionResponse(new JMSSecurityException(e.getMessage()));
     } else {
       resp = new ExceptionResponse(e);
     }
   }
   return resp;
 }
 @Override
 public Response processAddProducer(ProducerInfo info) throws Exception {
   Response resp = null;
   try {
     protocolManager.addProducer(this, info);
   } catch (Exception e) {
     if (e instanceof ActiveMQSecurityException) {
       resp = new ExceptionResponse(new JMSSecurityException(e.getMessage()));
     } else if (e instanceof ActiveMQNonExistentQueueException) {
       resp = new ExceptionResponse(new InvalidDestinationException(e.getMessage()));
     } else {
       resp = new ExceptionResponse(e);
     }
   }
   return resp;
 }
  @Override
  public Response processRemoveConnection(ConnectionId id, long lastDeliveredSequenceId)
      throws Exception {
    // Don't allow things to be added to the connection state while we
    // are shutting down.
    state.shutdown();
    // Cascade the connection stop to the sessions.
    for (SessionId sessionId : state.getSessionIds()) {
      try {
        processRemoveSession(sessionId, lastDeliveredSequenceId);
      } catch (Throwable e) {
        // LOG
      }
    }

    try {
      protocolManager.removeConnection(context, state.getInfo(), null);
    } catch (Throwable e) {
      // log
    }
    return null;
  }
 private void negotiate(WireFormatInfo command) throws IOException {
   this.wireFormat.renegotiateWireFormat(command);
   // throw back a brokerInfo here
   protocolManager.sendBrokerInfo(this);
 }
 @Override
 public Response processPrepareTransaction(TransactionInfo info) throws Exception {
   protocolManager.prepareTransaction(info);
   return null;
 }
 @Override
 public Response processRecoverTransactions(TransactionInfo info) throws Exception {
   Set<SessionId> sIds = state.getSessionIds();
   TransactionId[] recovered = protocolManager.recoverTransactions(sIds);
   return new DataArrayResponse(recovered);
 }
 @Override
 public Response processRemoveProducer(ProducerId id) throws Exception {
   protocolManager.removeProducer(id);
   return null;
 }
 @Override
 public Response processRemoveSubscription(RemoveSubscriptionInfo subInfo) throws Exception {
   protocolManager.removeSubscription(subInfo);
   return null;
 }
  @Override
  public Response processAddConnection(ConnectionInfo info) throws Exception {
    WireFormatInfo wireFormatInfo = wireFormat.getPreferedWireFormatInfo();
    // Older clients should have been defaulting this field to true.. but
    // they were not.
    if (wireFormatInfo != null && wireFormatInfo.getVersion() <= 2) {
      info.setClientMaster(true);
    }

    state = new ConnectionState(info);

    context = new AMQConnectionContext();

    state.reset(info);

    this.faultTolerantConnection = info.isFaultTolerant();
    // Setup the context.
    String clientId = info.getClientId();
    context.setBroker(protocolManager);
    context.setClientId(clientId);
    context.setClientMaster(info.isClientMaster());
    context.setConnection(this);
    context.setConnectionId(info.getConnectionId());
    // for now we pass the manager as the connector and see what happens
    // it should be related to activemq's Acceptor
    context.setConnector(this.acceptorUsed);
    context.setMessageAuthorizationPolicy(getMessageAuthorizationPolicy());
    context.setNetworkConnection(networkConnection);
    context.setFaultTolerant(faultTolerantConnection);
    context.setTransactions(new ConcurrentHashMap<TransactionId, AMQTransaction>());
    context.setUserName(info.getUserName());
    context.setWireFormatInfo(wireFormatInfo);
    context.setReconnect(info.isFailoverReconnect());
    this.manageable = info.isManageable();
    context.setConnectionState(state);
    if (info.getClientIp() == null) {
      info.setClientIp(getRemoteAddress());
    }

    try {
      protocolManager.addConnection(context, info);
    } catch (Exception e) {
      if (e instanceof SecurityException) {
        // close this down - in case the peer of this transport doesn't play
        // nice
        delayedStop(2000, "Failed with SecurityException: " + e.getLocalizedMessage(), e);
      }
      Response resp = new ExceptionResponse(e);
      return resp;
    }
    if (info.isManageable()) {
      // send ConnectionCommand
      ConnectionControl command = this.acceptorUsed.getConnectionControl();
      command.setFaultTolerant(protocolManager.isFaultTolerantConfiguration());
      if (info.isFailoverReconnect()) {
        command.setRebalanceConnection(false);
      }
      dispatchAsync(command);
    }
    return null;
  }
 // throw a WireFormatInfo to the peer
 public void init() {
   WireFormatInfo info = wireFormat.getPreferedWireFormatInfo();
   protocolManager.send(this, info);
 }
  @Override
  public void bufferReceived(Object connectionID, ActiveMQBuffer buffer) {
    try {
      dataReceived = true;

      Command command = (Command) wireFormat.unmarshal(buffer);

      boolean responseRequired = command.isResponseRequired();
      int commandId = command.getCommandId();
      // the connection handles pings, negotiations directly.
      // and delegate all other commands to manager.
      if (command.getClass() == KeepAliveInfo.class) {
        KeepAliveInfo info = (KeepAliveInfo) command;
        info.setResponseRequired(false);
        // if we don't respond to KeepAlive commands then the client will think the server is dead
        // and timeout
        // for some reason KeepAliveInfo.isResponseRequired() is always false
        protocolManager.sendReply(this, info);
      } else if (command.getClass() == WireFormatInfo.class) {
        // amq here starts a read/write monitor thread (detect ttl?)
        negotiate((WireFormatInfo) command);
      } else if (command.getClass() == ConnectionInfo.class
          || command.getClass() == ConsumerInfo.class
          || command.getClass() == RemoveInfo.class
          || command.getClass() == SessionInfo.class
          || command.getClass() == ProducerInfo.class
          || ActiveMQMessage.class.isAssignableFrom(command.getClass())
          || command.getClass() == MessageAck.class
          || command.getClass() == TransactionInfo.class
          || command.getClass() == DestinationInfo.class
          || command.getClass() == ShutdownInfo.class
          || command.getClass() == RemoveSubscriptionInfo.class) {
        Response response = null;

        if (pendingStop) {
          response = new ExceptionResponse(this.stopError);
        } else {
          response = ((Command) command).visit(this);

          if (response instanceof ExceptionResponse) {
            if (!responseRequired) {
              Throwable cause = ((ExceptionResponse) response).getException();
              serviceException(cause);
              response = null;
            }
          }
        }

        if (responseRequired) {
          if (response == null) {
            response = new Response();
          }
        }

        // The context may have been flagged so that the response is not
        // sent.
        if (context != null) {
          if (context.isDontSendReponse()) {
            context.setDontSendReponse(false);
            response = null;
          }
        }

        if (response != null && !protocolManager.isStopping()) {
          response.setCorrelationId(commandId);
          dispatchSync(response);
        }

      } else {
        // note!!! wait for negotiation (e.g. use a countdown latch)
        // before handling any other commands
        this.protocolManager.handleCommand(this, command);
      }
    } catch (IOException e) {
      ActiveMQServerLogger.LOGGER.error("error decoding", e);
    } catch (Throwable t) {
      ActiveMQServerLogger.LOGGER.error("error decoding", t);
    }
  }