Skip to content

Commit 9003c05

Browse files
committed
QPID-4968 - Added an adapter module for Python-to-Dispatch calls.
Implemented LogAdapter within the "dispatch" module to allow Python modules to emit logs in Dispatch. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1500073 13f79535-47bb-0310-9956-ffa450edef68
1 parent d244e9a commit 9003c05

File tree

5 files changed

+248
-41
lines changed

5 files changed

+248
-41
lines changed

qpid/extras/dispatch/src/python_embedded.h renamed to qpid/extras/dispatch/include/qpid/dispatch/python_embedded.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,45 @@
2424
#include <qpid/dispatch/parse.h>
2525
#include <qpid/dispatch/iterator.h>
2626

27+
/**
28+
* Initialize the embedded-python subsystem. This must be called before
29+
* any other call into this module is invoked.
30+
*/
2731
void dx_python_initialize();
32+
33+
/**
34+
* Finalize the embedded-python subsystem. After this is called, there
35+
* must be no further invocation of dx_python methods.
36+
*/
2837
void dx_python_finalize();
38+
39+
/**
40+
* Start using embedded python. This is called once by each module that plans
41+
* to use embedded python capabilities. It must call dx_python_start before
42+
* using any python components.
43+
*/
2944
void dx_python_start();
45+
46+
/**
47+
* Stop using embedded python. This is called once by each module after it is
48+
* finished using embedded python capabilities.
49+
*/
3050
void dx_python_stop();
3151

52+
/**
53+
* Convert a Python object to AMQP format and append to a composed_field.
54+
*
55+
* @param value A Python Object
56+
* @param field A composed field
57+
*/
3258
void dx_py_to_composed(PyObject *value, dx_composed_field_t *field);
59+
60+
/**
61+
* Convert a parsed field to a Python object
62+
*
63+
* @param field A parsed field
64+
* @return A generated Python object
65+
*/
3366
PyObject *dx_field_to_py(dx_parsed_field_t *field);
3467

3568
#endif

qpid/extras/dispatch/src/config.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* under the License.
1818
*/
1919

20-
#include "python_embedded.h"
20+
#include <qpid/dispatch/python_embedded.h>
2121
#include "config_private.h"
2222
#include <qpid/dispatch/alloc.h>
2323
#include <qpid/dispatch/log.h>

qpid/extras/dispatch/src/dispatch.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* under the License.
1818
*/
1919

20-
#include "python_embedded.h"
20+
#include <qpid/dispatch/python_embedded.h>
2121
#include <qpid/dispatch.h>
2222
#include <qpid/dispatch/server.h>
2323
#include <qpid/dispatch/ctools.h>

qpid/extras/dispatch/src/py/config/parser.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
##
1919

2020
import json
21-
from schema import config_schema
21+
from schema import config_schema
22+
from dispatch import LogAdapter, LOG_TRACE, LOG_ERROR, LOG_INFO
2223

