A template repo that contains a NodeJS app that will consume messages from a RabbitMQ queue and immediately send them to an Azure EventHub.

Overview

README.md

Summary

This repo (RabbitMQ to EventHub Shovel) is a template that contains a NodeJS app that will consume messages from a RabbitMQ queue and immediately send them to an Azure EventHub. It can be run directly using node, nvm or Docker (recommended).

Dependencies

Install NPM Dependencies

  • From the /app directory, run npm i.

Secrets, CA_Certificate

See Secrets Explained.

Environment

See Environment Variables Explained.

RabbitMQ & Azure

  • Last, you need an RMQ server and an Azure Event Hub. Messages from a queue in the RMQ server will be sent to the Azure Event Hub. Note the routing key sent to RMQ will be passed into Azure Event Hub via the properties bag. (EventHub sends your program an EventData object that has the properties "body" and "properties". The routing key will be passed into EventData.properties.routingKey).

Environment Variables Explained

The .env file is used to control all the parameters for the app.

  • You need environment variables set. See the file corresponding to your run method.
    • If you're running natively, see the template /app/environment.template and use it to create a .env file in /app.
    • If you're running rabbitmq-to-eventhub-dev, see the template /rabbitmq-to-eventhub-dev/environment.template and use it to create a .env file in /rabbitmq-to-eventhub-dev.
    • If you're running rabbitmq-to-eventhub-prod, see the template /rabbitmq-to-eventhub-prod/environment.template and use it to create a .env file in /rabbitmq-to-eventhub-prod.
# Set a log level that suits your needs.
# Supported Log Levels:
# OFF	 - nothing is logged
# FATAL - fatal errors are logged
# ERROR - errors are logged
# WARN	 - warnings are logged
# INFO	 - infos are logged
# DEBUG - debug infos are logged
# TRACE - traces are logged
# ALL   - everything is logged
logLevel=all

# RMQ (AMQP) Properties
amqpHost="some.host.com"
# vhost can be left blank or no vhost.
amqpVhost=""
# leave port blank to let the library automatically choose
amqpPort=
# Which Protocol to use to connect to AMQP (amqp, amqps)
amqpProtocol="amqps"
# Name of the queue to consume from (must exist on the RMQ host)
amqpConsumeQueue=""
# Should messages be ACK after consume? This will tell RMQ to remove them from the Queue once processed. (true, false)
ackAfterConsume=false

# EventHub Properties
eventHubName="mkalx-inputeventhub-test"

# Advanced Shovel Parameters

# ************
# Batch Mode *
# ************
# If working in batch mode, uncomment these parameters and comment the oneEach parameters
consumeMode=batch
# AMQP Prefetch Count (the maximum number of messages sent over the channel that can be awaiting acknowledgement).
# Default is unlimited. Either comment this out for unlimited OR set a sufficiently large number to meet your needs.
#amqpPrefetch=300
# How many bytes in flight before a batch is released for consumption
batchMaxSizeBytes=100000
# How many seconds in light before a batch is release for consumption
batchMaxTimeMs=5000

# **************
# OneEach Mode *
# **************
# If working in oneEach mode, uncomment these parameters and comment the batch parameters
#consumeMode=oneEach
# AMQP Prefetch Count (the maximum number of messages sent over the channel that can be awaiting acknowledgement).
# If using consumeLimit, set this to a number less than or equal your limit.
#amqpPrefetch=10
# How many messages to consume (0=all, otherwise enter a limit)
# Should be a multiple of amqpPrefetch (which should not be set to unlimited for limiting to work).
#consumeLimit=10

Note there are two modes for consumeMode:

  • oneEach - consumes one message at a time and is suitable for testing or very low volume queues. Messages will be sent to Eventhub one at a time, not in batches.
  • batch - consumes messages in batches controlled by batch size. Suitable for high volume queues. Messages will be sent to Eventhub in batches.

What is Prefetch?

Prefetch is the number of messages "in flight" that a connection into RMQ is allowed. "In flight" means messages that have been sent to a consumer but are not yet ACK by said consumer. The default is unlimited and should be used unless you specifically want to slow down message consumption. Setting a value of 1 would beam that each message must be sent to Eventhub (and then ACK) before RMQ will release a new one.

Secrets Explained

The /app/secrets.json5 file is used to hold secrets for the app and is excluded from the repo via .gitignore.

{
  "amqpUsername": "ENTER USERNAME HERE",
  "amqpPassword": "ENTER PASSWORD HERE",
  "amqpCACertName": "ENTER THE NAME OF YOUR CA CERT FILE AND COPY IT TO THE SAME DIR AS secrets.json5",

  // Event Hub Connection String
  "eventHubConnectionString": "Enter the Event Hub Connection String Here"
}
  • If your RMQ host uses AMQPS (AMQP over TLS), you'll need the CA Certfile for the server in /app/conf/ca_certfile.pem.
  • Be sure to set the environment variable amqpProtocol="amqps".
  • Also, in secrets.json5, make sure amqpCACertName="" contains the name of your cert file (recommended name is ca_certfile.pem).

How to run the app

Note: See the Dependencies section before trying to run!

  • Running natively via NVM (Node Version Manager)

    • .env in /app, secrets.json5 in /app/conf, possibly ca_certificate.pem (if needed) in /app/conf
    • Be sure you've done npm i
    • Run with: nvm index.js
  • Running natively via NodeJS

    • .env in /app, secrets.json5 in /app/conf, possibly ca_certificate.pem (if needed) in /app/conf
    • Be sure you've done npm i
    • node index.js
  • Running locally using the Docker dev config

    • .env in /rabbitmq-to-eventhub-dev, secrets.json5 in /app/conf, possibly ca_certificate.pem (if needed) in /app/conf
    • Be sure you've done npm i
    • docker compose up to run interactively or docker compose up -d to run in the background

Deploying and Running on your PROD remote server

Note: See the Dependencies section before trying to build/deploy!

  • When deploying to a remote host, either of the following should work:
    • Copy the whole repo (with the secrets.json5 and ca_certificate.pem if required) and then build the production docker compose in-place.
      • On the target server
        • On servers, Docker Compose needs to be installed. Ensure it's installed. If not, see Docker Compose Install.
        • Change into the rabbitmq-to-eventhub-prod folder
        • Ensure you have the proper values in .env
        • Ensure you've edited /conf/secrets.json5 to suit your needs.
          • If you need a ca_certificate.pem, make sure it's in /conf.
        • docker-compose build
        • docker-compose up to run the container interactively. It is recommended that you run the first time with "ackAfterConsume=false" so you don't lose any messages if there's a container error.
        • Once satisfied the container is working properly, stop the interactive mode, change "ackAfterConsume=true" and run with docker compose up -d to run in the background
        • Note that if you change values in /conf/secrets.json5, or update your ca_certificate.pem, you must repeat the Docker build step. Changing values in .env does not require a rebuild.
    • The production docker compose build can be done in a remote machine and then the docker container can be exported using Docker's export command.
      • On your build workstation
        • Change into the rabbitmq-to-eventhub-prod folder
        • Ensure you have the proper values in .env
        • Ensure you've edited /conf/secrets.json5 to suit your needs.
        • If you need a ca_certificate.pem, make sure it's in /conf.
        • docker compose build
        • docker export rabbitmq-to-eventhub-prod > rabbitmq-to-eventhub-prod.tar
      • On the host
        • Copy the three files (.env, docker-compose.yml, rabbitmq-to-eventhub-prod.tar to the host)
        • docker import rabbitmq-to-eventhub-prod.tar
        • docker compose up to run the container interactively. It is recommended that you run the first time with "ackAfterConsume=false" so you don't lose any messages if there's a container error.
        • Once satisfied the container is working properly, stop the interactive mode, change "ackAfterConsume=true" and run with docker compose up -d to run in the background
        • Note that if you change values in /conf/secrets.json5, or update your ca_certificate.pem, you must repeat the Docker build step (and export/upload/import to your host).

Environment variable notes for running in-place at an RMQ server (it's assumed said server is using AMQPS / AMQP over TLS):

  • The prod container rabbitmq-to-eventhub-prod is suitable to run on the RMQ server itself. Therefore, the RMQ host in this case will be the docker host (using the special "host-gateway" alias).
  • To avoid TLS issues, we used docker's extra_hosts to create a docker compose level HOSTS entry to map the TLS hostname to "host-gateway". See the section To run the Docker container on your RMQ host.

Azure EventHub Capture

During testing, it might be useful to capture what you send into EventHub in an Azure Storage Container.

  • If capturing files to Azure Storage, those will be in AVRO format.
    • There are AVRO viewers. In fact, JetBrains WebStorm has one as a plugin. Install Avro and Parquet Viewer from the JetBrains IDE Plugins manager.
    • To download the files there are options:
      • Azure Storage Explorer to see the files and download.
        • Use the full connection string from STORAGE ACCOUNT | ACCESS KEYS | key1 or key2 connection string
      • Azure Portal also lets you navigate into the folder/files and download.

Edge Cases

To run the Docker container (prod) on your RMQ host

In this edge case, the RMQ hostname needs to be mapped to the Docker host. To avoid TLS issues, we do this by adding the following to the docker-compose.yml service entry for rmq-to-eventhub:

    extra_hosts:
      # If this container will be run on the RMQ host directly, we need to map the RMQ hostname with the internal special host gateway 
      # in order send the traffic to the docker host! This is like setting the HOSTS file inside the container.
      - "${amqpHost}:host-gateway"
  • The ${amqpHost} will come from your .env file and is the hostname for the RMQ server.
  • "host-gateway" is a special docker setting that represents the host's IP internally.

RMQ host requires an SSH Tunnel in order to connect

In this edge case, the RMQ host is only accessible via an SSH tunnel running on the workstation executing the app. This is not a problem when running NodeJS or NVM natively, but it is a challenge when running inside Docker since the container needs to connect to the host instead of the remote RMQ server.

To do this we add the following to docker-compose.yml service entry for rmq-to-eventhub:

    extra_hosts:
      # If the RMQ host requires an SSH tunnel, we need to map the RMQ hostname with the internal special host gateway 
      # in order send the traffic to the docker host! This is like setting the HOSTS file inside the container.
      - "${amqpHost}:host-gateway"
  • The ${amqpHost} will come from your .env file and is the hostname for the RMQ server.
  • "host-gateway" is a special docker setting that represents the host's IP internally.

An example SSH tunnel on the docker host: (on the host, port 15671 will be forwarded to the RMQ's port 5671)

ssh -N -i "/path/to/your/key.pem" -L 127.0.0.1:15671:127.0.0.1:5671 -o ServerAliveInterval=15 -o ExitOnForwardFailure=yes -o ServerAliveCountMax=3 -p YOUR-PORT-NUMBER YOUR-USERNAME@YOU-HOST-IP-OR-NAME

TODO:

  • Nothing yet noted.
You might also like...

This is email scheduler made using MERN. This repo contains server code, client repo is linked in readme.

Email Scheduler Client This is an email scheduler server (client in different repository). It is made using node.js/express.js. Overview User can sign

Dec 3, 2022

Consume API's with no code.

Consume API's with no code.

NoAPIcode Consume API's with no code. Connect Once, use across all platforms. Tutorial Documentation JavaScript: npm npm install noapicode Example Us

Jun 15, 2022

This template is for generating a .NET C# wrapper for the RabbitMQ client based on your AsyncAPI document.

This template is for generating a .NET C# wrapper for the RabbitMQ client based on your AsyncAPI document.

.NET C# RabbitMQ template This is a .NET C# RabbitMQ template for the AsyncAPI generator This template is for generating a .NET C# wrapper for the Rab

Dec 21, 2022

This repo contains configurations for webpack, webhint, stylelint and eslint, it is a boiler-plate template and a starting point for coming projects.

Project Name Description the project. Built With Major languages Frameworks Technologies used Live Demo (if available) Experience a live Demo 🚀 Getti

Oct 20, 2022

This is a Webpack based to-do-list project. With this app, users can add thier daily routine tasks to the list, mark them as complet, edit them or delete them.

To Do List This is a Webpack based to-do-list project. With this app, users can add thier daily routine tasks to the list, mark them as complet, edit

Oct 30, 2022

Send encrypted and decrypted messages with verifiable keys and human readable names.

Send encrypted and decrypted messages with verifiable keys and human readable names.

zooko-msg Encrypt and decrypt messages using AES with a preshared ECDH key generated using keys associated with Handshake names. I noticed that there

Jul 27, 2022

Send messages to this bot and almacenate it on selected Notion's Database

Send messages to this bot and almacenate it on selected Notion's Database

Telegram to Notion Bot What can do this bot? With this bot you can authorize that it receive the text that you send and store it on one selected datab

Dec 11, 2022

This repo contains a To-Do List App developed as a Single Page Application using Webpack, Javascript, HTML and CSS.

Todo List App In this project I built an interactive Todo List Web App with Webpack, HTML, CSS, and JavaScript. This project contains a feature that a

Nov 4, 2022

an open-source package to make it easy and simple to work with RabbitMQ's RPC ( Remote Procedure Call )

an open-source package to make it easy and simple to work with RabbitMQ's RPC ( Remote Procedure Call )

RabbitMQ Easy RPC (Remote Procedure Call ) The Node.js's RabbitMQ Easy RPC Library rabbitmq-easy-RPC is an easy to use npm package for rabbitMQ's RPC

Sep 22, 2022
Comments
  • Remove volumes

    Remove volumes

    Main goal of this branch was to simplify the docker build to work better running as a base image for a service in the uni-dax analytics docker compose. It also fixed a bug with batch mode, and added a way to pass in specific shovel.env's into the NodeJS native running mode for easier env switching/switching between consume modes.

    opened by ebegue 0
  • Consuming batches of 300 from RMQ still only sends about 120 to EventHub

    Consuming batches of 300 from RMQ still only sends about 120 to EventHub

    ENV that causes this:

    consumeMode=batch
    amqpPrefetch=300
    batchMaxSizeBytes=2000000
    batchMaxTimeMs=5000
    

    With the above ENV, the shovel would receive 300 messages, but would only send 120 or so to EventHub or around 1000000 bytes (which is probably the limiting factor.)

    opened by EricWasTakenMJD 0
  • Eventhub package does not throw errors on connection issues

    Eventhub package does not throw errors on connection issues

    As noted in the README: https://github.com/valtech-sd/RabbitMQ-To-EventHub-Shovel/blob/272080e18dd5522cb848582dc678d7c315d5ef86/README.md?plain=1#L223

    Need to research to see why Eventhub won't throw errors on connection issues, or how to get it to do so.

    opened by EricWasTakenMJD 0
Releases(v2.0.0)
  • v2.0.0(Apr 1, 2022)

    New features:

    • Added a consumeMode parameter that supports oneEach (one message) and batch (multiple messages) at a time.
    • Added additional environment variables to control batch and oneEach.
    • Batch can now control the size of batch in bytes as well as message age (in seconds.)
    • OneEach can add a limit to ingest only a certain number of messages.
    Source code(tar.gz)
    Source code(zip)
  • v1.0.1(Mar 31, 2022)

    Minor update:

    • Readme update for clarification around Docker Build after changing secrets.
    • Added a symlink inside the Docker Prod config to make it easy to edit the secrets and certificate when packaging the container.
    Source code(tar.gz)
    Source code(zip)
  • v1.0(Mar 31, 2022)

    Initial app release:

    • Consumes messages from an RMQ Queue in batch and immediately publishes them in batch to EventHub. RMQ RoutingKey is preserved and passed into EventHub.
    • Can run locally via node or nvm.
    • Can run locally via Docker.
    • Can be built locally then deployed remotely using a Docker container.
    • Supports RMQ via SSH tunnel as well as Docker running on the same host as RMQ.
    Source code(tar.gz)
    Source code(zip)
Owner
Valtech San Diego
Valtech San Diego
Valtech San Diego
Queue is a node.js package to create background jobs in topic-based RabbitMQ exchanges and process them later.

Queue PLG Works Queue helps with managing subscription and publish critical events using RabbitMQ. All events are published through RabbitMQ, using to

PLG Works 23 Sep 21, 2022
Chat app using Azure Web PubSub, Static Web Apps and other Azure services

Chatr - Azure Web PubSub Sample App This is a demonstration & sample application designed to be a simple multi-user web based chat system. It provides

Ben Coleman 55 Dec 31, 2022
A cache for @azure/msal-node that uses Azure KeyVault as a store

@intility/msal-keyvault-cache A cache for @azure/msal-node that uses Azure KeyVault as a store. Usage Install with npm install @intility/msal-keyvault

Intility 10 Mar 17, 2022
Vamos a realizar un juego muy sencillo en TypeScript, posteriormente lo vamos a desplegar en Microsoft Azure con Servicio de Azure Static Web Apps.

Taller TypeScript Descripción Vamos a realizar un juego muy sencillo en TypeScript, posteriormente lo vamos a desplegar en Microsoft Azure con Servici

Manuel Ortiz 7 Oct 10, 2022
JavaScript project for the Leaderboard list app, using Webpack and ES6 features, notably modules. this app consume the Leaderboard API using JavaScript async and await and add some styling.

Leaderboard Project JavaScript project for the Leaderboard list app, using Webpack and ES6 features, notably modules. this app consume the Leaderboard

bizimungu pascal 4 May 20, 2022
Send encrypted messages and decrypt them without sharing keys. Built using the Handshake blockchain.

zmsg Encrypt and decrypt messages using AEAD with an ephemeral key Learn more by joining the Handshake Discord Community I noticed that there wasn't a

Publius Federalist 31 Jul 27, 2022
Util for kafkajs to buffer messages and send them in batches, inspired by node-rdkafka

kafkjajs-buffer Plugin for kafkajs to buffer messages and send them in batches, inspired by node-rdkafka Overview kafkajs-buffer adds queue/buffer cap

Alberto Juan 7 Sep 7, 2022
This project contains a leader board for a game which contains players name and list and store them on API build with HTML, CSS, JS and API

Leaderboard This App is a Game Leaderboard app Which is created by JavaScript and the big picture of this application is using API. Build With ??‍?? .

Sahar Saba Amiri 5 Dec 15, 2022
A simple to do list webpage where you can log the daily tasks you have to do, mark them as checked, modify them, reorder them and remove them. Made using HTML, CSS and JavaScript.

To-Do-List This Webpage is for an app called To-Do-List which helps you add, remove or check tasks you have to do. It is a simple web page which conta

Zeeshan Haider 9 Mar 12, 2022
A CLI tool to make Taobao's npm mirror sync your package immediately.

npm-mirror-sync A CLI tool to make Taobao's npm mirror sync your package immediately. 让淘宝的 NPM 镜像立即收录你的包的新版本。 背景 相信国内小伙伴都在用淘宝的 NPM 镜像(npmmirror.com)作为

CSS魔法 10 Jun 9, 2022