Back to index

nordugrid-arc-nox  1.1.0~rc6
Public Member Functions | Protected Member Functions | Protected Attributes | Static Protected Attributes
Arc::Service_PythonWrapper Class Reference

#include <pythonwrapper.h>

Inheritance diagram for Arc::Service_PythonWrapper:
Inheritance graph
[legend]
Collaboration diagram for Arc::Service_PythonWrapper:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 Service_PythonWrapper (Arc::Config *cfg)
virtual ~Service_PythonWrapper (void)
virtual Arc::MCC_Status process (Arc::Message &, Arc::Message &)
 Service request processing routine.
bool RegistrationCollector (Arc::XMLNode &)
 Service specific registartion collector, used for generate service registartions.
virtual void AddSecHandler (Config *cfg, ArcSec::SecHandler *sechandler, const std::string &label="")
 Add security components/handlers to this MCC.
virtual std::string getID ()
 Service may implement own service identitifer gathering method.

Protected Member Functions

Arc::MCC_Status make_fault (Arc::Message &outmsg)
bool ProcessSecHandlers (Message &message, const std::string &label="") const
 Executes security handlers of specified queue.

Protected Attributes

PyObject * arc_module
PyObject * module
PyObject * object
bool initialized
std::map< std::string,
std::list< ArcSec::SecHandler * > > 
sechandlers_
 Set of labeled authentication and authorization handlers.

Static Protected Attributes

static Arc::Logger logger
 Logger object used to print messages generated by this class.

Detailed Description

Definition at line 9 of file pythonwrapper.h.


Constructor & Destructor Documentation

Definition at line 121 of file pythonwrapper.cpp.

                                                          :RegisteredService(cfg)
{
    PyObject *py_module_name = NULL;
    PyObject *py_arc_module_name = NULL;
    PyObject *dict = NULL;
    PyObject *arc_dict = NULL;
    PyObject *arc_cfg_klass = NULL;
    PyObject *arg = NULL;
    PyObject *py_cfg = NULL;
    PyObject *klass = NULL;

    arc_module = NULL;
    module = NULL;
    object = NULL;
    initialized = false;

    if (tstate == NULL) {
        logger.msg(Arc::ERROR, "Main python thread is not initialized");
        return;
    }
    //PyEval_AcquireThread(tstate);

    std::string path = (std::string)(*cfg)["ClassName"];
    std::size_t p = path.rfind(".");
    if (p == std::string::npos) {
        logger.msg(Arc::ERROR, "Invalid class name");
        return;
    }
    std::string module_name = path.substr(0, p);
    std::string class_name = path.substr(p+1, path.length());
    logger.msg(Arc::VERBOSE, "class name: %s", class_name);
    logger.msg(Arc::VERBOSE, "module name: %s", module_name);

    // Convert module name to Python string
    py_module_name = PyString_FromString(module_name.c_str());
    if (py_module_name == NULL) {
        logger.msg(Arc::ERROR, "Cannot convert module name to Python string");
        if (PyErr_Occurred()) PyErr_Print();
        return;
    }
    // Load module
    module = PyImport_Import(py_module_name);
    if (module == NULL) {
        logger.msg(Arc::ERROR, "Cannot import module");
        if (PyErr_Occurred()) PyErr_Print();
        Py_DECREF(py_module_name);
        return;
    }
    Py_DECREF(py_module_name);

    // Import ARC python wrapper
    py_arc_module_name = PyString_FromString("arc");
    if (py_arc_module_name == NULL) {
        logger.msg(Arc::ERROR, "Cannot convert arc module name to Python string");
        if (PyErr_Occurred()) PyErr_Print();
        return;
    }

    // Load arc module
    arc_module = PyImport_Import(py_arc_module_name);
    if (arc_module == NULL) {
        logger.msg(Arc::ERROR, "Cannot import arc module");
        if (PyErr_Occurred()) PyErr_Print();
        Py_DECREF(py_arc_module_name);
        return;
    }
    Py_DECREF(py_arc_module_name);

    // arc_dict is a borrowed reference
    arc_dict = PyModule_GetDict(arc_module);
    if (arc_dict == NULL) {
        logger.msg(Arc::ERROR, "Cannot get dictionary of arc module");
        if (PyErr_Occurred()) PyErr_Print();
        return;
    }

    // Get the arc config class
    // arc_cfg_klass is a borrowed reference
    arc_cfg_klass = PyDict_GetItemString(arc_dict, "Config");
    if (arc_cfg_klass == NULL) {
        logger.msg(Arc::ERROR, "Cannot find arc Config class");
        if (PyErr_Occurred()) PyErr_Print();
        return;
    }

    // check is it really a class
    if (!PyCallable_Check(arc_cfg_klass)) {
        logger.msg(Arc::ERROR, "Config klass is not an object");
        return;
    }

    // Get dictionary of module content
    // dict is a borrowed reference
    dict = PyModule_GetDict(module);
    if (dict == NULL) {
        logger.msg(Arc::ERROR, "Cannot get dictionary of module");
        if (PyErr_Occurred()) PyErr_Print();
        return;
    }

    // Get the class
    // klass is a borrowed reference
    klass = PyDict_GetItemString(dict, (char*)class_name.c_str());
    if (klass == NULL) {
        logger.msg(Arc::ERROR, "Cannot find service class");
        if (PyErr_Occurred()) PyErr_Print();
        return;
    }

    // check is it really a class
    if (PyCallable_Check(klass)) {
        arg = Py_BuildValue("(l)", (long int)cfg);
        if (arg == NULL) {
            logger.msg(Arc::ERROR, "Cannot create config argument");
            if (PyErr_Occurred()) PyErr_Print();
            return;
        }

        py_cfg = PyObject_CallObject(arc_cfg_klass, arg);
        if (py_cfg == NULL) {
            logger.msg(Arc::ERROR, "Cannot convert config to python object");
            if (PyErr_Occurred()) PyErr_Print();
            Py_DECREF(arg);
            return;
        }
        Py_DECREF(arg);
        arg = Py_BuildValue("(O)", py_cfg);
        if (arg == NULL) {
            logger.msg(Arc::ERROR, "Cannot create argument of the constructor");
            if (PyErr_Occurred()) PyErr_Print();
            return;
        }

        // create instance of class
        object = PyObject_CallObject(klass, arg);
        if (object == NULL) {
            logger.msg(Arc::ERROR, "Cannot create instance of python class");
            if (PyErr_Occurred()) PyErr_Print();
            return;
        }
        Py_DECREF(arg);

    } else {
        logger.msg(Arc::ERROR, "%s is not an object", class_name);
        return;
    }

    // check is it really a class
    if (!PyCallable_Check(klass)) {
        logger.msg(Arc::ERROR, "Message klass is not an object");
        return;
    }
    //tstate = PyGILState_GetThisThreadState();
    //PyEval_ReleaseThread(tstate);

    logger.msg(Arc::VERBOSE, "Python Wrapper constructor succeeded");
    initialized = true;
}

