__init__.py 4.26 KB
from time import (
    time,
    sleep,
    )
from opensipkd.tcp.connection import join_ip_port
from iso8583_web.read_conf import (
    name_conf,
    web_path_conf,
    )
from iso8583_web.scripts.logger import (
    log_web_info,
    log_web_error,
    )
from ..connection import conn_mgr
from ..logger import log_web_info


# Daftar job dari web request, berisi iso request
# key: ip:port, value: list of iso
web_request = {}

# Daftar job yang sedang diproses, yaitu menunggu iso response
# key: ip:port, value: list of stan (bit 11)
web_process = {}

# Daftar job yang sudah selesai, berisi iso response
# key: ip:port, value: dict of (key: stan, value: iso)
web_response = {}


def append_web_process(ip_port, iso):
    stan = iso.get_stan()
    if ip_port in web_process:
        web_process[ip_port].append(stan)
    else:
        web_process[ip_port] = [stan]


def append_web_response(ip_port, stan, iso):
    if ip_port in web_response:
        web_response[ip_port][stan] = iso
    else:
        web_response[ip_port] = {stan: iso}


class WebJob:
    def __init__(self, conn, iso, conf=dict()):
        self.conn = conn
        self.iso = iso
        self.conf = conf

    def get_response(self):
        ip_port = join_ip_port(self.conn.conf['ip'], self.conn.conf['port'])
        if ip_port in web_request:
            web_request[ip_port].append(self.iso)
        else:
            web_request[ip_port] = [self.iso]
        stan = self.iso.get_stan()
        awal = time()
        while True:
            sleep(0.001)
            if time() - awal > self.conf.get('timeout', 30):
                raise self.timeout_error()
            if ip_port not in web_response:
                continue
            result = web_response[ip_port]
            if stan in result:
                iso = result[stan]
                del result[stan]
                return iso

    def timeout_error(self):
        return Exception('Timeout')


class View:
    def __init__(self, request):
        self.request = request

    def log_prefix(self):
        web_conf = self.get_web_conf()
        if web_conf:
            name = web_conf['name']
        else:
            name = 'unknown'
        return '{} {} {}'.format(
            self.request.client_addr, name, id(self.request))

    def log_receive(self, msg, error=False):
        msg = '{} {} {}'.format(self.log_prefix(), 'Receive', msg)
        if error:
            log_web_error(msg)
        else:
            log_web_info(msg)

    def log_send(self, msg, error=False):
        msg = '{} {} {}'.format(self.log_prefix(), 'Send', msg)
        if error:
            log_web_error(msg)
        else:
            log_web_info(msg)

    # Get ISO8583 connection
    def get_connection(self):
        web_conf = self.get_web_conf()
        if not web_conf:
            raise self.not_found_error(self.request.client_addr)
        name = web_conf['host']
        conf = name_conf[name]
        found_conn = None
        for ip_port, conn in conn_mgr:
            ip, port = ip_port.split(':')
            if conf['ip'] != ip:
                continue
            port = int(port)
            if conf['port'] != port:
                continue
            found_conn = conn
        if not found_conn:
            raise self.not_found_error(name)
        if not found_conn.running:
            raise self.not_running_error(name)
        return found_conn

    def get_web_conf(self):
        return web_path_conf.get(self.request.path)

    def get_iso_conf(self):
        web_conf = self.get_web_conf()
        name = web_conf['host']
        return name_conf[name]

    def validate(self):
        conf = self.get_web_conf()
        if not conf['allowed_ip']:
            return
        if self.request.client_addr not in conf['allowed_ip']:
            raise self.not_found_error(self.request.client_addr)

    def not_found_error(self, hostname):
        msg = 'Host {} tidak ditemukan di konfigurasi'.format(hostname)
        return Exception(msg)

    def not_running_error(self, hostname):
        msg = 'Host {} belum terhubung'.format(hostname)
        return Exception(msg)

    def get_web_job_cls(self):
        return WebJob

    def web_job(self, conn, iso):
        conf = self.get_web_conf()
        cls = self.get_web_job_cls()
        job = cls(conn, iso, conf)
        return job.get_response()