Пример #1
0
def init_rabbitMQ_msg_processors():
    """The main bootstrap for sspl automated tests"""

    # Initialize logging
    try:
        init_logging("SSPL-Tests", "DEBUG")
    except Exception as err:
        # We don't have logger since it threw an exception, use generic 'print'
        print("[ Error ] when initializing logging :")
        print(err)
        print("Exiting ...")
        exit(os.EX_USAGE)

    # Modules to be used for testing
    conf_modules = Conf.get(SSPL_TEST_CONF, f"{SSPL_SETTING}>{MODULES}")

    # Create a map of references to all the module's message queues.  Each module
    #  is passed this mapping so that it can send messages to other modules.
    msgQlist = {}

    # Create a mapping of all the instantiated modules to their names
    world.sspl_modules = {}

    # Read in product value from configuration file
    product = Conf.get(GLOBAL_CONF, f"release>{PRODUCT_NAME}")
    logger.info("sspl-ll Bootstrap: product name supported: %s" % product)
    # Use reflection to instantiate the class based upon its class name in config file
    for conf_thread in conf_modules:
        klass = globals()[conf_thread]

        # Create mappings of modules and their message queues
        world.sspl_modules[klass.name()] = klass()
        msgQlist[klass.name()] = queue.Queue()

    # Convert to a dict
    # TODO: Check use of this
    world.diskmonitor_file = json.loads("{}")

    try:
        # Loop through the list of instanced modules and start them on threads
        threads = []
        for name, curr_module in list(world.sspl_modules.items()):
            logger.info("SSPL-Tests Starting %s" % curr_module.name())
            curr_module._set_debug(True)
            thread = Thread(target=_run_thread_capture_errors,
                            args=(curr_module, msgQlist, conf_reader, product))
            thread.start()
            threads.append(thread)

        # Allow threads to startup before running tests
        time.sleep(2)

        # Clear the message queue buffer out from msgs sent at startup
        while not world.sspl_modules[
                RabbitMQingressProcessorTests.name()]._is_my_msgQ_empty():
            world.sspl_modules[
                RabbitMQingressProcessorTests.name()]._read_my_msgQ()

    except Exception as ex:
        logger.exception(ex)
Пример #2
0
 def _log_debug(self, message):
     """Logging messages"""
     if self._debug:
         log_msg = self.name() + ", " + message
         if use_journal:
             journal.send(log_msg, PRIORITY=7, SYSLOG_IDENTIFIER="sspl-ll")
         else:
             logger.info(log_msg)