Here is the call graph for this function:

Definition at line 280 of file pythonwrapper.cpp.

{
    service_lock.lock();
    PyEval_AcquireThread(tstate);
    // Release python objects - it is needed for Python
    // destructors to be called
    if(arc_module) Py_DECREF(arc_module);
    if(module) Py_DECREF(module);
    if(object) Py_DECREF(object);
    // Finish the Python Interpreter
    python_service_counter--;
    logger.msg(Arc::VERBOSE, "Python Wrapper destructor (%d)", python_service_counter);
    if (python_service_counter == 0) {
        Py_Finalize();
    } else {
        PyEval_ReleaseThread(tstate);
    }
    service_lock.unlock();
}

Here is the call graph for this function:


Member Function Documentation

void Arc::Service::AddSecHandler ( Config cfg,
ArcSec::SecHandler sechandler,
const std::string &  label = "" 
) [virtual, inherited]

Add security components/handlers to this MCC.

For more information please see description of MCC::AddSecHandler

Definition at line 14 of file Service.cpp.

                                                                                           {
    if(sechandler) {
        sechandlers_[label].push_back(sechandler); //need polishing to put the SecHandlerFactory->getinstance here
        XMLNode cn = (*cfg)["SecHandler"];
        Config cfg_(cn);
    }
}

Here is the caller graph for this function:

virtual std::string Arc::Service::getID ( ) [inline, virtual, inherited]

Service may implement own service identitifer gathering method.

This method return identifier of service which is used for registering it Information Services.

Reimplemented in ARex::ARexService.

Definition at line 69 of file Service.h.

{ return ""; };

Definition at line 300 of file pythonwrapper.cpp.

{
    Arc::PayloadSOAP* outpayload = new Arc::PayloadSOAP(Arc::NS(),true);
    Arc::SOAPFault* fault = outpayload->Fault();
    if(fault) {
        fault->Code(Arc::SOAPFault::Sender);
        fault->Reason("Failed processing request");
    };
    outmsg.Payload(outpayload);
    return Arc::MCC_Status();
}

Here is the call graph for this function:

Here is the caller graph for this function:

Service request processing routine.

Implements Arc::MCCInterface.

Definition at line 381 of file pythonwrapper.cpp.

