1. Overview

EnMasse is an open source project for managed, self-service messaging on Kubernetes. EnMasse can run on your own infrastructure or in the cloud, and simplifies running a messaging infrastructure for your organization.

The service admin can deploy and manage messaging infrastructure, while tenants can request messaging resources, both using cloud-native APIs and tools.

1.1. Features

  • Built-in authentication and authorization of clients and identity management

  • Runs on Kubernetes: deploy on-premise or in the cloud

  • Different messaging patterns such as request-response, publish-subscribe and events

  • Decouple operation of infrastructure from configuration and use by applications

EnMasse can be used for many purposes, such as moving your messaging infrastructure to the cloud without depending on a specific cloud provider, building a scalable messaging backbone for IoT, or just as a cloud-ready version of a message broker.

EnMasse can provision different types of messaging depending on your use case. A user can request messaging resources by creating an address space.

EnMasse currently supports a standard and a brokered address space type, each with different semantics.

1.1.1. Standard address space

The standard address space type is the default type in EnMasse, and is focused on scaling in the number of connections and the throughput of the system. It supports AMQP and MQTT protocols, with more to come in the future. This address space type is based on other open source projects such as Apache ActiveMQ Artemis and Apache Qpid Dispatch Router and provides elastic scaling of these components. This image illustrates the high-level architecture of the standard address space:

Standard Address Space

1.1.2. Brokered address space

The brokered address space type is the "classic" message broker in the cloud which supports AMQP, CORE, OpenWire, and MQTT protocols. It supports JMS with transactions, message groups, selectors on queues and so on. These features are useful for building complex messaging patterns. This address space is also more lightweight as it features only a single broker and a management console. This image illustrates the high-level architecture of the brokered address space:

Brokered Address Space

2. Installation

2.1. Installing EnMasse on OpenShift

EnMasse can be installed using automated Ansible playbooks, the OpenShift template, or the manual steps.

Prerequisites
  • To install EnMasse, the OpenShift client tools are required. You can download the OpenShift Origin client from OpenShift Origin. EnMasse has been tested to work with the latest stable release of the OpenShift Origin Client.

  • An OpenShift cluster is required. If you do not have an OpenShift cluster available, see Minishift for an example of how to run a local instance of OpenShift on your machine.

2.1.1. Downloading EnMasse

Procedure

2.1.2. Installing EnMasse using OpenShift Template

Installing EnMasse using the OpenShift Template is useful for evaluating EnMasse. For a production setup, it is recommended to follow Installing EnMasse using Ansible or Installing EnMasse manually.

Procedure
  1. Login as as a user with cluster-admin

    oc login -u system:admin
  2. Create the project where you want to deploy EnMasse

    oc new-project enmasse
  3. Deploy using enmasse-with-standard-authservice template

    oc process -f install/templates/enmasse-with-standard-authservice.yaml NAMESPACE=enmasse | oc apply -f -

2.1.3. Installing EnMasse using Ansible

Installing EnMasse using Ansible requires creating an inventory file with the variables for configuring the system. Example inventory files can be found in the ansible/inventory folder.

An example inventory file that enables both the API server and service broker integration:

[enmasse]
localhost ansible_connection=local

[enmasse:vars]
namespace=enmasse
enable_rbac=False
api_server=True
service_catalog=True
register_api_server=True
keycloak_admin_password=admin
authentication_services=["standard"]

The following Ansible configuration settings are supported:

Table 1. Ansible Configuration Settings

Name

Description

Default value

Required

namespace

Specifies the namespace where EnMasse is installed.

Not applicable

yes

enable_rbac

Specifies whether to enable RBAC authentication of REST APIs.

True

no

service_catalog

Specifies whether to enable integration with the Service Catalog.

False

no

authentication_services

Specifies the list of authentication services to deploy. none and standard are supported.

none

no

keycloak_admin_password

Specifies the admin password to use for the standard authentication service Keycloak instance.

Not applicable

yes (if standard authentication service is enabled)

api_server

Specifies whether to enable the REST API server.

True

no

register_api_server

Specifies whether to register the API server with Kubernetes master.

False

no

secure_api_server

Specifies whether to enable mutual TLS for the API server.

False

no

Procedure
  1. (Optional) Create an inventory file.

  2. Run the ansible playbook:

    ansible-playbook -i <inventory file> ansible/playbooks/openshift/deploy_all.yml

2.1.4. Installing EnMasse manually

The manual deployment procedure can be performed on any platform supporting the OpenShift client.

Creating the project for EnMasse
Procedure
  • Create the enmasse project:

    oc new-project enmasse
Deploying authentication services

EnMasse requires at least one authentication service to be deployed. The authentication service can be none (allow all), standard (Keycloak), or external (not managed by EnMasse).

Deploying the none authentication service
Procedure
  1. Create the none authentication service:

    oc create -f ./install/components/none-authservice
Deploying the standard authentication service
Prerequisites
  • Modify the installation files according to the namespace the Standard Authservice is going to be installed in

    sed -i 's/myproject/<my-namespace>/' install/components/standard-authservice/RoleBinding.yaml
Procedure
  1. Create the standard authentication service:

    oc create -f ./install/components/standard-authservice
Deploying the Address Space Controller

The Address Space Controller is responsible for creating the infrastructure used by address spaces.

Prerequisites
  • Modify the installation files according to the namespace the Address Space Controller is going to be installed in

    sed -i 's/myproject/<my-namespace>/' install/components/address-space-controller/RoleBinding.yaml
Procedure
  1. Deploy the Address Space Controller

    oc apply -f install/components/address-space-controller
Deploying the API server

The API server provides a REST API for creating address spaces and addresses. It can also serve as an aggregated API server if it is registered as an API service.

