// -*- Mode: C++; -*- // Package : omniORBpy // pyInterceptors.cc Created on: 2003/05/27 // Author : Duncan Grisby (dgrisby) // // Copyright (C) 2003 Apasphere Ltd. // // This file is part of the omniORBpy library // // The omniORBpy library is free software; you can redistribute it // and/or modify it under the terms of the GNU Lesser General // Public License as published by the Free Software Foundation; // either version 2.1 of the License, or (at your option) any later // version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free // Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, // MA 02111-1307, USA // // Description: // Python request interceptors // $Id: pyInterceptors.cc,v 1.1.4.3 2006/06/05 11:51:00 dgrisby Exp $ // $Log: pyInterceptors.cc,v $ // Revision 1.1.4.3 2006/06/05 11:51:00 dgrisby // Track ORB core interceptor change. // // Revision 1.1.4.2 2005/07/22 17:41:08 dgrisby // Update from omnipy2_develop. // // Revision 1.1.4.1 2005/01/07 00:22:32 dgrisby // Big merge from omnipy2_develop. // // Revision 1.1.2.2 2003/07/26 23:17:43 dgrisby // Avoid spurious warning about lack of return value. // // Revision 1.1.2.1 2003/05/28 10:13:01 dgrisby // Preliminary interceptor support. General clean-up. // #include #include #include #include #include #include #include #include OMNI_USING_NAMESPACE(omni) // Python lists of interceptor functions static PyObject* clientSendRequestFns = 0; static PyObject* clientReceiveReplyFns = 0; static PyObject* serverReceiveRequestFns = 0; static PyObject* serverSendReplyFns = 0; static PyObject* serverSendExceptionFns = 0; static inline CORBA::ULong pyNumberToULong(PyObject* obj, CORBA::CompletionStatus completion) { if (PyInt_Check(obj)) { long r = PyInt_AS_LONG(obj); if (r >= 0) return r; } if (PyLong_Check(obj)) { CORBA::ULong r = PyLong_AsUnsignedLong(obj); if (r == (CORBA::ULong)-1 && PyErr_Occurred()) PyErr_Clear(); else return r; } OMNIORB_THROW(BAD_PARAM, BAD_PARAM_WrongPythonType, completion); return 0; } static void callInterceptorsAndSetContexts(PyObject* fnlist, const char* opname, const char* exrepoid, IOP::ServiceContextList& service_contexts, CORBA::CompletionStatus completion) { PyObject* argtuple; if (exrepoid) argtuple = PyTuple_New(3); else argtuple = PyTuple_New(2); PyObject* ctxtlist = PyList_New(0); PyTuple_SetItem(argtuple, 0, PyString_FromString(opname)); PyTuple_SetItem(argtuple, 1, ctxtlist); if (exrepoid) PyTuple_SetItem(argtuple, 2, PyString_FromString(exrepoid)); CORBA::ULong sclen = service_contexts.length(); CORBA::ULong sci = sclen; try { for (int i=0; i < PyList_GET_SIZE(fnlist); i++) { PyObject* interceptor = PyList_GET_ITEM(fnlist, i); PyObject* result = PyObject_CallObject(interceptor, argtuple); if (!result) { omniPy::handlePythonException(); } if (result != Py_None) { Py_DECREF(result); OMNIORB_THROW(BAD_PARAM, BAD_PARAM_WrongPythonType, completion); } Py_DECREF(result); if (PyList_GET_SIZE(ctxtlist) > 0) { sclen += PyList_GET_SIZE(ctxtlist); service_contexts.length(sclen); for (int j=0; j < PyList_GET_SIZE(ctxtlist); j++, sci++) { PyObject* sc = PyList_GET_ITEM(ctxtlist, j); if (!PyTuple_Check(sc) || PyTuple_GET_SIZE(sc) != 2) { OMNIORB_THROW(BAD_PARAM, BAD_PARAM_WrongPythonType, completion); } service_contexts[sci].context_id = pyNumberToULong(PyTuple_GET_ITEM(sc, 0), completion); PyObject* data = PyTuple_GET_ITEM(sc, 1); if (!PyString_Check(data)) OMNIORB_THROW(BAD_PARAM, BAD_PARAM_WrongPythonType, completion); service_contexts[sci].context_data.length(PyString_GET_SIZE(data)); memcpy(service_contexts[sci].context_data.NP_data(), PyString_AS_STRING(data), PyString_GET_SIZE(data)); } PyList_SetSlice(ctxtlist, 0, PyList_GET_SIZE(ctxtlist), 0); } } } catch (...) { Py_DECREF(argtuple); throw; } Py_DECREF(argtuple); } static void getContextsAndCallInterceptors(PyObject* fnlist, const char* opname, IOP::ServiceContextList& service_contexts, CORBA::CompletionStatus completion) { int i; int sclen = service_contexts.length(); PyObject* argtuple = PyTuple_New(2); PyObject* sctuple = PyTuple_New(sclen); PyTuple_SET_ITEM(argtuple, 0, PyString_FromString(opname)); PyTuple_SET_ITEM(argtuple, 1, sctuple); for (i=0; i < sclen; i++) { PyObject* sc = PyTuple_New(2); PyTuple_SET_ITEM(sc, 0, PyLong_FromUnsignedLong(service_contexts[i].context_id)); const char* data = (const char*)service_contexts[i].context_data.NP_data(); int len = service_contexts[i].context_data.length(); PyTuple_SET_ITEM(sc, 1, PyString_FromStringAndSize(data, len)); PyTuple_SET_ITEM(sctuple, i, sc); } try { for (i=0; i < PyList_GET_SIZE(fnlist); i++) { PyObject* interceptor = PyList_GET_ITEM(fnlist, i); PyObject* result = PyObject_CallObject(interceptor, argtuple); if (!result) { omniPy::handlePythonException(); } if (result != Py_None) { Py_DECREF(result); OMNIORB_THROW(BAD_PARAM, BAD_PARAM_WrongPythonType, completion); } Py_DECREF(result); } } catch (...) { Py_DECREF(argtuple); throw; } Py_DECREF(argtuple); } static CORBA::Boolean pyClientSendRequestFn(omniInterceptors::clientSendRequest_T::info_T& info) { OMNIORB_ASSERT(clientSendRequestFns); omnipyThreadCache::lock _t; callInterceptorsAndSetContexts(clientSendRequestFns, info.giop_c.operation(), 0, info.service_contexts, CORBA::COMPLETED_NO); return 1; } static CORBA::Boolean pyClientReceiveReplyFn(omniInterceptors::clientReceiveReply_T::info_T& info) { OMNIORB_ASSERT(clientReceiveReplyFns); omnipyThreadCache::lock _t; getContextsAndCallInterceptors(clientReceiveReplyFns, info.giop_c.operation(), info.service_contexts, (CORBA::CompletionStatus) info.giop_c.completion()); return 1; } static CORBA::Boolean pyServerReceiveRequestFn(omniInterceptors:: serverReceiveRequest_T::info_T& info) { OMNIORB_ASSERT(serverReceiveRequestFns); omnipyThreadCache::lock _t; getContextsAndCallInterceptors(serverReceiveRequestFns, info.giop_s.operation(), info.giop_s.service_contexts(), (CORBA::CompletionStatus) info.giop_s.completion()); return 1; } static CORBA::Boolean pyServerSendReplyFn(omniInterceptors::serverSendReply_T::info_T& info) { OMNIORB_ASSERT(serverSendReplyFns); omnipyThreadCache::lock _t; callInterceptorsAndSetContexts(serverSendReplyFns, info.giop_s.operation(), 0, info.giop_s.service_contexts(), (CORBA::CompletionStatus) info.giop_s.completion()); return 1; } static CORBA::Boolean pyServerSendExceptionFn(omniInterceptors::serverSendException_T::info_T& info) { OMNIORB_ASSERT(serverSendExceptionFns); omnipyThreadCache::lock _t; callInterceptorsAndSetContexts(serverSendExceptionFns, info.giop_s.operation(), info.exception->_rep_id(), info.giop_s.service_contexts(), (CORBA::CompletionStatus) info.giop_s.completion()); return 1; } void omniPy:: registerInterceptors() { omniInterceptors* interceptors = omniORB::getInterceptors(); if (clientSendRequestFns) interceptors->clientSendRequest.add(pyClientSendRequestFn); if (clientReceiveReplyFns) interceptors->clientReceiveReply.add(pyClientReceiveReplyFn); if (serverReceiveRequestFns) interceptors->serverReceiveRequest.add(pyServerReceiveRequestFn); if (serverSendReplyFns) interceptors->serverSendReply.add(pyServerSendReplyFn); if (serverSendExceptionFns) interceptors->serverSendException.add(pyServerSendExceptionFn); } #define CHECK_ORB_NOT_INITIALISED() \ do { \ if (omniPy::orb) { \ CORBA::BAD_INV_ORDER _ex(BAD_INV_ORDER_InvalidPortableInterceptorCall, \ CORBA::COMPLETED_NO); \ return omniPy::handleSystemException(_ex); \ } \ } while(0) extern "C" { static char addClientSendRequest_doc [] = "addClientSendRequest(interceptor) -> None\n" "\n" "Install an interceptor for when clients send requests.\n"; static PyObject* pyInterceptor_addClientSendRequest(PyObject* self, PyObject* args) { PyObject* interceptor; if (!PyArg_ParseTuple(args, (char*)"O", &interceptor)) return 0; RAISE_PY_BAD_PARAM_IF(!PyCallable_Check(interceptor), BAD_PARAM_WrongPythonType); CHECK_ORB_NOT_INITIALISED(); if (!clientSendRequestFns) clientSendRequestFns = PyList_New(0); PyList_Append(clientSendRequestFns, interceptor); Py_INCREF(Py_None); return Py_None; } static char addClientReceiveReply_doc [] = "addClientReceiveReply(interceptor) -> None\n" "\n" "Install an interceptor for when clients receive replies.\n"; static PyObject* pyInterceptor_addClientReceiveReply(PyObject* self, PyObject* args) { PyObject* interceptor; if (!PyArg_ParseTuple(args, (char*)"O", &interceptor)) return 0; RAISE_PY_BAD_PARAM_IF(!PyCallable_Check(interceptor), BAD_PARAM_WrongPythonType); CHECK_ORB_NOT_INITIALISED(); if (!clientReceiveReplyFns) clientReceiveReplyFns = PyList_New(0); PyList_Append(clientReceiveReplyFns, interceptor); Py_INCREF(Py_None); return Py_None; } static char addServerReceiveRequest_doc [] = "addServerReceiveRequest(interceptor) -> None\n" "\n" "Install an interceptor for when servers receive requests.\n"; static PyObject* pyInterceptor_addServerReceiveRequest(PyObject* self, PyObject* args) { PyObject* interceptor; if (!PyArg_ParseTuple(args, (char*)"O", &interceptor)) return 0; RAISE_PY_BAD_PARAM_IF(!PyCallable_Check(interceptor), BAD_PARAM_WrongPythonType); CHECK_ORB_NOT_INITIALISED(); if (!serverReceiveRequestFns) serverReceiveRequestFns = PyList_New(0); PyList_Append(serverReceiveRequestFns, interceptor); Py_INCREF(Py_None); return Py_None; } static char addServerSendReply_doc [] = "addServerSendReply(interceptor) -> None\n" "\n" "Install an interceptor for when servers send replies.\n"; static PyObject* pyInterceptor_addServerSendReply(PyObject* self, PyObject* args) { PyObject* interceptor; if (!PyArg_ParseTuple(args, (char*)"O", &interceptor)) return 0; RAISE_PY_BAD_PARAM_IF(!PyCallable_Check(interceptor), BAD_PARAM_WrongPythonType); CHECK_ORB_NOT_INITIALISED(); if (!serverSendReplyFns) serverSendReplyFns = PyList_New(0); PyList_Append(serverSendReplyFns, interceptor); Py_INCREF(Py_None); return Py_None; } static char addServerSendException_doc [] = "addServerSendException(interceptor) -> None\n" "\n" "Install an interceptor for when servers send exceptions.\n"; static PyObject* pyInterceptor_addServerSendException(PyObject* self, PyObject* args) { PyObject* interceptor; if (!PyArg_ParseTuple(args, (char*)"O", &interceptor)) return 0; RAISE_PY_BAD_PARAM_IF(!PyCallable_Check(interceptor), BAD_PARAM_WrongPythonType); CHECK_ORB_NOT_INITIALISED(); if (!serverSendExceptionFns) serverSendExceptionFns = PyList_New(0); PyList_Append(serverSendExceptionFns, interceptor); Py_INCREF(Py_None); return Py_None; } static PyMethodDef pyInterceptor_methods[] = { {(char*)"addClientSendRequest", pyInterceptor_addClientSendRequest, METH_VARARGS, addClientSendRequest_doc}, {(char*)"addClientReceiveReply", pyInterceptor_addClientReceiveReply, METH_VARARGS, addClientReceiveReply_doc}, {(char*)"addServerReceiveRequest", pyInterceptor_addServerReceiveRequest, METH_VARARGS, addServerReceiveRequest_doc}, {(char*)"addServerSendReply", pyInterceptor_addServerSendReply, METH_VARARGS, addServerSendReply_doc}, {(char*)"addServerSendException", pyInterceptor_addServerSendException, METH_VARARGS, addServerSendException_doc}, {NULL,NULL} }; } void omniPy::initInterceptorFunc(PyObject* d) { PyObject* m = Py_InitModule((char*)"_omnipy.interceptor_func", pyInterceptor_methods); PyDict_SetItemString(d, (char*)"interceptor_func", m); }