示例#1
0
 def test_service_on_a_loop(self):
     composition = "10.10.10.1_java:C:S1+10.10.10.1_java:C:S2+" +\
                   "10.10.10.1_java:C:S1;"
     cc = CCompiler("10.10.10.1_java:C:S2")
     cc.compile(composition)
     self.assertEqual(set(["10.10.10.1_java:C:S1"]),
                      cc.get_unconditional_links())
    def __init__(self, name,
                 local_address, frontend_address, user_engine,
                 service_sys_configuration, service_report):
        """A Service engine.

        Every engine process a request in its own thread.
        Args:
            name: Service canonical name
            local_address (ProxyAddress): Address info for local connection
            frontend_address (ProxyAddress): Address info for FE connection
            user_engine (Engine): User engine deployed
            service_sys_configuration (ServiceSysConfig): Service system config
            service_report (ServiceReport): Service report object
        """
        super(ServiceEngine, self).__init__(name,
                                            local_address.host,
                                            local_address.pub_port,
                                            frontend_address.host,
                                            frontend_address.pub_port)
        self._engine_object = user_engine
        self._semaphore = Semaphore(1)
        self._compiler = CCompiler(self.myname)
        self._prev_composition = xMsgConstants.UNDEFINED
        self._report = service_report
        self._logger = ClaraLogger(repr(self))

        self.execution_time = 0
        self.sys_config = service_sys_configuration
示例#3
0
    def test_on_multiple_call(self):
        composition_extra = "10.10.10.1_java:C:S1+10.10.10.1_java:C:S2+" + \
                            "10.10.10.1_java:C:S1;"

        cc = CCompiler("10.10.10.1_java:C:S2")
        cc.compile(TestCCompiler.get_composition())
        cc.compile(composition_extra)
        self.assertEqual(set(["10.10.10.1_java:C:S1"]),
                         cc.get_unconditional_links())
示例#4
0
 def test_conditional_last_service_in_loop(self):
     cc = CCompiler("10.10.10.1_java:C:S3")
     cc.compile(TestCCompiler.get_composition())
     composition2 = "10.10.10.1_java:C:S1+" +\
                    "10.10.10.1_java:C:S3+" +\
                    "10.10.10.1_java:C:S1;"
     cc.compile(composition2)
     owner_ss = ServiceState("10.10.10.1_java:C:S3", "Undefined")
     input_ss = ServiceState("10.10.10.1_java:C:S3", "Undefined")
     self.assertEqual(OrderedSet(["10.10.10.1_java:C:S1"]),
                      cc.get_links(owner_ss, input_ss))
示例#5
0
 def test_conditional(self):
     cc = CCompiler("10.10.10.1_java:C:S1")
     cc.compile(TestCCompiler.get_composition())
     composition2 = "10.10.10.1_java:C:S1;" +\
                    "if (10.10.10.1_java:C:S1 == \"FOO\") { " +\
                    "  10.10.10.1_java:C:S1+10.10.10.1_java:C:S2;" +\
                    "}"
     cc.compile(composition2)
     owner_ss = ServiceState("10.10.10.1_java:C:S1", "\"FOO\"")
     input_ss = ServiceState("WHATEVER", "DON'T CARE")
     self.assertEqual(OrderedSet(["10.10.10.1_java:C:S2"]),
                      cc.get_links(owner_ss, input_ss))
示例#6
0
 def test_service_at_the_beginning(self):
     cc = CCompiler("10.10.10.1_java:C:S1")
     cc.compile(TestCCompiler.get_composition())
     self.assertEqual(set(["10.10.10.1_java:C:S2"]),
                      cc.get_unconditional_links())
示例#7
0
 def test_catch_missing_statement_with_exception(self):
     with self.assertRaises(ClaraException):
         cc = CCompiler("10.10.10.1_java:C:S5")
         cc.compile(TestCCompiler.get_composition())
class ServiceEngine(ClaraBase):

    def __init__(self, name,
                 local_address, frontend_address, user_engine,
                 service_sys_configuration, service_report):
        """A Service engine.

        Every engine process a request in its own thread.
        Args:
            name: Service canonical name
            local_address (ProxyAddress): Address info for local connection
            frontend_address (ProxyAddress): Address info for FE connection
            user_engine (Engine): User engine deployed
            service_sys_configuration (ServiceSysConfig): Service system config
            service_report (ServiceReport): Service report object
        """
        super(ServiceEngine, self).__init__(name,
                                            local_address.host,
                                            local_address.pub_port,
                                            frontend_address.host,
                                            frontend_address.pub_port)
        self._engine_object = user_engine
        self._semaphore = Semaphore(1)
        self._compiler = CCompiler(self.myname)
        self._prev_composition = xMsgConstants.UNDEFINED
        self._report = service_report
        self._logger = ClaraLogger(repr(self))

        self.execution_time = 0
        self.sys_config = service_sys_configuration

    def configure(self, message):
        """Configure the deployed Engine

        Args:
            message (xMsgMessage): message containing engine configuration data
        """
        input_data = None
        outgoing_data = None

        try:
            input_data = self._get_engine_data(message)
            outgoing_data = self._configure_engine(input_data)

        except Exception as e:
            self._logger.log_exception(e.message)
            outgoing_data = self.build_system_error_data(message,
                                                         -4, e.message)
        finally:
            self._update_metadata(input_data.metadata, outgoing_data.metadata)

        if message.has_reply_topic():
            outgoing_message = self._put_engine_data(outgoing_data,
                                                     message.get_reply_topic())
            self.send(outgoing_message)
        else:
            self._report_problem(outgoing_data)

    def _configure_engine(self, engine_input_data):
        output_data = self._engine_object.configure(engine_input_data)
        if not output_data:
            output_data = EngineData()
        if output_data.get_data():
            output_data.set_data(Mimetype.STRING, xMsgConstants.DONE)
        return output_data

    def _get_engine_data(self, message):
        msg = self.de_serialize(message,
                                self._engine_object.get_input_data_types())
        self._report.increment_bytes_received(sys.getsizeof(msg))
        return msg

    def _get_links(self, engine_input_data, engine_output_data):
        owner_ss = ServiceState(engine_output_data.engine_name(),
                                engine_output_data.state)
        input_ss = ServiceState(engine_input_data.engine_name(),
                                engine_input_data.state)
        return self._compiler.get_links(owner_ss, input_ss)

    def _update_metadata(self, in_meta, out_meta):
        out_meta.author = self.myname
        out_meta.version = self._engine_object.get_version()

        if not out_meta.communicationId:
            out_meta.communicationId = in_meta.communicationId

        out_meta.composition = in_meta.composition
        out_meta.executionTime = self.execution_time
        out_meta.action = in_meta.action

    def _parse_composition(self, engine_input_data):
        current_composition = engine_input_data.composition
        if current_composition != self._prev_composition:
            self._compiler.compile(current_composition)
            self._prev_composition = current_composition

    def _put_engine_data(self, data, receiver):
        topic = ClaraUtils.build_topic(CConstants.SERVICE, receiver)
        msg = self.serialize(topic, data,
                             self._engine_object.get_output_data_types())
        self._report.increment_bytes_sent(sys.getsizeof(msg))
        return msg

    def _report_problem(self, engine_data):
        status = engine_data.status
        if status == EngineStatus.ERROR:
            self._report(xMsgConstants.ERROR, engine_data)
        elif status == EngineStatus.WARNING:
            self._report(xMsgConstants.WARNING, engine_data)

    def _report(self, topic_prefix, engine_data):
        topic = xMsgTopic.wrap(str(topic_prefix) + ":" + self.myname)
        msg = self.serialize(topic, engine_data,
                             self._engine_object.get_output_data_types())
        self.send_frontend(msg)

    def _report_data(self, data):
        self._report(xMsgConstants.DATA, data)

    def _report_done(self, data):
        self._report(xMsgConstants.DONE, data)

    def _send_reports(self, outgoing_data):
        if self.sys_config.data_request:
            self._report_data(outgoing_data)
            self.sys_config.reset_data_request_count()
        if self.sys_config.done_request:
            self._report_done(outgoing_data)
            self.sys_config.reset_done_request_count()

    def _send_response(self, outgoing_data, outgoing_links):
        for link in outgoing_links:
            msg = self._put_engine_data(outgoing_data, link)
            self.send(msg)

    def execute(self, message):
        """Executes the deployed engine with the given input data

        Args:
            message (xMsgMessage): message containing input data
        """
        in_data = None
        outgoing_data = None
        self.sys_config.add_request()
        self._report.increment_request_count()

        try:
            in_data = self._get_engine_data(message)
            self._parse_composition(in_data)
            start_time = time.time()
            outgoing_data = self._execute_engine(in_data)
            elapsed_time = time.time() - start_time
            self._report.increment_execution_time(elapsed_time)

        except Exception as e:
            self._logger.log_exception(e.message)
            self._report.increment_failure_count()
            outgoing_data = self.build_system_error_data(message, -4,
                                                         e.message)
            raise e
        finally:
            self._update_metadata(message.metadata, outgoing_data.metadata)

        if message.has_reply_topic():
            outgoing_message = self._put_engine_data(outgoing_data,
                                                     message.get_reply_topic())
            self.send(outgoing_message)

        self._send_reports(outgoing_data)
        self._report_problem(outgoing_data)
        self._send_response(outgoing_data, self._get_links(in_data,
                                                           outgoing_data))

    def _execute_engine(self, engine_input_data):
        out_data = self._engine_object.execute(engine_input_data)
        if not out_data:
            self._logger.log_exception("null engine result")
            raise Exception("null engine result")

        return out_data

    def try_acquire_semaphore(self):
        """Returns true if service semaphore is available in a non blocking op

        Returns:
            boolean
        """
        return self._semaphore.acquire(blocking=False)

    def release_semaphore(self):
        """Releases engine semaphore

        Returns:
            boolean
        """
        return self._semaphore.release()