Skip to main content

Python bindings for writing Oracle Tuxedo clients and servers

Project description

Python3 bindings for Oracle Tuxedo.

https://travis-ci.org/aivarsk/tuxedo-python.svg?branch=master

Why?

I’m a fan of the way tuxmodule enables you to interact with Oracle Tuxedo. Unfortunately, it’s out-dated and somehow limited. So I cloned tuxmodule and started to clean up compiler warnings and work on some features I had in mind:

  • A multi-threaded server

  • Support nested FML32 buffers and more types

  • Support newest Oracle Tuxedo features like tpadvertisex() and tpappthrinit()

  • Receive response even when the service returns TPFAIL (instead of exception)

But I realized that’s too much of C for me, so I decided to write my own Python module for Oracle Tuxedo in C++ and pybind11 focusing on the parts I find most important first.

General

tuxedo module supports only STRING and FML32 buffer types at the moment.

STRING is mapped to/from Python str type.

FML32 is mapped to/from Python dict type with field names (str) as keys and lists (list) of different types (int, str, float or dict) as values. dict to FML32 conversion also treats types int, str, float or dict as lists with a single element:

{'TA_CLASS': 'Single value'}

converted to FML32 and then back to dict becomes

{'TA_CLASS': ['Single value']}

All XATMI functions that take buffer and length arguments in C take only buffer argument in Python.

Calling a service

tuxedo.tpcall() and tuxedo.tpgetrply() functions return a tuple with 3 elements or throw an exception when no data is received. This is the part I believe tuxmodule got wrong: a service may return a response both when it succeeds (TPSUCCESS) and fails (TPFAIL) and often the failure response contains some important information.

  • 0 or TPESVCFAIL

  • tpurcode (the second argument to tpreturn)

  • data buffer

rval, rcode, data = t.tpcall('.TMIB', {'TA_CLASS': 'T_SVCGRP', 'TA_OPERATION': 'GET'})
if rval == 0:
  # Service returned TPSUCCESS
else:
  # rval == tuxedo.TPESVCFAIL
  # Service returned TPFAIL

Writing servers

Tuxedo servers are written as Python classes. tpsvrinit method of object will be called when Tuxedo calls tpsvrinit(3c) function and it must return 0 on success or -1 on error. A common task for tpsvrinit is to advertise services the server provides by calling tuxedo.tpadvertise() with a service name. A method with the same name must exist. tpsvrdone, tpsvrthrinit and tpsvrthrdone will be called when Tuxedo calls corresponding functions. All of these 4 methods are optional and tuxedo module always calls tpopen() and tpclose() functions before calling user-supplied methods.

Each service method receives a single argument with incoming buffer and service must end with either call to tuxedo.tpreturn() or tuxedo.tpforward(). Following two code fragments are equivalent but I believe the first one is less error-prone. Unlike in C tuxedo.tpreturn() and tuxedo.tpforward() do not perform longjmp but set up arguments for those calls once service method will return.

def ECHO(self, args):
    return t.tpreturn(t.TPSUCCESS, 0, args)
def ECHO(self, args):
    t.tpreturn(t.TPSUCCESS, 0, args)

After that tuxedo.run() must be called with an instance of the class and command-line arguments to start Tuxedo server’s main loop.

#!/usr/bin/env python3
import sys
import tuxedo as t

class Server:
    def tpsvrinit(self, args):
        t.tpadvertise('ECHO')
        return 0

    def tpsvrthrinit(self, args):
        return 0

    def tpsvrthrdone(self):
        pass

    def tpsvrdone(self):
        pass

    def ECHO(self, args):
        return t.tpreturn(t.TPSUCCESS, 0, args)

if __name__ == '__main__':
    t.run(Server(), sys.argv)

UBBCONFIG

To use Python code as Tuxedo server the file itself must be executable (chmod +x *.py) and it must contain shebang line with Python:

#!/usr/bin/env python3

After that you can use the *.py file as server executable in UBBCONFIG:

"api.py" SRVGRP=GROUP1 SRVID=20 RQADDR="api" MIN=1 SECONDARYRQ=Y REPLYQ=Y

Writing clients

Nothing special is needed to implement Tuxedo clients, just import the module and start calling XATMI functions.

#!/usr/bin/env python3
import sys
import tuxedo as t

rval, rcode, data = t.tpcall('.TMIB', {'TA_CLASS': 'T_SVCGRP', 'TA_OPERATION': 'GET'})

Demo

demo has some proof-of-concept code:

  • client.py Oracle Tuxedo client

  • api.py HTTP+JSON server running inside Oracle Tuxedo server

  • ecb.py HTTP+XML client running inside Oracle Tuxedo server

  • mem.py multi-threaded in-memory cache

TODO

  • Implementing few more useful APIs

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tuxedo-0.0.4.tar.gz (10.3 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page