Prerequisites
  • To install the EnMasse API Server on OpenShift, you must have cluster-admin access to set up the required roles for delegating authentication to the OpenShift master; otherwise, you are restricted to using templates for creating address spaces. For more information about how to deploy without cluster-admin access, which restricts EnMasse to using templates, see Installing EnMasse without cluster-admin privileges.

  • Modify the installation files according to the namespace the API Server is going to be installed in

    sed -i 's/myproject/<my-namespace>/' install/components/api-service/.yaml
    sed -i 's/myproject/<my-namespace>/' install/components/api-server/*RoleBinding.yaml
Procedure
  1. Register API service

    oc apply -f install/components/api-service
  2. Deploy the API Server

    oc apply -f install/components/api-server/
(Optional) Deploying the service broker

The service broker provides an implementation of the Open Service Broker API that integrates with the OpenShift Service Catalog.

Prerequisites
  • The service broker requires the standard authentication service to be deployed.

  • To install the EnMasse Service Broker on OpenShift, you must have cluster-admin access to set up the required roles for delegating authentication to the OpenShift master; otherwise, you are restricted to using templates for creating address spaces. For more information about how to deploy without cluster-admin access, which restricts EnMasse to using templates, see Installing EnMasse without cluster-admin privileges.

  • Modify the installation files according to the namespace the Service Broker is going to be installed in

    sed -i 's/myproject/<my-namespace>/' install/components/service-broker/.yaml
    sed -i 's/myproject/<my-namespace>/' install/components/cluster-service-broker/.yaml
Procedure
  1. Deploy the Service Broker:

    oc apply -f install/components/service-broker
  2. Register the Service Broker with the OpenShift Service Catalog:

    oc apply -f install/components/cluster-service-broker

2.1.5. Installing EnMasse without cluster-admin privileges

Prerequisites
Procedure
  1. Deploy the template for creating address spaces:

    oc create -f ./install/components/tenant/address-space.yaml -n enmasse
  2. Create an address space:

    oc process -f ./install/components/tenant/address-space.yaml NAME=myspace INFRA_UUID=abcd TYPE=standard PLAN=unlimited-standard | oc create -f -
  3. Deploy the template for creating addresses:

    oc create -f ./install/components/tenant/address.yaml -n enmasse
  4. Create an address:

    oc process address ADDRESS_SPACE=myspace ADDRESS=queue1 INFRA_UUID=abcd | oc create -f -

2.2. Installing EnMasse on Kubernetes

These steps follow the manual deployment procedure and work on any platform supporting the kubectl command-line client.

Prerequisite

To install EnMasse, you must have Kubernetes installed. You can use minikube if you want to install EnMasse on your laptop.

2.2.1. Downloading EnMasse

Procedure

2.2.2. Installing EnMasse manually

The manual deployment procedure can be performed on any platform supporting the Kubernetes client.

Creating the project for EnMasse
Procedure
  1. Create the enmasse namespace:

    kubectl create namespace enmasse
  2. Set the enmasse namespace as the default namespace:

    kubectl config set-context $(kubectl config current-context) --namespace=enmasse
Deploying authentication services

EnMasse requires at least one authentication service to be deployed. The authentication service can be none (allow all), standard (Keycloak), or external (not managed by EnMasse).

Deploying the none authentication service
Procedure
  1. Create a certificate to use with the none authentication service. For testing purposes, you can create a self-signed certificate:

    mkdir -p none-authservice-cert
    openssl req -new -x509 -batch -nodes -days 11000 -subj "/O=io.enmasse/CN=none-authservice.enmasse.svc.cluster.local" -out none-authservice-cert/tls.crt -keyout none-authservice-cert/tls.key
  2. Create a secret with the none authentication service certificate:

    kubectl create secret tls none-authservice-cert --cert=none-authservice-cert/tls.crt --key=none-authservice-cert/tls.key
  3. Create the none authentication service:

    kubectl create -f ./install/components/none-authservice
Deploying the standard authentication service
Prerequisites
  • Modify the installation files according to the namespace the Standard Authservice is going to be installed in

    sed -i 's/myproject/<my-namespace>/' install/components/standard-authservice/RoleBinding.yaml
Procedure
  1. Create a certificate to use with the standard authentication service. For testing purposes, you can create a self-signed certificate:

    mkdir -p standard-authservice-cert
    openssl req -new -x509 -batch -nodes -days 11000 -subj "/O=io.enmasse/CN=standard-authservice.enmasse.svc.cluster.local" -out standard-authservice-cert/tls.crt -keyout standard-authservice-cert/tls.key
  2. Create a secret with the standard authentication service certificate:

    kubectl create secret tls standard-authservice-cert --cert=standard-authservice-cert/tls.crt --key=standard-authservice-cert/tls.key
  3. Create the standard authentication service:

    kubectl create -f ./install/components/standard-authservice
Deploying the Address Space Controller

The Address Space Controller is responsible for creating the infrastructure used by address spaces.

Prerequisites
  • Modify the installation files according to the namespace the Address Space Controller is going to be installed in

    sed -i 's/myproject/<my-namespace>/' install/components/address-space-controller/RoleBinding.yaml
Procedure
  1. Deploy the Address Space Controller

    kubectl apply -f install/components/address-space-controller
Deploying the API server

The API server provides a REST API for creating address spaces and addresses. It can also serve as an aggregated API server if it is registered as an API service.

Prerequisites
  • Modify the installation files according to the namespace the API Server is going to be installed in

    sed -i 's/myproject/<my-namespace>/' install/components/api-service/.yaml
    sed -i 's/myproject/<my-namespace>/' install/components/api-server/*RoleBinding.yaml
Procedure
  1. Register API service

    kubectl apply -f install/components/api-service
  2. Create a certificate to use with the API server. For testing purposes, you can create a self-signed certificate:

    mkdir -p api-server-cert/
    openssl req -new -x509 -batch -nodes -days 11000 -subj "/O=io.enmasse/CN=api-server.enmasse.svc.cluster.local" -out api-server-cert/tls.crt -keyout api-server-cert/tls.key
  3. Create a secret containing the API server certificate:

    kubectl create secret tls api-server-cert --cert=api-server-cert/tls.crt --key=api-server-cert/tls.key
  4. Deploy the API Server

    kubectl apply -f install/components/api-server/

3. Address spaces and addresses

3.1. Address space

An address space is a group of addresses that can be accessed through a single connection (per protocol). This means that clients connected to the endpoints of an address space can send messages to or receive messages from any authorized address within that address space. An address space can support multiple protocols, as defined by the address space type.

EnMasse has two types of address spaces:

  • Standard

  • Brokered

3.2. Address

An address is part of an address space and represents a destination for sending and receiving messages. An address has a type, which defines the semantics of sending messages to and receiving messages from that address.

The types of addresses available in EnMasse depend on the address space type.

3.3. Standard Address Space

The standard address space is the default address space in EnMasse. It consists of an AMQP router network in combination with attachable storage units. The implementation of a storage unit is hidden from the client and the routers with a well-defined API. This address space type is appropriate when you have many connections and addresses. However, it has the following limitations:

  • No transaction support

  • No message ordering

  • No selectors on queues

  • No message groups

Clients connect and send and receive messages in this address space using the AMQP or MQTT protocols. Note that MQTT does not support qos2 or retained messages.

3.3.1. Standard address types

The standard address space supports five different address types:

  • queue

  • topic

  • anycast

  • multicast

  • subscription

Queue

The queue address type is a store-and-forward queue. This address type is appropriate for implementing a distributed work queue, handling traffic bursts, and other use cases where you want to decouple the producer and consumer. A queue can be sharded across multiple storage units; however, message order is no longer guaranteed.

Topic

The topic address type supports the publish-subscribe messaging pattern where there are 1..N producers and 1..M consumers. Each message published to a topic address is forwarded to all subscribers for that address. A subscriber can also be durable, in which case messages are kept until the subscriber has acknowledged them.

Anycast

The anycast address type is a scalable direct address for sending messages to one consumer. Messages sent to an anycast address are not stored, but are instead forwarded directly to the consumer. This method makes this address type ideal for request-reply (RPC) uses or even work distribution. This is the cheapest address type as it does not require any persistence.

Multicast

The multicast address type is a scalable direct address for sending messages to multiple consumers. Messages sent to a multicast address are forwarded to all consumers receiving messages on that address. Because message acknowledgments from consumers are not propagated to producers, only pre-settled messages can be sent to multicast addresses.

Subscription

The subscription address type allows a subscription to be created for a topic that holds messages published to the topic even if the subscriber is not attached. The subscription is accessed by the consumer using <topic-address>::<subscription-address>. For example, for a subscription mysub on a topic mytopic the consumer consumes from the address mytopic::mysub.

3.4. Brokered address space

The brokered address space is designed to support broker-specific features, at the cost of limited scale in terms of the number of connections and addresses. This address space supports JMS transactions, message groups, and so on.

Clients connect to and send and receive messages in this address space using the AMQP protocol.

3.4.1. Brokered address types

The brokered address space supports two address types:

  • queue

  • topic

Queue

The queue address type is a store-and-forward queue. This address type is appropriate for implementing a distributed work queue, handling traffic bursts, and other use cases where you want to decouple the producer and consumer. A queue in the brokered address spaces supports selectors, message groups, transactions, and other JMS features.

Topic

The topic address type supports the publish-subscribe messaging pattern in which there are 1..N producers and 1..M consumers. Each message published to a topic address is forwarded to all subscribers for that address. A subscriber can also be durable, in which case messages are kept until the subscriber has acknowledged them.

3.5. Configuring address spaces and addresses from the command line on OpenShift

EnMasse is configured to support manipulating address spaces and addresses by using the ifdef::Kubernetes[Kubernetes and] OpenShift command-line tools.

3.5.1. Creating an address space

Procedure
  1. Log in as a messaging tenant:

    oc login -u developer
  2. Create the project for the messaging application:

    oc new-project myapp
  3. Create an address space definition:

    apiVersion: enmasse.io/v1alpha1
    kind: AddressSpace
    metadata:
      name: myspace
    spec:
      type: standard
      plan: unlimited-standard
  4. Create the address space:

    oc create -f standard-address-space.yaml

    The address space is ready for use when .status.isReady field is set to true.

  5. Check the status of the address space:

    oc get addressspace myspace -o jsonpath={.status.isReady}
  6. Retrieve console URL:

    oc get addressspace myspace -o jsonpath={.status.endpointStatuses[?(@.name==\'console\')].host}

3.5.2. Creating an address

Procedure
  1. Create an address definition:

    apiVersion: enmasse.io/v1alpha1
    kind: Address
    metadata:
        name: myspace.myqueue
    spec:
        address: myqueue
        type: queue
        plan: pooled-queue
    Note
    Prefixing the name with the address space name is required to ensure addresses from different address spaces do not collide.
  2. Create the address:

    oc create -f standard-pooled-queue.yaml
  3. List the addresses:

    oc get addresses -o yaml

3.6. Configuring address spaces and addresses from the command line on Kubernetes

EnMasse is configured to support manipulating address spaces and addresses by using the ifdef::Kubernetes[Kubernetes and] OpenShift command-line tools.

3.6.1. Creating an address space

Procedure
  1. Create an address space definition:

    apiVersion: enmasse.io/v1alpha1
    kind: AddressSpace
    metadata:
      name: myspace
    spec:
      type: standard
      plan: unlimited-standard
  2. Create the address space:

    kubectl create -f standard-address-space.yaml

    The address space is ready for use when .status.isReady field is set to true.

  3. Check the status of the address space:

    kubectl get addressspace myspace -o jsonpath={.status.isReady}
  4. Retrieve console URL:

    kubectl get addressspace myspace -o jsonpath={.status.endpointStatuses[?(@.name==\'console\')].host}

3.6.2. Creating an address

Procedure
  1. Create an address definition:

    apiVersion: enmasse.io/v1alpha1
    kind: Address
    metadata:
        name: myspace.myqueue
    spec:
        address: myqueue
        type: queue
        plan: pooled-queue
    Note
    Prefixing the name with the address space name is required to ensure addresses from different address spaces do not collide.
  2. Create the address:

    kubectl create -f standard-pooled-queue.yaml
  3. List the addresses:

    kubectl get addresses -o yaml

3.7. Configuring address spaces and addresses using the REST API

EnMasse provides an API that you can use to configure address spaces and their addresses. Clients can be configured to authenticate using RBAC.

All API URIs are namespaced, so all address spaces are within the scope of a particular namespace. Addresses are within the scope of an address space. This means that:

  • An address space in address space A might have the same name as an address in address space B.

  • An address space in namespace A might have the same name as an address space in namespace B.

3.7.1. Creating an address space

Procedure
  1. Save the following JSON data to a space.json file:

    {
        "apiVersion": "enmasse.io/v1alpha1",
        "kind": "AddressSpace",
        "metadata": {
            "name": "myspace"
        },
        "spec": {
            "type": "standard",
            "plan": "unlimited-standard"
        }
    }
  2. POST the address space definition to the API using curl:

    TOKEN=`oc whoami -t`
    curl -X POST -T space.json -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" -k https://$(oc get route restapi -o jsonpath='{.spec.host}')/apis/enmasse.io/v1alpha1/namespaces/[:namespace]/addressspaces

    This command creates the infrastructure required for that address space. Replace namespace with the namespace of the application requesting the address space to be created. Starting up the address space can take a while, usually depending on how fast it is able to download the Docker images for the various components.

Viewing address space status
Procedure
  • You can use the API to check the status of the address space:

    TOKEN=`oc whoami -t`
    curl -k -H "Authorization: Bearer $TOKEN" https://$(oc get route restapi -o jsonpath='{.spec.host}')/apis/enmasse.io/v1alpha1/namespaces/[:namespace]/addressspaces/myspace

    You can consider the address space to be ready to use when status.isReady is true in the returned JSON object.

3.7.2. Creating addresses

Procedure
  1. To create addresses in the standard address space, save the address definition to a file:

    {
      "apiVersion": "enmasse.io/v1alpha1",
      "kind": "Address",
      "metadata": {
          "addressSpace": "myspace"
      },
      "spec": {
        "address": "myqueue",
        "type": "queue",
        "plan": "pooled-queue"
      }
    }
  2. You can then create the address using the following API:

    TOKEN=`oc whoami -t`
    curl -X POST -T address.json -H "content-type: application/json" -H "Authorization: Bearer $TOKEN" -k https://$(oc get route restapi -o jsonpath='{.spec.host}')/apis/enmasse.io/v1alpha1/namespaces/[:namespace]/addressspaces/myspace/addresses

where namespace is the name of the address space.

Viewing configured addresses
Procedure
  • To check which addresses are configured:

    curl -k https://$(oc get route restapi -o jsonpath='{.spec.host}')/apis/enmasse.io/v1alpha1/namespaces/[:namespace]/addressspaces/myspace/addresses

    The addresses are ready to be used by messaging clients once the status.isReady field of each address is set to true.

4. Managing users

EnMasse user management is only supported when using the standard authentication service. Users can be managed using a Kubernetes native REST API and custom resources using the command-line tools.

Prerequisites
  • EnMasse is installed with custom resources enabled

  • You must have already created an address space

4.1. User model

Users define authentication and authorization for messaging clients and console users. Users are configured as MessagingUsers resources. Users can only be created, deleted, read and listed (not modified). Following is an example user:

apiVersion: user.enmasse.io/v1alpha1
kind: MessagingUser
metadata:
  name: myspace.user1
spec:
  username: user1
  authentication:
    type: password
    password: cGFzc3dvcmQ= # Base64 encoded
  authorization:
    - addresses: ["queue1", "queue2", "topic*"]
      operations: ["send", "recv"]
    - addresses: ["anycast1"]
      operations: ["send"]

The following fields are required:

  • metadata.name

  • metadata.namespace

  • spec.authentication

  • spec.authorization

The spec.authentication object defines how the user is authenticated, whereas spec.authorization defines the authorization policies for that user.

4.1.1. Authentication

The supported values for the authentication type are password and federated.

Note
At present, password type users can be used for both applications and console users, whereas federated type users will only work when using the messaging console.
Password authentication type

For the password type, an additional field password must be set to a base64-encoded value of the password for that user. The password will not be printed out when reading the resource.

A password can be base64-encoded on the command line. To encode my-password, for example:

$ echo -n my-password | base64
bXktcGFzc3dvcmQ=
Federated authentication type

For the federated type, an additional field provider must be specified. The supported values depend on the identity providers configured for the address space. The fields federatedUsername and federatedUserid must be set, and should map to the username and userid in the federated identity provider.

4.1.2. Authorization

In addition, authorization policies can be defined using operations and addresses. Valid operations are send, recv, view, manage. If addresses are omitted, operations will be applied to all addresses.

Additional resources

4.2. Creating users using the command line

In EnMasse users can be created using standard command-line tools.

Prerequisites
  • An address space must have been created.

Procedure
  1. Save the user definition to a file:

    apiVersion: user.enmasse.io/v1alpha1
    kind: MessagingUser
    metadata:
      name: myspace.user1
    spec:
      username: user1
      authentication:
        type: password
        password: cGFzc3dvcmQ= # Base64 encoded
      authorization:
        - addresses: ["queue1", "queue2", "topic*"]
          operations: ["send", "recv"]
        - addresses: ["anycast1"]
          operations: ["send"]
  2. Create the user:

    kubectl create -f user-example1.yaml
Additional resources

4.3. Deleting users using the command line

Users can in EnMasse can be deleted using standard command line tools.

Prerequisites
  • An address space must have been created.

  • A user must have been created.

Procedure
  1. List the current users:

    kubectl get messagingusers
  2. Delete the desired user:

    kubectl delete messaginguser myspace.user1
Additional resources
Additional resources

5. Connecting applications to EnMasse

You can connect your application to EnMasse using one of the following client examples.

To connect to the messaging service from outside the OpenShift or Kubernetes cluster, TLS must be used with SNI set to specify the fully qualified host name for the address space. The port used is 443.

The messaging protocols supported depends on the type of address space used. For more information, see the address space section.

5.1. Client examples

5.2. Apache Qpid Proton Python example

You can use the following Apache Qpid Proton Python example to connect your application to EnMasse. This example assumes you have created an address of type queue named myqueue.

from __future__ import print_function, unicode_literals
from proton import Message
from proton.handlers import MessagingHandler
from proton.reactor import Container

class HelloWorld(MessagingHandler):
    def __init__(self, server, address):
        super(HelloWorld, self).__init__()
        self.server = server
        self.address = address

    def on_start(self, event):
        conn = event.container.connect(self.server)
        event.container.create_receiver(conn, self.address)
        event.container.create_sender(conn, self.address)

    def on_sendable(self, event):
        event.sender.send(Message(body="Hello World!"))
        event.sender.close()

    def on_message(self, event):
        print(event.message.body)
        event.connection.close()

Container(HelloWorld("amqps://<messaging-route-hostname>:443", "myqueue")).run()

5.2.1. Apache Qpid JMS example

You can use the following Apache Qpid JMS example to connect your application to EnMasse. This example assumes you have created an address of type queue named myqueue.

package org.apache.qpid.jms.example;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;

public class HelloWorld {
    public static void main(String[] args) throws Exception {
        try {
            // The configuration for the Qpid InitialContextFactory has been supplied in
            // a jndi.properties file in the classpath, which results in it being picked
            // up automatically by the InitialContext constructor.
            Context context = new InitialContext();

            ConnectionFactory factory = (ConnectionFactory) context.lookup("myFactoryLookup");
            Destination queue = (Destination) context.lookup("myQueueLookup");

            Connection connection = factory.createConnection(System.getProperty("USER"), System.getProperty("PASSWORD"));
            connection.setExceptionListener(new MyExceptionListener());
            connection.start();

            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            MessageProducer messageProducer = session.createProducer(queue);
            MessageConsumer messageConsumer = session.createConsumer(queue);

            TextMessage message = session.createTextMessage("Hello world!");
            messageProducer.send(message, DeliveryMode.NON_PERSISTENT, Message.DEFAULT_PRIORITY, Message.DEFAULT_TIME_TO_LIVE);
            TextMessage receivedMessage = (TextMessage) messageConsumer.receive(2000L);

            if (receivedMessage != null) {
                System.out.println(receivedMessage.getText());
            } else {
                System.out.println("No message received within the given timeout!");
            }

            connection.close();
        } catch (Exception exp) {
            System.out.println("Caught exception, exiting.");
            exp.printStackTrace(System.out);
            System.exit(1);
        }
    }

    private static class MyExceptionListener implements ExceptionListener {
        @Override
        public void onException(JMSException exception) {
            System.out.println("Connection ExceptionListener fired, exiting.");
            exception.printStackTrace(System.out);
            System.exit(1);
        }
    }
}

with jndi.properties:

connectionfactory.myFactoryLookup = amqps://<messaging-route-hostname>:443?transport.trustAll=true&transport.verifyHost=false
queue.myQueueLookup = myqueue

5.2.2. Rhea JavaScript Client example

You can use the following Rhea JavaScript Client example to connect your application to EnMasse. This example assumes you have created an address of type queue named myqueue.

var container = require('rhea');
container.on('connection_open', function (context) {
    context.connection.open_receiver('myqueue');
    context.connection.open_sender('myqueue');
});
container.on('message', function (context) {
    console.log(context.message.body);
    context.connection.close();
});
container.on('sendable', function (context) {
    context.sender.send({body:'Hello World!'});
    context.sender.detach();
});
container.connect({username: '<username>', password: '<password>', port:443, host:'<messaging-route-hostname>', transport:'tls', rejectUnauthorized:false});
Rhea JavaScript Client example using WebSockets
var container = require('rhea');
var WebSocket = require('ws');

container.on('connection_open', function (context) {
    context.connection.open_receiver('myqueue');
    context.connection.open_sender('myqueue');
});
container.on('message', function (context) {
    console.log(context.message.body);
    context.connection.close();
});
container.on('sendable', function (context) {
    context.sender.send({body:'Hello World!'});
    context.sender.detach();
});

var ws = container.websocket_connect(WebSocket);
container.connect({username: '<username>', password: '<password>', connection_details: ws("wss://<messaging-route-hostname>:443", ["binary"], {rejectUnauthorized: false})});

5.2.3. Apache Qpid Proton C++ example

The C client has equivalent `simple_recv` and `simple_send` examples with the same options as Python. However, the C library does not perform the same level of processing on the URL; in particular it won’t take amqps:// to imply using TLS, so the example needs to be modified as follows:

#include <proton/connection.hpp>
#include <proton/container.hpp>
#include <proton/default_container.hpp>
#include <proton/delivery.hpp>
#include <proton/message.hpp>
#include <proton/messaging_handler.hpp>
#include <proton/ssl.hpp>
#include <proton/thread_safe.hpp>
#include <proton/tracker.hpp>
#include <proton/url.hpp>

#include <iostream>

#include "fake_cpp11.hpp"

class hello_world : public proton::messaging_handler {
  private:
    proton::url url;

  public:
    hello_world(const std::string& u) : url(u) {}

    void on_container_start(proton::container& c) OVERRIDE {
        proton::connection_options co;
        co.ssl_client_options(proton::ssl_client_options());
        c.client_connection_options(co);
        c.connect(url);
    }

    void on_connection_open(proton::connection& c) OVERRIDE {
        c.open_receiver(url.path());
        c.open_sender(url.path());
    }

    void on_sendable(proton::sender &s) OVERRIDE {
        proton::message m("Hello World!");
        s.send(m);
        s.close();
    }

    void on_message(proton::delivery &d, proton::message &m) OVERRIDE {
        std::cout << m.body() << std::endl;
        d.connection().close();
    }
};

int main(int argc, char **argv) {
    try {
        std::string url = argc > 1 ? argv[1] : "<messaging-route-hostname>:443/myqueue";

        hello_world hw(url);
        proton::default_container(hw).run();

        return 0;
    } catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
    }

    return 1;
}

5.2.4. AMQP.Net Lite example

You can use the following AMQP.Net Lite example to connect your application to EnMasse. This example assumes you have created an address of type queue named myqueue.

using System;
using Amqp;

namespace Test
{
    public class Program
    {
        public static void Main(string[] args)
        {
            String url = (args.Length > 0) ? args[0] : "amqps://<messaging-route-hostname>:443";
            String address = (args.Length > 1) ? args[1] : "myqueue";

            Connection.DisableServerCertValidation = true;
            Connection connection = new Connection(new Address(url));
            Session session = new Session(connection);
            SenderLink sender = new SenderLink(session, "test-sender", address);

            Message messageSent = new Message("Test Message");
            sender.Send(messageSent);

            ReceiverLink receiver = new ReceiverLink(session, "test-receiver", address);
            Message messageReceived = receiver.Receive(TimeSpan.FromSeconds(2));
            Console.WriteLine(messageReceived.Body);
            receiver.Accept(messageReceived);

            sender.Close();
            receiver.Close();
            session.Close();
            connection.Close();
        }
    }
}

6. Address space and address plans

6.1. Plans

Plans are used to configure quotas and control the resources consumed by a particular deployment. Plans are configured by the EnMasse service operator and are selected when creating an address space and an address.

EnMasse includes a default set of plans that are sufficient for most use cases.

6.1.1. Address space plans

Address space plans specify the quota available to a given address space. By default, EnMasse includes an unlimited quota plan for both the standard and brokered address spaces.

Plans are configured as custom resources. The following example shows a plan for the standard address space:

apiVersion: admin.enmasse.io/v1alpha1
kind: AddressSpacePlan
metadata:
  name: restrictive-plan
  labels:
    app: enmasse
  annotations:
    defined-by: default
displayName: Restrictive Plan
displayOrder: 0
shortDescription: A plan with restrictive quotas
longDescription: A plan with restrictive quotas for the standard address space
uuid: 74b9a40e-117e-11e8-b4e1-507b9def37d9
addressSpaceType: standard
addressPlans:
- small-queue
- small-anycast
resources:
- name: router
  min: 0.0
  max: 2.0
- name: broker
  min: 0.0
  max: 2.0
- name: aggregate
  min: 0.0
  max: 2.0

The following fields are required:

  • metadata.name

  • resources

  • addressPlans

  • addressSpaceType

The other fields are used by the EnMasse console UI. Note the annotation defined-by, which points to a infrastructure config that must exist when an address space using this plan is created.

6.1.2. Address plans

Address plans specify the expected resource usage of a given address. The sum of the resource usage for all resource types determines the amount of infrastructure provisioned for an address space. A single router and broker pod has a maximum usage of one. If a new address requires additional resources and the resource consumption is within the address space plan limits, a new pod will be created automatically to handle the increased load.

In the Address space plans section, the address space plan references two address plans: small-queue and small-anycast. These address plans are stored as custom resources and are defined as follows:

apiVersion: admin.enmasse.io/v1alpha1
kind: AddressPlan
metadata:
  name: small-queue
  labels:
    app: enmasse
displayName: Small queue plan
displayOrder: 0
shortDescription: A plan for small queues
longDescription: A plan for small queues that consume little resources
uuid: 98feabb6-1183-11e8-a769-507b9def37d9
addressType: queue
requiredResources:
- name: router
  credit: 0.2
- name: broker
  credit: 0.3

The following fields are required:

  • metadata.name

  • requiredResources

  • addressType

A single router can support five instances of addresses and broker can support three instances of addresses with this plan. If the number of addresses with this plan increases to four, another broker is created. If it increases further to six, another router is created as well.

Note, however, that although the address space plan allows two routers and two brokers to be deployed, it only allows two pods to be deployed in total. This means that the address space is restricted to three addresses with the small-queue plan.

The small-anycast plan does not consume any broker resources, and can provision two routers at the expense of not being able to create any brokers:

apiVersion: admin.enmasse.io/v1alpha1
kind: AddressPlan
metadata:
  name: small-anycast
  labels:
    app: enmasse
displayName: Small anycast plan
displayOrder: 0
shortDescription: A plan for small anycast addresses
longDescription: A plan for small anycast addresses that consume little resources
uuid: cb61f440-1184-11e8-adda-507b9def37d9
addressType: anycast
requiredResources:
- name: router
  credit: 0.2

With this plan, up to 10 addresses can be created.

7. Infrastructure configuration

7.1. Infrastructure configuration

EnMasse creates infrastructure components such as routers, brokers, and consoles. These components can be configured while the system is running, and EnMasse automatically updates the components with the new settings.

The EnMasse service operator can edit the EnMasse default infrastructure configuration.

Infrastructure configuration can be managed for both brokered and standard infrastructure using BrokeredInfraConfig and StandardInfraConfig resources.

7.1.1. Brokered infrastructure configuration

BrokeredInfraConfig resources is used to configure infrastructure deployed by brokered address spaces. The brokered infra configuration is referenced by address space plans using a defined-by annotation. For more information, see Address space plans.

apiVersion: admin.enmasse.io/v1alpha1
kind: BrokeredInfraConfig
metadata:
  name: brokered-infra-config-example
  annotations:
    enmasse.io/template-name: brokered-space-infra
spec:
  version: 0.23.0
  admin:
    resources:
      memory: 256Mi
  broker:
    resources:
      memory: 2Gi
      storage: 100Gi
    addressFullPolicy: PAGE

The version field specifies the EnMasse version used. When upgrading, EnMasse uses this field whether to upgrade the infrastructure to the requested version.

The admin object specifies the settings you can configure for the admin components.

The broker object specifies the settings you can configure for the broker components. Changing the .broker.resources.storage setting does not configure existing broker storage size.

7.1.2. Standard infrastructure configuration

StandardInfraConfig resources is used to configure infrastructure deployed by standard address spaces. The standard infra configuration is referenced by address space plans using a defined-by annotation. For more information, see Address space plans.

apiVersion: admin.enmasse.io/v1alpha1
kind: StandardInfraConfig
metadata:
  name: myconfig
  annotations:
    enmasse.io/template-name: standard-space-infra
    enmasse.io/queue-template-name: queue-persisted
    enmasse.io/topic-template-name: topic-persisted
spec:
  version: 0.23.0
  admin:
    resources:
      memory: 256Mi
  broker:
    resources:
      memory: 2Gi
      storage: 100Gi
    addressFullPolicy: PAGE
  router:
    resources:
      memory: 256Mi
    linkCapcity: 1000

The version field specifies the EnMasse version used. When upgrading, EnMasse uses this field whether to upgrade the infrastructure to the requested version.

The admin object specifies the settings you can configure for the admin components.

The broker object specifies the settings you can configure for the broker components. Changing the .broker.resources.storage setting does not configure existing broker storage size.

The router object specifies the settings you can configure for the router components.

7.2. Applying configuration changes on OpenShift

7.2.1. Applying standard infrastructure configuration

You can edit existing configurations or create new ones.

Prerequisites
Procedure
  1. Log in as a service operator:

    oc login -u developer
  2. Select the project where EnMasse is installed:

    oc project enmasse
  3. Apply the configuration changes:

    oc apply -f standard-infra-config-example.yaml
  4. Monitor the pods while they are restarted:

    oc get pods -w

    The configuration changes will be applied within a couple of minutes.

7.3. Applying configuration changes on Kubernetes

7.3.1. Applying standard infrastructure configuration

You can edit existing configurations or create new ones.

Prerequisites
Procedure
  1. Apply the configuration changes:

    kubectl apply -f standard-infra-config-example.yaml
  2. Monitor the pods while they are restarted:

    kubectl get pods -w

    The configuration changes will be applied within a couple of minutes.

8. Upgrading

8.1. Upgrading EnMasse

EnMasse supports upgrades between minor versions using cloud native tools and the same mechanism used to apply configuration changes. When upgrading, the updated infrastructure configuration of the new version will trigger the upgrade to start.

Upgrading EnMasse is done by applying the YAML files for the new version.

8.1.1. Upgrading EnMasse on OpenShift using Template

Prerequisites
Procedure
  1. Log in as a service operator:

    oc login -u system:admin
  2. Select the project where EnMasse is installed:

    oc project enmasse
  3. Apply the new release template:

    oc process -f install/templates/enmasse-with-standard-authservice.yaml NAMESPACE=enmasse | oc apply -f -
  4. Monitor pods while they are restarted:

    oc get pods -w

    The upgrade should cause all pods to be restarted within a couple of minutes.

8.1.2. Upgrading EnMasse on OpenShift using Ansible

Prerequisites
Procedure
  1. Log in as a service operator:

    oc login -u system:admin
  2. Run the ansible playbook form the new release:

    ansible-playbook -i <inventory file> ansible/playbooks/openshift/deploy_all.yml
  3. Monitor pods while they are restarted:

    oc get pods -w

    The upgrade should cause all pods to be restarted within a couple of minutes.

9. Monitoring

9.1. Monitoring EnMasse on OpenShift

You can use Prometheus and Grafana for monitoring the EnMasse service.

9.1.1. Deploying Prometheus

Prerequisites
  • For Prometheus to monitor pods in the cluster, cluster-admin privileges are required.

Procedure
  1. Create the Prometheus deployment:

    oc apply -f ./install/components/prometheus
  2. Grant cluster-reader privileges to the Prometheus service account:

    oc adm policy add-cluster-role-to-user cluster-reader system:serviceaccount:enmasse:prometheus-server

9.1.2. Deploying Grafana

Procedure
  1. Create the Grafana deployment:

    oc apply -f ./install/components/grafana
  2. Expose the Grafana service:

    oc expose service grafana

Grafana accepts the default username admin and default password admin. For more information about how to connect Grafana to Prometheus, see the Prometheus documentation. If connecting Grafana to Prometheus, use prometheus.enmasse.svc.cluster.local as the Prometheus host name.

9.1.3. Restarting a Component

Procedure
  • Delete the component’s pod:

    oc delete pod -l name=<component>

The component will be automatically restarted in a new pod.

9.1.4. Viewing Router Logs

Procedure
  1. List all router pods and choose the pod for the relevant address space:

    oc get pods -l name=qdrouterd -o go-template --template '{{range .items}}{{.metadata.name}}{{"\t"}}{{.metadata.annotations.addressSpace}}{{"\n"}}{{end}}'
  2. Display the logs for the pod:

    oc logs <pod> -c router

9.1.5. Viewing Broker Logs

Procedure
  1. List all broker pods and choose the pod for the relevant address space:

    oc get pods -l name=broker -o go-template --template '{{range .items}}{{.metadata.name}}{{"\t"}}{{.metadata.annotations.addressSpace}}{{"\n"}}{{end}}'
  2. Display the logs for the pod:

    oc logs <pod>

9.2. Monitoring EnMasse on Kubernetes

You can use Prometheus and Grafana for monitoring the EnMasse service.

9.2.1. Deploying Prometheus

Prerequisites
  • For Prometheus to monitor pods in the cluster, cluster-admin privileges are required.

Procedure
  1. Create the Prometheus deployment:

    kubectl apply -f ./install/components/prometheus

9.2.2. Deploying Grafana

Procedure
  1. Create the Grafana deployment:

    kubectl apply -f ./install/components/grafana
  2. Expose the Grafana service:

    kubectl expose service grafana

Grafana accepts the default username admin and default password admin. For more information about how to connect Grafana to Prometheus, see the Prometheus documentation. If connecting Grafana to Prometheus, use prometheus.enmasse.svc.cluster.local as the Prometheus host name.

9.2.3. Restarting a Component

Procedure
  • Delete the component’s pod:

    kubectl delete pod -l name=<component>

The component will be automatically restarted in a new pod.

9.2.4. Viewing Router Logs

Procedure
  1. List all router pods and choose the pod for the relevant address space:

    oc get pods -l name=qdrouterd -o go-template --template '{{range .items}}{{.metadata.name}}{{"\t"}}{{.metadata.annotations.addressSpace}}{{"\n"}}{{end}}'
  2. Display the logs for the pod:

    kubectl logs <pod> -c router

9.2.5. Viewing Broker Logs

Procedure
  1. List all broker pods and choose the pod for the relevant address space:

    oc get pods -l name=broker -o go-template --template '{{range .items}}{{.metadata.name}}{{"\t"}}{{.metadata.annotations.addressSpace}}{{"\n"}}{{end}}'
  2. Display the logs for the pod:

    kubectl logs <pod>

Appendix A: Quick start guides

A.1. EnMasse on OpenShift

This guide will walk through the process of setting up EnMasse on OpenShift with clients for sending and receiving messages.

Prerequisites
  • To install EnMasse, the OpenShift client tools are required. You can download the OpenShift Origin client from OpenShift Origin. EnMasse has been tested to work with the latest stable release of the OpenShift Origin Client.

  • An OpenShift cluster is required. If you do not have an OpenShift cluster available, see Minishift for an example of how to run a local instance of OpenShift on your machine.

  • If you want to install EnMasse on Minishift and want to use Service Catalog, you must explicitly enable it during the start-up, like

MINISHIFT_ENABLE_EXPERIMENTAL="y" minishift start --extra-clusterup-flags "--service-catalog"
  • A method to generate certificates is required. This guide uses OpenSSL.

  • A user with cluster-admin permissions is needed

A.1.1. Installing EnMasse

Procedure
  1. Download one of the releases from https://github.com/EnMasseProject/enmasse/releases and unpack it.

  2. Login as as a user with cluster-admin

    oc login -u system:admin
  3. Create the project where you want to deploy EnMasse

    oc new-project enmasse
  4. Deploy using enmasse-with-none-authservice template

    oc process -f install/templates/enmasse-with-none-authservice.yaml NAMESPACE=enmasse | oc apply -f -

A.1.2. Creating an address space

Procedure
  1. Log in as a messaging tenant:

    oc login -u developer
  2. Create the project for the messaging application:

    oc new-project myapp
  3. Create an address space definition:

    apiVersion: enmasse.io/v1alpha1
    kind: AddressSpace
    metadata:
      name: myspace
    spec:
      type: standard
      plan: unlimited-standard
  4. Create the address space:

    oc create -f standard-address-space.yaml

    The address space is ready for use when .status.isReady field is set to true.

  5. Check the status of the address space:

    oc get addressspace myspace -o jsonpath={.status.isReady}
  6. Retrieve console URL:

    oc get addressspace myspace -o jsonpath={.status.endpointStatuses[?(@.name==\'console\')].host}

A.1.3. Configuring addresses

EnMasse is configured with a set of addresses that you can use for messages. Currently, EnMasse supports four different address types for the standard address space:

  • Brokered queues

  • Brokered topics (pub/sub)

  • Direct anycast addresses

  • Direct broadcast addresses

For more details, see address space. EnMasse also comes with a console that you can use for managing addresses.

EnMasse supports managing addresses natively in OpenShift.

Procedure
  1. Create an address list definition

    apiVersion: enmasse.io/v1alpha1
    kind: AddressList
    items:
    - metadata:
        name: myspace.anycast1
      spec:
        address: anycast1
        type: anycast
        plan: standard-anycast
    - metadata:
        name: myspace.multicast1
      spec:
        address: multicast1
        type: multicast
        plan: standard-multicast
    - metadata:
        name: myspace.queue1
      spec:
        address: queue1
        type: queue
        plan: pooled-queue
    - metadata:
        name: myspace.topic1
      spec:
        address: topic1
        type: topic
        plan: pooled-topic
  2. Create the addressses

    oc create -f standard-addresses.yaml

    The addresses are ready when the field .status.isReady is set to true.

  3. Check status of addressses

    oc get addresses -o jsonpath={.items[*].status.isReady}

A.1.4. Sending and receiving messages

Connecting with AMQP

For sending and receiving messages, have a look at an example python sender and receiver.

To send and receive messages, you should connect to the exposed route. To start a receiver, run:

./simple_recv.py -a "amqps://$(oc get addressspace myspace -o jsonpath={.status.endpointStatuses[?(@.name==\'messaging\')].host):443/myanycast" -m 10

This will block until it has received 10 messages. To start the sender, run:

./simple_send.py -a "amqps://$(oc get addressspace myspace -o jsonpath={.status.endpointStatuses[?(@.name==\'messaging\')].host):443/myanycast" -m 10

The server certificates is not verified in the above examples as we have deployed EnMasse with self-signed certificates. To fetch the certificate, run:

mkdir -p certs
oc get secret $(oc get addressspace myspace -o jsonpath={.spec.endpoints[?(@.name==\'messaging\')].cert.secretName}) -o jsonpath='{.data.tls\.crt}' | base64 -d > certs/tls.crt

You can modify the client code to use this cert to verify the server connection.

For more information, see Client examples.

Connecting using MQTT

For sending and receiving messages route, you can use the paho-mqtt client library. To connect, fetch the server certificate:

mkdir -p certs
oc get secret $(oc get addressspace myspace -o jsonpath={.spec.endpoints[?(@.name==\'mqtt\')].cert.secretName}) -o jsonpath='{.data.tls\.crt}' | base64 -d > certs/tls.crt
Subscriber client

Save the following to tls_mqtt_recv.py or download:

#!/usr/bin/env python

import paho.mqtt.client as mqtt
import ssl
import optparse

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))

    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    client.subscribe(opts.topic, int(opts.qos))

# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    print(msg.topic + " " + str(msg.payload))

def on_log(client, userdata, level, string):
    print(string)

parser = optparse.OptionParser(usage="usage: %prog [options]",
                               description="Receive messages from the supplied address.")

parser.add_option("-c", "--connectHost", default="localhost",
                  help="host to connect to (default %default)")

parser.add_option("-p", "--portHost", default="8883",
                  help="port to connect to (default %default)")

parser.add_option("-t", "--topic", default="mytopic",
                  help="topic to subscribe to (default %default)")

parser.add_option("-q", "--qos", default="0",
                  help="quality of service (default %default)")

parser.add_option("-s", "--serverCert", default=None,
                  help="server certificate file path (default %default)")

opts, args = parser.parse_args()

client = mqtt.Client("recv")
client.on_connect = on_connect
client.on_message = on_message
client.on_log = on_log

context = ssl.create_default_context()
if opts.serverCert == None:
    context.check_hostname = False
    context.verify_mode = ssl.CERT_NONE
else:
    context.load_verify_locations(cafile=opts.serverCert)

# just useful to activate for decrypting local TLS traffic with Wireshark
#context.set_ciphers("RSA")

client.tls_set_context(context)
client.tls_insecure_set(True)
client.connect(opts.connectHost, opts.portHost, 60)

# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
client.loop_forever()

In order to subscribe to a topic (that is, mytopic from the previous addresses configuration), the subscriber client can be used in the following way:

./tls_mqtt_recv.py -c "$(oc get route -o jsonpath='{.spec.host}' mqtt)" -p 443 -t mytopic -q 1 -s ./certs/tls.crt
Publisher client

Save the following to tls_mqtt_send.py or download:

#!/usr/bin/env python

import paho.mqtt.client as mqtt
import ssl
import optparse

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))

    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    client.publish(opts.topic, opts.message, int(opts.qos))

def on_publish(client, userdata, mid):
    print("mid: " + str(mid))
    client.disconnect()

def on_log(client, userdata, level, string):
    print(string)

parser = optparse.OptionParser(usage="usage: %prog [options]",
                               description="Sends messages to the supplied address.")

parser.add_option("-c", "--connectHost", default="localhost",
                  help="host to connect to (default %default)")

parser.add_option("-p", "--portHost", default="8883",
                  help="port to connect to (default %default)")

parser.add_option("-t", "--topic", default="mytopic",
                  help="topic to subscribe to (default %default)")

parser.add_option("-q", "--qos", default="0",
                  help="quality of service (default %default)")

parser.add_option("-s", "--serverCert", default=None,
                  help="server certificate file path (default %default)")

parser.add_option("-m", "--message", default="Hello",
                  help="message to publish (default %default)")

opts, args = parser.parse_args()

client = mqtt.Client("send")
client.on_connect = on_connect
client.on_publish = on_publish
client.on_log = on_log

context = ssl.create_default_context()
if opts.serverCert == None:
    context.check_hostname = False
    context.verify_mode = ssl.CERT_NONE
else:
    context.load_verify_locations(cafile=opts.serverCert)

# just useful to activate for decrypting local TLS traffic with Wireshark
#context.set_ciphers("RSA")

client.tls_set_context(context)
client.tls_insecure_set(True)
client.connect(opts.connectHost, opts.portHost, 60)

# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
client.loop_forever()

To start the publisher, the client can be used in the following way:

./tls_mqtt_send.py -c "$({OcGetRoute} mqtt)" -p 443 -t mytopic -q 1 -s ./certs/tls.crt -m "Hello EnMasse"

The publisher publishes the message and disconnects from EnMasse. The message is received by the previous connected subscriber.

A.1.5. Conclusion

We have seen how to setup EnMasse on OpenShift, and how to communicate with it using AMQP and MQTT clients.

A.2. EnMasse on Kubernetes

This guide will walk through the process of setting up EnMasse on a Kubernetes cluster together with clients for sending and receiving messages.

Prerequisites

To install EnMasse, you need to have Kubernetes installed. You can use minikube if you want to install EnMasse on your laptop.

A.2.1. Installing EnMasse

Procedure
  1. Download one of the releases from https://github.com/EnMasseProject/enmasse/releases and unpack it.

  2. Create the namespace where you want to deploy EnMasse

    kubectl create namespace enmasse
    kubectl config set-context $(kubectl config current-context) --namespace=enmasse
  3. Replace namespace references in bundle

    sed -i "s/myproject/enmasse/" install/bundles/enmasse-with-none-authservice/*.yaml
  4. Deploy using enmasse-with-none-authservice template

    kubectl create -f install/bundles/enmasse-with-none-authservice

A.2.2. Creating an address space

Procedure
  1. Create an address space definition:

    apiVersion: enmasse.io/v1alpha1
    kind: AddressSpace
    metadata:
      name: myspace
    spec:
      type: standard
      plan: unlimited-standard
  2. Create the address space:

    kubectl create -f standard-address-space.yaml

    The address space is ready for use when .status.isReady field is set to true.

  3. Check the status of the address space:

    kubectl get addressspace myspace -o jsonpath={.status.isReady}
  4. Retrieve console URL:

    kubectl get addressspace myspace -o jsonpath={.status.endpointStatuses[?(@.name==\'console\')].host}

A.2.3. Configuring addresses

EnMasse is configured with a set of addresses that you can use for messages. Currently, EnMasse supports four different address types for the standard address space:

  • Brokered queues

  • Brokered topics (pub/sub)

  • Direct anycast addresses

  • Direct broadcast addresses

For more details, see address space. EnMasse also comes with a console that you can use for managing addresses.

EnMasse supports managing addresses natively in OpenShift.

Procedure
  1. Create an address list definition

    apiVersion: enmasse.io/v1alpha1
    kind: AddressList
    items:
    - metadata:
        name: myspace.anycast1
      spec:
        address: anycast1
        type: anycast
        plan: standard-anycast
    - metadata:
        name: myspace.multicast1
      spec:
        address: multicast1
        type: multicast
        plan: standard-multicast
    - metadata:
        name: myspace.queue1
      spec:
        address: queue1
        type: queue
        plan: pooled-queue
    - metadata:
        name: myspace.topic1
      spec:
        address: topic1
        type: topic
        plan: pooled-topic
  2. Create the addressses

    kubectl create -f standard-addresses.yaml

    The addresses are ready when the field .status.isReady is set to true.

  3. Check status of addressses

    kubectl get addresses -o jsonpath={.items[*].status.isReady}
Sending and receiving messages
Connecting with AMQP

For sending and receiving messages, have a look at an example python sender and receiver.

To send and receive messages, you should connect to the exposed route. To start a receiver, run:

./simple_recv.py -a "amqps://$(kubectl get addressspace myspace -o jsonpath={.status.endpointStatuses[?(@.name==\'messaging\')].host):443/myanycast" -m 10

This will block until it has received 10 messages. To start the sender, run:

./simple_send.py -a "amqps://$(kubectl get addressspace myspace -o jsonpath={.status.endpointStatuses[?(@.name==\'messaging\')].host):443/myanycast" -m 10

The server certificates is not verified in the above examples as we have deployed EnMasse with self-signed certificates. To fetch the certificate, run:

mkdir -p certs
kubectl get secret $(kubectl get addressspace myspace -o jsonpath={.spec.endpoints[?(@.name==\'messaging\')].cert.secretName}) -o jsonpath='{.data.tls\.crt}' | base64 -d > certs/tls.crt

You can modify the client code to use this cert to verify the server connection.

For more information, see Client examples.

Connecting using MQTT

For sending and receiving messages route, you can use the paho-mqtt client library. To connect, fetch the server certificate:

mkdir -p certs
kubectl get secret $(kubectl get addressspace myspace -o jsonpath={.spec.endpoints[?(@.name==\'mqtt\')].cert.secretName}) -o jsonpath='{.data.tls\.crt}' | base64 -d > certs/tls.crt
Subscriber client

Save the following to tls_mqtt_recv.py or download:

#!/usr/bin/env python

import paho.mqtt.client as mqtt
import ssl
import optparse

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))

    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    client.subscribe(opts.topic, int(opts.qos))

# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    print(msg.topic + " " + str(msg.payload))

def on_log(client, userdata, level, string):
    print(string)

parser = optparse.OptionParser(usage="usage: %prog [options]",
                               description="Receive messages from the supplied address.")

parser.add_option("-c", "--connectHost", default="localhost",
                  help="host to connect to (default %default)")

parser.add_option("-p", "--portHost", default="8883",
                  help="port to connect to (default %default)")

parser.add_option("-t", "--topic", default="mytopic",
                  help="topic to subscribe to (default %default)")

parser.add_option("-q", "--qos", default="0",
                  help="quality of service (default %default)")

parser.add_option("-s", "--serverCert", default=None,
                  help="server certificate file path (default %default)")

opts, args = parser.parse_args()

client = mqtt.Client("recv")
client.on_connect = on_connect
client.on_message = on_message
client.on_log = on_log

context = ssl.create_default_context()
if opts.serverCert == None:
    context.check_hostname = False
    context.verify_mode = ssl.CERT_NONE
else:
    context.load_verify_locations(cafile=opts.serverCert)

# just useful to activate for decrypting local TLS traffic with Wireshark
#context.set_ciphers("RSA")

client.tls_set_context(context)
client.tls_insecure_set(True)
client.connect(opts.connectHost, opts.portHost, 60)

# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
client.loop_forever()

In order to subscribe to a topic (that is, mytopic from the previous addresses configuration), the subscriber client can be used in the following way:

./tls_mqtt_recv.py -c "$(oc get route -o jsonpath='{.spec.host}' mqtt)" -p 443 -t mytopic -q 1 -s ./certs/tls.crt
Publisher client

Save the following to tls_mqtt_send.py or download:

#!/usr/bin/env python

import paho.mqtt.client as mqtt
import ssl
import optparse

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))

    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    client.publish(opts.topic, opts.message, int(opts.qos))

def on_publish(client, userdata, mid):
    print("mid: " + str(mid))
    client.disconnect()

def on_log(client, userdata, level, string):
    print(string)

parser = optparse.OptionParser(usage="usage: %prog [options]",
                               description="Sends messages to the supplied address.")

parser.add_option("-c", "--connectHost", default="localhost",
                  help="host to connect to (default %default)")

parser.add_option("-p", "--portHost", default="8883",
                  help="port to connect to (default %default)")

parser.add_option("-t", "--topic", default="mytopic",
                  help="topic to subscribe to (default %default)")

parser.add_option("-q", "--qos", default="0",
                  help="quality of service (default %default)")

parser.add_option("-s", "--serverCert", default=None,
                  help="server certificate file path (default %default)")

parser.add_option("-m", "--message", default="Hello",
                  help="message to publish (default %default)")

opts, args = parser.parse_args()

client = mqtt.Client("send")
client.on_connect = on_connect
client.on_publish = on_publish
client.on_log = on_log

context = ssl.create_default_context()
if opts.serverCert == None:
    context.check_hostname = False
    context.verify_mode = ssl.CERT_NONE
else:
    context.load_verify_locations(cafile=opts.serverCert)

# just useful to activate for decrypting local TLS traffic with Wireshark
#context.set_ciphers("RSA")

client.tls_set_context(context)
client.tls_insecure_set(True)
client.connect(opts.connectHost, opts.portHost, 60)

# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
client.loop_forever()

To start the publisher, the client can be used in the following way:

./tls_mqtt_send.py -c "$({OcGetRoute} mqtt)" -p 443 -t mytopic -q 1 -s ./certs/tls.crt -m "Hello EnMasse"

The publisher publishes the message and disconnects from EnMasse. The message is received by the previous connected subscriber.

Conclusion

We have seen how to setup a messaging service in Kubernetes, and how to communicate with it using python example AMQP clients.

Appendix B: REST API Reference

B.1. EnMasse REST API

B.1.1. Overview

This is the EnMasse API specification.

Version information

Version : 1.0.0

URI scheme

Schemes : HTTPS

Tags
  • addresses : Operating on Addresses.

  • addressplans : Operating on AddressPlans.

  • addressspaceplans : Operating on AddressSpacePlans.

  • addressspaces : Operate on AddressSpaces

  • brokeredinfraconfigs : Operating on BrokeredInfraConfigs.

  • messagingusers : Operating on MessagingUsers.

  • standardinfraconfigs : Operating on StandardInfraConfigs.

External Docs

Description : Find out more about EnMasse
URL : http://enmasse.io

B.1.2. Paths

POST /apis/admin.enmasse.io/v1alpha1/namespaces/{namespace}/addressspaceplans
Description

create an AddressSpacePlan

Parameters
Type Name Description Schema

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Body

body
required

Responses
HTTP Code Description Schema

200

OK

201

Created

401

Unauthorized

No Content

Consumes
  • application/json

Produces
  • application/json

Tags
  • addressspaceplan

  • admin

  • enmasse_v1alpha1

GET /apis/admin.enmasse.io/v1alpha1/namespaces/{namespace}/addressspaceplans
Description

list objects of kind AddressSpacePlan

Parameters
Type Name Description Schema

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Query

labelSelector
optional

A selector to restrict the list of returned objects by their labels. Defaults to everything.

string

Responses
HTTP Code Description Schema

200

OK

401

Unauthorized

No Content

Produces
  • application/json

Tags
  • addressspaceplan

  • admin

  • enmasse_v1alpha1

GET /apis/admin.enmasse.io/v1alpha1/namespaces/{namespace}/addressspaceplans/{name}
Description

read the specified AddressSpacePlan

Parameters
Type Name Description Schema

Path

name
required

Name of AddressSpacePlan to read.

string

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Responses
HTTP Code Description Schema

200

OK

401

Unauthorized

No Content

404

Not found

No Content

Consumes
  • application/json

Produces
  • application/json

Tags
  • addressspaceplan

  • admin

  • enmasse_v1alpha1

PUT /apis/admin.enmasse.io/v1alpha1/namespaces/{namespace}/addressspaceplans/{name}
Description

replace the specified AddressSpacePlan

Parameters
Type Name Description Schema

Path

name
required

Name of AddressSpacePlan to replace.

string

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Body

body
required

Responses
HTTP Code Description Schema

200

OK

201

Created

401

Unauthorized

No Content

Produces
  • application/json

Tags
  • addressspaceplan

  • admin

  • enmasse_v1alpha1

DELETE /apis/admin.enmasse.io/v1alpha1/namespaces/{namespace}/addressspaceplans/{name}
Description

delete an AddressSpacePlan

Parameters
Type Name Description Schema

Path

name
required

Name of AddressSpacePlan to delete.

string

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Responses
HTTP Code Description Schema

200

OK

401

Unauthorized

No Content

404

Not found

No Content

Produces
  • application/json

Tags
  • addressspaceplan

  • admin

  • enmasse_v1alpha1

POST /apis/enmasse.io/v1alpha1/namespaces/{namespace}/addresses
Description

create an Address

Parameters
Type Name Description Schema

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Body

body
required

Responses
HTTP Code Description Schema

200

OK

201

Created

401

Unauthorized

No Content

Consumes
  • application/json

Produces
  • application/json

Tags
  • addresses

  • enmasse_v1alpha1

GET /apis/enmasse.io/v1alpha1/namespaces/{namespace}/addresses
Description

list objects of kind Address

Parameters
Type Name Description Schema

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Query

labelSelector
optional

A selector to restrict the list of returned objects by their labels. Defaults to everything.

string

Responses
HTTP Code Description Schema

200

OK

401

Unauthorized

No Content

Produces
  • application/json

Tags
  • addresses

  • enmasse_v1alpha1

GET /apis/enmasse.io/v1alpha1/namespaces/{namespace}/addresses/{name}
Description

read the specified Address

Parameters
Type Name Description Schema

Path

name
required

Name of Address to read

string

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Responses
HTTP Code Description Schema

200

OK

401

Unauthorized

No Content

404

Not found

No Content

Consumes
  • application/json

Produces
  • application/json

Tags
  • addresses

  • enmasse_v1alpha1

PUT /apis/enmasse.io/v1alpha1/namespaces/{namespace}/addresses/{name}
Description

replace the specified Address

Parameters
Type Name Description Schema

Path

name
required

Name of Address to replace

string

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Body

body
required

Responses
HTTP Code Description Schema

200

OK

201

Created

401

Unauthorized

No Content

Produces
  • application/json

Tags
  • addresses

  • enmasse_v1alpha1

DELETE /apis/enmasse.io/v1alpha1/namespaces/{namespace}/addresses/{name}
Description

delete an Address

Parameters
Type Name Description Schema

Path

name
required

Name of Address to delete

string

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Responses
HTTP Code Description Schema

200

OK

401

Unauthorized

No Content

404

Not found

No Content

Produces
  • application/json

Tags
  • addresses

  • enmasse_v1alpha1

POST /apis/enmasse.io/v1alpha1/namespaces/{namespace}/addressspaces
Description

create an AddressSpace

Parameters
Type Name Description Schema

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Body

body
required

Responses
HTTP Code Description Schema

200

OK

201

Created

401

Unauthorized

No Content

Consumes
  • application/json

Produces
  • application/json

Tags
  • addressspaces

  • enmasse_v1alpha1

GET /apis/enmasse.io/v1alpha1/namespaces/{namespace}/addressspaces
Description

list objects of kind AddressSpace

Parameters
Type Name Description Schema

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Query

labelSelector
optional

A selector to restrict the list of returned objects by their labels. Defaults to everything.

string

Responses
HTTP Code Description Schema

200

OK

401

Unauthorized

No Content

Produces
  • application/json

Tags
  • addressspaces

  • enmasse_v1alpha1

POST /apis/enmasse.io/v1alpha1/namespaces/{namespace}/addressspaces/{addressSpace}/addresses
Description

create Addresses in an AddressSpace

Parameters
Type Name Description Schema

Path

addressSpace
required

Name of AddressSpace

string

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Body

body
required

AddressList object

Responses
HTTP Code Description Schema

200

OK

401

Unauthorized

No Content

404

Not found

No Content

Consumes
  • application/json

Produces
  • application/json

Tags
  • addressspace_addresses

  • enmasse_v1alpha1

GET /apis/enmasse.io/v1alpha1/namespaces/{namespace}/addressspaces/{addressSpace}/addresses
Description

list objects of kind Address in AddressSpace

Parameters
Type Name Description Schema

Path

addressSpace
required

Name of AddressSpace

string

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Responses
HTTP Code Description Schema

200

OK

401

Unauthorized

No Content

404

Not found

No Content

Produces
  • application/json

Tags
  • addressspace_addresses

  • enmasse_v1alpha1

GET /apis/enmasse.io/v1alpha1/namespaces/{namespace}/addressspaces/{addressSpace}/addresses/{address}
Description

read the specified Address in AddressSpace

Parameters
Type Name Description Schema

Path

address
required

Name of Address

string

Path

addressSpace
required

Name of AddressSpace

string

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Responses
HTTP Code Description Schema

200

OK

401

Unauthorized

No Content

404

Not found

No Content

Produces
  • application/json

Tags
  • addressspace_addresses

  • enmasse_v1alpha1

PUT /apis/enmasse.io/v1alpha1/namespaces/{namespace}/addressspaces/{addressSpace}/addresses/{address}
Description

replace Address in an AddressSpace

Parameters
Type Name Description Schema

Path

address
required

Name of address

string

Path

addressSpace
required

Name of AddressSpace

string

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Body

body
required

Address object

Responses
HTTP Code Description Schema

200

OK

201

Created

401

Unauthorized

No Content

404

Not found

No Content

Consumes
  • application/json

Produces
  • application/json

Tags
  • addressspace_addresses

  • enmasse_v1alpha1

DELETE /apis/enmasse.io/v1alpha1/namespaces/{namespace}/addressspaces/{addressSpace}/addresses/{address}
Description

delete an Address in AddressSpace

Parameters
Type Name Description Schema

Path

address
required

Name of Address

string

Path

addressSpace
required

Name of AddressSpace

string

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Responses
HTTP Code Description Schema

200

OK

401

Unauthorized

No Content

404

Not found

No Content

Produces
  • application/json

Tags
  • addressspace_addresses

  • enmasse_v1alpha1

GET /apis/enmasse.io/v1alpha1/namespaces/{namespace}/addressspaces/{name}
Description

read the specified AddressSpace

Parameters
Type Name Description Schema

Path

name
required

Name of AddressSpace to read

string

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Responses
HTTP Code Description Schema

200

OK

401

Unauthorized

No Content

404

Not found

No Content

Consumes
  • application/json

Produces
  • application/json

Tags
  • addressspaces

  • enmasse_v1alpha1

PUT /apis/enmasse.io/v1alpha1/namespaces/{namespace}/addressspaces/{name}
Description

replace the specified AddressSpace

Parameters
Type Name Description Schema

Path

name
required

Name of AddressSpace to replace

string

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Body

body
required

Responses
HTTP Code Description Schema

200

OK

201

Created

401

Unauthorized

No Content

Produces
  • application/json

Tags
  • addressspaces

  • enmasse_v1alpha1

DELETE /apis/enmasse.io/v1alpha1/namespaces/{namespace}/addressspaces/{name}
Description

delete an AddressSpace

Parameters
Type Name Description Schema

Path

name
required

Name of AddressSpace to delete

string

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Responses
HTTP Code Description Schema

200

OK

401

Unauthorized

No Content

404

Not found

No Content

Produces
  • application/json

Tags
  • addressspaces

  • enmasse_v1alpha1

POST /apis/user.enmasse.io/v1alpha1/namespaces/{namespace}/messagingusers
Description

create a MessagingUser

Parameters
Type Name Description Schema

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Body

body
required

Responses
HTTP Code Description Schema

200

OK

201

Created

401

Unauthorized

No Content

Consumes
  • application/json

Produces
  • application/json

Tags
  • auth

  • enmasse_v1alpha1

  • user

GET /apis/user.enmasse.io/v1alpha1/namespaces/{namespace}/messagingusers
Description

list objects of kind MessagingUser

Parameters
Type Name Description Schema

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Query

labelSelector
optional

A selector to restrict the list of returned objects by their labels. Defaults to everything.

string

Responses
HTTP Code Description Schema

200

OK

401

Unauthorized

No Content

Produces
  • application/json

Tags
  • auth

  • enmasse_v1alpha1

  • user

GET /apis/user.enmasse.io/v1alpha1/namespaces/{namespace}/messagingusers/{name}
Description

read the specified MessagingUser

Parameters
Type Name Description Schema

Path

name
required

Name of MessagingUser to read. Must include addressSpace and dot separator in the name (that is, 'myspace.user1').

string

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Responses
HTTP Code Description Schema

200

OK

401

Unauthorized

No Content

404

Not found

No Content

Consumes
  • application/json

Produces
  • application/json

Tags
  • auth

  • enmasse_v1alpha1

  • user

PUT /apis/user.enmasse.io/v1alpha1/namespaces/{namespace}/messagingusers/{name}
Description

replace the specified MessagingUser

Parameters
Type Name Description Schema

Path

name
required

Name of MessagingUser to replace. Must include addressSpace and dot separator in the name (that is, 'myspace.user1').

string

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Body

body
required

Responses
HTTP Code Description Schema

200

OK

201

Created

401

Unauthorized

No Content

Produces
  • application/json

Tags
  • auth

  • enmasse_v1alpha1

  • user

DELETE /apis/user.enmasse.io/v1alpha1/namespaces/{namespace}/messagingusers/{name}
Description

delete a MessagingUser

Parameters
Type Name Description Schema

Path

name
required

Name of MessagingUser to delete. Must include addressSpace and dot separator in the name (that is, 'myspace.user1').

string

Path

namespace
required

object name and auth scope, such as for teams and projects

string

Responses
HTTP Code Description Schema

200

OK

401

Unauthorized

No Content

404

Not found

No Content

Produces
  • application/json

Tags
  • auth

  • enmasse_v1alpha1

  • user

B.1.3. Definitions

ObjectMeta

ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create.

Name Schema

name
required

string

namespace
optional

string

Status

Status is a return value for calls that do not return other objects.

Name Description Schema

code
optional

Suggested HTTP return code for this status, 0 if not set.

integer (int32)

io.enmasse.admin.v1alpha1.AddressPlan
Name Schema

addressType
required

string

apiVersion
required

enum (admin.enmasse.io/v1alpha1)

displayName
required

string

displayOrder
required

integer

kind
required

enum (AddressPlan)

longDescription
optional

string

metadata
required

requiredResources
required

< requiredResources > array

shortDescription
required

string

uuid
required

string

requiredResources

Name Schema

credit
required

number

name
required

string

io.enmasse.admin.v1alpha1.AddressPlanList
Name Schema

apiVersion
required

enum (admin.enmasse.io/v1alpha1)

items
required

kind
required

enum (AddressPlanList)

io.enmasse.admin.v1alpha1.AddressSpacePlan
Name Schema

addressPlans
optional

< string > array

addressSpaceType
required

string

apiVersion
required

enum (admin.enmasse.io/v1alpha1)

displayName
required

string

displayOrder
required

integer

kind
required

enum (AddressSpacePlan)

longDescription
optional

string

metadata
required

resources
required

< resources > array

shortDescription
required

string

uuid
required

string

resources

Name Schema

max
required

number

min
required

number

name
required

string

io.enmasse.admin.v1alpha1.AddressSpacePlanList
Name Schema

apiVersion
required

enum (admin.enmasse.io/v1alpha1)

items
required

kind
required

enum (AddressSpacePlanList)

io.enmasse.admin.v1alpha1.BrokeredInfraConfig
Name Schema

apiVersion
required

enum (admin.enmasse.io/v1alpha1)

kind
required

enum (BrokeredInfraConfig)

metadata
required

spec
required

io.enmasse.admin.v1alpha1.BrokeredInfraConfigList
Name Schema

apiVersion
required

enum (admin.enmasse.io/v1alpha1)

items
required

kind
required

enum (BrokeredInfraConfigList)

io.enmasse.admin.v1alpha1.BrokeredInfraConfigSpec
Name Schema

admin
optional

broker
optional

version
required

string

io.enmasse.admin.v1alpha1.BrokeredInfraConfigSpecAdmin
Name Schema

resources
optional

resources

Name Schema

memory
optional

string

io.enmasse.admin.v1alpha1.BrokeredInfraConfigSpecBroker
Name Schema

addressFullPolicy
optional

enum (PAGE, BLOCK, FAIL)

resources
optional

resources

Name Schema

memory
optional

string

storage
optional

string

io.enmasse.admin.v1alpha1.StandardInfraConfig
Name Schema

apiVersion
required

enum (admin.enmasse.io/v1alpha1)

kind
required

enum (StandardInfraConfig)

metadata
required

spec
required

io.enmasse.admin.v1alpha1.StandardInfraConfigList
Name Schema

apiVersion
required

enum (admin.enmasse.io/v1alpha1)

items
required

kind
required

enum (StandardInfraConfigList)

io.enmasse.admin.v1alpha1.StandardInfraConfigSpec
Name Schema

admin
optional

broker
optional

router
optional

version
required

string

io.enmasse.admin.v1alpha1.StandardInfraConfigSpecAdmin
Name Schema

resources
optional

resources

Name Schema

memory
optional

string

io.enmasse.admin.v1alpha1.StandardInfraConfigSpecBroker
Name Schema

addressFullPolicy
optional

enum (PAGE, BLOCK, FAIL)

resources
optional

resources

Name Schema

memory
optional

string

storage
optional

string

io.enmasse.admin.v1alpha1.StandardInfraConfigSpecRouter
Name Schema

linkCapacity
optional

string

resources
optional

resources

Name Schema

memory
optional

string

io.enmasse.user.v1alpha1.MessagingUser
Name Schema

apiVersion
required

enum (user.enmasse.io/v1alpha1)

kind
required

enum (MessagingUser)

metadata
required

spec
required

io.enmasse.user.v1alpha1.MessagingUserList
Name Schema

apiVersion
required

enum (user.enmasse.io/v1alpha1)

items
required

kind
required

enum (MessagingUserList)

io.enmasse.user.v1alpha1.UserSpec
Name Schema

authentication
optional

authorization
optional

< authorization > array

username
required

string

authentication

Name Description Schema

federatedUserid
optional

User id of the user to federate when 'federated' type is specified.

string

federatedUsername
optional

User name of the user to federate when 'federated' type is specified.

string

password
optional

Base64 encoded value of password when 'password' type is specified.

string

provider
optional

Name of provider to use for federated identity when 'federated' type is specified.

string

type
required

enum (password, federated)

authorization

Name Schema

addresses
optional

< string > array

operations
required

< enum (send, receive, view, manage) > array

io.enmasse.v1alpha1.Address
Name Schema

apiVersion
required

enum (enmasse.io/v1alpha1)

kind
required

enum (Address)

metadata
required

spec
required

status
optional

io.enmasse.v1alpha1.AddressList
Name Description Schema

apiVersion
required

Default : "enmasse.io/v1alpha1"

enum (enmasse.io/v1alpha1)

items
required

kind
required

enum (AddressList)

io.enmasse.v1alpha1.AddressSpace
Name Schema

apiVersion
required

enum (enmasse.io/v1alpha1)

kind
required

enum (AddressSpace)

metadata
required

spec
required

status
optional

io.enmasse.v1alpha1.AddressSpaceList
Name Description Schema

apiVersion
required

Default : "enmasse.io/v1alpha1"

enum (enmasse.io/v1alpha1)

items
required

kind
required

enum (AddressSpaceList)

io.enmasse.v1alpha1.AddressSpaceSpec
Name Schema

authenticationService
optional

endpoints
optional

< endpoints > array

plan
required

string

type
required

authenticationService

Name Schema

details
optional

object

type
optional

string

endpoints

Name Schema

cert
optional

host
optional

string

name
optional

string

service
optional

string

servicePort
optional

string

cert

Name Schema

provider
optional

string

secretName
optional

string

io.enmasse.v1alpha1.AddressSpaceStatus
Name Schema

endpointStatuses
optional

< endpointStatuses > array

isReady
optional

boolean

messages
optional

< string > array

endpointStatuses

Name Schema

host
optional

string

name
optional

string

port
optional

integer

serviceHost
optional

string

servicePorts
optional

< servicePorts > array

servicePorts

Name Schema

name
optional

string

port
optional

integer

io.enmasse.v1alpha1.AddressSpaceType

AddressSpaceType is the type of address space (standard, brokered). Each type supports different types of addresses and semantics for those types.

Type : enum (standard, brokered)

io.enmasse.v1alpha1.AddressSpec
Name Schema

address
required

string

plan
required

string

type
required

io.enmasse.v1alpha1.AddressStatus
Name Schema

isReady
optional

boolean

messages
optional

< string > array

phase
optional

enum (Pending, Configuring, Active, Failed, Terminating)

io.enmasse.v1alpha1.AddressType

Type of address (queue, topic, …). Each address type support different kinds of messaging semantics.

Type : enum (queue, topic, anycast, multicast)