{
    //PyObject *py_status = NULL;
    //PyObject *py_inmsg = NULL;
    //PyObject *py_outmsg = NULL;
    PyObject *arg = NULL;

    logger.msg(Arc::VERBOSE, "Python wrapper process called");

    if(!initialized) return Arc::MCC_Status();

    PythonLock plock(logger);

    // Convert in message to SOAP message
    Arc::SOAPMessageP inmsg_ptr(inmsg);
    if(!inmsg_ptr) {
        logger.msg(Arc::ERROR, "Failed to create input SOAP container");
        return make_fault(outmsg);
    }
    if(!inmsg_ptr->Payload()) {
        logger.msg(Arc::ERROR, "input is not SOAP");
        return make_fault(outmsg);
    }
    // Convert incomming message to python object
    arg = Py_BuildValue("(l)", (long int)inmsg_ptr);
    if (arg == NULL) {
        logger.msg(Arc::ERROR, "Cannot create inmsg argument");
        if (PyErr_Occurred()) PyErr_Print();
        return make_fault(outmsg);
    }
    // arc_dict is a borrowed reference
    PyObject *arc_dict = PyModule_GetDict(arc_module);
    if (arc_dict == NULL) {
        logger.msg(Arc::ERROR, "Cannot get dictionary of arc module");
        if (PyErr_Occurred()) PyErr_Print();
        return make_fault(outmsg);
    }
    // arc_msg_klass is a borrowed reference
    PyObject *arc_msg_klass = PyDict_GetItemString(arc_dict, "SOAPMessage");
    if (arc_msg_klass == NULL) {
        logger.msg(Arc::ERROR, "Cannot find arc Message class");
        if (PyErr_Occurred()) PyErr_Print();
        return make_fault(outmsg);
    }
    PyObjectP py_inmsg(PyObject_CallObject(arc_msg_klass, arg));
    if (!py_inmsg) {
        logger.msg(Arc::ERROR, "Cannot convert inmsg to python object");
        if (PyErr_Occurred()) PyErr_Print();
        Py_DECREF(arg);
        return make_fault(outmsg);
    }
    Py_DECREF(arg);

    Arc::SOAPMessageP outmsg_ptr(outmsg);
    if(!outmsg_ptr) {
        logger.msg(Arc::ERROR, "Failed to create SOAP containers");
        return make_fault(outmsg);
    }
    // Convert incomming and outcoming messages to python objects
    arg = Py_BuildValue("(l)", (long int)outmsg_ptr);
    if (arg == NULL) {
        logger.msg(Arc::ERROR, "Cannot create outmsg argument");
        if (PyErr_Occurred()) PyErr_Print();
        return make_fault(outmsg);
    }
    PyObjectP py_outmsg = PyObject_CallObject(arc_msg_klass, arg);
    if (!py_outmsg) {
        logger.msg(Arc::ERROR, "Cannot convert outmsg to python object");
        if (PyErr_Occurred()) PyErr_Print();
        Py_DECREF(arg);
        return make_fault(outmsg);
    }
    Py_DECREF(arg);

    // Call the process method
    PyObjectP py_status(PyObject_CallMethod(object, (char*)"process", (char*)"(OO)",
                                    (PyObject*)py_inmsg, (PyObject*)py_outmsg));
    if (!py_status) {
        if (PyErr_Occurred()) PyErr_Print();
        return make_fault(outmsg);
    }

    MCC_Status *status_ptr2 = (MCC_Status *)extract_swig_wrappered_pointer(py_status);
    Arc::MCC_Status status;
    if(status_ptr2) status=(*status_ptr2);
    {
        // std::string str = (std::string)status;
        // std::cout << "status: " << str << std::endl;
    };
    SOAPMessage *outmsg_ptr2 = (SOAPMessage *)extract_swig_wrappered_pointer(py_outmsg);
    if(outmsg_ptr2 == NULL) return make_fault(outmsg);
    SOAPEnvelope *p = outmsg_ptr2->Payload();
    if(p == NULL) return make_fault(outmsg);
    {
        // std::string xml;
        // if(p) p->GetXML(xml);
        // std::cout << "XML: " << xml << std::endl;
    };

    Arc::PayloadSOAP *pl = new Arc::PayloadSOAP(*p);
    {
        // std::string xml;
        // pl->GetXML(xml);
        // std::cout << "XML: " << xml << std::endl;
    };

    outmsg.Payload(pl);
    return status;
}

Here is the call graph for this function:

bool Arc::Service::ProcessSecHandlers ( Message message,
const std::string &  label = "" 
) const [protected, inherited]

Executes security handlers of specified queue.

For more information please see description of MCC::ProcessSecHandlers

