Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions crates/rabbitmq-broker/AMQP Client/queue-publisher-amqp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import pika
import time

# topic username and password
SERVICE_NAME= 'service-name'
SERVICE_TOKEN= 'token-service'
TOPIC='oscar.service-name'

delay=5 # Delay time between messages

credentials = pika.PlainCredentials(SERVICE_NAME,SERVICE_TOKEN)

#connection = pika.BlockingConnection(pika.ConnectionParameters('localhost', credentials=credentials))

# REPLACE the long URL with the mapped host and port
# If you're in the same environment as Rabbit: 'localhost'
# If it's remote: the domain without 'https://' or routes
host_cluster = 'cluster.im.grycap.net'
amqp_port = 30300 # # Make sure this is the AMQP NodePort, not the HTTPS one

connection = pika.BlockingConnection(
pika.ConnectionParameters(
host=host_cluster,
port=amqp_port,
credentials=credentials
)
)

channel = connection.channel()
number_message=8
# We posted x messages in a row to test the accumulator
for i in range(1, number_message):
message = f"Message - {i}"
channel.basic_publish(
exchange='amq.topic',
routing_key=TOPIC, # topic
body=message
)
print(f" [!] Send: {message}")
time.sleep(delay)

connection.close()
62 changes: 62 additions & 0 deletions crates/rabbitmq-broker/AMQP Client/queue-publisher-http.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import requests
import json
import time

def send_burst_of_messages(number):
# --- Configuration---
USER = "service-name"
PASS = "service-token"
URL = "http://cluster.im.grycap.net:30100/api/exchanges/%2f/amq.topic/publish"

print(f"🚀 Starting to send {number} messages...")

for i in range(1, number + 1):
# Variable message body
message = {
"id": i,
"timestamp": time.time(),
"content": f"Burst message number {i}",
"source": "python-script"
}

payload_api = {
"properties": {
"content_type": "application/json",
"delivery_mode": 2
},
"routing_key": f"oscar.{USER}",
"payload": json.dumps(message),
"payload_encoding": "string"
}

try:
response = requests.post(
URL,
auth=(USER, PASS),
data=json.dumps(payload_api),
allow_redirects=False,
headers={"Content-Type": "application/json"}
)

if response.status_code == 200:
result = response.json()
if result.get("routed"):
print(f"✅ [{i}/{number}] Message successfully routed.")
else:
print(f"⚠️ [{i}/{number}] Sent but NOT routed. Check routing_key.")
else:
print(f"❌ Error in message {i}: {response.status_code} - {response.text}")

except Exception as e:
print(f"❌ Connection error in message {i}: {e}")
break

# Optional: a short pause of 3s between messages for improved flow
time.sleep(3)

print("🏁 Process completed.")

if __name__ == "__main__":
# Change this value as needed
AMOUNT_TO_SEND = 10
send_burst_of_messages(AMOUNT_TO_SEND)
43 changes: 43 additions & 0 deletions crates/rabbitmq-broker/AMQP Client/queue-publisher-mqtt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import paho.mqtt.client as mqtt
import time

# Configuration
BROKER = 'cluster.im.grycap.net'
PORT = 30200 # nodePort
TOPIC = "oscar/service-name" # RabbitMQ routes the MQTT topic 'oscar' to the amq.topic exchange with routing key 'oscar'
USER = "service-name"
PASSWORD = "tokenService"

delay=4 # We send one every x second

def on_connect(client, userdata, flags, rc):
if rc == 0:
print("✅ Simulator connected to the RabbitMQ broker via MQTT")
else:
print(f"❌ Connection error. Code: {rc}")

# Create client
client = mqtt.Client()
client.username_pw_set(USER, PASSWORD)
client.on_connect = on_connect

try:
client.connect(BROKER, PORT, 60)
client.loop_start()

print("Sending messages... (Press CTRL+C to stop)")
count = 1

while True:
message = f"Message - {count}"
# Send message
client.publish(TOPIC, message)
print(f" [>>] Published in MQTT: {message}")

count += 1
time.sleep(delay)

except KeyboardInterrupt:
print("\nSimulator stopped.")
client.loop_stop()
client.disconnect()
130 changes: 130 additions & 0 deletions crates/rabbitmq-broker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# 🐰 RabbitMQ Broker