Пример #3
0
    def _debug_off_globally(self):
        """Turns debug mode off on all threads"""
        jsonMsg = {'sspl_ll_debug': {'debug_component':'all', 'debug_enabled' : False}}
        for _msgQ in self._msgQlist:
            if _msgQ != "ThreadController":
                logger.info("_debug_off_globally, notifying: %s" % _msgQ)
                self._write_internal_msgQ(_msgQ, jsonMsg)

        # Notify the ThreadController to bounce all threads so that blocking ones switch debug mode
        jsonMsg = {'sspl_ll_debug': {'debug_component':'all'}}
        self._write_internal_msgQ("ThreadController", jsonMsg)
 def shutdown(self):
     """Clean up scheduler queue and gracefully shutdown thread"""
     super(RabbitMQingressProcessorTests, self).shutdown()
     time.sleep(4)
     try:
         self._connection.cleanup()
     except pika.exceptions.ConnectionClosed:
         logger.info(
             "RabbitMQingressProcessorTests, shutdown, RabbitMQ ConnectionClosed"
         )
     except Exception as err:
         logger.info(
             "RabbitMQingressProcessorTests, shutdown, RabbitMQ {}".format(
                 str(err)))
 def _retry_connection(self):
     """Retries to establish the connection until a connection is made
     with RabbitMQ a node in the cluster.
     """
     while True:
         try:
             self._establish_connection()
             logger.info('Connection established with RabbitMQ...')
             break
         except connection_exceptions as e:
             logger.error(connection_error_msg.format(repr(e)))
             time.sleep(self.wait_time)
         except Exception:
             raise
    def run(self):
        """Run the module periodically on its own thread. """
        self._log_debug("Start accepting requests")

        try:
            self._connection.consume(callback=self._process_msg)
        except Exception:
            if self.is_running() == True:
                logger.info(
                    "RabbitMQingressProcessorTests ungracefully breaking out of run loop, restarting."
                )

                # Configure RabbitMQ Exchange to receive messages
                self._configure_exchange()
                self._scheduler.enter(1, self._priority, self.run, ())
            else:
                logger.info(
                    "RabbitMQingressProcessorTests gracefully breaking out of run Loop, not restarting."
                )

        self._log_debug("Finished processing successfully")
    def _transmit_msg_on_exchange(self):
        """Transmit json message onto RabbitMQ exchange"""
        self._log_debug("_transmit_msg_on_exchange, jsonMsg: %s" % self._jsonMsg)

        try:
            # Check for shut down message from sspl_ll_d and set a flag to shutdown
            #  once our message queue is empty
            if self._jsonMsg.get("message").get("actuator_response_type") is not None and \
                self._jsonMsg.get("message").get("actuator_response_type").get("thread_controller") is not None and \
                self._jsonMsg.get("message").get("actuator_response_type").get("thread_controller").get("thread_response") == \
                    "SSPL-LL is shutting down":
                    logger.info("RabbitMQegressProcessor, _transmit_msg_on_exchange, received" \
                                    "global shutdown message from sspl_ll_d")
                    self._request_shutdown = True

            msg_props = pika.BasicProperties()
            msg_props.content_type = "text/plain"

            # Publish json message to the correct channel
            # NOTE: We need to route ThreadController messages to ACK channel.
            # We can't modify schema as it will affect other modules too. As a
            # temporary solution we have added a extra check to see if actuator_response_type
            # is "thread_controller".
            # TODO: Find a proper way to solve this issue. Avoid changing
            # core egress processor code
            if self._jsonMsg.get("message").get("actuator_response_type") is not None and \
              (self._jsonMsg.get("message").get("actuator_response_type").get("ack") is not None or \
                self._jsonMsg.get("message").get("actuator_response_type").get("thread_controller") is not None):
                self._add_signature()
                jsonMsg = json.dumps(self._jsonMsg).encode('utf8')
                self._ack_connection.publish(exchange=self._exchange_name,
                                             routing_key=self._ack_routing_key,
                                             properties=msg_props,
                                             body=jsonMsg)
            # Routing requests for IEM msgs sent from the LoggingMsgHandler
            elif self._jsonMsg.get("message").get("IEM_routing") is not None:
                log_msg = self._jsonMsg.get("message").get("IEM_routing").get("log_msg")
                self._log_debug("Routing IEM: %s" % log_msg)
                if self._iem_route_addr != "":
                    self._iem_connection.publish(exchange=self._iem_route_exchange_name,
                                                 routing_key=self._routing_key,
                                                 properties=msg_props,
                                                 body=str(log_msg))
                else:
                    logger.warn("RabbitMQegressProcessor, Attempted to route IEM without a valid 'iem_route_addr' set.")

            elif self._jsonMsg.get("message") is not None:
                message = self._jsonMsg.get("message")
                if message.get("actuator_request_type") or \
                    message.get("sensor_request_type") is not None:
                    logger.error("inside egress, test actuator")
                    unique_routing_key = f'{self._routing_key}_node{self._node_id}'
                    logger.info(f"Connecting using routing key: {unique_routing_key}")
                    logger.error(f"Connecting using routing key: {unique_routing_key}")
                    self._add_signature()
                    jsonMsg = json.dumps(self._jsonMsg).encode('utf8')
                    self._connection.publish(exchange=self._exchange_name,
                                            routing_key=unique_routing_key,
                                            properties=msg_props,
                                            body=jsonMsg)

            else:
                self._add_signature()
                jsonMsg = json.dumps(self._jsonMsg).encode('utf8')
                self._connection.publish(exchange=self._exchange_name,
                                         routing_key=self._routing_key,
                                         properties=msg_props,
                                         body=jsonMsg)
            # No exceptions thrown so success
            self._log_debug("_transmit_msg_on_exchange, Successfully Sent: %s" % self._jsonMsg)
            self._msg_sent_succesfull = True

        except Exception as ex:
            logger.exception("RabbitMQegressProcessor, _transmit_msg_on_exchange: %r" % ex)
            self._msg_sent_succesfull = False
    def _read_config(self):
        """Configure the RabbitMQ exchange with defaults available"""
        try:
            self._virtual_host  = self._conf_reader._get_value_with_default(self.RABBITMQPROCESSOR,
                                                                 self.VIRT_HOST,
                                                                 'SSPL')

            # Read common RabbitMQ configuration
            self._primary_rabbitmq_host = self._conf_reader._get_value_with_default(self.RABBITMQPROCESSOR,
                                                                 self.PRIMARY_RABBITMQ_HOST,
                                                                 'localhost')

            # Read RabbitMQ configuration for sensor messages
            self._queue_name    = self._conf_reader._get_value_with_default(self.RABBITMQPROCESSOR,
                                                                 self.QUEUE_NAME,
                                                                 'sensor-queue')
            self._exchange_name = self._conf_reader._get_value_with_default(self.RABBITMQPROCESSOR,
                                                                 self.EXCHANGE_NAME,
                                                                 'sspl-out')
            self._routing_key   = self._conf_reader._get_value_with_default(self.RABBITMQPROCESSOR,
                                                                 self.ROUTING_KEY,
                                                                 'sensor-key')
            # Read RabbitMQ configuration for Ack messages
            self._ack_queue_name = self._conf_reader._get_value_with_default(self.RABBITMQPROCESSOR,
                                                                 self.ACK_QUEUE_NAME,
                                                                 'sensor-queue')
            self._ack_routing_key = self._conf_reader._get_value_with_default(self.RABBITMQPROCESSOR,
                                                                 self.ACK_ROUTING_KEY,
                                                                 'sensor-key')

            self._username      = self._conf_reader._get_value_with_default(self.RABBITMQPROCESSOR,
                                                                 self.USER_NAME,
                                                                 'sspluser')
            self._password      = self._conf_reader._get_value_with_default(self.RABBITMQPROCESSOR,
                                                                 self.PASSWORD,
                                                                 'sspl4ever')
            self._signature_user = self._conf_reader._get_value_with_default(self.RABBITMQPROCESSOR,
                                                                 self.SIGNATURE_USERNAME,
                                                                 'sspl-ll')
            self._signature_token = self._conf_reader._get_value_with_default(self.RABBITMQPROCESSOR,
                                                                 self.SIGNATURE_TOKEN,
                                                                 'FAKETOKEN1234')
            self._signature_expires = self._conf_reader._get_value_with_default(self.RABBITMQPROCESSOR,
                                                                 self.SIGNATURE_EXPIRES,
                                                                 "3600")
            self._iem_route_addr = self._conf_reader._get_value_with_default(self.RABBITMQPROCESSOR,
                                                                 self.IEM_ROUTE_ADDR,
                                                                 '')
            self._iem_route_exchange_name = self._conf_reader._get_value_with_default(self.RABBITMQPROCESSOR,
                                                                 self.IEM_ROUTE_EXCHANGE_NAME,
                                                                 'sspl-in')
            self._rack_id = self._conf_reader._get_value_with_default(
                self.SYSTEM_INFORMATION, self.RACK_ID, '')

            self._node_id = self._conf_reader._get_value_with_default(
                self.SYSTEM_INFORMATION, self.NODE_ID, '')

            self._cluster_id = self._conf_reader._get_value_with_default(
                self.SYSTEM_INFORMATION, self.CLUSTER_ID, '')

            self._site_id = self._conf_reader._get_value_with_default(
                self.SYSTEM_INFORMATION, self.SITE_ID, '')


            if self._iem_route_addr != "":
                logger.info("         Routing IEMs to host: %s" % self._iem_route_addr)
                logger.info("         Using IEM exchange: %s" % self._iem_route_exchange_name)
        except Exception as ex:
            logger.exception("RabbitMQegressProcessor, _read_config: %r" % ex)
import json
import pika
import os
import time
from sspl_test.framework.base.module_thread import ScheduledModuleThread
from sspl_test.framework.base.internal_msgQ import InternalMsgQ
from sspl_test.framework.utils.service_logging import logger
from .rabbitmq_sspl_test_connector import RabbitMQSafeConnection

import ctypes
try:
    use_security_lib=True
    SSPL_SEC = ctypes.cdll.LoadLibrary('libsspl_sec.so.0')
except Exception as ae:
    logger.info("RabbitMQegressProcessor, libsspl_sec not found, disabling authentication on egress msgs")
    use_security_lib=False


class RabbitMQegressProcessor(ScheduledModuleThread, InternalMsgQ):
    """Handles outgoing messages via rabbitMQ over localhost"""

    MODULE_NAME = "RabbitMQegressProcessor"
    PRIORITY    = 1

    # Section and keys in configuration file
    SYSTEM_INFORMATION = "SYSTEM_INFORMATION"
    RACK_ID = "rack_id"
    NODE_ID = "node_id"
    CLUSTER_ID = "cluster_id"
    SITE_ID = "site_id"
    def _read_config(self):
        """Configure the RabbitMQ exchange with defaults available"""
        try:
            self._virtual_host = Conf.get(
                SSPL_TEST_CONF, f"{self.RABBITMQPROCESSOR}>{self.VIRT_HOST}",
                'SSPL')

            # Read common RabbitMQ configuration
            self._primary_rabbitmq_host = Conf.get(
                SSPL_TEST_CONF,
                f"{self.RABBITMQPROCESSOR}>{self.PRIMARY_RABBITMQ_HOST}",
                'localhost')

            # Read RabbitMQ configuration for sensor messages
            self._queue_name = Conf.get(
                SSPL_TEST_CONF, f"{self.RABBITMQPROCESSOR}>{self.QUEUE_NAME}",
                'sensor-queue')
            self._exchange_name = Conf.get(
                SSPL_TEST_CONF,
                f"{self.RABBITMQPROCESSOR}>{self.EXCHANGE_NAME}", 'sspl-out')
            self._routing_key = Conf.get(
                SSPL_TEST_CONF, f"{self.RABBITMQPROCESSOR}>{self.ROUTING_KEY}",
                'sensor-key')
            # Read RabbitMQ configuration for Ack messages
            self._ack_queue_name = Conf.get(
                SSPL_TEST_CONF,
                f"{self.RABBITMQPROCESSOR}>{self.ACK_QUEUE_NAME}",
                'sensor-queue')
            self._ack_routing_key = Conf.get(
                SSPL_TEST_CONF,
                f"{self.RABBITMQPROCESSOR}>{self.ACK_ROUTING_KEY}",
                'sensor-key')

            self._username = Conf.get(
                SSPL_TEST_CONF, f"{self.RABBITMQPROCESSOR}>{self.USER_NAME}",
                'sspluser')
            self._password = Conf.get(
                SSPL_TEST_CONF, f"{self.RABBITMQPROCESSOR}>{self.PASSWORD}",
                '')
            self._signature_user = Conf.get(
                SSPL_TEST_CONF,
                f"{self.RABBITMQPROCESSOR}>{self.SIGNATURE_USERNAME}",
                'sspl-ll')
            self._signature_token = Conf.get(
                SSPL_TEST_CONF,
                f"{self.RABBITMQPROCESSOR}>{self.SIGNATURE_TOKEN}",
                'FAKETOKEN1234')
            self._signature_expires = Conf.get(
                SSPL_TEST_CONF,
                f"{self.RABBITMQPROCESSOR}>{self.SIGNATURE_EXPIRES}", "3600")
            self._iem_route_addr = Conf.get(
                SSPL_TEST_CONF,
                f"{self.RABBITMQPROCESSOR}>{self.IEM_ROUTE_ADDR}", '')
            self._iem_route_exchange_name = Conf.get(
                SSPL_TEST_CONF,
                f"{self.RABBITMQPROCESSOR}>{self.IEM_ROUTE_EXCHANGE_NAME}",
                'sspl-in')
            self._node_id = Conf.get(
                SSPL_TEST_CONF, f"{self.SYSTEM_INFORMATION}>{self.NODE_ID}",
                'SN01')
            cluster_id = Conf.get(
                SSPL_TEST_CONF, f"{self.SYSTEM_INFORMATION}>{self.CLUSTER_ID}",
                'CC01')

            # Decrypt RabbitMQ Password
            decryption_key = encryptor.gen_key(cluster_id,
                                               ServiceTypes.RABBITMQ.value)
            self._password = encryptor.decrypt(decryption_key,
                                               self._password.encode('ascii'),
                                               "RabbitMQegressProcessor")

            if self._iem_route_addr != "":
                logger.info("         Routing IEMs to host: %s" %
                            self._iem_route_addr)
                logger.info("         Using IEM exchange: %s" %
                            self._iem_route_exchange_name)
        except Exception as ex:
            print(ex)
            logger.error("RabbitMQegressProcessor, _read_config: %r" % ex)