Move custom event handlers away

This commit is contained in:
R. Richard 2019-07-05 15:37:54 +02:00
parent d597e4e004
commit f1a68f20db
3 changed files with 110 additions and 101 deletions

View File

@ -0,0 +1,100 @@
import logging
from ast import literal_eval
from tfw.components import MessageSender, TerminalCommands
from tfw.builtins import EventHandler, FSMAwareEventHandler, TFWServerUplinkConnector
LOG = logging.getLogger(__name__)
class TerminalCallbackEventHandler(EventHandler):
"""
Logs commands executed in terminal to messages and invokes an
additional callback function to handle special commands.
!! Please remove from production code. !!
"""
def __init__(self, key, callback):
self.callback = callback
super().__init__(key)
def handle_event(self, message):
command = message['value']
self.cenator(command)
self.callback(command)
def cenator(self, command):
LOG.debug('User executed command: "%s"', command)
MessageSender(self.server_connector).send('JOHN CENA', f'You\'ve executed "{command}"')
class TestCommands(TerminalCommands):
"""
Some example commands useful for debugging.
!! Please remove from production code !! and inherit your own
class from TerminalCommands if you need to define custom
commands in your challenge.
"""
# pylint: disable=unused-argument, attribute-defined-outside-init, no-self-use
def command_sendmessage(self, *args):
"""
Insert TFW message template as first argument if executed without args.
Evaluate first argumen as a dict and send it to the frontend.
This is useful for playing around with frontend APIs.
"""
if not args:
message_template = """'{"key": "", "data": {"command": ""}}'"""
TFWServerUplinkConnector().send_message({
'key': 'shell',
'data': {
'command': 'write',
'value': f'sendmessage {message_template}'
}
})
else:
TFWServerUplinkConnector().send_message(literal_eval(args[0]))
def command_seppuku_tfw(self, *args):
"""
Restart tfw_server.py and event_handler_main.py.
This can speed up development when combined with mounting
volumes from host to container.
"""
seppuku = (
'nohup sh -c "supervisorctl restart tfwserver event_handler_main" &> /dev/null & '
'clear && echo "Committed seppuku! :)" && sleep infinity'
)
uplink = TFWServerUplinkConnector()
uplink.send_message({
'key': 'shell',
'data': {
'command': 'write',
'value': f'{seppuku}\n'
}
})
uplink.send_message({
'key': 'dashboard',
'data': {
'command': 'reloadFrontend'
}
})
class MessageFSMStepsEventHandler(FSMAwareEventHandler):
"""
This example EventHandler is capable of detecting FSM state.
!! Please remove from production code !!
"""
def handle_event(self, message):
pass
def handle_fsm_step(self, **kwargs):
"""
When the FSM steps this method is invoked.
Receives a 'data' field from an fsm_update message as kwargs.
"""
MessageSender(self.server_connector).send(
'FSM info',
f'FSM has stepped from state "{kwargs["last_event"]["from_state"]}" '
f'to state "{kwargs["current_state"]}" in response to trigger "{kwargs["last_event"]["trigger"]}"'
)

View File

@ -1,118 +1,25 @@
import logging
from sys import stderr
from ast import literal_eval
from functools import partial
from signal import signal, SIGTERM, SIGINT
from tornado.ioloop import IOLoop
from tfw.fsm import YamlFSM
from tfw.builtins import EventHandler, FSMAwareEventHandler, TFWServerUplinkConnector
from tfw.builtins import EventHandler
from tfw.builtins import IdeEventHandler, TerminalEventHandler, FrontendEventHandler
from tfw.builtins import LogMonitoringEventHandler, ProcessManagingEventHandler
from tfw.builtins import DirectorySnapshottingEventHandler, FSMManagingEventHandler, MessageSender
from tfw.components import TerminalCommands
from tfw.builtins import DirectorySnapshottingEventHandler, FSMManagingEventHandler
from tfw.config import TFWENV
from tfw.logging import Log, Logger, LogFormatter, VerboseLogFormatter
from tao.config import TAOENV
from custom_event_handlers import MessageFSMStepsEventHandler
from custom_event_handlers import TerminalCallbackEventHandler, TestCommands
LOG = logging.getLogger(__name__)
class TerminalCallbackEventHandler(EventHandler):
"""
Logs commands executed in terminal to messages and invokes an
additional callback function to handle special commands.
!! Please remove from production code. !!
"""
def __init__(self, key, callback):
self.callback = callback
super().__init__(key)
def handle_event(self, message):
command = message['value']
self.cenator(command)
self.callback(command)
@staticmethod
def cenator(command):
LOG.debug('User executed command: "%s"', command)
MessageSender().send('JOHN CENA', f'You\'ve executed "{command}"')
class TestCommands(TerminalCommands):
"""
Some example commands useful for debugging.
!! Please remove from production code !! and inherit your own
class from TerminalCommands if you need to define custom
commands in your challenge.
"""
# pylint: disable=unused-argument, attribute-defined-outside-init, no-self-use
def command_sendmessage(self, *args):
"""
Insert TFW message template as first argument if executed without args.
Evaluate first argumen as a dict and send it to the frontend.
This is useful for playing around with frontend APIs.
"""
if not args:
message_template = """'{"key": "", "data": {"command": ""}}'"""
TFWServerUplinkConnector().send_message({
'key': 'shell',
'data': {
'command': 'write',
'value': f'sendmessage {message_template}'
}
})
else:
TFWServerUplinkConnector().send_message(literal_eval(args[0]))
def command_seppuku_tfw(self, *args):
"""
Restart tfw_server.py and event_handler_main.py.
This can speed up development when combined with mounting
volumes from host to container.
"""
seppuku = (
'nohup sh -c "supervisorctl restart tfwserver event_handler_main" &> /dev/null & '
'clear && echo "Committed seppuku! :)" && sleep infinity'
)
uplink = TFWServerUplinkConnector()
uplink.send_message({
'key': 'shell',
'data': {
'command': 'write',
'value': f'{seppuku}\n'
}
})
uplink.send_message({
'key': 'dashboard',
'data': {
'command': 'reloadFrontend'
}
})
class MessageFSMStepsEventHandler(FSMAwareEventHandler):
"""
This example EventHandler is capable of detecting FSM state.
!! Please remove from production code !!
"""
def handle_event(self, message):
pass
def handle_fsm_step(self, **kwargs):
"""
When the FSM steps this method is invoked.
Receives a 'data' field from an fsm_update message as kwargs.
"""
MessageSender().send(
'FSM info',
f'FSM has stepped from state "{kwargs["last_event"]["from_state"]}" '
f'to state "{kwargs["current_state"]}" in response to trigger "{kwargs["last_event"]["trigger"]}"'
)
def main():
# pylint: disable=unused-variable
Logger([
@ -165,7 +72,7 @@ def main():
key='test'
)
def stop(*_):
def stop(*_):
EventHandler.stop_all_instances()
exit(0)
signal(SIGTERM, stop)

View File

@ -3,7 +3,8 @@
from os.path import exists
from tfw.fsm import LinearFSM
from tfw.builtins import MessageSender
from tfw.components import MessageSender
from tfw.builtins import TFWServerUplinkConnector
class TestFSM(LinearFSM):
@ -11,7 +12,8 @@ class TestFSM(LinearFSM):
def __init__(self):
super().__init__(6)
self.message_sender = MessageSender()
self.uplink = TFWServerUplinkConnector()
self.message_sender = MessageSender(self.uplink)
self.subscribe_predicate('step_3', self.step_3_allowed)
@staticmethod