This project implements a broker [RabbitMQ](https://www.rabbitmq.com) that can be used for IoT applications. The service also creates an administrator user (**service-name-admin**) with a password (**service-token**) that will be used to configure all broker operations.
---

### 📌 RabbitMQ Admin

The **Administrator** role represents the highest level of privileges in the broker. Unlike other technical roles (such as `monitoring` or `policymaker`), the Admin has absolute control over security, network topology, and the overall behavior of the system, regardless of the environment (*Virtual Host*).

### 🏛️ Key Areas of Responsibility

The functions of an administrator are consolidated into four fundamental pillars, accessible both via the **Command Line (`rabbitmqctl`)** and the **Web Interface (Dashboard)**:

#### 1. Access Control and Security (AuthN/AuthZ)
* **Identity Management:** Creation, modification, and deletion of user accounts.

* **Role Assignment:** Definition of profiles (Admin, Monitoring, Management).

* **Permission Governance:** Restriction or granting of read/write access for applications to different independent environments (Virtual Hosts).

#### 2. Environment Management (Virtual Hosts)
* **Traffic Isolation:** Creation and deletion of *vhosts* to segment projects or stages of the software lifecycle (e.g., `/development`, `/testing`, `/production`) within the same server, either physically or logically.

#### 3. Behavior Orchestration (Policies)
* The administrator defines the **Policies**, which are automatic rules that alter the message lifecycle without requiring modifications to application code. This includes:

* Configuring **High Availability (HA)** and message replication between nodes.

* Defining automatic timeouts (**TTL**) to prevent memory runout.

* Setting maximum size and overflow limits for queues.

#### 4. Operational Support and Crisis Mitigation
* **Hot Intervention:** Ability to force close faulty or overloaded applications.

* **Emergency Cleanup:** Bulk purging of accumulated messages or removal of corrupted queues.

* **Cluster Health:** Monitoring of critical system alarms (crashes due to insufficient RAM or disk space).


## Definition of the service in the fdl file

The FDL that defines the exposed service is the following:

```
functions:
oscar:
- rabbitMQ-cluster:
name: rabbitmq-broker
image: rabbitmq:4.3.0
memory: 2Gi
cpu: '1.0'
script: script.sh
expose:
min_scale: 1
max_scale: 1
api_port: [15672,1883,5672]
cpu_threshold: 80
default_command: false
rewrite_target: false
nodePort: [0, 0, 0]

```

Key elements to highlight include the following:

Image: The latest available version of RabbitMQ (**rabbitmq:4.3.0**) is used.

api_port: Defines the ports to be used in the exposed service for each of the protocols (15672 -- api/dashboard, 1183 -- MQTT, 5672 -- AMQP)

nodePort: In this image, they are generated dynamically by the service to avoid interference with other services.

## Service script configuration

The service script configures the broker and creates an administrator user (**service-name-admin**) and password (**service-token**) with full privileges to interact with the broker via console or dashboard.


## Run client

The administration interface can be accessed via a web browser using the OSCAR exposed service definition (cluster.im.grycap.net/system/services/serviceName/exposed/) and the generated credentials.

![Dashboard](images/dashboard.png)

From this interface, you can perform the tasks necessary for your application.

![Admin interface](images/admin-web.png)

Once you have your application set up, you can use any client that sends AMQP messages, MQTT messages, or HTTP requests.

We have developed 3 Python scripts that will allow you to interact with the broker through different protocols.

Key elements:

- Username: This will be the name you assigned to the service (SERVICE_NAME).

- Password: This will be the token for the created service.

- Publishing topic: This will have the format oscar.SERVICE_NAME for AMQP and HTTP requests, and oscar/SERVICE_NAME for MQTT.

- RabbitMQ broker URL: The domain name of the cluster where you deployed the service. The domain without HTTPS.

- Port: The nodePort defined when creating the service. If the protocols were created dynamically, use the OSCAR API (/system/services/serviceName) to view the port assigned to each protocol.

Important libraries for each script:

- queue-publisher-amqp.py

pika: This is the official Python client library for communicating with RabbitMQ.

boto3: This is the standard library for any S3-compatible system (like your MinIO).

- queue-publisher-mqtt.py

paho.mqtt: The most widely used open-source library for implementing the MQTT protocol.

- queue-publisher-http.py

requests: Python's most popular way to make HTTP requests.

## Notes

All information about using the RabbitMQ broker can be found at:

[Official website](https://www.rabbitmq.com/)

[Github](https://github.com/rabbitmq/rabbitmq-website)




16 changes: 16 additions & 0 deletions crates/rabbitmq-broker/fdl.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
functions:
oscar:
- rabbitMQ-broker:
name: rabbitmq-broker
image: rabbitmq:4.3.0
memory: 0.5Gi
cpu: '0.3'
script: script.sh
expose:
min_scale: 1
max_scale: 1
api_port: [15672, 1883, 5672]
cpu_threshold: 80
default_command: false
rewrite_target: false
nodePort: [0,0,0]
Binary file added crates/rabbitmq-broker/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added crates/rabbitmq-broker/images/admin-web.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added crates/rabbitmq-broker/images/dashboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading