Ejemplo n.º 1
0
    def __init__(self,
                 meta,
                 service_name,
                 osa_backend_base_dir='/../../../',
                 port=8000):
        self.meta = meta
        _cache_password(self.meta)
        file_abs_dir = os.path.dirname(os.path.abspath(__file__))
        relative_path = [
            *(osa_backend_base_dir.split('/')), 'common', 'config',
            'services.json'
        ]
        service_config = file_abs_dir + os.path.sep + os.path.join(
            *relative_path)
        with open(service_config) as f:
            services = json.load(f)

        self.service_list = []  # used in communicator
        if (service_name in services
                and 'module_name' in services[service_name]
                and 'handler_class_name' in services[service_name]
                and 'routing_key' in services[service_name]
                and 'queue_name' in services[service_name]):
            service = services[service_name]
            module_name = service['module_name']
            handler_class_name = service['handler_class_name']
            module = __import__(module_name, fromlist=[handler_class_name])
            klass = getattr(module, handler_class_name)
            self.service_list.append(service_name)
            logger = Logger(log_level="info", vendor_key=-1, retailer_key=-1)
            logger.set_keys(module_name=service_name)
            self.consumer = self.NestedConsumer(
                meta=meta,
                service_routing_key=services[service_name]['routing_key'],
                service_queue_name=services[service_name]['queue_name'],
                handler_class=klass,
                service_name=service_name,
                logger=logger)
Ejemplo n.º 2
0
class MasterHandler(RequestHandler, ABC):

    executor = ThreadPoolExecutor(MAX_EXECUTOR)

    def initialize(self, meta):
        self.meta = meta
        self.logger = Logger(log_level="info", vendor_key=-1, retailer_key=-1)
        self.service_name = None
        self.is_sync_service = False
        self.is_notifiable = True

    def prepare(self):
        self.set_header('Content-Type', 'application/json')
        self.logger.info("Accepted query arguments: %s" %
                         self.request.query_arguments)
        self.query_arguments = {
            k: self.get_query_argument(k)
            for k in self.request.query_arguments
        }
        self.logger.info("Ajusted query arguments: %s" % self.query_arguments)
        self.request_body = {}
        if 'Content-Type' in self.request.headers and self.request.headers[
                "Content-Type"].startswith("application/json"):
            self.request_body = json.loads(
                self.request.body.decode('utf-8'))  # it may get list
            self.logger.info("Accepted post: %s" % self.request_body)

        osa_backend_base_dir = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), "..", "..", "..")
        service_config = os.path.join(osa_backend_base_dir, 'common', 'config',
                                      'services.json')
        with open(service_config) as f:
            services = json.load(f)

        self.set_service_properties()
        if not self.service_name:
            raise ValueError('service_name is empty.')
        elif not self.service_name in services:
            raise ValueError('%s is not found.' % self.service_name)

        self.logger.set_keys(module_name=self.service_name)
        self.service = services[self.service_name]
        module_name = self.service['module_name']
        class_name = self.service['class_name']
        module = __import__(module_name, fromlist=[class_name])
        self.klass = getattr(module, class_name)

    @run_on_executor
    @Notifier
    def async_main(self, params):
        self.cls = self.klass(meta=copy.deepcopy(self.meta),
                              request_body=copy.deepcopy(params),
                              logger=self.logger)  # init class_name
        return eval('self.cls.%s' % self.service['class_main_func']
                    )  # call main func and return result

    @Notifier
    def sync_main(self, params):
        self.cls = self.klass(meta=copy.deepcopy(self.meta),
                              request_body=copy.deepcopy(params),
                              logger=self.logger)
        return eval('self.cls.%s' % self.service['class_main_func'])

    def post(self):
        if self.is_sync_service:
            msg = self.sync_main(self.request_body)
            self.send_response(msg)
        else:
            self.async_main(self.request_body)
            msg = '%s - Running %s...' % (datetime.now(), self.service_name)
            self.send_response(msg)

    def send_response(self, msg):
        job_params = {}
        if self.is_notifiable:
            job_required_keys = [
                'jobId', 'stepId', 'batchId', 'retry', 'groupName'
            ]
            job_params = dict([(k, self.request_body[k])
                               for k in job_required_keys
                               if k in self.request_body])
            job_params['status'] = StepStatus.RUNNING.value
        job_params['message'] = msg
        job_params['request_body'] = self.request_body
        self.write(json.dumps(job_params))
        self.flush()

    @abstractmethod
    def set_service_properties(self):
        '''
        [Mandatory] set self.service_name
        [Optional] call self.set_as_sync_service() to set self.is_sync_service = True
        [Optional] call self.set_as_not_notifiable() to set self.is_notifiable = False
        '''
        pass

    def set_as_sync_service(self):
        self.is_sync_service = True

    def set_as_not_notifiable(self):
        self.is_notifiable = False