Commit ccf246e0 authored by David Trattnig's avatar David Trattnig
Browse files

Mailer as event handler. #38

parent abfeed02
......@@ -24,7 +24,7 @@ from threading import Thread
from src.base.config import AuraConfig
from src.base.utils import SimpleUtil as SU
from src.base.mail import AuraMailer
from src.plugins.mailer import AuraMailer
from src.plugins.monitor import AuraMonitor
from src.plugins.trackservice import TrackServiceHandler
......@@ -76,7 +76,6 @@ class EngineEventDispatcher():
config = None
subscriber_registry = None
mailer = None
engine = None
scheduler = None
monitor = None
......@@ -89,9 +88,13 @@ class EngineEventDispatcher():
self.subscriber_registry = dict()
self.logger = logging.getLogger("AuraEngine")
self.config = AuraConfig.config()
self.mailer = AuraMailer(self.config)
self.engine = engine
binding = self.attach(AuraMailer)
binding.subscribe("on_critical")
binding.subscribe("on_sick")
binding.subscribe("on_resurrect")
binding = self.attach(AuraMonitor)
binding.subscribe("on_boot")
binding.subscribe("on_sick")
......@@ -314,8 +317,6 @@ class EngineEventDispatcher():
"""
def func(self, subject, message, data):
self.logger.debug("on_critical(..)")
if not data: data = ""
self.mailer.send_admin_mail(subject, message + "\n\n" + str(data))
self.call_event("on_critical", (subject, message, data))
thread = Thread(target = func, args = (self, subject, message, data))
......
......@@ -18,8 +18,10 @@
import smtplib
from email.message import EmailMessage
from src.base.config import AuraConfig
class MailingException(Exception):
......@@ -31,47 +33,97 @@ class MailingException(Exception):
class AuraMailer():
"""
Event handler to send emails to Aura administrators and programme coordinators.
"""
engine = None
mail = None
def __init__(self, engine):
"""
Constructor
Args:
engine (Engine): The Engine
"""
self.engine = engine
self.mail = MailService()
#
# METHODS
#
def on_sick(self, data):
"""
Called when the engine is in some unhealthy state.
"""
subject = "ERROR - Engine turned into some INVALID STATE!"
message = "There's an issue with your AURA Engine '%s':\n\n%s" % (data.get("engine_id"), data.get("status"))
self.mail.send_admin(subject, message)
def on_resurrect(self, data):
"""
Called when the engine turned healthy again after being sick.
"""
subject = "OK - Engine became healthy again"
message = "Good news, things seem fine again with your AURA Engine '%s':\n\n%s" % (data.get("engine_id"), data.get("status"))
self.mail.send_admin(subject, message)
def on_critical(self, subject, message, data=None):
"""
Callend when some critical event occurs
"""
if not data: data = ""
self.mail.send_admin(subject, message + "\n\n" + str(data))
class MailService():
"""
Service to send emails to Aura administrators.
"""
config = None
admin_mails = None
def __init__(self, config):
def __init__(self):
"""
Constructor to initialize service with Aura `config`.
Args:
config (AuraConfig): The configuration with the mail server details
Constructor
"""
self.config = config
self.admin_mails = config.get("admin_mail")
self.config = AuraConfig.config()
self.admin_mails = self.config.get("admin_mail")
#
# PUBLIC METHODS
# METHODS
#
def send_admin_mail(self, subject, body):
def send_admin(self, subject, body):
"""
Sends an email to the administrator as defined in the configuration.
Args:
subject (String): The email's subject
body (String): The email's body text
subject (String): The email subject
body (String): The email body text
"""
admin_mails = self.admin_mails.split()
for mail_to in admin_mails:
self.__send(mail_to, subject, body)
self.send(mail_to, subject, body)
#
# PRIVATE METHODS
#
def __send(self, mail_to, subject, body):
def send(self, mail_to, subject, body):
"""
Sends an email to the given address.
......
......@@ -33,7 +33,6 @@ import meta
from src.base.config import AuraConfig
from src.base.utils import SimpleUtil as SU
from src.base.mail import AuraMailer
......@@ -81,7 +80,6 @@ class AuraMonitor:
self.logger = logging.getLogger("AuraEngine")
self.config = AuraConfig.config()
self.engine = engine
self.mailer = AuraMailer(self.config)
self.status = dict()
self.status["engine"] = dict()
self.status["lqs"] = dict()
......@@ -267,22 +265,16 @@ class AuraMonitor:
self.already_invalid = False
status = json.dumps(self.get_status())
self.logger.info(SU.green("OK - Engine turned back into some healthy state!")+"\n"+str(status))
self.mailer.send_admin_mail( \
"OK - Engine turned back into some HEALTHY STATE!", \
"Things seem fine again at '%s':\n\n%s" % (self.engine_id, status))
# Route call of event via event dispatcher to provide ability for additional hooks
self.engine.event_dispatcher.on_resurrect(status)
self.engine.event_dispatcher.on_resurrect({"engine_id": self.engine_id, "status": status})
else:
# Engine turned into invalid state
if not self.already_invalid:
self.already_invalid = True
status = json.dumps(self.get_status())
self.logger.critical(SU.red("Engine turned into some INVALID STATE!")+"\n"+str(status))
self.mailer.send_admin_mail( \
"ERROR - Engine turned into some INVALID STATE!", \
"There's an issue with Aura Engine '%s':\n\n%s" % (self.engine_id, status))
# Route call of event via event dispatcher to provide ability for additional hooks
self.engine.event_dispatcher.on_sick(status)
self.engine.event_dispatcher.on_sick({"engine_id": self.engine_id, "status": status})
threading.Timer(self.config.get("heartbeat_frequency"), self.heartbeat).start()
......
......@@ -26,7 +26,6 @@ from datetime import timedelta
from src.base.config import AuraConfig
from src.base.utils import SimpleUtil as SU
from src.base.mail import AuraMailer
from src.core.resources import ResourceClass
from src.core.channels import Channel
from src.core.control import EngineExecutor
......@@ -64,7 +63,6 @@ class FallbackManager:
"""
config = None
logger = None
mailer = None
scheduler = None
......@@ -77,7 +75,6 @@ class FallbackManager:
"""
self.config = AuraConfig.config()
self.logger = logging.getLogger("AuraEngine")
self.mailer = AuraMailer(self.config)
self.scheduler = scheduler
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment