Commit 2b983f40 by Owo Sugiana

Versi 0.1.2: tambah fitur dan bug fixed

1 parent bdb39dd3
0.1.2 2019-07-11
----------------
- Tambah remove_if_old() agar connection manager tidak salah hapus saat new
connection.
- Tambah get_amount()
- Masa tunggu receive_raw() 5 detik saja agar kill tidak terlalu lama.
Sebelumnya sesuai timeout pada konfigurasi. Nilai timeout tetap digunakan
untuk menetapkan kapan echo request.
- Menyertakan conf saat Job.create_iso()
0.1.1 2019-05-24
----------------
- on_loop() mendukung beberapa transaksi dalam sebuah raw stream.
- class Doc ditambah abstract function terkait transaksi.
0.1 2019-02-04
--------------
- Kali pertama
......@@ -34,18 +34,13 @@ class BaseISO8583(ISO8583):
return {}
def get_value(self, bit):
v = self.getBit(bit)
type_ = self.getBitType(bit)
if type_.find('LL') < 0:
return v
size_length = len(type_)
return v[size_length:]
return self.getBit(bit)
def get_values(self):
r = {}
for item in self.getBitsAndValues():
bit = int(item['bit'])
r[bit] = self.get_value(bit)
r[bit] = self.getBit(bit)
return r
def copy(self, bits=[], from_iso=None):
......
......@@ -13,19 +13,165 @@ from .structure import (
)
class StanGenerator:
def __init__(self):
self.stan = '0' * 6
def create(self):
kini = datetime.now()
new_stan = kini.strftime('%H%M%S')
if new_stan == self.stan:
new_stan = int(self.stan) + 1
self.stan = str(new_stan).zfill(6)
else:
self.stan = new_stan
return self.stan
stan_gen = StanGenerator()
class Doc(BaseISO8583):
def __init__(self, *args, **kwargs):
if 'conf' in kwargs:
self.conf = kwargs['conf']
del kwargs['conf']
else:
self.conf = dict()
BaseISO8583.__init__(self, *args, **kwargs)
self.transmission = DateTimeVar()
if self.from_iso:
self.set_response()
# Override
def get_bit_definition(self):
return NETWORK_BITS
# Override, please
def get_inquiry_code(self):
pass
# Override, please
def get_payment_code(self):
pass
def is_network_request(self):
return self.getMTI() == '0800'
def is_network_response(self):
return self.getMTI() == '0810'
def is_transaction_request(self):
return self.getMTI() == '0200' # sebagai pemda
def is_transaction_response(self): # sebagai bank
return self.getMTI() == '0210'
def is_request(self):
return self.is_network_request() or \
self.is_transaction_request() or \
self.is_reversal_request()
def is_response(self):
return self.is_network_response() or \
self.is_transaction_response() or \
self.is_reversal_response()
def get_name(self):
return self.is_echo() or self.is_sign_on() or self.is_sign_off() or \
self.is_reversal() or self.is_inquiry() or self.is_payment()
def get_transaction_code(self):
return self.getBit(3)
def is_inquiry(self):
return self.get_transaction_code() == self.get_inquiry_code() and \
'inquiry'
def is_inquiry_request(self): # sebagai pemda
return self.is_transaction_request() and self.is_inquiry() and \
'inquiry_response'
def is_inquiry_response(self): # sebagai bank
return self.is_transaction_response() and self.is_inquiry() and \
'inquiry_done'
def is_payment(self):
return self.get_transaction_code() == self.get_payment_code() and \
'payment'
def is_payment_request(self): # sebagai pemda
return self.is_transaction_request() and self.is_payment() and \
'payment_response'
def is_payment_response(self): # sebagai bank
return self.is_transaction_request() and self.is_payment() and \
'payment_done'
def is_reversal(self):
return self.getMTI()[:2] == '04' and 'reversal'
def is_reversal_request(self): # sebagai pemda
return self.getMTI() == '0400' and 'reversal_response'
def is_reversal_response(self): # sebagai bank
return self.getMTI() == '0410' and 'reversal_done'
# Override, please
def copy_inquiry_bits(self):
#self.copy([2, 3, 11])
pass
# Override, please
def copy_payment_bits(self):
self.copy_inquiry_bits()
#self.copy([4, 48]) # amount, NTB
def set_transaction_request(self):
self.setMTI('0200')
def set_transaction_response(self):
self.setMTI('0210')
def set_inquiry_request(self): # sebagai bank
self.set_transaction_request()
self.setBit(3, self.get_inquiry_code())
def set_inquiry_response(self): # sebagai pemda
self.set_transaction_response()
self.copy_inquiry_bits()
def set_amount(self, value):
self.setBit(4, value)
def get_amount(self):
return int(self.getBit(4))
def set_payment_request(self): # sebagai bank
self.set_transaction_request()
self.setBit(3, self.get_payment_code())
def set_payment_response(self): # sebagai pemda
self.set_transaction_response()
self.copy_payment_bits()
def set_reversal_response(self): # sebagai pemda
self.setMTI('0410')
self.copy_payment_bits()
def get_func_name(self):
return self.is_echo_request() or self.is_sign_on_request() or \
self.is_sign_off_request()
return self.is_echo_request() or \
self.is_echo_response() or \
self.is_sign_on_request() or \
self.is_sign_on_response() or \
self.is_sign_off_request() or \
self.is_sign_off_response() or \
self.is_inquiry_request() or \
self.is_inquiry_response() or \
self.is_payment_request() or \
self.is_payment_response() or \
self.is_reversal_request() or \
self.is_reversal_response()
# Dipanggil Job.process()
def process(self):
......@@ -36,12 +182,15 @@ class Doc(BaseISO8583):
else:
self.ack_function_not_found()
def is_response(self):
return self.is_network_response()
def set_response(self):
if self.from_iso.is_network_request():
self.set_network_response()
elif self.from_iso.is_inquiry_request():
self.set_inquiry_response()
elif self.from_iso.is_payment_request():
self.set_payment_response()
elif self.from_iso.is_reversal_request():
self.set_reversal_response()
def is_ok_response(self):
try:
......@@ -63,8 +212,8 @@ class Doc(BaseISO8583):
t.year, t.month, t.day, t.hour, t.minute, t.second)
def set_stan(self): # System Trace Audit Number
kini = datetime.now()
self.setBit(11, kini.strftime('%H%M%S'))
stan = stan_gen.create()
self.setBit(11, stan)
def get_stan(self):
return self.get_value(11)
......@@ -89,12 +238,6 @@ class Doc(BaseISO8583):
def get_func_code(self):
return self.getBit(70)
def is_network_request(self):
return self.getMTI() == '0800'
def is_network_response(self):
return self.getMTI() == '0810'
###################
# Network Sign On #
###################
......@@ -105,7 +248,11 @@ class Doc(BaseISO8583):
def is_sign_on_response(self):
return self.is_network_response() and \
self.get_func_code() == '001'
self.get_func_code() == '001' and 'sign_on_done'
def is_sign_on(self):
return (self.is_sign_on_request() or self.is_sign_on_response()) and \
'sign on'
def sign_on_request(self):
self.set_func_code('001')
......@@ -114,6 +261,9 @@ class Doc(BaseISO8583):
self.set_network_response()
self.ack()
def sign_on_done(self): # Sebagai bank
pass
#####################
# Network Echo Test #
#####################
......@@ -123,11 +273,11 @@ class Doc(BaseISO8583):
'echo_response'
def is_echo_response(self):
return self.is_network_response() and \
self.get_func_code() == '301'
return self.is_network_response() and self.get_func_code() == '301' \
and 'echo_done'
def is_echo(self):
return self.is_echo_request() or self.is_echo_response()
return (self.is_echo_request() or self.is_echo_response()) and 'echo'
def echo_request(self):
self.set_func_code('301')
......@@ -136,6 +286,9 @@ class Doc(BaseISO8583):
self.set_network_response()
self.ack()
def echo_done(self):
pass
####################
# Network Sign Off #
####################
......@@ -145,10 +298,12 @@ class Doc(BaseISO8583):
'sign_off_response'
def is_sign_off_response(self):
return self.is_network_request() and self.get_func_code() == '002'
return self.is_network_response() and self.get_func_code() == '002' \
and 'sign_off_done'
def is_sign_off(self):
return self.is_sign_off_request() or self.is_sign_off_response()
return (self.is_sign_off_request() or self.is_sign_off_response()) \
and 'sign off'
def sign_off_request(self):
self.set_func_code('002')
......@@ -157,6 +312,30 @@ class Doc(BaseISO8583):
self.set_network_response()
self.ack()
def sign_off_done(self): # Sebagai bank
pass
###############
# Transaction #
###############
def inquiry_response(self): # Sebagai pemda
pass
def inquiry_done(self): # Sebagai bank
pass
def payment_response(self): # Sebagai pemda
pass
def payment_done(self): # Sebagai bank
pass
def reversal_response(self): # Sebagai pemda
pass
def reversal_done(self): # Sebagai bank
pass
###################
# Acknowledgement #
###################
......@@ -165,6 +344,7 @@ class Doc(BaseISO8583):
self.set_transmission()
self.ack_log(msg)
# Override, please
def ack_log(self, msg):
pass
......@@ -173,6 +353,3 @@ class Doc(BaseISO8583):
def ack_function_not_found(self):
self.ack_other('Fungsi tidak ditemukan')
def ack_unknown(self):
self.ack_other('Unknown')
......@@ -15,7 +15,7 @@ class Job:
def create_iso(self, from_iso=None):
cls = self.get_iso_class()
return cls(from_iso=from_iso)
return cls(from_iso=from_iso, conf=self.conf)
def get_iso(self):
if self.do_echo:
......@@ -40,6 +40,8 @@ class Job:
if self.sign_on_time:
return
return self.sign_on_request()
if from_iso.is_sign_on_request():
self.sign_on_time = time()
iso = self.create_iso(from_iso=from_iso)
iso.process()
return iso
......
import sys
import socket
import select
from time import (
time,
sleep,
......@@ -15,6 +16,7 @@ class Connection:
self.conf = conf
self.connected_time = None
self.running = False
self.created_time = time()
def process(self, raw):
return self.job.process(raw)
......@@ -61,16 +63,20 @@ class Connection:
if self.is_timeout():
self.close_because_timeout()
return
raw = self.streamer.get(raw)
if not raw:
return
raw = self.process(raw)
if raw:
self.send(raw)
while True:
raw = self.streamer.get(raw)
if not raw:
return
raw = self.process(raw)
if raw:
self.send(raw)
raw = ''
def receive_raw(self):
try:
raw = self.request.recv(self.get_receive_size())
ready, _, _ = select.select([self.request], [], [], 5)
raw = ready and self.request.recv(
self.get_receive_size(), socket.MSG_DONTWAIT) or ''
if isinstance(raw, bytes):
raw = raw.decode('utf-8')
if raw:
......@@ -104,6 +110,9 @@ class Connection:
def send(self, raw):
raw = self.raw_for_send(raw)
self.just_send(raw)
def just_send(self, raw):
if sys.version_info.major > 2:
raw = raw.encode('utf-8')
try:
......@@ -182,6 +191,12 @@ class ConnectionManager:
sleep(0.1)
count = self.count(ip_port)
def remove_if_old(self, index):
ip_port, conn = self.conns[index]
if time() - conn.created_time > 5:
self.remove(index)
return True
def __iter__(self): # for loop
for ip_port, conn in self.conns:
yield [ip_port, conn]
......
......@@ -19,7 +19,6 @@ requires = [
packages = [
'opensipkd',
'opensipkd.tcp',
'opensipkd.tcp',
'opensipkd.streamer',
'opensipkd.iso8583',
'opensipkd.iso8583.network',
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!