2324
class Section:
2425
"""
@@ -198,10 +199,12 @@ def __init__(self, path):
198199
self.raw_config = None
199200
self.config = None
200201
self.schema = Schema()
202+
self.log = LogAdapter('config.parser')
201203

202204

203205
def read_file(self):
204206
try:
207+
self.log.log(LOG_INFO, "Reading Configuration File: %s" % self.path)
205208
cfile = open(self.path)
206209
text = cfile.read()
207210
cfile.close()

qpid/extras/dispatch/src/python_embedded.c

Lines changed: 209 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,65 @@
1717
* under the License.
1818
*/
1919

20-
#include "python_embedded.h"
20+
#include <qpid/dispatch/python_embedded.h>
2121
#include <qpid/dispatch/threading.h>
2222
#include <qpid/dispatch/log.h>
2323
#include <qpid/dispatch/amqp.h>
24+
#include <qpid/dispatch/alloc.h>
25+
26+
27+
//===============================================================================
28+
// Control Functions
29+
//===============================================================================
2430

2531
static uint32_t ref_count = 0;
2632
static sys_mutex_t *lock = 0;
2733
static char *log_module = "PYTHON";
2834

35+
static void dx_python_setup();
36+
37+
38+
void dx_python_initialize()
39+
{
40+
lock = sys_mutex();
41+
}
42+
43+
44+
void dx_python_finalize()
45+
{
46+
assert(ref_count == 0);
47+
sys_mutex_free(lock);
48+
}
49+
50+
51+
void dx_python_start()
52+
{
53+
sys_mutex_lock(lock);
54+
if (ref_count == 0) {
55+
Py_Initialize();
56+
dx_python_setup();
57+
dx_log(log_module, LOG_TRACE, "Embedded Python Interpreter Initialized");
58+
}
59+
ref_count++;
60+
sys_mutex_unlock(lock);
61+
}
62+
63+
64+
void dx_python_stop()
65+
{
66+
sys_mutex_lock(lock);
67+
ref_count--;
68+
if (ref_count == 0) {
69+
Py_Finalize();
70+
dx_log(log_module, LOG_TRACE, "Embedded Python Interpreter Shut Down");
71+
}
72+
sys_mutex_unlock(lock);
73+
}
74+
75+
76+
//===============================================================================
77+
// Data Conversion Functions
78+
//===============================================================================
2979

3080
static PyObject *parsed_to_py_string(dx_parsed_field_t *field)
3181
{
@@ -67,43 +117,6 @@ static PyObject *parsed_to_py_string(dx_parsed_field_t *field)
67117
}
68118

69119

70-
void dx_python_initialize()
71-
{
72-
lock = sys_mutex();
73-
}
74-
75-
76-
void dx_python_finalize()
77-
{
78-
assert(ref_count == 0);
79-
sys_mutex_free(lock);
80-
}
81-
82-
83-
void dx_python_start()
84-
{
85-
sys_mutex_lock(lock);
86-
if (ref_count == 0) {
87-
Py_Initialize();
88-
dx_log(log_module, LOG_TRACE, "Embedded Python Interpreter Initialized");
89-
}
90-
ref_count++;
91-
sys_mutex_unlock(lock);
92-
}
93-
94-
95-
void dx_python_stop()
96-
{
97-
sys_mutex_lock(lock);
98-
ref_count--;
99-
if (ref_count == 0) {
100-
Py_Finalize();
101-
dx_log(log_module, LOG_TRACE, "Embedded Python Interpreter Shut Down");
102-
}
103-
sys_mutex_unlock(lock);
104-
}
105-
106-
107120
void dx_py_to_composed(PyObject *value, dx_composed_field_t *field)
108121
{
109122
if (PyBool_Check(value))
@@ -255,3 +268,161 @@ PyObject *dx_field_to_py(dx_parsed_field_t *field)
255268
return result;
256269
}
257270

271+
272+
//===============================================================================
273+
// Logging Object
274+
//===============================================================================
275+
276+
typedef struct {
277+
PyObject_HEAD
278+
PyObject *module_name;
279+
} LogAdapter;
280+
281+
282+
static int LogAdapter_init(LogAdapter *self, PyObject *args, PyObject *kwds)
283+
{
284+
const char *text;
285+
if (!PyArg_ParseTuple(args, "s", &text))
286+
return -1;
287+
288+
self->module_name = PyString_FromString(text);
289+
return 0;
290+
}
291+
292+
293+
static void LogAdapter_dealloc(LogAdapter* self)
294+
{
295+
Py_XDECREF(self->module_name);
296+
self->ob_type->tp_free((PyObject*)self);
297+
}
298+
299+
300+
static PyObject* dx_python_log(PyObject *self, PyObject *args)
301+
{
302+
int level;
303+
const char* text;
304+
305+
if (!PyArg_ParseTuple(args, "is", &level, &text))
306+
return 0;
307+
308+
LogAdapter *self_ptr = (LogAdapter*) self;
309+
char *logmod = PyString_AS_STRING(self_ptr->module_name);
310+
311+
dx_log(logmod, level, text);
312+
313+
Py_INCREF(Py_None);
314+
return Py_None;
315+
}
316+
317+
318+
static PyMethodDef LogAdapter_methods[] = {
319+
{"log", dx_python_log, METH_VARARGS, "Emit a Log Line"},
320+
{0, 0, 0, 0}
321+
};
322+
323+
static PyMethodDef empty_methods[] = {
324+
{0, 0, 0, 0}
325+
};
326+
327+
static PyTypeObject LogAdapterType = {
328+
PyObject_HEAD_INIT(0)
329+
0, /* ob_size*/
330+
"dispatch.LogAdapter", /* tp_name*/
331+
sizeof(LogAdapter), /* tp_basicsize*/
332+
0, /* tp_itemsize*/
333+
(destructor)LogAdapter_dealloc, /* tp_dealloc*/
334+
0, /* tp_print*/
335+
0, /* tp_getattr*/
336+
0, /* tp_setattr*/
337+
0, /* tp_compare*/
338+
0, /* tp_repr*/
339+
0, /* tp_as_number*/
340+
0, /* tp_as_sequence*/
341+
0, /* tp_as_mapping*/
342+
0, /* tp_hash */
343+
0, /* tp_call*/
344+
0, /* tp_str*/
345+
0, /* tp_getattro*/
346+
0, /* tp_setattro*/
347+
0, /* tp_as_buffer*/
348+
Py_TPFLAGS_DEFAULT, /* tp_flags*/
349+
"Dispatch Log Adapter", /* tp_doc */
350+
0, /* tp_traverse */
351+
0, /* tp_clear */
352+
0, /* tp_richcompare */
353+
0, /* tp_weaklistoffset */
354+
0, /* tp_iter */
355+
0, /* tp_iternext */
356+
LogAdapter_methods, /* tp_methods */
357+
0, /* tp_members */
358+
0, /* tp_getset */
359+
0, /* tp_base */
360+
0, /* tp_dict */
361+
0, /* tp_descr_get */
362+
0, /* tp_descr_set */
363+
0, /* tp_dictoffset */
364+
(initproc)LogAdapter_init, /* tp_init */
365+
0, /* tp_alloc */
366+
0, /* tp_new */
367+
0, /* tp_free */
368+
0, /* tp_is_gc */
369+
0, /* tp_bases */
370+
0, /* tp_mro */
371+
0, /* tp_cache */
372+
0, /* tp_subclasses */
373+
0, /* tp_weaklist */
374+
0, /* tp_del */
375+
0 /* tp_version_tag */
376+
};
377+
378+
379+
//===============================================================================
380+
// Message IO Object
381+
//===============================================================================
382+
383+
typedef struct dx_python_io_adapter {
384+
int x;
385+
} dx_python_io_adapter;
386+
387+
ALLOC_DECLARE(dx_python_io_adapter);
388+
ALLOC_DEFINE(dx_python_io_adapter);
389+
390+
//static PyObject* dx_python_send(PyObject *self, PyObject *args)
391+
//{
392+
// return 0;
393+
//}
394+
395+
396+
//===============================================================================
397+
// Initialization of Modules and Types
398+
//===============================================================================
399+
400+
static void dx_python_setup()
401+
{
402+
//
403+
// Add LogAdapter
404+
//
405+
LogAdapterType.tp_new = PyType_GenericNew;
406+
if (PyType_Ready(&LogAdapterType) < 0) {
407+
PyErr_Print();
408+
dx_log(log_module, LOG_ERROR, "Unable to initialize LogAdapter");
409+
assert(0);
410+
} else {
411+
PyObject *m = Py_InitModule3("dispatch", empty_methods, "Dispatch Adapter Module");
412+
413+
Py_INCREF(&LogAdapterType);
414+
PyModule_AddObject(m, "LogAdapter", (PyObject*) &LogAdapterType);
415+
416+
PyObject *LogTrace = PyInt_FromLong((long) LOG_TRACE);
417+
Py_INCREF(LogTrace);
418+
PyModule_AddObject(m, "LOG_TRACE", LogTrace);
419+
420+
PyObject *LogError = PyInt_FromLong((long) LOG_ERROR);
421+
Py_INCREF(LogError);
422+
PyModule_AddObject(m, "LOG_ERROR", LogError);
423+
424+
PyObject *LogInfo = PyInt_FromLong((long) LOG_INFO);
425+
Py_INCREF(LogInfo);
426+
PyModule_AddObject(m, "LOG_INFO", LogInfo);
427+
}
428+
}

0 commit comments

Comments
 (0)