server/backend/mlmAccess.py
Dorian Zedler b6f8b54bc2
- Add Dockerfile
- Add Config in backend using env vars
- Clean up mock actor
2021-08-19 11:27:39 +02:00

114 lines
No EOL
3.9 KiB
Python

import paho.mqtt.client as mqtt
from dbHelper import MaDbHelper
from pairingHandler import MaPairingHandler
import logging, coloredlogs, os, sys, random, string
coloredlogs.install(level='INFO', fmt='%(asctime)s - [%(levelname)s] %(message)s')
class MlmAccess:
def __init__(self):
logging.info("=== MlmAccess ===")
self._config = self._readConfig()
self._initDb()
self._initMqtt()
self._pairingHanlder = MaPairingHandler(self._mqtt, self._db)
self._mqtt.loop_forever()
def _initDb(self):
logging.info("Initializing Database")
self._db = MaDbHelper(self._config)
initUsers = [
("backend", self._config["MQTT_BACKEND_PASSWORD"], ["mlmAccess/#"], ["mlmAccess/#"]),
("pair-actor", self._config["PAIR_SECRET"], ["mlmAccess/pair/request/actor"], ["mlmAccess/pair/response/actor"])
]
for username, password, publishAclPatterns, subscribeAclPatterns in initUsers:
if not self._db.addUser(username, password, publishAclPatterns, subscribeAclPatterns):
self._db.updateUser(username, password, publishAclPatterns, subscribeAclPatterns)
def _initMqtt(self):
logging.info("Initializing MQTT")
self._mqtt = client = mqtt.Client(client_id="backend")
self._mqtt.username_pw_set("backend", self._config["MQTT_BACKEND_PASSWORD"])
self._mqtt.on_connect = self._mqttOnConnect
self._mqtt.on_message = self._mqttOnMessage
self._mqtt.connect(self._config["MQTT_HOST"], self._config["MQTT_PORT"], 60)
def _mqttOnConnect(self, client, userdata, flags, rc):
if rc != 0:
logging.error(f"Error connecting to MQTT broker: {rc}")
return
logging.info("Successfully connected to MQTT broker")
logging.info("Subscribing to actor subjects:")
for user in self._db.getAllUsers():
if user.startswith("actor-"):
actorSubject = f"mlmAccess/actor/{user.replace('actor-', '')}/status"
logging.info(f"* {actorSubject}")
client.subscribe(actorSubject)
# call hooks of child objects
self._pairingHanlder._mqttOnConnect(client, userdata, flags, rc)
def _mqttOnMessage(self, client, userdata, message):
topic = message.topic
topic = topic.replace("mlmAccess/", "")
messageContent = str(message.payload.decode("utf-8"))
logging.info(f"Message on topic {topic}: {messageContent}")
if topic.startswith("pair"):
self._pairingHanlder.handlePairingRequest(topic, messageContent)
def _readConfig(self):
configKeyPrefix = "MLMACCESS_"
requiredConfigKeys = [
'MYSQL_USER',
'MYSQL_PASSWORD',
'MYSQL_DATABASE',
'PAIR_SECRET'
]
allowedConfigKeys = [
'MYSQL_HOST',
'MYSQL_PORT',
'MQTT_HOST',
'MQTT_PORT',
]
backendPassword = ''.join(random.choices(string.ascii_uppercase + string.ascii_lowercase + string.digits, k=20))
config = {
"MYSQL_HOST": "mysql",
"MYSQL_PORT": 4306,
"MQTT_HOST": "mqtt",
"MQTT_PORT": 1883,
"MQTT_BACKEND_PASSWORD": backendPassword
}
for configKey in requiredConfigKeys:
if configKeyPrefix + configKey not in os.environ:
logging.error(f"Required environment value {configKeyPrefix + configKey} is not set")
sys.exit(1)
config[configKey] = os.environ[configKeyPrefix + configKey]
for configKey in allowedConfigKeys:
if configKeyPrefix + configKey in os.environ:
config[configKey] = os.environ[configKeyPrefix + configKey]
logging.info("CONFIG:")
for key, value in config.items():
logging.info(" * {:25}: {}".format(key, value))
return config
if __name__ == "__main__":
MlmAccess()