简体   繁体   English

如何从慰藉中获得所有队列和主题

[英]How to get all the queues and topics from solace

I want to discover all the destinations from solace (queues and topics) 我想从安慰中发现所有目的地(队列和主题)

I tried using MBeanServerConnection and query after names (but I didn't find a proper way to use this) or JNDI lookups Destination dest = (Destination) context.lookup(Dest_name), but I don't have the names of the queues/topics. 我尝试使用MBeanServerConnection并在名称后进行查询(但我没有找到使用此名称的正确方法)或JNDI查找Destination dest =(Destination)context.lookup(Dest_name),但我没有队列的名称/主题。 I am using solace - jms library. 我正在使用solace-jms库。

I am searching for smth like this: (but for solace, not activeMq) get all Queue from activeMQ 我正在搜索这样的东西:(但要安慰,而不是activeMq) 从activeMQ获取所有队列

You will need to make use of SEMP over the management interface for this. 为此,您将需要通过管理界面使用SEMP。

Sample commands: 示例命令:

curl -d '<rpc><show><queue><name>*</name></queue></show></rpc>' -u semp_username:semp_password http://your_management_ip:your_management_port/SEMP
curl -d '<rpc><show><topic-endpoint><name>*</name></topic-endpoint></show></rpc>' -u semp_username:semp_password http://your_management_ip:your_management_port/SEMP

Note that I'm using curl for simplicity, but any application can perform HTTP POSTs to execute these commands. 请注意,为了简化起见,我使用curl ,但是任何应用程序都可以执行HTTP POST来执行这些命令。 If you are using Java, you can refer to the SempHttpSetRequest sample found within the Solace API samples. 如果使用的是Java,则可以参考Solace API示例中的SempHttpSetRequest示例。

Documentation on SEMP can be found here . 关于SEMP的文档可以在这里找到。


However, the larger question here is why do you need to discover all destinations? 但是,这里更大的问题是为什么您需要发现所有目的地?

One of the features of the message broker is to decouple the publishers and consumers. 消息代理的功能之一是使发布者和使用者脱钩。

If you need to know if your persistent message is being published to a topic with no consumers, you can make use of the reject-msg-to-sender-on-no-subscription-match setting in the publishing application's client-profile. 如果您需要了解是否将持久消息发布到没有使用者的主题中,则可以使用发布应用程序的客户端配置文件中的“拒绝订阅的味精到发件人”设置。 This means that the publisher will obtain a negative acknowledgement in the event that it tries to publish a message on a topic that has no matching subscribers. 这意味着,如果发布者尝试发布有关主题不匹配的订阅者的消息,则发布者将获得否定确认。

You can refer to "Handling Guaranteed Messages with No Matches" at https://docs.solace.com/Configuring-and-Managing/Configuring-Client-Profiles.htm for further details. 您可以参考https://docs.solace.com/Configuring-and-Managing/Configuring-Client-Profiles.htm上的“处理不匹配的保证消息”以获取更多详细信息。

Here is some source code that might help. 这是一些可能有用的源代码。 With the appliance configured correctly, SEMP is also available over JMS on topic "#SEMP/(router)/SHOW". 正确配置设备后,还可以通过JMS在主题“#SEMP /(路由器)/ SHOW”上使用SEMP。

  /**
   * Return the SolTopicInfo for this topic (or all topics if 'topic' is null).
   * 
   * @param session
   * @param endpointName
   * @return
   */
  public static SolTopicInfo[] getTopicInfo(JCSMPSession session, String endpointName, String vpn,
      String sempVersion) {
    XMLMessageConsumer cons = null;
    XMLMessageProducer prod = null;
    Map<String, SolTopicInfo> tiMap = new HashMap<String, SolTopicInfo>();
    try {
      // Create a producer and a consumer, and connect to appliance.
      prod = session.getMessageProducer(new PubCallback());
      cons = session.getMessageConsumer(new SubCallback());
      cons.start();

      if (vpn == null) vpn = (String) session.getProperty(JCSMPProperties.VPN_NAME);
      if (sempVersion == null) sempVersion = getSempVersion(session);

      // Extract the router name.
      final String SEMP_SHOW_TE_TOPICS = "<rpc semp-version=\""
          + sempVersion
          + "\"><show><topic-endpoint><name>"
          + endpointName
          + "</name><vpn-name>"+ vpn + "</vpn-name></topic-endpoint></show></rpc>";

      RpcReply teTopics =  sendRequest(session, SEMP_SHOW_TE_TOPICS);

      for (TopicEndpoint2 te : teTopics.getRpc().getShow().getTopicEndpoint().getTopicEndpoints()
          .getTopicEndpointArray()) {
        SolTopicInfo ti = new SolTopicInfo();
        ti.setBindCount(te.getInfo().getBindCount());
        //qi.setDescription(qt.getInfo().getNetworkTopic());
        ti.setEndpoint(te.getName());
        ti.setMessageVPN(te.getInfo().getMessageVpn());
        ti.setTopic(te.getInfo().getDestination());
        ti.setDurable(te.getInfo().getDurable());
        ti.setInSelPres(te.getInfo().getIngressSelectorPresent());
        ti.setHwmMB(formatter.format(te.getInfo().getHighWaterMarkInMb()));
        ti.setSpoolUsageMB(formatter.format(te.getInfo().getCurrentSpoolUsageInMb()));
        ti.setMessagesSpooled(te.getInfo().getNumMessagesSpooled().longValue());
        String status = te.getInfo().getIngressConfigStatus().substring(0, 1).toUpperCase();
        status += " " + te.getInfo().getEgressConfigStatus().substring(0, 1).toUpperCase();
        status += " " + te.getInfo().getIngressSelectorPresent().substring(0, 1).toUpperCase();
        status += " " + te.getInfo().getType().substring(0, 1).toUpperCase();
        ti.setStatus(status);

        tiMap.put(ti.getEndpoint(), ti);
      }

    } catch (JCSMPException e) {

      throw new RuntimeException(e.getMessage(), e);
    } finally {
      if (cons != null)
        cons.close();
      if (prod != null)
        prod.close();
    }
    return tiMap.values().toArray(new SolTopicInfo[0]);
  }

  /**
   * Return the SolQueueInfo for this queue (or all queues if 'queue' is null).
   * 
   * @param session
   * @param queue
   * @param vpn (if null, use the session's vpn name)
   * @param sempVersion, if null use 'soltr/7_1_1'
   * @return
   */
  public static SolQueueInfo[] getQueueInfo(JCSMPSession session, String queue, String vpn,
      String sempVersion) {
    XMLMessageConsumer cons = null;
    XMLMessageProducer prod = null;
    Map<String, SolQueueInfo> qiMap = new HashMap<String, SolQueueInfo>();
    try {
      // Create a producer and a consumer, and connect to appliance.
      prod = session.getMessageProducer(new PubCallback());
      cons = session.getMessageConsumer(new SubCallback());
      cons.start();

      if (vpn == null) vpn = (String) session.getProperty(JCSMPProperties.VPN_NAME);
      if (sempVersion == null) sempVersion = getSempVersion(session);

      // Extract the router name.

      final String SEMP_SHOW_QUEUE_SUBS = "<rpc semp-version=\""
          + sempVersion
          + "\"><show><queue><name>"
          + queue
          + "</name><vpn-name>"+ vpn + "</vpn-name><subscriptions/><count/><num-elements>200</num-elements></queue></show></rpc>";

      RpcReply queueSubs = sendRequest(session, SEMP_SHOW_QUEUE_SUBS);

      for (QueueType qt : queueSubs.getRpc().getShow().getQueue().getQueues().getQueueArray()) {
        SolQueueInfo qi = new SolQueueInfo();
        qi.setBindCount(qt.getInfo().getBindCount());
        //qi.setDescription(qt.getInfo().getNetworkTopic());
        qi.setName(qt.getName());
        qi.setMessageVPN(qt.getInfo().getMessageVpn());
        qi.setDurable(qt.getInfo().getDurable());
        qi.setEgSelPres(qt.getInfo().getEgressSelectorPresent());
        qi.setHwmMB(formatter.format(qt.getInfo().getHighWaterMarkInMb()));
        qi.setMessagesSpooled(qt.getInfo().getNumMessagesSpooled().longValue());
        qi.setSpoolUsageMB(formatter.format(qt.getInfo().getCurrentSpoolUsageInMb()));
        String status = qt.getInfo().getIngressConfigStatus().substring(0, 1).toUpperCase();
        status += " " + qt.getInfo().getEgressConfigStatus().substring(0, 1).toUpperCase();
        status += " " + qt.getInfo().getAccessType().substring(0, 1).toUpperCase();
        status += " " + qt.getInfo().getEgressSelectorPresent().substring(0, 1).toUpperCase();
        status += " " + qt.getInfo().getType().substring(0, 1).toUpperCase();
        status += qt.getInfo().getDurable() ? " D" : " N";
        qi.setStatus(status);

        for (Subscription sub : qt.getSubscriptions().getSubscriptionArray()) {
          qi.addSubscription(sub.getTopic());
        }

        qiMap.put(qi.getName(), qi);
      }

    } catch (JCSMPException e) {

      throw new RuntimeException(e.getMessage(), e);
    } finally {
      if (cons != null)
        cons.close();
      if (prod != null)
        prod.close();
    }
    return qiMap.values().toArray(new SolQueueInfo[0]);
  }

  private static String getSempVersion(JCSMPSession session)
  {
    String retval = "soltr/7_1_1";
    try {
      String peerVersion = (String)session.getCapability(CapabilityType.PEER_SOFTWARE_VERSION);
      if (peerVersion != null)
      {
        retval = "soltr/";
        String[] version = peerVersion.split("\\.");
        retval += version[0];
        retval += "_" + version[1];
        if (!version[2].equals("0")) retval += "_" + version[2];
      }
    } catch (Throwable e) {
      System.err.println(e);
    }
    return retval;
  }

  private static RpcReply sendRequest(JCSMPSession session,
      final String requestStr)  {
    try {
      // Set up the requestor and request message.
      String routerName = (String) session
          .getCapability(CapabilityType.PEER_ROUTER_NAME);

      final String SEMP_TOPIC_STRING = String.format("#SEMP/%s/SHOW",
          routerName);
      final Topic SEMP_TOPIC = JCSMPFactory.onlyInstance().createTopic(
          SEMP_TOPIC_STRING);
      Requestor requestor = session.createRequestor();
      BytesXMLMessage requestMsg = JCSMPFactory.onlyInstance().createMessage(
          BytesXMLMessage.class);
      requestMsg.writeAttachment(requestStr.getBytes());

      BytesXMLMessage replyMsg = requestor
          .request(requestMsg, 5000, SEMP_TOPIC);

      String replyStr = new String();
      if (replyMsg.getAttachmentContentLength() > 0) {
        byte[] bytes = new byte[replyMsg.getAttachmentContentLength()];
        replyMsg.readAttachmentBytes(bytes);
        replyStr = new String(bytes, "US-ASCII");
      }

      RpcReplyDocument doc = RpcReplyDocument.Factory.parse(replyStr);

      RpcReply reply = doc.getRpcReply();

      if (reply.isSetPermissionError()) {
        throw new RuntimeException(
            "Permission Error: Make sure SEMP over message bus SHOW commands are enabled for this VPN");
      }

      if( reply.isSetParseError() ) {
        throw new RuntimeException( "SEMP Parse Error: " + reply.getParseError() );
      }

      if( reply.isSetLimitError() ) {
        throw new RuntimeException( "SEMP Limit Error: " + reply.getLimitError() );
      }

      if( reply.isSetExecuteResult() && reply.getExecuteResult().isSetReason() ) { // axelp: encountered this error on invalid 'queue' name
        throw new RuntimeException( "SEMP Execution Error: " + reply.getExecuteResult().getReason() );
      }

      return reply;
    } catch (JCSMPException e) {

      throw new RuntimeException(e.getMessage(), e);
    } catch (UnsupportedEncodingException e) {

      throw new RuntimeException(e.getMessage(), e);
    } catch (XmlException e) {

      throw new RuntimeException(e.getMessage(), e);
    }
  }

You can get message VPN specific queues and topics using following SEMPv2 command. 您可以使用以下SEMPv2命令获取特定于消息VPN的队列和主题。

curl -s -X GET -u semp_user:semp_pass management_host:management_port/SEMP/v2/monitor/msgVpns/{vpn-name}/queues?select="queueName"

curl -s -X GET -u semp_user:semp_pass management_host:management_port/SEMP/v2/monitor/msgVpns/{vpn-name}/topicEndpoints?select="topicEndpointName"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM