common.py
4.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import logging
from time import (
time,
sleep,
)
from sqlalchemy import exc
from opensipkd.tcp.connection import join_ip_port
from .iso8583.read_conf import name_conf
from .iso8583.connection import conn_mgr
log = logging.getLogger(__name__)
# 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 = {}
# Nilai timeout dalam detik saat menunggu ISO-8583 response
ISO_TIMEOUT = 30
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}
# Abstract class. Inherit, please.
class BaseView:
def __init__(self, request):
self.request = request
def get_name(self): # Override, please
return 'unknown'
def get_allowed_ip(self): # Override, please
return ['0.0.0.0']
def validate(self):
allowed_ip = self.get_allowed_ip()
if '0.0.0.0' in allowed_ip:
return
if self.request.client_addr not in allowed_ip:
raise self.not_found_error(self.request.client_addr)
def log_prefix(self):
ip = self.request.client_addr
name = self.get_name()
mem_id = id(self.request)
return f'{ip} {name} {mem_id}'
def log_receive(self, msg):
prefix = self.log_prefix()
path = self.request.path
msg = f'{prefix} Receive {path} {msg}'
log.info(msg)
def log_send(self, msg):
prefix = self.log_prefix()
msg = f'{prefix} Send {msg}'
log.info(msg)
def log_debug(self, msg):
prefix = self.log_prefix()
msg = f'{prefix} {msg}'
log.debug(msg)
# Abstract class. Inherit, please.
class BaseIsoView(BaseView):
# Get ISO8583 connection
def get_connection(self):
conf = self.get_iso_conf()
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(conf['name'])
if not found_conn.running:
raise self.not_running_error(conf['name'])
return found_conn
def send_iso(self, conn, iso):
ip_port = join_ip_port(conn.conf['ip'], conn.conf['port'])
if ip_port in web_request:
web_request[ip_port].append(iso)
else:
web_request[ip_port] = [iso]
stan = iso.get_stan()
awal = time()
while True:
sleep(0.001)
if time() - awal > ISO_TIMEOUT:
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 get_iso_conf_name(self): # Override, please
return 'bjb'
def get_iso_conf(self):
name = self.get_iso_conf_name()
return name_conf[name]
def not_found_error(self, hostname):
msg = f'Host {hostname} tidak ditemukan di konfigurasi'
return Exception(msg)
def not_running_error(self, hostname):
msg = f'Host {hostname} belum terhubung'
return Exception(msg)
def timeout_error(self):
return Exception('Timeout')
SQL_CHECK = dict(
postgresql='SELECT 1',
oracle='SELECT 1 FROM dual')
def db_check(engine):
sql = SQL_CHECK[engine.dialect.name]
try:
engine.execute(sql)
except exc.DBAPIError as e:
if e.connection_invalidated:
log.debug('Database connection problem')