zone_loader_python.cc 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. // Enable this if you use s# variants with PyArg_ParseTuple(), see
  15. // http://docs.python.org/py3k/c-api/arg.html#strings-and-buffers
  16. //#define PY_SSIZE_T_CLEAN
  17. // Python.h needs to be placed at the head of the program file, see:
  18. // http://docs.python.org/py3k/extending/extending.html#a-simple-example
  19. #include <Python.h>
  20. #include <util/python/pycppwrapper_util.h>
  21. #include <datasrc/zone_loader.h>
  22. #include <dns/python/name_python.h>
  23. #include <dns/python/pydnspp_common.h>
  24. #include <exceptions/exceptions.h>
  25. #include "client_python.h"
  26. #include "datasrc.h"
  27. #include "zone_loader_inc.cc"
  28. using namespace std;
  29. using namespace isc::dns::python;
  30. using namespace isc::datasrc;
  31. using namespace isc::datasrc::python;
  32. namespace {
  33. // The s_* Class simply covers one instantiation of the object
  34. class s_ZoneLoader : public PyObject {
  35. public:
  36. s_ZoneLoader() : cppobj(NULL), client(NULL) {};
  37. ZoneLoader* cppobj;
  38. // a zoneloader should not survive its associated client,
  39. // so add a ref to it at init
  40. PyObject* client;
  41. };
  42. // General creation and destruction
  43. int
  44. ZoneLoader_init(PyObject* po_self, PyObject* args, PyObject*) {
  45. s_ZoneLoader* self = static_cast<s_ZoneLoader*>(po_self);
  46. PyObject *po_target_client = NULL;
  47. PyObject *po_source_client = NULL;
  48. PyObject *po_name = NULL;
  49. char* master_file;
  50. if (!PyArg_ParseTuple(args, "O!O!s", &datasourceclient_type,
  51. &po_target_client, &name_type, &po_name,
  52. &master_file) &&
  53. !PyArg_ParseTuple(args, "O!O!O!", &datasourceclient_type,
  54. &po_target_client, &name_type, &po_name,
  55. &datasourceclient_type, &po_source_client)
  56. ) {
  57. return (-1);
  58. }
  59. PyErr_Clear();
  60. try {
  61. Py_INCREF(po_target_client);
  62. self->client = po_target_client;
  63. if (po_source_client != NULL) {
  64. self->cppobj = new ZoneLoader(
  65. PyDataSourceClient_ToDataSourceClient(po_target_client),
  66. PyName_ToName(po_name),
  67. PyDataSourceClient_ToDataSourceClient(po_source_client));
  68. } else {
  69. self->cppobj = new ZoneLoader(
  70. PyDataSourceClient_ToDataSourceClient(po_target_client),
  71. PyName_ToName(po_name),
  72. master_file);
  73. }
  74. return (0);
  75. } catch (const isc::InvalidParameter& ivp) {
  76. PyErr_SetString(po_InvalidParameter, ivp.what());
  77. } catch (const isc::datasrc::DataSourceError& dse) {
  78. PyErr_SetString(getDataSourceException("Error"), dse.what());
  79. } catch (const isc::NotImplemented& ni) {
  80. PyErr_SetString(getDataSourceException("NotImplemented"), ni.what());
  81. } catch (const std::exception& stde) {
  82. PyErr_SetString(getDataSourceException("Error"), stde.what());
  83. } catch (...) {
  84. PyErr_SetString(getDataSourceException("Error"),
  85. "Unexpected exception");
  86. }
  87. return (-1);
  88. }
  89. void
  90. ZoneLoader_destroy(PyObject* po_self) {
  91. s_ZoneLoader* self = static_cast<s_ZoneLoader*>(po_self);
  92. delete self->cppobj;
  93. self->cppobj = NULL;
  94. if (self->client != NULL) {
  95. Py_DECREF(self->client);
  96. }
  97. Py_TYPE(self)->tp_free(self);
  98. }
  99. PyObject* ZoneLoader_load(PyObject* po_self, PyObject*) {
  100. s_ZoneLoader* self = static_cast<s_ZoneLoader*>(po_self);
  101. try {
  102. self->cppobj->load();
  103. Py_RETURN_NONE;
  104. } catch (const isc::InvalidOperation& ivo) {
  105. PyErr_SetString(po_InvalidOperation, ivo.what());
  106. return (NULL);
  107. } catch (const isc::datasrc::MasterFileError& mfe) {
  108. PyErr_SetString(getDataSourceException("MasterFileError"), mfe.what());
  109. return (NULL);
  110. } catch (const isc::datasrc::DataSourceError& dse) {
  111. PyErr_SetString(getDataSourceException("Error"), dse.what());
  112. return (NULL);
  113. } catch (const std::exception& exc) {
  114. PyErr_SetString(getDataSourceException("Error"), exc.what());
  115. return (NULL);
  116. } catch (...) {
  117. PyErr_SetString(getDataSourceException("Error"),
  118. "Unexpected exception");
  119. return (NULL);
  120. }
  121. }
  122. PyObject* ZoneLoader_loadIncremental(PyObject* po_self, PyObject* args) {
  123. s_ZoneLoader* self = static_cast<s_ZoneLoader*>(po_self);
  124. int limit;
  125. if (!PyArg_ParseTuple(args, "i", &limit)) {
  126. return (NULL);
  127. }
  128. if (limit < 0) {
  129. PyErr_SetString(PyExc_ValueError,
  130. "load_incremental argument must be positive");
  131. return (NULL);
  132. }
  133. try {
  134. const bool complete = self->cppobj->loadIncremental(limit);
  135. if (complete) {
  136. Py_RETURN_TRUE;
  137. } else {
  138. Py_RETURN_FALSE;
  139. }
  140. } catch (const isc::InvalidOperation& ivo) {
  141. PyErr_SetString(po_InvalidOperation, ivo.what());
  142. return (NULL);
  143. } catch (const isc::datasrc::MasterFileError& mfe) {
  144. PyErr_SetString(getDataSourceException("MasterFileError"), mfe.what());
  145. return (NULL);
  146. } catch (const isc::datasrc::DataSourceError& dse) {
  147. PyErr_SetString(getDataSourceException("Error"), dse.what());
  148. return (NULL);
  149. } catch (const std::exception& exc) {
  150. PyErr_SetString(getDataSourceException("Error"), exc.what());
  151. return (NULL);
  152. } catch (...) {
  153. PyErr_SetString(getDataSourceException("Error"),
  154. "Unexpected exception");
  155. return (NULL);
  156. }
  157. }
  158. // This list contains the actual set of functions we have in
  159. // python. Each entry has
  160. // 1. Python method name
  161. // 2. Our static function here
  162. // 3. Argument type
  163. // 4. Documentation
  164. PyMethodDef ZoneLoader_methods[] = {
  165. { "load", ZoneLoader_load, METH_NOARGS, ZoneLoader_load_doc },
  166. { "load_incremental", ZoneLoader_loadIncremental, METH_VARARGS,
  167. ZoneLoader_loadIncremental_doc },
  168. { NULL, NULL, 0, NULL }
  169. };
  170. } // end of unnamed namespace
  171. namespace isc {
  172. namespace datasrc {
  173. namespace python {
  174. PyTypeObject zone_loader_type = {
  175. PyVarObject_HEAD_INIT(NULL, 0)
  176. "datasrc.ZoneLoader",
  177. sizeof(s_ZoneLoader), // tp_basicsize
  178. 0, // tp_itemsize
  179. ZoneLoader_destroy, // tp_dealloc
  180. NULL, // tp_print
  181. NULL, // tp_getattr
  182. NULL, // tp_setattr
  183. NULL, // tp_reserved
  184. NULL, // tp_repr
  185. NULL, // tp_as_number
  186. NULL, // tp_as_sequence
  187. NULL, // tp_as_mapping
  188. NULL, // tp_hash
  189. NULL, // tp_call
  190. NULL, // tp_str
  191. NULL, // tp_getattro
  192. NULL, // tp_setattro
  193. NULL, // tp_as_buffer
  194. Py_TPFLAGS_DEFAULT, // tp_flags
  195. ZoneLoader_doc,
  196. NULL, // tp_traverse
  197. NULL, // tp_clear
  198. NULL, // tp_richcompare
  199. 0, // tp_weaklistoffset
  200. NULL, // tp_iter
  201. NULL, // tp_iternext
  202. ZoneLoader_methods, // tp_methods
  203. NULL, // tp_members
  204. NULL, // tp_getset
  205. NULL, // tp_base
  206. NULL, // tp_dict
  207. NULL, // tp_descr_get
  208. NULL, // tp_descr_set
  209. 0, // tp_dictoffset
  210. ZoneLoader_init, // tp_init
  211. NULL, // tp_alloc
  212. PyType_GenericNew, // tp_new
  213. NULL, // tp_free
  214. NULL, // tp_is_gc
  215. NULL, // tp_bases
  216. NULL, // tp_mro
  217. NULL, // tp_cache
  218. NULL, // tp_subclasses
  219. NULL, // tp_weaklist
  220. NULL, // tp_del
  221. 0 // tp_version_tag
  222. };
  223. } // namespace python
  224. } // namespace datasrc
  225. } // namespace isc