

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# ActiveMQ 教學
<a name="activemq-on-amazon-mq"></a>

以下教學說明如何建立及連線至 ActiveMQ 代理程式。若要使用 ActiveMQ Java 範例程式碼，您必須安裝 [Java 標準版開發套件](https://www.oracle.com/technetwork/java/javase/downloads/index.html)，並對程式碼進行一些變更。

**Topics**
+ [Creating and Configuring a Network of Brokers](amazon-mq-creating-configuring-network-of-brokers.md)
+ [Connecting a Java application to your broker](amazon-mq-connecting-application.md)
+ [整合 ActiveMQ 代理程式與 LDAP](security-authentication-authorization.md)
+ [Connect your Amazon MQ for ActiveMQ broker to Lambda](#activemq-connect-to-lambda)
+ [建立 ActiveMQ 代理程式使用者](amazon-mq-listing-managing-users.md)
+ [編輯 ActiveMQ 代理程式使用者](edit-existing-user-console.md)
+ [刪除 ActiveMQ 代理程式使用者](delete-existing-user-console.md)
+ [Working Java Example](amazon-mq-working-java-example.md)

# 建立和設定 Amazon MQ 代理程式網路
<a name="amazon-mq-creating-configuring-network-of-brokers"></a>

*代理程式網路*由多個同時作用中[單一執行個體代理程式](amazon-mq-broker-architecture.md#single-broker-deployment)或[作用中/待命代理程式](amazon-mq-broker-architecture.md#active-standby-broker-deployment)組成。在此教學中，您將了解如何使用*來源與目的*拓撲來建立包含兩個代理程式的代理程式網路。

如需概念性的概觀和詳細的組態資訊，請參閱下列內容：
+ [代理程式的 Amazon MQ 網路](network-of-brokers.md)
+ [正確地設定您的代理程式網路](best-practices-activemq.md#network-of-brokers-configure-correctly)
+ `networkConnector`
+ `networkConnectionStartAsync`
+ ActiveMQ 文件中的 [Networks of Brokers (代理程式網路)](http://activemq.apache.org/networks-of-brokers.html)

您可以使用 Amazon MQ 主控台來建立 Amazon MQ 代理程式網路。由於您可以同時開始建立兩個代理程式，因此這項程序約需 15 分鐘的時間完成。

**Topics**
+ [先決條件](#creating-configuring-network-of-brokers-create-brokers)
+ [Configure the Brokers in a Network](#creating-configuring-network-of-brokers-allow-traffic)
+ [Configure Network Connectors for Your Broker](#creating-configuring-network-of-brokers-configure-network-connectors)
+ [Next Steps: Test the Network of Brokers](#creating-configuring-network-of-brokers-test)

## 先決條件
<a name="creating-configuring-network-of-brokers-create-brokers"></a>

若要建立代理程式網路，您必須具有下列項目：
+ 兩個或多個同時運作中的代理程式 (在本教學課程中命名為 `MyBroker1` 和 `MyBroker2`)。如需關於建立代理程式的詳細資訊，請參閱[入門：建立並連線至 ActiveMQ 代理程式](getting-started-activemq.md)。
+ 這兩個代理程式必須位於同一個 VPC 或對等 VPC 中。如需 VPC 的詳細資訊，請參閱《*Amazon VPC 使用者指南*》中的[什麼是 Amazon VPC？](https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html)和《*Amazon VPC 對等互連指南*》中的[什麼是 VPC 對等互連？](https://docs.aws.amazon.com/vpc/latest/peering/Welcome.html)。
**重要**  
如果您沒有預設的 VPC、子網路或安全群組，則必須先建立這些項目。如需詳細資訊，請參閱《*Amazon VPC 使用者指南*》中的下列項目：  
[建立預設的 VPC](https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html#create-default-vpc)
[建立預設子網路](https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html#create-default-subnet)
[建立安全群組](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html#CreatingSecurityGroups)
+ 兩個使用者對於兩個代理程式具有相同的登入憑證。如需有關建立使用者的詳細資訊，請參閱[建立 ActiveMQ 代理程式使用者](amazon-mq-listing-managing-users.md)。
**注意**  
將 LDAP 身分驗證與代理程式網路整合時，請確定使用者以 ActiveMQ 代理程式及 LDAP 使用者存在。

下列的範例使用兩個[單一執行個體代理程式](amazon-mq-broker-architecture.md#single-broker-deployment)。不過，您可以使用[運作中/待命的代理程式](amazon-mq-broker-architecture.md#active-standby-broker-deployment)或代理程式部署模式的組合，來建立代理程式的網路。

## 步驟 1：允許代理程式之間的流量
<a name="creating-configuring-network-of-brokers-allow-traffic"></a>

建立代理程式之後，您必須允許裝置之間的流量。

1. 在 [Amazon MQ 主控台](https://console.aws.amazon.com/amazon-mq/)中，於 **MyBroker2** 頁面的 **Details (詳細資訊) **區段中, 在 **Security and network (安全與網路)** 之下，選擇您的安全群組名稱或 ![\[Pencil icon indicating an edit or modification action.\]](http://docs.aws.amazon.com/zh_tw/amazon-mq/latest/developer-guide/images/amazon-mq-tutorials-broker-details-link.png)。

   隨即會顯示 EC2 儀表板的 **Security Groups (安全群組)** 頁面。

1. 從安全群組清單選擇您的安全群組。

1. 在頁面的最下方，選擇 **Inbound (傳入)**，然後選擇 **Edit (編輯)**。

1. 在 **Edit inbound rules (編輯傳入規則)** 對話方塊中，新增 OpenWire 端點的規則。

   1. 選擇 **Add Rule** (新增規則)。

   1. 針對**類型**，選取**自訂 TCP**。

   1. 針對 **Port Range (連接埠範圍)**，輸入 OpenWire 連接埠 (`61617`)。

   1. 執行以下任意一項：
      + 如果您想限制對特定 IP 地址的存取，則請讓 **Source (來源)** 維持選取 **Custom (自訂)**，然後輸入 `MyBroker1` 的 IP 地址，後面接 `/32`。(這會將 IP 地址轉換為有效的 CIDR 記錄)。如需詳細資訊，請參閱[彈性網路界面](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html)。
**提示**  
若要擷取 `MyBroker1` 的 IP 地址，請在 [Amazon MQ 主控台](https://console.aws.amazon.com/amazon-mq/)上，選擇代理程式的名稱，然後瀏覽至 **Details (詳細資訊)** 區塊。
      + 如果全部代理程式都為私有，並隸屬於同一個 VPC，則請讓 **Source (來源)** 維持選取 **Custom (自訂)**，然後輸入您所編輯安全群組的 ID。
**注意**  
用於公有代理程式時，您必須使用 IP 地址來限制存取。

   1. 選擇**儲存**。

      您的代理程式現在已可接受傳入連線。

## 步驟 2：設定代理程式的網路連接器
<a name="creating-configuring-network-of-brokers-configure-network-connectors"></a>

在允許代理程式之間的流量之後，您必須針對其中一個代理程式，設定其網路連接器。

1. 編輯代理程式 `MyBroker1` 的組態版本。

   1. 在 **MyBroker1 (MyBroker1)** 頁面上，選擇 **Edit (編輯)**。

   1. 在 **Edit MyBroker1 (編輯 MyBroker1)** 頁面的 **Configuration (組態)** 區塊中，選擇 **View (檢視)**。

      隨即會顯示組態所使用的代理程式引擎類型和版本 (例如 **Apache ActiveMQ 5.15.0 (Apache ActiveMQ 5.15.0)**)。

   1. 在 **Configuration details** (組態詳細資訊) 標籤上，會顯示組態修訂編號、描述及 XML 格式的代理程式組態。

   1. 選擇 **Edit Configuration (編輯組態)**。

   1. 在組態檔案的底部，將 `<networkConnectors>` 部分改成非註解，然後加入下列的資訊：
      + 網路連接器的 `name`。
      + 兩個代理程式共同的 [ActiveMQ Web 主控台`username`](#creating-configuring-network-of-brokers-create-brokers)。
      + 啟用 `duplex` 連線。
      + 執行以下任意一項：
        + 如果您要將代理程式連接到單一執行個體的代理程式，請針對 `static:` 使用 `uri` 前綴和 OpenWire 端點 `MyBroker2`。例如：

          ```
          <networkConnectors>
            <networkConnector name="connector_1_to_2" userName="myCommonUser" duplex="true"
              uri="static:(ssl://b-1234a5b6-78cd-901e-2fgh-3i45j6k178l9-1.mq.us-east-2.amazonaws.com:61617)"/>
          </networkConnectors>
          ```
        + 如果您要將代理程式連接到運作中/待命的代理程式，請以下列查詢參數 `?randomize=false&maxReconnectAttempts=0` 針對兩個代理程式使用 `static+failover` 傳輸和 OpenWire 端點 `uri`。例如：

          ```
          <networkConnectors>
            <networkConnector name="connector_1_to_2" userName="myCommonUser" duplex="true"
              uri="static:(failover:(ssl://b-1234a5b6-78cd-901e-2fgh-3i45j6k178l9-1.mq.us-east-2.amazonaws.com:61617,
              ssl://b-9876l5k4-32ji-109h-8gfe-7d65c4b132a1-2.mq.us-west-2.amazonaws.com:61617)?randomize=false&amp;maxReconnectAttempts=0)"/>
          </networkConnectors>
          ```
**注意**  
請勿納入 ActiveMQ 使用者的登入憑證。

   1. 選擇**儲存**。

   1. 在 **Save revision (儲存修改)** 對話方塊中，輸入 `Add network of brokers connector for MyBroker2`。

   1. 選擇 **Save (儲存)** 以儲存組態的新版本。

1. 編輯 `MyBroker1` 以設定立即套用最新的組態修改內容。

   1. 在 **MyBroker1 (MyBroker1)** 頁面上，選擇 **Edit (編輯)**。

   1. 在 **Edit MyBroker1** (編輯 MyBroker1) 頁面的 **Configuration** (組態) 區段中，選擇 **Schedule Modifications** (排程修改)。

   1. 在 **Schedule broker modifications (排程代理程式修改)** 區塊中，選擇 **Immediately (立即)** 套用修改。

   1. 選擇**套用**。

      `MyBroker1` 會重新啟動並套用您組態的修改內容。

   代理程式網路已建立。

## 後續步驟
<a name="creating-configuring-network-of-brokers-test"></a>

設定代理程式網路之後，您可以藉由產生和使用訊息，來測試該網路。

**重要**  
請務必針對`MyBroker1`連接埠 8162 (適用於 ActiveMQ Web 主控台) 和連接埠 61617 (適用於 OpenWire 端點) 上的代理程式，*從您的本機電腦*[啟用傳入連線](amazon-mq-working-java-example.md#quick-start-allow-inbound-connections)。  
您可能也需要調整安全群組的設定，來允許生產者和使用者連線到代理程式網路。

1. 在 [Amazon MQ 主控台](https://console.aws.amazon.com/amazon-mq/)中，瀏覽至 **Connections (連線)** 區塊，然後記下代理程式 `MyBroker1` 的 ActiveMQ Web 主控台端點。

1. 瀏覽至代理程式 `MyBroker1` 的 ActiveMQ Web 主控台。

1. 若要確認網路橋接器已連接，請選擇 **Network (網路)**。

   在 **Network Bridges** (網路橋接器) 區段中，`MyBroker2` 的名稱和地址會列於 **Remote Broker** (遠端代理程式) 和 **Remote Address** (遠端地址) 欄中。

1. 從對代理程式 `MyBroker2` 具有存取權限的任何機器，來建立使用者。例如：

   ```
   activemq consumer --brokerUrl "ssl://b-1234a5b6-78cd-901e-2fgh-3i45j6k178l9-1.mq.us-east-2.amazonaws.com:61617" \
   	--user commonUser \
   	--password myPassword456 \
   	--destination queue://MyQueue
   ```

   使用者可連線到 `MyBroker2` 的 OpenWire 端點，並開始使用來自佇列 `MyQueue` 的訊息。

1. 從對代理程式 `MyBroker1` 具有存取權限的任何機器，來建立生產者和傳送一些訊息。例如：

   ```
   activemq producer --brokerUrl "ssl://b-9876l5k4-32ji-109h-8gfe-7d65c4b132a1-1.mq.us-east-2.amazonaws.com:61617" \
   	--user commonUser \
   	--password myPassword456 \
   	--destination queue://MyQueue \
   	--persistent true \
   	--messageSize 1000 \
   	--messageCount 10000
   ```

   生產者可連線到 `MyBroker1` 的 OpenWire 端點，並開始生產要傳送到佇列 `MyQueue` 的持久性訊息。

# 將 Java 應用程式連線到您的 Amazon MQ 代理程式
<a name="amazon-mq-connecting-application"></a>

建立 Amazon MQ ActiveMQ 代理程式後，您可以將應用程式連接到它。下列範例示範如何使用 Java 訊息服務 (JMS) 建立與代理程式的連線、建立佇列以及傳送訊息。如需完整的作用中 Java 範例，請參閱 [搭配使用 Java Message Service (JMS) 與 ActiveMQ 的運作範例](amazon-mq-working-java-example.md)。

您可以使用[多種 ActiveMQ 用戶端](http://activemq.apache.org/cross-language-clients.html)連線至 ActiveMQ 代理程式。建議使用 [ActiveMQ 用戶端](https://mvnrepository.com/artifact/org.apache.activemq/activemq-client)。

**Topics**
+ [先決條件](#connect-application-prerequisites-tutorial)
+ [建立訊息生產者和傳送訊息](#create-producer-send-message-tutorial)
+ [建立訊息消費者和接收訊息](#create-consumer-receive-message-tutorial)

## 先決條件
<a name="connect-application-prerequisites-tutorial"></a>

### 啟用 VPC 屬性
<a name="connect-application-enable-vpc-attributes-tutorial"></a>

若要確保代理程式可以在 VPC 內存取，您必須啟用 `enableDnsHostnames` 和 `enableDnsSupport` VPC 屬性。如需詳細資訊，請參閱《*Amazon VPC 使用者指南*》中的 [VPC 中的 DNS Support](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html#vpc-dns-support)。

### 啟用傳入連線
<a name="connect-application-allow-inbound-connections-tutorial"></a>

接著，為您的應用程式啟用傳入連線。

1. 登入 [Amazon MQ 主控台](https://console.aws.amazon.com/amazon-mq/)。

1. 從代理程式清單中，選擇您的代理程式名稱 (例如，**MyBroker**)。

1. 在 ***MyBroker*** 頁面的 **Connections (連線)** 區段中，記下代理程式 Web 主控台 URL 和線路通訊協定的位址和連接埠。

1. 在 **Details (詳細資訊)** 區段的 **Security and network (安全與網路)** 下，選擇您的安全群組名稱或 ![\[Pencil icon indicating an edit or modification action.\]](http://docs.aws.amazon.com/zh_tw/amazon-mq/latest/developer-guide/images/amazon-mq-tutorials-broker-details-link.png)。

   隨即會顯示 EC2 儀表板的 **Security Groups (安全群組)** 頁面。

1. 從安全群組清單選擇您的安全群組。

1. 在頁面的最下方，選擇 **Inbound (傳入)**，然後選擇 **Edit (編輯)**。

1. 在 **Edit inbound rules (編輯傳入規則)** 對話方塊中，為您要公開存取的每個 URL 或端點新增規則 (下列範例顯示如何針對代理程式 Web 主控台執行此動作)。

   1. 選擇 **Add Rule** (新增規則)。

   1. 針對**類型**，選取**自訂 TCP**。

   1. 針對 **Port Range (連接埠範圍)**，輸入 Web 主控台連接埠 (`8162`)。

   1. 針對 **Source (來源)**，讓 **Custom (自訂)** 保持已選取狀態，然後輸入您希望能夠存取 Web 主控台的系統 IP 地址 (例如，`192.0.2.1`)。

   1. 選擇 **Save (儲存)**。

      您的代理程式現在已可接受傳入連線。

### 新增 Java 相依性
<a name="connect-application-java-dependencies-tutorial"></a>

將 `activemq-client.jar` 和 `activemq-pool.jar` 套件新增到您的 Java 類別路徑。以下範例顯示 Maven 專案 `pom.xml` 檔案中的此等依存關係。

```
<dependencies>
    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-client</artifactId>
        <version>5.15.16</version>
    </dependency>
    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-pool</artifactId>
        <version>5.15.16</version>
    </dependency>
</dependencies>
```

如需 `activemq-client.jar` 的詳細資訊，請參閱 Apache ActiveMQ 文件中的[初始組態](http://activemq.apache.org/initial-configuration.html)。

**重要**  
在以下的範例程式碼中，生產者和消費者會在單一執行緒中執行。對於生產系統 (或測試代理程式執行個體容錯移轉)，請確定您的生產者和消費者在不同的主機或執行緒上執行。

## 建立訊息生產者和傳送訊息
<a name="create-producer-send-message-tutorial"></a>

 使用下列指示來建立訊息製作者並接收訊息。

1. 使用代理程式的端點為訊息生產者建立 JMS 集區連接工廠，然後對工廠呼叫 `createConnection` 方法。
**注意**  
對於作用中/待命代理程式，Amazon MQ 會提供兩個 ActiveMQ Web 主控台 URL，但一次只有一個作用中的 URL。同樣地，Amazon MQ 為每個線路通訊協定提供兩個端點，但每個配對中一次只有一個作用中的端點。`-1` 和 `-2` 尾碼表示備援組合。如需詳細資訊，請參閱 [Amazon MQ for ActiveMQ 代理程式的部署選項](amazon-mq-broker-architecture.md)。  
對於線路層級通訊協定端點，您應該允許應用程式使用[容錯移轉傳輸](http://activemq.apache.org/failover-transport-reference.html)連線到任一端點。

   ```
   // Create a connection factory.
   final ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(wireLevelEndpoint);
   
   // Pass the sign-in credentials.
   connectionFactory.setUserName(activeMqUsername);
   connectionFactory.setPassword(activeMqPassword);
   
   // Create a pooled connection factory.
   final PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory();
   pooledConnectionFactory.setConnectionFactory(connectionFactory);
   pooledConnectionFactory.setMaxConnections(10);
   
   // Establish a connection for the producer.
   final Connection producerConnection = pooledConnectionFactory.createConnection();
   producerConnection.start(); 
   
   // Close all connections in the pool.
   pooledConnectionFactory.clear();
   ```
**注意**  
訊息生產者應一律使用 `PooledConnectionFactory` 類別。如需詳細資訊，請參閱[一律使用連線集區](best-practices-activemq.md#always-use-connection-pooling)。

1. 建立工作階段、名為 `MyQueue` 的佇列和訊息生產者。

   ```
   // Create a session.
   final Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
   
   // Create a queue named "MyQueue".
   final Destination producerDestination = producerSession.createQueue("MyQueue");
   
   // Create a producer from the session to the queue.
   final MessageProducer producer = producerSession.createProducer(producerDestination);
   producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
   ```

1. 建立訊息字串 `"Hello from Amazon MQ!"`，然後傳送訊息。

   ```
   // Create a message.
   final String text = "Hello from Amazon MQ!";
   TextMessage producerMessage = producerSession.createTextMessage(text);
   
   // Send the message.
   producer.send(producerMessage);
   System.out.println("Message sent.");
   ```

1. 清除生產者。

   ```
   producer.close();
   producerSession.close();
   producerConnection.close();
   ```

## 建立訊息消費者和接收訊息
<a name="create-consumer-receive-message-tutorial"></a>

 使用下列指示來建立訊息製作者並接收訊息。

1. 使用代理程式的端點為訊息生產者建立 JMS 連線工廠，然後對工廠呼叫 `createConnection` 方法。

   ```
   // Create a connection factory.
   final ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(wireLevelEndpoint);
   
   // Pass the sign-in credentials.
   connectionFactory.setUserName(activeMqUsername);
   connectionFactory.setPassword(activeMqPassword);
   
   // Establish a connection for the consumer.
   final Connection consumerConnection = connectionFactory.createConnection();
   consumerConnection.start();
   ```
**注意**  
訊息消費者*不應*使用 `PooledConnectionFactory` 類別。如需詳細資訊，請參閱[一律使用連線集區](best-practices-activemq.md#always-use-connection-pooling)。

1. 建立工作階段、名為 `MyQueue` 佇列和訊息消費者。

   ```
   // Create a session.
   final Session consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
   
   // Create a queue named "MyQueue".
   final Destination consumerDestination = consumerSession.createQueue("MyQueue");
   
   // Create a message consumer from the session to the queue.
   final MessageConsumer consumer = consumerSession.createConsumer(consumerDestination);
   ```

1. 開始等待訊息，並在訊息送達時接收訊息。

   ```
   // Begin to wait for messages.
   final Message consumerMessage = consumer.receive(1000);
   
   // Receive the message when it arrives.
   final TextMessage consumerTextMessage = (TextMessage) consumerMessage;
   System.out.println("Message received: " + consumerTextMessage.getText());
   ```
**注意**  
與 AWS 簡訊服務 （例如 Amazon SQS) 不同，消費者會持續連線到代理程式。

1. 關閉消費者、工作階段和連線。

   ```
   consumer.close();
   consumerSession.close();
   consumerConnection.close();
   ```

# 整合 ActiveMQ 代理程式與 LDAP
<a name="security-authentication-authorization"></a>

**重要**  
Amazon MQ 不支援私有 CA 發行的伺服器憑證。

您可以使用已啟用 TLS 的下列通訊協定來存取 ActiveMQ 代理程式：
+ [AMQP](http://activemq.apache.org/amqp.html)
+ [MQTT](http://activemq.apache.org/mqtt.html)
+ MQTT over [WebSocket](http://activemq.apache.org/websockets.html)
+ [OpenWire](http://activemq.apache.org/openwire.html)
+ [STOMP](http://activemq.apache.org/stomp.html)
+ STOMP over WebSocket

Amazon MQ 提供了原生 ActiveMQ 身分驗證和 LDAP 身分驗證之間的選擇，以及管理使用者許可的授權。如需與 ActiveMQ 使用者名稱和密碼相關限制的相關資訊，請參閱[使用者](amazon-mq-limits.md#activemq-user-limits)。

若要授權 ActiveMQ 使用者和群組使用佇列和主題，您必須[編輯代理程式的組態](amazon-mq-creating-applying-configurations.md)。Amazon MQ 使用 ActiveMQ 的[簡單身分驗證外掛程式](http://activemq.apache.org/security.html#Security-SimpleAuthenticationPlugin)，將讀取和寫入限制於目的地。如需詳細資訊和範例，請參閱 [一律設定授權映射](using-amazon-mq-securely.md#always-configure-authorization-map) 和 `authorizationEntry`。

**注意**  
目前，Amazon MQ 不支援用戶端憑證身分驗證。

**Topics**
+ [整合 LDAP 與 ActiveMQ](#integrate-ldap)
+ [先決條件](#ldap-prerequisites)
+ [LDAP 入門](#ldap-get-started)
+ [LDAP 整合的運作方式](#ldap-support-details)

## 整合 LDAP 與 ActiveMQ
<a name="integrate-ldap"></a>

您可以透過儲存在輕量型目錄存取通訊協定 (LDAP) 伺服器中的登入資料驗證 Amazon MQ 使用者。您也可以新增、刪除和修改 Amazon MQ 使用者，並指派主題和佇列的許可。建立、更新和刪除代理程式之類的管理作業仍需要 IAM 登入資料，且並未與 LDAP 整合。

想要使用 LDAP 伺服器簡化和集中管理其 Amazon MQ 代理程式身分驗證和授權的客戶可以使用此功能。將所有使用者登入資料保留在 LDAP 伺服器中，可藉由提供儲存和管理這些登入資料的集中位置，節省時間和精力。

Amazon MQ 提供使用 Apache ActiveMQ JAAS 外掛程式的 LDAP 支援。Amazon MQ 也支援任何 LDAP 伺服器，例如外部程式所支援的 Microsoft Active Directory 或 OpenLDAP。如需外掛程式的詳細資訊，請參閱 Active MQ 文件的[安全](https://activemq.apache.org/security)一節。

除了使用者之外，您還可以透過 LDAP 伺服器為特定群組或使用者指定對主題和佇列的存取權。在 LDAP 伺服器中建立代表主題和佇列的項目，然後將許可指派給特定 LDAP 使用者或群組，即可執行此動作。然後，您可設定代理程式從 LDAP 伺服器擷取授權資料。

**重要**  
 使用 LDAP 時，身分驗證不區分大小寫，但授權對您的使用者名稱區分大小寫。

## 先決條件
<a name="ldap-prerequisites"></a>

將 LDAP 支援新增至新的或現有 Amazon MQ 代理程式之前，您必須先設定服務帳戶。必須有此服務帳戶才能起始與 LDAP 伺服器的連線，而且必須具有正確的許可才能進行此連線。此服務帳戶會為您的代理程式設定 LDAP 身分驗證。任何連續的用戶端連線都會透過相同的連線進行驗證。

服務帳戶是 LDAP 伺服器中有權起始連線的帳戶。這是標準 LDAP 要求，您只必須提供一次服務帳戶登入資料。設定連線後，所有未來的用戶端連線都會透過 LDAP 伺服器進行驗證。您的服務帳戶登入資料會以加密形式安全地儲存，只有 Amazon MQ 可以存取。

若要與 ActiveMQ 整合，LDAP 伺服器上需要特定的目錄資訊樹狀結構 (DIT)。如需可清楚顯示此結構的範例`ldif` 檔案，請參閱 ActiveMQ 文件的[安全](https://activemq.apache.org/security)一節中的*將以下 LDIF 檔案匯入 LDAP 伺服器*。

## LDAP 入門
<a name="ldap-get-started"></a>

若要開始使用，請瀏覽至 Amazon MQ 主控台，然後在您建立新的 Amazon MQ 或編輯現有代理程式執行個體時，選擇 **LDAP authentication and authorization (LDAP 身分驗證和授權)**。

提供服務帳戶的相關資訊：
+ **Fully qualified domain name (完整網域名稱)** 要對其發出身分驗證和授權請求的 LDAP 伺服器位置。
**注意**  
您提供的 LDAP 伺服器完整網域名稱不得包含通訊協定或連接埠號碼。Amazon MQ 會在完整網域名稱前面加上通訊協定 `ldaps`，並附加連接埠號碼 `636`。  
例如，如果您提供以下完整網域：`example.com`，Amazon MQ 會使用以下 URL：`ldaps://example.com:636` 來存取您的 LDAP 伺服器。  
為了讓代理程式主機能夠順利與 LDAP 伺服器通訊，完整網域名稱必須可公開解析。若要使 LDAP 伺服器保持私密和安全，請限制伺服器的輸入規則中的輸入流量，只允許來自代理程式 VPC 內的流量。
+ **Service account username (服務帳戶使用名稱)** 用來執行 LDAP 伺服器初始繫連之使用者的辨別名稱。
+ **Service account password (服務帳戶密碼)** 執行初始繫結之使用者的密碼。

下圖突顯提供這些詳細資料的位置。

![\[指定 LDAP 服務帳戶詳細資料的位置。\]](http://docs.aws.amazon.com/zh_tw/amazon-mq/latest/developer-guide/images/active-mq-ldap-service-account.png)


在 **LDAP login configuration (LDAP 登入組態)** 區段中，提供下列必要資訊：
+ **User Base (使用者基礎)** 目錄資訊樹狀結構 (DIT) 中將搜尋使用者之節點的辨別名稱。
+ **User Search Matching (使用者搜尋比對)** LDAP 搜尋篩選條件，將用於尋找 `userBase` 內的使用者。用戶端的使用者名稱會替換為搜尋篩選條件中的 `{0}` 預留位置。如需詳細資訊，請參閱 [身分驗證](#ldap-authentication) 及 [Authorization](#ldap-authorization)。
+ **Role Base (角色基礎)** DIT 中將搜尋角色之節點的辨別名稱。角色可以設定為目錄中明確的 LDAP 群組項目。典型的角色項目可能包含角色名稱的一個屬性，例如**一般名稱 (CN)**，以及另一個屬性 (例如 `member`)，其值代表屬於角色群組之使用者的辨別名稱或使用者名稱。例如，假設組織單位 `group`，您可以提供以下辨別名稱：`ou=group,dc=example,dc=com`。
+ **Role Search Matching (使用者搜尋比對)** LDAP 搜尋篩選條件，將用於尋找 `roleBase` 內的角色。`userSearchMatching` 比對的使用者辨別名稱會替換為搜尋篩選條件中的 `{0}` 預留位置。用戶端的使用者名稱會替換為 `{1}` 預留位置。例如，如果目錄中的角色項目包含名為 `member` 的屬性 (包含該角色中所有使用者的使用者名稱)，您可以提供以下搜尋篩選條件：`(member:=uid={1})`。

 下圖突顯指定這些詳細資料的位置。

![\[指定 LDAP 登入詳細資訊的位置。\]](http://docs.aws.amazon.com/zh_tw/amazon-mq/latest/developer-guide/images/active-mq-ldap-login-configuration.png)


在 **Optional settings (選用設定)** 區段中，您可以提供下列選用資訊：
+ **User Role Name (使用者角色名稱)** 使用者群組成員資格之使用者目錄項目中的 LDAP 屬性名稱。在某些情況下，使用者角色可能會以使用者目錄項目中的屬性值來識別。`userRoleName` 選項可讓您提供此屬性的名稱。例如，讓我們考慮以下使用者項目：

  ```
  dn: uid=jdoe,ou=user,dc=example,dc=com
  objectClass: user
  uid: jdoe
  sn: jane
  cn: Jane Doe
  mail: j.doe@somecompany.com
  memberOf: role1
  userPassword: password
  ```

  若要對上述範例提供正確的 `userRoleName`，您會指定 `memberOf` 屬性。如果身分驗證成功，則會為使用者指派角色 `role1`。
+ **Role Name (角色名稱)** 角色項目中的群組名稱屬性，其值為該角色的名稱。例如，您可以為群組項目的**一般名稱**指定 `cn`。如果身分驗證成功，則會為使用者指派其所屬的每個角色項目的 `cn` 屬性值。
+ **User Search Subtree (使用者搜尋子樹狀結構)** 定義 LDAP 使用者搜尋查詢的範圍。如果為 true，範圍會設定為搜尋 `userBase` 所定義的節點下的整個子樹樹狀結構。
+ **Role Search Subtree (角色搜尋子樹狀結構)** 定義 LDAP 角色搜尋查詢的範圍。如果為 true，範圍會設定為搜尋 `roleBase` 所定義的節點下的整個子樹樹狀結構。

下圖突顯指定這些選用設定的位置。

![\[Optional settings for LDAP attributes and search scope in role search matching.\]](http://docs.aws.amazon.com/zh_tw/amazon-mq/latest/developer-guide/images/amazon-mq-active-ldap-optional-settings.png)


## LDAP 整合的運作方式
<a name="ldap-support-details"></a>

您可考慮到兩個主要類別的集成：身分驗證結構和授權結構。

### 身分驗證
<a name="ldap-authentication"></a>

若要身分驗證，用戶端登入資料必須是有效的。這些登入資料會針對 LDAP 伺服器的使用者基礎中的使用者進行驗證。

提供給 ActiveMQ 代理程式的使用者基礎必須指向 DIT 中將使用者儲存在 LDAP 伺服器中的節點。例如，如果您使用的是 AWS Managed Microsoft AD，而且您擁有網域元件 `corp`、 `example`和 `com`，並且在您擁有組織單位 `corp`和 的網域元件中`Users`，您會使用下列項目做為您的使用者基礎：

```
OU=Users,OU=corp,DC=corp,DC=example,DC=com
```

ActiveMQ 代理程式會在 DIT 中的這個位置搜尋使用者，以便驗證對代理程式的用戶端連線請求。

![\[搜尋使用者的位置\]](http://docs.aws.amazon.com/zh_tw/amazon-mq/latest/developer-guide/images/active-mq-ldap-structure.png)


因為 ActiveMQ 原始程式碼會將使用者的屬性名稱硬式編碼為 `uid`，您必須確定每個使用者都已設定此屬性。為了簡單起見，您可以使用使用者的連線使用者名稱。如需詳細資訊，請參閱 [activemq](https://github.com/apache/activemq/blob/c3d9b388e4f1fe73e348bf466122fe6862e064a0/activemq-broker/src/main/java/org/apache/activemq/security/SimpleCachedLDAPAuthorizationMap.java#L89) 原始程式碼和[在 Windows Server 2016 (及後續) 版本的 Active Directory 使用者和電腦中設定 ID 映射](https://www.ibm.com/support/knowledgecenter/en/STXKQY_5.0.3/com.ibm.spectrum.scale.v5r03.doc/bl1adm_confidmapaduc.htm)。

若要為特定使用者啟用 ActiveMQ 主控台存取，請確定他們屬於 `amazonmq-console-admins` 群組。

### Authorization
<a name="ldap-authorization"></a>

若要授權，會在代理程式組態中指定許可搜尋基礎。授權會依每個目的地 (或萬用字元、目的地集) 透過 `cachedLdapAuthorizationMap` 元素 (在代理程式的 `activemq.xml` 組態檔中找到) 進行。如需詳細資訊，請參閱[快取的 LDAP 授權模組](https://activemq.apache.org/cached-ldap-authorization-module)。

**注意**  
若要能夠在代理程式的`activemq.xml`組態檔案中使用 `cachedLDAPAuthorizationMap`元素，您必須在[透過 建立組態 AWS 管理主控台](amazon-mq-creating-applying-configurations.md)時選擇 **LDAP 身分驗證和授權**選項，或透過 設定[組態 AWS 管理主控台](amazon-mq-creating-applying-configurations.md)，或使用 Amazon MQ API 建立新組態`LDAP`時，將 [https://docs.aws.amazon.com//amazon-mq/latest/api-reference/configurations.html#configurations-model-authenticationstrategy](https://docs.aws.amazon.com//amazon-mq/latest/api-reference/configurations.html#configurations-model-authenticationstrategy) 屬性設定為 。

您必須提供下列三個屬性做為 `cachedLDAPAuthorizationMap` 元素的一部分：
+ `queueSearchBase`
+ `topicSearchBase`
+ `tempSearchBase`

**重要**  
為了防止敏感資訊直接放入代理程式的組態檔中，Amazon MQ 會阻止下列屬性使用於 `cachedLdapAuthorizationMap` 中：  
`connectionURL`
`connectionUsername`
`connectionPassword`
當您建立代理程式時，Amazon MQ 會將您透過 AWS 管理主控台或在 API 請求的 [https://docs.aws.amazon.com//amazon-mq/latest/api-reference/brokers.html#brokers-prop-createbrokerinput-ldapservermetadata](https://docs.aws.amazon.com//amazon-mq/latest/api-reference/brokers.html#brokers-prop-createbrokerinput-ldapservermetadata) 屬性中提供的值替換為上述屬性。

以下示範 `cachedLdapAuthorizationMap` 的正常運作範例。

```
<authorizationPlugin>
    <map>
        <cachedLDAPAuthorizationMap
            queueSearchBase="ou=Queue,ou=Destination,ou=corp,dc=corp,dc=example,dc=com"
            topicSearchBase="ou=Topic,ou=Destination,ou=corp,dc=corp,dc=example,dc=com"
            tempSearchBase="ou=Temp,ou=Destination,ou=corp,dc=corp,dc=example,dc=com"
            refreshInterval="300000"
            legacyGroupMapping="false"
        />
    </map>
</authorizationPlugin>
```

這些值會識別 DIT 中指定每種目的地許可的位置。因此，對於上述 範例 AWS Managed Microsoft AD，使用 `corp`、 `example`和 的相同網域元件`com`，您可以指定名為 的組織單位`destination`，以包含所有目的地類型。在該 OU 內，您會分別為 `queues`、`topics` 及 `temp` 目的地建立一個類型。

這表示您的佇列搜尋基礎 (針對佇列類型的目的地提供授權資訊) 會在您的 DIT 中具有以下位置：

```
OU=Queue,OU=Destination,OU=corp,DC=corp,DC=example,DC=com
```

![\[佇列搜尋基礎位置。\]](http://docs.aws.amazon.com/zh_tw/amazon-mq/latest/developer-guide/images/active-mq-ldap-queue-structure.png)


同樣地，主題和暫存目的地的許可規則會位於 DIT 中的相同層級：

```
OU=Topic,OU=Destination,OU=corp,DC=corp,DC=example,DC=com
OU=Temp,OU=Destination,OU=corp,DC=corp,DC=example,DC=com
```

在每種目的地類型 (佇列、主題、暫存) 的 OU 中，可以提供萬用字元或特定目的地名稱。例如，若要為以前置詞 DEMO.EVENTS.\$1 開頭的所有佇列提供授權規則，您可以建立以下 OU：

```
OU=DEMO.EVENTS.$,OU=Queue,OU=Destination,OU=corp,DC=corp,DC=example,DC=com
```

**注意**  
`DEMO.EVENTS.$` OU 位於 `Queue` OU 內。

如需 ActiveMQ 中萬用字元的詳細資訊，請參閱[萬用字元](https://activemq.apache.org/wildcards)

若要為特定佇列 (例如 DEMO.MYQUEUE) 提供授權規則，請指定類似下列的項目：

```
OU=DEMO.MYQUEUE,OU=Queue,OU=Destination,OU=corp,DC=corp,DC=example,DC=com
```

![\[特定佇列的授權規則\]](http://docs.aws.amazon.com/zh_tw/amazon-mq/latest/developer-guide/images/active-mq-ldap-authorization-rules.png)


### 安全群組
<a name="ldap-security-groups"></a>

在代表目的地或萬用字元的每個 OU 中，您必須建立三個安全群組。如同 ActiveMQ 中的所有許可，這些是讀取/寫入/管理員許可。如需各個許可允許使用者執行的動作詳細資訊，請參閱 ActiveMQ 文件中的[安全](https://activemq.apache.org/security)。

您必須將這些安全群組命名為 `read`、`write` 及 `admin`。在這些安全群組中，您可以新增使用者或群組，而後這些使用者或群組就會有執行相關動作的許可。每個萬用字元目的地集或個別目的地都需要這些安全群組。

![\[Security groups (安全群組)\]](http://docs.aws.amazon.com/zh_tw/amazon-mq/latest/developer-guide/images/active-mq-ldap-security-groups.png)


**注意**  
當您建立管理員群組時，群組名稱會發生衝突。發生這種衝突是因為舊版 Windows 2000 之前的規則不允許群組共用相同的名稱，即使群組位於 DIT 的不同位置亦然。**Windows 2000 之前**文字方塊中的值對設定沒有影響，但它必須是全域唯一的。為了避免這種衝突，您可以將 `uuid` 字尾附加至 `admin` 群組。  

![\[這是我的映像。\]](http://docs.aws.amazon.com/zh_tw/amazon-mq/latest/developer-guide/images/active-mq-ldap-admin-qualifier.png)


將使用者新增至特殊目的地的 `admin` 安全群組，可讓使用者建立和刪除該主題。將它們新增至 `read` 安全群組可讓它們從目的地讀取，而將它們新增至 `write` 群組可讓它們能夠寫入至目的地。

除了將個別使用者新增至安全群組許可之外，您也可以新增整個群組。不過，因為 ActiveMQ 再次硬式編碼群組的屬性名稱，所以您必須確定要新增的群組具有物件類別 `groupOfNames`，如 [activemq](https://github.com/apache/activemq/blob/c3d9b388e4f1fe73e348bf466122fe6862e064a0/activemq-broker/src/main/java/org/apache/activemq/security/SimpleCachedLDAPAuthorizationMap.java#L86) 原始程式碼所示。

如果要執行這項操作，請讓使用者遵循 `uid` 的相同程序。請參閱[在 Windows Server 2016 (及後續) 版本的 Active Directory 使用者和電腦中設定 ID 映射](https://www.ibm.com/support/knowledgecenter/en/STXKQY_5.0.3/com.ibm.spectrum.scale.v5r03.doc/bl1adm_confidmapaduc.htm)。

## 步驟 3：（選用） 連接至 AWS Lambda 函數
<a name="activemq-connect-to-lambda"></a>

 AWS Lambda 可以連線至您的 Amazon MQ 代理程式並使用訊息。當您將代理程式連接到 Lambda 時，您可以建立[事件來源映射](https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventsourcemapping.html)，其會讀取佇列中的訊息並[同步](https://docs.aws.amazon.com/lambda/latest/dg/invocation-sync.html)叫用函數。您建立的事件來源映射會分批讀取來自代理程式的訊息，並以 JSON 物件的形式將它們轉換為 Lambda 承載。

**將代理程式連接到 Lambda 函數**

1. 將下列 IAM 角色許可新增到 Lambda 函數[執行角色](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)。
   + [mq:DescribeBroker](https://docs.aws.amazon.com/amazon-mq/latest/api-reference/brokers-broker-id.html#brokers-broker-id-http-methods)
   + [ec2:CreateNetworkInterface](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateNetworkInterface.html)
   + [ec2:DeleteNetworkInterface](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeleteNetworkInterface.html)
   + [ec2:DescribeNetworkInterfaces](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeNetworkInterfaces.html)
   + [ec2:DescribeSecurityGroups](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSecurityGroups.html)
   + [ec2:DescribeSubnets](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSubnets.html)
   + [ec2:DescribeVpcs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeVpcs.html)
   + [logs:CreateLogGroup](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogGroup.html)
   + [logs:CreateLogStream](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogStream.html)
   + [日誌：PutLogEvents](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html)
   + [secretsmanager:GetSecretValue](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html)
**注意**  
若沒有必要的 IAM 許可，您的函數將無法成功從 Amazon MQ 資源讀取記錄。

1.  (選用) 如果您已建立沒有公開可存取性的代理程式，您必須執行下列其中一項作業，以允許 Lambda 連線到代理程式：
   +  為每個公用子網路設定一個 NAT 閘道。如需詳細資訊，請參閱 *AWS Lambda 開發人員指南*中的 [VPC 連線函數的網際網路和服務存取](https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc.html#vpc-internet)。
   + 使用 VPC 端點建立 Amazon Virtual Private Cloud (Amazon VPC) 與 Lambda 之間的連線。您的 Amazon VPC 也必須連線到 AWS Security Token Service (AWS STS) 和 Secrets Manager 端點。如需詳細資訊，請參閱 *AWS Lambda 開發人員指南*中的[設定 Lambda 的介面 VPC 端點](https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc-endpoints.html)。

1.  使用 AWS 管理主控台，針對 Lambda 函數[將您的代理程式設定為事件來源](https://docs.aws.amazon.com/lambda/latest/dg/with-mq.html#services-mq-eventsourcemapping)。您也可以使用 [https://docs.aws.amazon.com/cli/latest/reference/lambda/create-event-source-mapping.html](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-event-source-mapping.html) AWS Command Line Interface 命令。

1.  為 Lambda 函數編寫一些程式碼，以處理從代理程式取用的訊息。事件來源映射擷取的 Lambda 承載取決於代理程式的引擎類型。以下是 Amazon MQ for ActiveMQ 佇列的 Lambda 承載範例。
**注意**  
 在此範例中，`testQueue` 是佇列的名稱。

   ```
   {
     "eventSource": "aws:amq",
     "eventSourceArn": "arn:aws:mq:us-west-2:112556298976:broker:test:b-9bcfa592-423a-4942-879d-eb284b418fc8",
     "messages": {
       [
         {
           "messageID": "ID:b-9bcfa592-423a-4942-879d-eb284b418fc8-1---mq---us-west-2.amazonaws.com.rproxy.govskope.us-37557-1234520418293-4:1:1:1:1",
           "messageType": "jms/text-message",
           "data": "QUJDOkFBQUE=",
           "connectionId": "myJMSCoID",
           "redelivered": false,
           "destination": {
             "physicalname": "testQueue" 
           }, 
           "timestamp": 1598827811958,
           "brokerInTime": 1598827811958,
           "brokerOutTime": 1598827811959
         },
         {
           "messageID": "ID:b-9bcfa592-423a-4942-879d-eb284b418fc8-1---mq---us-west-2.amazonaws.com.rproxy.govskope.us-37557-1234520418293-4:1:1:1:1",
           "messageType":"jms/bytes-message",
           "data": "3DTOOW7crj51prgVLQaGQ82S48k=",
           "connectionId": "myJMSCoID1",
           "persistent": false,
           "destination": {
             "physicalname": "testQueue" 
           }, 
           "timestamp": 1598827811958,
           "brokerInTime": 1598827811958,
           "brokerOutTime": 1598827811959
         }
       ]
     }
   }
   ```

如需有關將 Amazon MQ 連接到 Lambda 的詳細資訊、Lambda 對 Amazon MQ 事件來源支援的選項，以及事件來源映射錯誤的詳細資訊，請參閱 *AWS Lambda 開發人員指南*中的[搭配使用 Lambda 與 Amazon MQ](https://docs.aws.amazon.com/lambda/latest/dg/with-mq.html)。

# 建立 ActiveMQ 代理程式使用者
<a name="amazon-mq-listing-managing-users"></a>

ActiveMQ *使用者*是可以存取 ActiveMQ 代理程式的佇列和主題的人員或應用程式。您可以將使用者設定為具有特定許可。例如，您可以允許某些使用者存取 [ActiveMQ Web 主控台](http://activemq.apache.org/web-console.html)。

*群組*是一個語義標籤。您可以將群組指派給使用者，並設定可供群組傳送、接收和管理特定佇列和主題的許可。

**注意**  
您無法獨立於使用者來設定群組。當您至少新增一位使用者至群組標籤時，就會建立群組標籤，並在您移除其中的所有使用者時刪除該群組標籤。

**注意**  
 Amazon MQ 上 ActiveMQ 中的 `activemq-webconsole`群組具有所有佇列和主題的管理員許可。此群組中的所有使用者都將擁有管理員存取權。

以下範例顯示如何使用 AWS 管理主控台來建立、編輯和刪除 Amazon MQ 代理程式使用者。

## 建立新的 ActiveMQ 代理程式使用者
<a name="create-new-user-console"></a>

1. 登入 [Amazon MQ 主控台](https://console.aws.amazon.com/amazon-mq/)。

1. 從代理程式清單，選擇您的代理程式名稱 (例如 **MyBroker**)，然後選擇 **View details (檢視詳細資訊)**。

   在 ***MyBroker*** 頁面的 **Users (使用者)** 區段中，會列出此代理程式的所有使用者。  
![\[Table showing two users with their console access and group information.\]](http://docs.aws.amazon.com/zh_tw/amazon-mq/latest/developer-guide/images/amazon-mq-tutorials-list-users.png)

1. 選擇 **Create user** (建立使用者)。

1. 在 **Create user (建立使用者)** 對話方塊中，輸入 **Username (使用者名稱)** 和 **Password (密碼)**。

1. (選用) 輸入使用者所屬的群組名稱，以逗號分隔 (例如：`Devs, Admins`)。

1. (選用) 若要讓使用者可存取 [ActiveMQ Web 主控台](http://activemq.apache.org/web-console.html)，請選擇 **ActiveMQ Web Console (ActiveMQ Web 主控台)**。

1. 選擇 **Create user** (建立使用者)。
**重要**  
對使用者進行變更，*不會*立即將變更套用至使用者。若要套用變更，您必須等待下一個維護時段或[重新啟動代理程式](amazon-mq-rebooting-broker.md)。

# 編輯 ActiveMQ 代理程式使用者
<a name="edit-existing-user-console"></a>

 若要編輯現有的使用者，請執行下列動作：

1. 登入 [Amazon MQ 主控台](https://console.aws.amazon.com/amazon-mq/)。

1. 從代理程式清單，選擇您的代理程式名稱 (例如 **MyBroker**)，然後選擇 **View details (檢視詳細資訊)**。

   在 ***MyBroker*** 頁面的 **Users (使用者)** 區段中，會列出此代理程式的所有使用者。  
![\[Table showing two users with their console access and group information.\]](http://docs.aws.amazon.com/zh_tw/amazon-mq/latest/developer-guide/images/amazon-mq-tutorials-list-users.png)

1. 選取您的登入憑證，然後選擇 **編輯**。

   即會顯示 **Edit user (編輯使用者)** 對話方塊。

1. (選用) 輸入新的 **Password (密碼)**。

1. (選用) 新增或移除使用者所屬的群組名稱，以逗號分隔 (例如：`Managers, Admins`)。

1. (選用) 若要讓使用者可存取 [ActiveMQ Web 主控台](http://activemq.apache.org/web-console.html)，請選擇 **ActiveMQ Web Console (ActiveMQ Web 主控台)**。

1. 若要儲存使用者的變更，請選擇 **Done (完成)**。
**重要**  
對使用者進行變更，*不會*立即將變更套用至使用者。若要套用變更，您必須等待下一個維護時段或[重新啟動代理程式](amazon-mq-rebooting-broker.md)。

# 刪除 ActiveMQ 代理程式使用者
<a name="delete-existing-user-console"></a>

 當您不再需要使用者時，您可以刪除該使用者。

1. 登入 [Amazon MQ 主控台](https://console.aws.amazon.com/amazon-mq/)。

1. 從代理程式清單，選擇您的代理程式名稱 (例如 **MyBroker**)，然後選擇 **View details (檢視詳細資訊)**。

   在 ***MyBroker*** 頁面的 **Users (使用者)** 區段中，會列出此代理程式的所有使用者。  
![\[Table showing two users with their console access and group information.\]](http://docs.aws.amazon.com/zh_tw/amazon-mq/latest/developer-guide/images/amazon-mq-tutorials-list-users.png)

1. 選取您的登入憑證 (例如 ***MyUser***)，然後選擇 **刪除**。

1. 若要確認在 **Delete *MyUser*? (刪除 MyUser？)** 對話方塊中刪除使用者，請選擇 **Delete (刪除)**。
**重要**  
對使用者進行變更，*不會*立即將變更套用至使用者。若要套用變更，您必須等待下一個維護時段或[重新啟動代理程式](amazon-mq-rebooting-broker.md)。

# 搭配使用 Java Message Service (JMS) 與 ActiveMQ 的運作範例
<a name="amazon-mq-working-java-example"></a>

以下範例顯示如何以程式設計方式使用 ActiveMQ：
+ OpenWire 範例 Java 程式碼連接至代理程式、建立佇列，並傳送及接收訊息。如需細節和詳細說明，請參閱 [將 Java 應用程式連線到您的 Amazon MQ 代理程式](amazon-mq-connecting-application.md)。
+ MQTT 範例 Java 程式碼會連接至代理程式、建立主題，以及發佈和接收訊息。
+ STOMP\$1WSS 範例 Java 程式碼會連接至代理程式、建立主題，以及發佈和接收訊息。

## 先決條件
<a name="quick-start-prerequisites"></a>

### 啟用 VPC 屬性
<a name="quick-start-enable-vpc-attributes"></a>

若要確保代理程式可以在 VPC 內存取，您必須啟用 `enableDnsHostnames` 和 `enableDnsSupport` VPC 屬性。如需詳細資訊，請參閱《*Amazon VPC 使用者指南*》中的 [VPC 中的 DNS Support](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html#vpc-dns-support)。

### 啟用傳入連線
<a name="quick-start-allow-inbound-connections"></a>

 若要以程式設計方式使用 Amazon MQ，您必須使用傳入連線。

1. 登入 [Amazon MQ 主控台](https://console.aws.amazon.com/amazon-mq/)。

1. 從代理程式清單中，選擇您的代理程式名稱 (例如，**MyBroker**)。

1. 在 ***MyBroker*** 頁面的 **Connections (連線)** 區段中，記下代理程式 Web 主控台 URL 和線路通訊協定的位址和連接埠。

1. 在 **Details (詳細資訊)** 區段的 **Security and network (安全與網路)** 下，選擇您的安全群組名稱或 ![\[Pencil icon indicating an edit or modification action.\]](http://docs.aws.amazon.com/zh_tw/amazon-mq/latest/developer-guide/images/amazon-mq-tutorials-broker-details-link.png)。

   隨即會顯示 EC2 儀表板的 **Security Groups (安全群組)** 頁面。

1. 從安全群組清單選擇您的安全群組。

1. 在頁面的最下方，選擇 **Inbound (傳入)**，然後選擇 **Edit (編輯)**。

1. 在 **Edit inbound rules (編輯傳入規則)** 對話方塊中，為您要公開存取的每個 URL 或端點新增規則 (下列範例顯示如何針對代理程式 Web 主控台執行此動作)。

   1. 選擇 **Add Rule** (新增規則)。

   1. 針對**類型**，選取**自訂 TCP**。

   1. 針對 **Port Range (連接埠範圍)**，輸入 Web 主控台連接埠 (`8162`)。

   1. 針對 **Source (來源)**，讓 **Custom (自訂)** 保持已選取狀態，然後輸入您希望能夠存取 Web 主控台的系統 IP 地址 (例如，`192.0.2.1`)。

   1. 選擇 **Save (儲存)**。

      您的代理程式現在已可接受傳入連線。

### 新增 Java 相依性
<a name="quick-start-java-dependencies"></a>

------
#### [ OpenWire ]

將 `activemq-client.jar` 和 `activemq-pool.jar` 套件新增到您的 Java 類別路徑。以下範例顯示 Maven 專案 `pom.xml` 檔案中的此等依存關係。

```
<dependencies>
    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-client</artifactId>
        <version>5.15.16</version>
    </dependency>
    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-pool</artifactId>
        <version>5.15.16</version>
    </dependency>
</dependencies>
```

如需 `activemq-client.jar` 的詳細資訊，請參閱 Apache ActiveMQ 文件中的[初始組態](http://activemq.apache.org/initial-configuration.html)。

------
#### [ MQTT ]

將 `org.eclipse.paho.client.mqttv3.jar` 套件新增至您的 Java 類別路徑。以下範例顯示 Maven 專案 `pom.xml` 檔案中的此一依存關係。

```
<dependencies>
                    <dependency>
                        <groupId>org.eclipse.paho</groupId>
                        <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
                        <version>1.2.0</version>
                    </dependency>                               
                    </dependencies>
```

如需 `org.eclipse.paho.client.mqttv3.jar` 的詳細資訊，請參閱 [Eclipse Paho Java Client](https://www.eclipse.org/paho/clients/java/)。

------
#### [ STOMP\$1WSS ]

將以下套件新增到您的 Java 類別路徑：
+ `spring-messaging.jar`
+ `spring-websocket.jar`
+ `javax.websocket-api.jar`
+ `jetty-all.jar`
+ `slf4j-simple.jar`
+ `jackson-databind.jar`

以下範例顯示 Maven 專案 `pom.xml` 檔案中的此等依存關係。

```
<dependencies>
                    <dependency>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-messaging</artifactId>
                        <version>5.0.5.RELEASE</version>
                    </dependency>
                    <dependency>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-websocket</artifactId>
                        <version>5.0.5.RELEASE</version>
                    </dependency>
                    <dependency>
                        <groupId>javax.websocket</groupId>
                        <artifactId>javax.websocket-api</artifactId>
                        <version>1.1</version>
                    </dependency>
                    <dependency>
                        <groupId>org.eclipse.jetty.aggregate</groupId>
                        <artifactId>jetty-all</artifactId>
                        <type>pom</type>
                        <version>9.3.3.v20150827</version>
                    </dependency>
                    <dependency>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-simple</artifactId>
                        <version>1.6.6</version>
                    </dependency>
                    <dependency>
                        <groupId>com.fasterxml.jackson.core</groupId>
                        <artifactId>jackson-databind</artifactId>
                        <version>2.5.0</version>
                    </dependency>
                    </dependencies>
```

如需詳細資訊，請參閱 Spring Framework 文件中的 [STOMP Support](https://docs.spring.io/spring-integration/docs/5.0.5.RELEASE/reference/html/stomp.html)。

------

## AmazonMQExample.java
<a name="working-java-example"></a>

**重要**  
在以下的範例程式碼中，生產者和消費者會在單一執行緒中執行。對於生產系統 (或測試代理程式執行個體容錯移轉)，請確定您的生產者和消費者在不同的主機或執行緒上執行。

------
#### [ OpenWire ]

```
/*
 * Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  https://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 */
                    
                    import org.apache.activemq.ActiveMQConnectionFactory;
                    import org.apache.activemq.jms.pool.PooledConnectionFactory;
                    
                    import javax.jms.*;
                    
                    public class AmazonMQExample {
                    
                    // Specify the connection parameters.
                    private final static String WIRE_LEVEL_ENDPOINT 
                            = "ssl://b-1234a5b6-78cd-901e-2fgh-3i45j6k178l9-1.mq.us-east-2.amazonaws.com:61617";
                    private final static String ACTIVE_MQ_USERNAME = "MyUsername123";
                    private final static String ACTIVE_MQ_PASSWORD = "MyPassword456";
                    
                    public static void main(String[] args) throws JMSException {
                        final ActiveMQConnectionFactory connectionFactory =
                                createActiveMQConnectionFactory();
                        final PooledConnectionFactory pooledConnectionFactory =
                                createPooledConnectionFactory(connectionFactory);
                    
                        sendMessage(pooledConnectionFactory);
                        receiveMessage(connectionFactory);
                    
                        pooledConnectionFactory.stop();
                    }
                    
                    private static void
                    sendMessage(PooledConnectionFactory pooledConnectionFactory) throws JMSException {
                        // Establish a connection for the producer.
                        final Connection producerConnection = pooledConnectionFactory
                                .createConnection();
                        producerConnection.start();
                    
                        // Create a session.
                        final Session producerSession = producerConnection
                                .createSession(false, Session.AUTO_ACKNOWLEDGE);
                    
                        // Create a queue named "MyQueue".
                        final Destination producerDestination = producerSession
                                .createQueue("MyQueue");
                    
                        // Create a producer from the session to the queue.
                        final MessageProducer producer = producerSession
                                .createProducer(producerDestination);
                        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
                    
                        // Create a message.
                        final String text = "Hello from Amazon MQ!";
                        final TextMessage producerMessage = producerSession
                                .createTextMessage(text);
                    
                        // Send the message.
                        producer.send(producerMessage);
                        System.out.println("Message sent.");
                    
                        // Clean up the producer.
                        producer.close();
                        producerSession.close();
                        producerConnection.close();
                    }
                    
                    private static void
                    receiveMessage(ActiveMQConnectionFactory connectionFactory) throws JMSException {
                        // Establish a connection for the consumer.
                        // Note: Consumers should not use PooledConnectionFactory.
                        final Connection consumerConnection = connectionFactory.createConnection();
                        consumerConnection.start();
                    
                        // Create a session.
                        final Session consumerSession = consumerConnection
                                .createSession(false, Session.AUTO_ACKNOWLEDGE);
                    
                        // Create a queue named "MyQueue".
                        final Destination consumerDestination = consumerSession
                                .createQueue("MyQueue");
                    
                        // Create a message consumer from the session to the queue.
                        final MessageConsumer consumer = consumerSession
                                .createConsumer(consumerDestination);
                    
                        // Begin to wait for messages.
                        final Message consumerMessage = consumer.receive(1000);
                    
                        // Receive the message when it arrives.
                        final TextMessage consumerTextMessage = (TextMessage) consumerMessage;
                        System.out.println("Message received: " + consumerTextMessage.getText());
                    
                        // Clean up the consumer.
                        consumer.close();
                        consumerSession.close();
                        consumerConnection.close();
                    }
                    
                    private static PooledConnectionFactory
                    createPooledConnectionFactory(ActiveMQConnectionFactory connectionFactory) {
                        // Create a pooled connection factory.
                        final PooledConnectionFactory pooledConnectionFactory =
                                new PooledConnectionFactory();
                        pooledConnectionFactory.setConnectionFactory(connectionFactory);
                        pooledConnectionFactory.setMaxConnections(10);
                        return pooledConnectionFactory;
                    }
                    
                    private static ActiveMQConnectionFactory createActiveMQConnectionFactory() {
                        // Create a connection factory.
                        final ActiveMQConnectionFactory connectionFactory =
                                new ActiveMQConnectionFactory(WIRE_LEVEL_ENDPOINT);
                    
                        // Pass the sign-in credentials.
                        connectionFactory.setUserName(ACTIVE_MQ_USERNAME);
                        connectionFactory.setPassword(ACTIVE_MQ_PASSWORD);
                        return connectionFactory;
                    }
                    }
```

------
#### [ MQTT ]

```
/*
 * Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  https://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 */
                    
                    import org.eclipse.paho.client.mqttv3.*;
                    
                    public class AmazonMQExampleMqtt implements MqttCallback {
                    
                    // Specify the connection parameters.
                    private final static String WIRE_LEVEL_ENDPOINT =
                            "ssl://b-1234a5b6-78cd-901e-2fgh-3i45j6k178l9-1.mq.us-east-2.amazonaws.com:8883";
                    private final static String ACTIVE_MQ_USERNAME = "MyUsername123";
                    private final static String ACTIVE_MQ_PASSWORD = "MyPassword456";
                    
                    public static void main(String[] args) throws Exception {
                        new AmazonMQExampleMqtt().run();
                    }
                    
                    private void run() throws MqttException, InterruptedException {
                    
                        // Specify the topic name and the message text.
                        final String topic = "myTopic";
                        final String text = "Hello from Amazon MQ!";
                    
                        // Create the MQTT client and specify the connection options.
                        final String clientId = "abc123";
                        final MqttClient client = new MqttClient(WIRE_LEVEL_ENDPOINT, clientId);
                        final MqttConnectOptions connOpts = new MqttConnectOptions();
                    
                        // Pass the sign-in credentials.
                        connOpts.setUserName(ACTIVE_MQ_USERNAME);
                        connOpts.setPassword(ACTIVE_MQ_PASSWORD.toCharArray());
                    
                        // Create a session and subscribe to a topic filter.
                        client.connect(connOpts);
                        client.setCallback(this);
                        client.subscribe("+");
                    
                        // Create a message.
                        final MqttMessage message = new MqttMessage(text.getBytes());
                    
                        // Publish the message to a topic.
                        client.publish(topic, message);
                        System.out.println("Published message.");
                    
                        // Wait for the message to be received.
                        Thread.sleep(3000L);
                    
                        // Clean up the connection.
                        client.disconnect();
                    }
                    
                    @Override
                    public void connectionLost(Throwable cause) {
                        System.out.println("Lost connection.");
                    }
                    
                    @Override
                    public void messageArrived(String topic, MqttMessage message) throws MqttException {
                        System.out.println("Received message from topic " + topic + ": " + message);
                    }
                    
                    @Override
                    public void deliveryComplete(IMqttDeliveryToken token) {
                        System.out.println("Delivered message.");
                    }
                    }
```

------
#### [ STOMP\$1WSS ]

```
/*
 * Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  https://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 */
                    
                    import org.springframework.messaging.converter.StringMessageConverter;
                    import org.springframework.messaging.simp.stomp.*;
                    import org.springframework.web.socket.WebSocketHttpHeaders;
                    import org.springframework.web.socket.client.WebSocketClient;
                    import org.springframework.web.socket.client.standard.StandardWebSocketClient;
                    import org.springframework.web.socket.messaging.WebSocketStompClient;
                    
                    import java.lang.reflect.Type;
                    
                    public class AmazonMQExampleStompWss {
                    
                    // Specify the connection parameters.
                    private final static String DESTINATION = "/queue";
                    private final static String WIRE_LEVEL_ENDPOINT =
                            "wss://b-1234a5b6-78cd-901e-2fgh-3i45j6k178l9-1.mq.us-east-2.amazonaws.com:61619";
                    private final static String ACTIVE_MQ_USERNAME = "MyUsername123";
                    private final static String ACTIVE_MQ_PASSWORD = "MyPassword456";
                    
                    public static void main(String[] args) throws Exception {
                        final AmazonMQExampleStompWss example = new AmazonMQExampleStompWss();
                    
                        final StompSession stompSession = example.connect();
                        System.out.println("Subscribed to a destination using session.");
                        example.subscribeToDestination(stompSession);
                    
                        System.out.println("Sent message to session.");
                        example.sendMessage(stompSession);
                        Thread.sleep(60000);
                    }
                    
                    private StompSession connect() throws Exception {
                        // Create a client.
                        final WebSocketClient client = new StandardWebSocketClient();
                        final WebSocketStompClient stompClient = new WebSocketStompClient(client);
                        stompClient.setMessageConverter(new StringMessageConverter());
                    
                        final WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
                    
                        // Create headers with authentication parameters.
                        final StompHeaders head = new StompHeaders();
                        head.add(StompHeaders.LOGIN, ACTIVE_MQ_USERNAME);
                        head.add(StompHeaders.PASSCODE, ACTIVE_MQ_PASSWORD);
                    
                        final StompSessionHandler sessionHandler = new MySessionHandler();
                    
                        // Create a connection.
                        return stompClient.connect(WIRE_LEVEL_ENDPOINT, headers, head,
                                sessionHandler).get();
                    }
                    
                    private void subscribeToDestination(final StompSession stompSession) {
                        stompSession.subscribe(DESTINATION, new MyFrameHandler());
                    }
                    
                    private void sendMessage(final StompSession stompSession) {
                        stompSession.send(DESTINATION, "Hello from Amazon MQ!".getBytes());
                    }
                    
                    private static class MySessionHandler extends StompSessionHandlerAdapter {
                        public void afterConnected(final StompSession stompSession,
                                                final StompHeaders stompHeaders) {
                            System.out.println("Connected to broker.");
                        }
                    }
                    
                    private static class MyFrameHandler implements StompFrameHandler {
                        public Type getPayloadType(final StompHeaders headers) {
                            return String.class;
                        }
                    
                        public void handleFrame(final StompHeaders stompHeaders,
                                                final Object message) {
                            System.out.print("Received message from topic: " + message);
                        }
                    }
                    }
```

------