@Override
  public void start() throws Exception {
    if (this.isStarted) {
      return;
    }
    System.setProperty(
        "vertx.clusterManagerFactory", HazelcastClusterManagerFactory.class.getName());
    if (quorumSize != -1) {
      platformManager =
          PlatformLocator.factory.createPlatformManager(port, host, quorumSize, haGroup);
    } else {
      platformManager = PlatformLocator.factory.createPlatformManager(port, host);
    }

    eventBus = platformManager.vertx().eventBus();

    Binding b = postOffice.getBinding(new SimpleString(queueName));
    if (b == null) {
      throw new Exception(connectorName + ": queue " + queueName + " not found");
    }

    handler = new EventHandler();
    eventBus.registerHandler(vertxAddress, handler);

    isStarted = true;
    ActiveMQVertxLogger.LOGGER.debug(connectorName + ": started");
  }
  @Override
  public int moveMessages(
      final int flushLimit,
      final String filterStr,
      final String otherQueueName,
      final boolean rejectDuplicates)
      throws Exception {
    checkStarted();

    clearIO();
    try {
      Filter filter = FilterImpl.createFilter(filterStr);

      Binding binding = postOffice.getBinding(new SimpleString(otherQueueName));

      if (binding == null) {
        throw ActiveMQMessageBundle.BUNDLE.noQueueFound(otherQueueName);
      }

      int retValue =
          queue.moveReferences(flushLimit, filter, binding.getAddress(), rejectDuplicates);

      return retValue;
    } finally {
      blockOnIO();
    }
  }
  @Override
  public void handlePreparedSendMessage(ServerMessage message, Transaction tx, long queueID)
      throws Exception {
    Queue queue = queues.get(queueID);

    if (queue == null) {
      ActiveMQServerLogger.LOGGER.journalMessageInPreparedTX(queueID);
      return;
    }
    postOffice.reroute(message, queue, tx);
  }
  @Override
  public void handleDuplicateIds(Map<SimpleString, List<Pair<byte[], Long>>> duplicateIDMap)
      throws Exception {
    for (Map.Entry<SimpleString, List<Pair<byte[], Long>>> entry : duplicateIDMap.entrySet()) {
      SimpleString address = entry.getKey();

      DuplicateIDCache cache = postOffice.getDuplicateIDCache(address);

      if (configuration.isPersistIDCache()) {
        cache.load(entry.getValue());
      }
    }
  }
  @Override
  public void handleAddMessage(Map<Long, Map<Long, AddMessageRecord>> queueMap) throws Exception {
    for (Map.Entry<Long, Map<Long, AddMessageRecord>> entry : queueMap.entrySet()) {
      long queueID = entry.getKey();

      Map<Long, AddMessageRecord> queueRecords = entry.getValue();

      Queue queue = this.queues.get(queueID);

      if (queue == null) {
        if (queueRecords.values().size() != 0) {
          ActiveMQServerLogger.LOGGER.journalCannotFindQueueForMessage(queueID);
        }

        continue;
      }

      // Redistribution could install a Redistributor while we are still loading records, what will
      // be an issue with
      // prepared ACKs
      // We make sure te Queue is paused before we reroute values.
      queue.pause();

      Collection<AddMessageRecord> valueRecords = queueRecords.values();

      long currentTime = System.currentTimeMillis();

      for (AddMessageRecord record : valueRecords) {
        long scheduledDeliveryTime = record.getScheduledDeliveryTime();

        if (scheduledDeliveryTime != 0 && scheduledDeliveryTime <= currentTime) {
          scheduledDeliveryTime = 0;
          record.getMessage().removeProperty(Message.HDR_SCHEDULED_DELIVERY_TIME);
        }

        if (scheduledDeliveryTime != 0) {
          record
              .getMessage()
              .putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, scheduledDeliveryTime);
        }

        MessageReference ref = postOffice.reroute(record.getMessage(), queue, null);

        ref.setDeliveryCount(record.getDeliveryCount());

        if (scheduledDeliveryTime != 0) {
          record.getMessage().removeProperty(Message.HDR_SCHEDULED_DELIVERY_TIME);
        }
      }
    }
  }
 @Override
 public String[] getBindingNames() throws Exception {
   clearIO();
   try {
     Bindings bindings = postOffice.getBindingsForAddress(address);
     String[] bindingNames = new String[bindings.getBindings().size()];
     int i = 0;
     for (Binding binding : bindings.getBindings()) {
       bindingNames[i++] = binding.getUniqueName().toString();
     }
     return bindingNames;
   } catch (Throwable t) {
     throw new IllegalStateException(t.getMessage());
   } finally {
     blockOnIO();
   }
 }
 @Override
 public String[] getQueueNames() throws Exception {
   clearIO();
   try {
     Bindings bindings = postOffice.getBindingsForAddress(address);
     List<String> queueNames = new ArrayList<>();
     for (Binding binding : bindings.getBindings()) {
       if (binding instanceof QueueBinding) {
         queueNames.add(binding.getUniqueName().toString());
       }
     }
     return queueNames.toArray(new String[queueNames.size()]);
   } catch (Throwable t) {
     throw new IllegalStateException(t.getMessage());
   } finally {
     blockOnIO();
   }
 }
  @Override
  public String sendMessage(
      final Map<String, String> headers,
      final int type,
      final String body,
      final String userID,
      boolean durable,
      final String user,
      final String password)
      throws Exception {
    securityStore.check(
        queue.getAddress(),
        CheckType.SEND,
        new SecurityAuth() {
          @Override
          public String getUsername() {
            return user;
          }

          @Override
          public String getPassword() {
            return password;
          }

          @Override
          public RemotingConnection getRemotingConnection() {
            return null;
          }
        });
    ServerMessageImpl message = new ServerMessageImpl(storageManager.generateID(), 50);
    for (String header : headers.keySet()) {
      message.putStringProperty(new SimpleString(header), new SimpleString(headers.get(header)));
    }
    message.setType((byte) type);
    message.setDurable(durable);
    message.setTimestamp(System.currentTimeMillis());
    message.setUserID(new UUID(UUID.TYPE_TIME_BASED, UUID.stringToBytes(userID)));
    if (body != null) {
      message.getBodyBuffer().writeBytes(Base64.decode(body));
    }
    message.setAddress(queue.getAddress());
    postOffice.route(message, null, true);
    return "" + message.getMessageID();
  }
 @Override
 public long getNumberOfMessages() throws Exception {
   clearIO();
   long totalMsgs = 0;
   try {
     Bindings bindings = postOffice.getBindingsForAddress(address);
     List<String> queueNames = new ArrayList<>();
     for (Binding binding : bindings.getBindings()) {
       if (binding instanceof QueueBinding) {
         totalMsgs += ((QueueBinding) binding).getQueue().getMessageCount();
       }
     }
     return totalMsgs;
   } catch (Throwable t) {
     throw new IllegalStateException(t.getMessage());
   } finally {
     blockOnIO();
   }
 }
  @Override
  public boolean moveMessage(
      final long messageID, final String otherQueueName, final boolean rejectDuplicates)
      throws Exception {
    checkStarted();

    clearIO();
    try {
      Binding binding = postOffice.getBinding(new SimpleString(otherQueueName));

      if (binding == null) {
        throw ActiveMQMessageBundle.BUNDLE.noQueueFound(otherQueueName);
      }

      return queue.moveReference(messageID, binding.getAddress(), rejectDuplicates);
    } finally {
      blockOnIO();
    }
  }
 private void checkStarted() {
   if (!postOffice.isStarted()) {
     throw new IllegalStateException("Broker is not started. Queue can not be managed yet");
   }
 }
  @Override
  public void initQueues(
      Map<Long, QueueBindingInfo> queueBindingInfosMap, List<QueueBindingInfo> queueBindingInfos)
      throws Exception {
    int duplicateID = 0;
    for (QueueBindingInfo queueBindingInfo : queueBindingInfos) {
      queueBindingInfosMap.put(queueBindingInfo.getId(), queueBindingInfo);

      Filter filter = FilterImpl.createFilter(queueBindingInfo.getFilterString());

      boolean isTopicIdentification =
          filter != null
              && filter.getFilterString() != null
              && filter
                  .getFilterString()
                  .toString()
                  .equals(ActiveMQServerImpl.GENERIC_IGNORED_FILTER);

      if (postOffice.getBinding(queueBindingInfo.getQueueName()) != null) {

        if (isTopicIdentification) {
          long tx = storageManager.generateID();
          storageManager.deleteQueueBinding(tx, queueBindingInfo.getId());
          storageManager.commitBindings(tx);
          continue;
        } else {

          SimpleString newName = queueBindingInfo.getQueueName().concat("-" + (duplicateID++));
          ActiveMQServerLogger.LOGGER.queueDuplicatedRenaming(
              queueBindingInfo.getQueueName().toString(), newName.toString());
          queueBindingInfo.replaceQueueName(newName);
        }
      }

      PageSubscription subscription = null;

      if (!isTopicIdentification) {
        subscription =
            pagingManager
                .getPageStore(queueBindingInfo.getAddress())
                .getCursorProvider()
                .createSubscription(queueBindingInfo.getId(), filter, true);
      }

      Queue queue =
          queueFactory.createQueue(
              queueBindingInfo.getId(),
              queueBindingInfo.getAddress(),
              queueBindingInfo.getQueueName(),
              filter,
              subscription,
              queueBindingInfo.getUser(),
              true,
              false,
              queueBindingInfo.isAutoCreated());

      if (queueBindingInfo.isAutoCreated()) {
        queue.setConsumersRefCount(
            new AutoCreatedQueueManagerImpl(
                ((PostOfficeImpl) postOffice).getServer().getJMSQueueDeleter(),
                queueBindingInfo.getQueueName()));
      }

      Binding binding =
          new LocalQueueBinding(queueBindingInfo.getAddress(), queue, nodeManager.getNodeId());

      queues.put(queueBindingInfo.getId(), queue);

      postOffice.addBinding(binding);

      managementService.registerAddress(queueBindingInfo.getAddress());
      managementService.registerQueue(queue, queueBindingInfo.getAddress(), storageManager);
    }
  }