Definition at line 22 of file Service.cpp.

                                                                              {
    std::map<std::string,std::list<ArcSec::SecHandler*> >::const_iterator q = sechandlers_.find(label);
    if(q == sechandlers_.end()) {
        logger.msg(DEBUG, "No security processing/check requested for '%s'", label);
        return true;
    }

    std::list<ArcSec::SecHandler*>::const_iterator h = q->second.begin();
    for(;h!=q->second.end();++h) {
        const ArcSec::SecHandler* handler = *h;
        if(handler) if(!(handler->Handle(&message))) {
            logger.msg(DEBUG, "Security processing/check for '%s' failed", label);
            return false;
        }
    }
    logger.msg(DEBUG, "Security processing/check for '%s' passed", label);
    return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Service specific registartion collector, used for generate service registartions.

In implemented service this method should generate GLUE2 document with part of service description which service wishes to advertise to Information Services.

Reimplemented from Arc::Service.

Definition at line 491 of file pythonwrapper.cpp.

                                                                 {
    PyObject *arg = NULL;

    // logger.msg(Arc::VERBOSE, "Python 'RegistrationCollector' wrapper process called");

    if(!initialized) return false;

    PythonLock plock(logger);

    // Convert doc to XMLNodeP
    // logger.msg(Arc::VERBOSE, "Convert doc to XMLNodeP");
    Arc::XMLNodeP doc_ptr(doc);
    if (!doc_ptr) {
        logger.msg(Arc::ERROR, "Failed to create XMLNode container");
        return false;
    }

    // Convert doc to python object
    // logger.msg(Arc::VERBOSE, "Convert doc to python object");
    // logger.msg(Arc::VERBOSE, "Create python XMLNode");
    // arc_dict is a borrowed reference
    PyObject *arc_dict = PyModule_GetDict(arc_module);
    if (arc_dict == NULL) {
        logger.msg(Arc::ERROR, "Cannot get dictionary of arc module");
        if (PyErr_Occurred()) PyErr_Print();
        return false;
    }
    // arc_xmlnode_klass is a borrowed reference
    PyObject *arc_xmlnode_klass = PyDict_GetItemString(arc_dict, "XMLNode");
    if (arc_xmlnode_klass == NULL) {
        logger.msg(Arc::ERROR, "Cannot find arc XMLNode class");
        if (PyErr_Occurred()) PyErr_Print();
        return false;
    }
    arg = Py_BuildValue("(l)", (long int)doc_ptr);
    if (arg == NULL) {
        logger.msg(Arc::ERROR, "Cannot create doc argument");
        if (PyErr_Occurred()) PyErr_Print();
        return false;
    }
    PyObjectP py_doc(PyObject_CallObject(arc_xmlnode_klass, arg));
        if (!py_doc) {
        logger.msg(Arc::ERROR, "Cannot convert doc to python object");
        if (PyErr_Occurred()) PyErr_Print();
        Py_DECREF(arg);
        return false;
    }
    Py_DECREF(arg);

    // Call the RegistrationCollector method
    // logger.msg(Arc::VERBOSE, "Call the RegistrationCollector method");
    PyObjectP py_bool(PyObject_CallMethod(object, (char*)"RegistrationCollector", (char*)"(O)",
                      (PyObject*)py_doc));

    if (!py_bool) {
        if (PyErr_Occurred()) PyErr_Print();
        return false;
    }

    // Convert the return value of the function back to cpp
    // logger.msg(Arc::VERBOSE, "Convert the return value of the function back to cpp");
    bool *ret_val2 = (bool *)extract_swig_wrappered_pointer(py_bool);
    bool return_value = false;
    if (ret_val2) return_value = (*ret_val2);

    XMLNode *doc2 = (XMLNode *)extract_swig_wrappered_pointer(py_doc);
    if (doc2 == NULL) return false;
    (*doc2).New(doc);
    return true;
}

Here is the call graph for this function:


Member Data Documentation

Definition at line 13 of file pythonwrapper.h.

Definition at line 16 of file pythonwrapper.h.

Logger object used to print messages generated by this class.

Reimplemented from Arc::Service.

Definition at line 12 of file pythonwrapper.h.

PyObject* Arc::Service_PythonWrapper::module [protected]

Definition at line 14 of file pythonwrapper.h.

PyObject* Arc::Service_PythonWrapper::object [protected]

Definition at line 15 of file pythonwrapper.h.

std::map<std::string,std::list<ArcSec::SecHandler*> > Arc::Service::sechandlers_ [protected, inherited]

Set of labeled authentication and authorization handlers.

MCC calls sequence of handlers at specific point depending on associated identifier. in most aces those are "in" and "out" for incoming and outgoing messages correspondingly.

Definition at line 40 of file Service.h.


The documentation for this class was generated from the following files: