blob: 077e4a44377f57acfd37d84981e919a841fd888d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <qpid/dispatch/python_embedded.h>
#include "config_private.h"
#include <qpid/dispatch/alloc.h>
#include <qpid/dispatch/log.h>
#define PYTHON_MODULE "qpid_dispatch_internal.config"
static const char *log_module = "CONFIG";
struct qd_config_t {
PyObject *pModule;
PyObject *pClass;
PyObject *pObject;
};
ALLOC_DECLARE(qd_config_t);
ALLOC_DEFINE(qd_config_t);
void qd_config_initialize()
{
qd_python_start();
}
void qd_config_finalize()
{
qd_python_stop();
}
qd_config_t *qd_config(const char *filename)
{
qd_config_t *config = new_qd_config_t();
//
// Load the Python configuration module and get a reference to the config class.
//
PyObject *pName = PyString_FromString(PYTHON_MODULE);
config->pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (!config->pModule) {
PyErr_Print();
free_qd_config_t(config);
qd_log(log_module, LOG_ERROR, "Unable to load configuration module: %s", PYTHON_MODULE);
return 0;
}
config->pClass = PyObject_GetAttrString(config->pModule, "DispatchConfig");
if (!config->pClass || !PyClass_Check(config->pClass)) {
PyErr_Print();
Py_DECREF(config->pModule);
free_qd_config_t(config);
qd_log(log_module, LOG_ERROR, "Problem with configuration module: Missing DispatchConfig class");
return 0;
}
//
// Instantiate the DispatchConfig class, passing in the configuration file name.
//
PyObject *pArgs = PyTuple_New(1);
PyObject *fname = PyString_FromString(filename);
PyTuple_SetItem(pArgs, 0, fname);
config->pObject = PyInstance_New(config->pClass, pArgs, 0);
Py_DECREF(pArgs);
if (config->pObject == 0) {
PyErr_Print();
Py_DECREF(config->pModule);
free_qd_config_t(config);
qd_log(log_module, LOG_ERROR, "Configuration file '%s' could not be read", filename);
return 0;
}
return config;
}
void qd_config_read(qd_config_t *config)
{
PyObject *pMethod;
PyObject *pArgs;
PyObject *pResult;
if (!config)
return;
pMethod = PyObject_GetAttrString(config->pObject, "read_file");
if (!pMethod || !PyCallable_Check(pMethod)) {
qd_log(log_module, LOG_ERROR, "Problem with configuration module: No callable 'item_count'");
if (pMethod) {
Py_DECREF(pMethod);
}
return;
}
pArgs = PyTuple_New(0);
pResult = PyObject_CallObject(pMethod, pArgs);
Py_DECREF(pArgs);
if (pResult) {
Py_DECREF(pResult);
} else {
PyErr_Print();
}
Py_DECREF(pMethod);
}
void qd_config_free(qd_config_t *config)
{
if (config) {
Py_DECREF(config->pClass);
Py_DECREF(config->pModule);
free_qd_config_t(config);
}
}
int qd_config_item_count(const qd_config_t *config, const char *section)
{
PyObject *pSection;
PyObject *pMethod;
PyObject *pArgs;
PyObject *pResult;
int result = 0;
if (!config)
return 0;
pMethod = PyObject_GetAttrString(config->pObject, "item_count");
if (!pMethod || !PyCallable_Check(pMethod)) {
qd_log(log_module, LOG_ERROR, "Problem with configuration module: No callable 'item_count'");
if (pMethod) {
Py_DECREF(pMethod);
}
return 0;
}
pSection = PyString_FromString(section);
pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs, 0, pSection);
pResult = PyObject_CallObject(pMethod, pArgs);
Py_DECREF(pArgs);
if (pResult && PyInt_Check(pResult))
result = (int) PyInt_AsLong(pResult);
if (pResult) {
Py_DECREF(pResult);
}
Py_DECREF(pMethod);
return result;
}
static PyObject *item_value(const qd_config_t *config, const char *section, int index, const char* key, const char* method)
{
PyObject *pSection;
PyObject *pIndex;
PyObject *pKey;
PyObject *pMethod;
PyObject *pArgs;
PyObject *pResult;
if (!config)
return 0;
pMethod = PyObject_GetAttrString(config->pObject, method);
if (!pMethod || !PyCallable_Check(pMethod)) {
qd_log(log_module, LOG_ERROR, "Problem with configuration module: No callable '%s'", method);
if (pMethod) {
Py_DECREF(pMethod);
}
return 0;
}
pSection = PyString_FromString(section);
pIndex = PyInt_FromLong((long) index);
pKey = PyString_FromString(key);
pArgs = PyTuple_New(3);
PyTuple_SetItem(pArgs, 0, pSection);
PyTuple_SetItem(pArgs, 1, pIndex);
PyTuple_SetItem(pArgs, 2, pKey);
pResult = PyObject_CallObject(pMethod, pArgs);
Py_DECREF(pArgs);
Py_DECREF(pMethod);
return pResult;
}
const char *qd_config_item_value_string(const qd_config_t *config, const char *section, int index, const char* key)
{
PyObject *pResult = item_value(config, section, index, key, "value_string");
char *value = 0;
if (pResult && PyString_Check(pResult)) {
Py_ssize_t size = PyString_Size(pResult);
value = (char*) malloc(size + 1);
strncpy(value, PyString_AsString(pResult), size + 1);
}
if (pResult) {
Py_DECREF(pResult);
}
return value;
}
uint32_t qd_config_item_value_int(const qd_config_t *config, const char *section, int index, const char* key)
{
PyObject *pResult = item_value(config, section, index, key, "value_int");
uint32_t value = 0;
if (pResult && PyLong_Check(pResult))
value = (uint32_t) PyLong_AsLong(pResult);
if (pResult) {
Py_DECREF(pResult);
}
return value;
}
int qd_config_item_value_bool(const qd_config_t *config, const char *section, int index, const char* key)
{
PyObject *pResult = item_value(config, section, index, key, "value_bool");
int value = 0;
if (pResult && pResult != Py_None)
value = 1;
if (pResult) {
Py_DECREF(pResult);
}
return value;
}