From f21dc7edfb5b0bdbc2b7aaffd65de0ac07ac8723 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi <soltanmm@users.noreply.github.com> Date: Fri, 20 Nov 2015 19:28:41 -0800 Subject: [PATCH] Migrate to Cython --- src/python/grpcio/grpc/_adapter/_c/module.c | 67 --- src/python/grpcio/grpc/_adapter/_c/types.c | 61 -- src/python/grpcio/grpc/_adapter/_c/types.h | 286 ---------- .../grpcio/grpc/_adapter/_c/types/call.c | 186 ------- .../grpc/_adapter/_c/types/call_credentials.c | 203 ------- .../grpcio/grpc/_adapter/_c/types/channel.c | 187 ------- .../_adapter/_c/types/channel_credentials.c | 165 ------ .../grpc/_adapter/_c/types/completion_queue.c | 124 ----- .../grpcio/grpc/_adapter/_c/types/server.c | 196 ------- .../_adapter/_c/types/server_credentials.c | 137 ----- src/python/grpcio/grpc/_adapter/_c/utility.c | 524 ------------------ .../grpcio/grpc/_adapter/_intermediary_low.py | 26 +- src/python/grpcio/grpc/_adapter/_low.py | 134 ++++- src/python/grpcio/grpc/_adapter/_types.py | 94 ++-- src/python/grpcio/setup.py | 23 +- .../grpcio/tests/unit/_adapter/_c_test.py | 55 -- .../unit/_adapter/_intermediary_low_test.py | 14 +- .../grpcio/tests/unit/_adapter/_low_test.py | 8 +- 18 files changed, 183 insertions(+), 2307 deletions(-) delete mode 100644 src/python/grpcio/grpc/_adapter/_c/module.c delete mode 100644 src/python/grpcio/grpc/_adapter/_c/types.c delete mode 100644 src/python/grpcio/grpc/_adapter/_c/types.h delete mode 100644 src/python/grpcio/grpc/_adapter/_c/types/call.c delete mode 100644 src/python/grpcio/grpc/_adapter/_c/types/call_credentials.c delete mode 100644 src/python/grpcio/grpc/_adapter/_c/types/channel.c delete mode 100644 src/python/grpcio/grpc/_adapter/_c/types/channel_credentials.c delete mode 100644 src/python/grpcio/grpc/_adapter/_c/types/completion_queue.c delete mode 100644 src/python/grpcio/grpc/_adapter/_c/types/server.c delete mode 100644 src/python/grpcio/grpc/_adapter/_c/types/server_credentials.c delete mode 100644 src/python/grpcio/grpc/_adapter/_c/utility.c delete mode 100644 src/python/grpcio/tests/unit/_adapter/_c_test.py diff --git a/src/python/grpcio/grpc/_adapter/_c/module.c b/src/python/grpcio/grpc/_adapter/_c/module.c deleted file mode 100644 index 9b93b051f6..0000000000 --- a/src/python/grpcio/grpc/_adapter/_c/module.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include <stdlib.h> - -#define PY_SSIZE_T_CLEAN -#include <Python.h> -#include <grpc/grpc.h> - -#include "grpc/_adapter/_c/types.h" - -static PyMethodDef c_methods[] = { - {NULL} -}; - -PyMODINIT_FUNC init_c(void) { - PyObject *module; - - module = Py_InitModule3("_c", c_methods, - "Wrappings of C structures and functions."); - - if (pygrpc_module_add_types(module) < 0) { - return; - } - - if (PyModule_AddStringConstant( - module, "PRIMARY_USER_AGENT_KEY", - GRPC_ARG_PRIMARY_USER_AGENT_STRING) < 0) { - return; - } - - /* GRPC maintains an internal counter of how many times it has been - initialized and handles multiple pairs of grpc_init()/grpc_shutdown() - invocations accordingly. */ - grpc_init(); - atexit(&grpc_shutdown); -} diff --git a/src/python/grpcio/grpc/_adapter/_c/types.c b/src/python/grpcio/grpc/_adapter/_c/types.c deleted file mode 100644 index 8dedf5902b..0000000000 --- a/src/python/grpcio/grpc/_adapter/_c/types.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "grpc/_adapter/_c/types.h" - -#define PY_SSIZE_T_CLEAN -#include <Python.h> -#include <grpc/grpc.h> - -int pygrpc_module_add_types(PyObject *module) { - int i; - PyTypeObject *types[] = { - &pygrpc_CallCredentials_type, - &pygrpc_ChannelCredentials_type, - &pygrpc_ServerCredentials_type, - &pygrpc_CompletionQueue_type, - &pygrpc_Call_type, - &pygrpc_Channel_type, - &pygrpc_Server_type - }; - for (i = 0; i < sizeof(types)/sizeof(PyTypeObject *); ++i) { - if (PyType_Ready(types[i]) < 0) { - return -1; - } - } - for (i = 0; i < sizeof(types)/sizeof(PyTypeObject *); ++i) { - Py_INCREF(types[i]); - PyModule_AddObject(module, types[i]->tp_name, (PyObject *)types[i]); - } - return 0; -} diff --git a/src/python/grpcio/grpc/_adapter/_c/types.h b/src/python/grpcio/grpc/_adapter/_c/types.h deleted file mode 100644 index 9ab415d216..0000000000 --- a/src/python/grpcio/grpc/_adapter/_c/types.h +++ /dev/null @@ -1,286 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef GRPC__ADAPTER__C_TYPES_H_ -#define GRPC__ADAPTER__C_TYPES_H_ - -#define PY_SSIZE_T_CLEAN -#include <Python.h> -#include <grpc/grpc.h> -#include <grpc/grpc_security.h> - - -/*=========================*/ -/* Client-side credentials */ -/*=========================*/ - -typedef struct ChannelCredentials { - PyObject_HEAD - grpc_channel_credentials *c_creds; -} ChannelCredentials; -void pygrpc_ChannelCredentials_dealloc(ChannelCredentials *self); -ChannelCredentials *pygrpc_ChannelCredentials_google_default( - PyTypeObject *type, PyObject *ignored); -ChannelCredentials *pygrpc_ChannelCredentials_ssl( - PyTypeObject *type, PyObject *args, PyObject *kwargs); -ChannelCredentials *pygrpc_ChannelCredentials_composite( - PyTypeObject *type, PyObject *args, PyObject *kwargs); -extern PyTypeObject pygrpc_ChannelCredentials_type; - -typedef struct CallCredentials { - PyObject_HEAD - grpc_call_credentials *c_creds; -} CallCredentials; -void pygrpc_CallCredentials_dealloc(CallCredentials *self); -CallCredentials *pygrpc_CallCredentials_composite( - PyTypeObject *type, PyObject *args, PyObject *kwargs); -CallCredentials *pygrpc_CallCredentials_compute_engine( - PyTypeObject *type, PyObject *ignored); -CallCredentials *pygrpc_CallCredentials_jwt( - PyTypeObject *type, PyObject *args, PyObject *kwargs); -CallCredentials *pygrpc_CallCredentials_refresh_token( - PyTypeObject *type, PyObject *args, PyObject *kwargs); -CallCredentials *pygrpc_CallCredentials_iam( - PyTypeObject *type, PyObject *args, PyObject *kwargs); -extern PyTypeObject pygrpc_CallCredentials_type; - -/*=========================*/ -/* Server-side credentials */ -/*=========================*/ - -typedef struct ServerCredentials { - PyObject_HEAD - grpc_server_credentials *c_creds; -} ServerCredentials; -void pygrpc_ServerCredentials_dealloc(ServerCredentials *self); -ServerCredentials *pygrpc_ServerCredentials_ssl( - PyTypeObject *type, PyObject *args, PyObject *kwargs); -extern PyTypeObject pygrpc_ServerCredentials_type; - - -/*==================*/ -/* Completion queue */ -/*==================*/ - -typedef struct CompletionQueue { - PyObject_HEAD - grpc_completion_queue *c_cq; -} CompletionQueue; -CompletionQueue *pygrpc_CompletionQueue_new( - PyTypeObject *type, PyObject *args, PyObject *kwargs); -void pygrpc_CompletionQueue_dealloc(CompletionQueue *self); -PyObject *pygrpc_CompletionQueue_next( - CompletionQueue *self, PyObject *args, PyObject *kwargs); -PyObject *pygrpc_CompletionQueue_shutdown( - CompletionQueue *self, PyObject *ignored); -extern PyTypeObject pygrpc_CompletionQueue_type; - - -/*======*/ -/* Call */ -/*======*/ - -typedef struct Call { - PyObject_HEAD - grpc_call *c_call; - CompletionQueue *cq; -} Call; -Call *pygrpc_Call_new_empty(CompletionQueue *cq); -void pygrpc_Call_dealloc(Call *self); -PyObject *pygrpc_Call_start_batch(Call *self, PyObject *args, PyObject *kwargs); -PyObject *pygrpc_Call_cancel(Call *self, PyObject *args, PyObject *kwargs); -PyObject *pygrpc_Call_peer(Call *self); -PyObject *pygrpc_Call_set_credentials(Call *self, PyObject *args, - PyObject *kwargs); -extern PyTypeObject pygrpc_Call_type; - - -/*=========*/ -/* Channel */ -/*=========*/ - -typedef struct Channel { - PyObject_HEAD - grpc_channel *c_chan; -} Channel; -Channel *pygrpc_Channel_new( - PyTypeObject *type, PyObject *args, PyObject *kwargs); -void pygrpc_Channel_dealloc(Channel *self); -Call *pygrpc_Channel_create_call( - Channel *self, PyObject *args, PyObject *kwargs); -PyObject *pygrpc_Channel_check_connectivity_state(Channel *self, PyObject *args, - PyObject *kwargs); -PyObject *pygrpc_Channel_watch_connectivity_state(Channel *self, PyObject *args, - PyObject *kwargs); -PyObject *pygrpc_Channel_target(Channel *self); -extern PyTypeObject pygrpc_Channel_type; - - -/*========*/ -/* Server */ -/*========*/ - -typedef struct Server { - PyObject_HEAD - grpc_server *c_serv; - CompletionQueue *cq; - int shutdown_called; -} Server; -Server *pygrpc_Server_new(PyTypeObject *type, PyObject *args, PyObject *kwargs); -void pygrpc_Server_dealloc(Server *self); -PyObject *pygrpc_Server_request_call( - Server *self, PyObject *args, PyObject *kwargs); -PyObject *pygrpc_Server_add_http2_port( - Server *self, PyObject *args, PyObject *kwargs); -PyObject *pygrpc_Server_start(Server *self, PyObject *ignored); -PyObject *pygrpc_Server_shutdown( - Server *self, PyObject *args, PyObject *kwargs); -PyObject *pygrpc_Server_cancel_all_calls(Server *self, PyObject *unused); -extern PyTypeObject pygrpc_Server_type; - -/*=========*/ -/* Utility */ -/*=========*/ - -/* Every tag that passes from Python GRPC to GRPC core is of this type. */ -typedef struct pygrpc_tag { - PyObject *user_tag; - Call *call; - grpc_call_details request_call_details; - grpc_metadata_array request_metadata; - grpc_op *ops; - size_t nops; - int is_new_call; -} pygrpc_tag; - -/* Construct a tag associated with a batch call. Does not take ownership of the - resources in the elements of ops. */ -pygrpc_tag *pygrpc_produce_batch_tag(PyObject *user_tag, Call *call, - grpc_op *ops, size_t nops); - - -/* Construct a tag associated with a server request. The calling code should - use the appropriate fields of the produced tag in the invocation of - grpc_server_request_call. */ -pygrpc_tag *pygrpc_produce_request_tag(PyObject *user_tag, Call *empty_call); - -/* Construct a tag associated with a server shutdown. */ -pygrpc_tag *pygrpc_produce_server_shutdown_tag(PyObject *user_tag); - -/* Construct a tag associated with a channel state change. */ -pygrpc_tag *pygrpc_produce_channel_state_change_tag(PyObject *user_tag); - -/* Frees all resources owned by the tag and the tag itself. */ -void pygrpc_discard_tag(pygrpc_tag *tag); - -/* Consumes an event and its associated tag, providing a Python tuple of the - form `(type, tag, call, call_details, results)` (where type is an integer - corresponding to a grpc_completion_type, tag is an arbitrary PyObject, call - is the call object associated with the event [if any], call_details is a - tuple of form `(method, host, deadline)` [if such details are available], - and resultd is a list of tuples of form `(type, metadata, message, status, - cancelled)` [where type corresponds to a grpc_op_type, metadata is a - sequence of 2-sequences of strings, message is a byte string, and status is - a 2-tuple of an integer corresponding to grpc_status_code and a string of - status details]). - - Frees all resources associated with the event tag. */ -PyObject *pygrpc_consume_event(grpc_event event); - -/* Transliterate the Python tuple of form `(type, metadata, message, - status)` (where type is an integer corresponding to a grpc_op_type, metadata - is a sequence of 2-sequences of strings, message is a byte string, and - status is 2-tuple of an integer corresponding to grpc_status_code and a - string of status details) to a grpc_op suitable for use in a - grpc_call_start_batch invocation. The grpc_op is a 'directory' of resources - that must be freed after GRPC core is done with them. - - Calls gpr_malloc (or the appropriate type-specific grpc_*_create function) - to populate the appropriate union-discriminated members of the op. - - Returns true on success, false on failure. */ -int pygrpc_produce_op(PyObject *op, grpc_op *result); - -/* Discards all resources associated with the passed in op that was produced by - pygrpc_produce_op. */ -void pygrpc_discard_op(grpc_op op); - -/* Transliterate the grpc_ops (which have been sent through a - grpc_call_start_batch invocation and whose corresponding event has appeared - on a completion queue) to a Python tuple of form `(type, metadata, message, - status, cancelled)` (where type is an integer corresponding to a - grpc_op_type, metadata is a sequence of 2-sequences of strings, message is a - byte string, and status is 2-tuple of an integer corresponding to - grpc_status_code and a string of status details). - - Calls gpr_free (or the appropriate type-specific grpc_*_destroy function) on - the appropriate union-discriminated populated members of the ops. */ -PyObject *pygrpc_consume_ops(grpc_op *op, size_t nops); - -/* Transliterate from a gpr_timespec to a double (in units of seconds, either - from the epoch if interpreted absolutely or as a delta otherwise). */ -double pygrpc_cast_gpr_timespec_to_double(gpr_timespec timespec); - -/* Transliterate from a double (in units of seconds from the epoch if - interpreted absolutely or as a delta otherwise) to a gpr_timespec. */ -gpr_timespec pygrpc_cast_double_to_gpr_timespec(double seconds); - -/* Returns true on success, false on failure. */ -int pygrpc_cast_pyseq_to_send_metadata( - PyObject *pyseq, grpc_metadata **metadata, size_t *count); -/* Returns a metadata array as a Python object on success, else NULL. */ -PyObject *pygrpc_cast_metadata_array_to_pyseq(grpc_metadata_array metadata); - -/* Transliterate from a list of python channel arguments (2-tuples of string - and string|integer|None) to a grpc_channel_args object. The strings placed - in the grpc_channel_args object's grpc_arg elements are views of the Python - object. The Python object must live long enough for the grpc_channel_args - to be used. Arguments set to None are silently ignored. Returns true on - success, false on failure. */ -int pygrpc_produce_channel_args(PyObject *py_args, grpc_channel_args *c_args); -void pygrpc_discard_channel_args(grpc_channel_args args); - -/* Read the bytes from grpc_byte_buffer to a gpr_malloc'd array of bytes; - output to result and result_size. */ -void pygrpc_byte_buffer_to_bytes( - grpc_byte_buffer *buffer, char **result, size_t *result_size); - - -/*========*/ -/* Module */ -/*========*/ - -/* Returns 0 on success, -1 on failure. */ -int pygrpc_module_add_types(PyObject *module); - -#endif /* GRPC__ADAPTER__C_TYPES_H_ */ diff --git a/src/python/grpcio/grpc/_adapter/_c/types/call.c b/src/python/grpcio/grpc/_adapter/_c/types/call.c deleted file mode 100644 index 04ec871880..0000000000 --- a/src/python/grpcio/grpc/_adapter/_c/types/call.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "grpc/_adapter/_c/types.h" - -#define PY_SSIZE_T_CLEAN -#include <Python.h> -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> - - -PyMethodDef pygrpc_Call_methods[] = { - {"start_batch", (PyCFunction)pygrpc_Call_start_batch, METH_KEYWORDS, ""}, - {"cancel", (PyCFunction)pygrpc_Call_cancel, METH_KEYWORDS, ""}, - {"peer", (PyCFunction)pygrpc_Call_peer, METH_NOARGS, ""}, - {"set_credentials", (PyCFunction)pygrpc_Call_set_credentials, METH_KEYWORDS, - ""}, - {NULL} -}; -const char pygrpc_Call_doc[] = "See grpc._adapter._types.Call."; -PyTypeObject pygrpc_Call_type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "Call", /* tp_name */ - sizeof(Call), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pygrpc_Call_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - pygrpc_Call_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - pygrpc_Call_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0 /* tp_new */ -}; - -Call *pygrpc_Call_new_empty(CompletionQueue *cq) { - Call *call = (Call *)pygrpc_Call_type.tp_alloc(&pygrpc_Call_type, 0); - call->c_call = NULL; - call->cq = cq; - Py_XINCREF(call->cq); - return call; -} -void pygrpc_Call_dealloc(Call *self) { - if (self->c_call) { - grpc_call_destroy(self->c_call); - } - Py_XDECREF(self->cq); - self->ob_type->tp_free((PyObject *)self); -} -PyObject *pygrpc_Call_start_batch(Call *self, PyObject *args, PyObject *kwargs) { - PyObject *op_list; - PyObject *user_tag; - grpc_op *ops; - size_t nops; - size_t i; - size_t j; - pygrpc_tag *tag; - grpc_call_error errcode; - static char *keywords[] = {"ops", "tag", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO:start_batch", keywords, - &op_list, &user_tag)) { - return NULL; - } - if (!PyList_Check(op_list)) { - PyErr_SetString(PyExc_TypeError, "expected a list of OpArgs"); - return NULL; - } - nops = PyList_Size(op_list); - ops = gpr_malloc(sizeof(grpc_op) * nops); - for (i = 0; i < nops; ++i) { - PyObject *item = PyList_GET_ITEM(op_list, i); - if (!pygrpc_produce_op(item, &ops[i])) { - for (j = 0; j < i; ++j) { - pygrpc_discard_op(ops[j]); - } - return NULL; - } - } - tag = pygrpc_produce_batch_tag(user_tag, self, ops, nops); - errcode = grpc_call_start_batch(self->c_call, tag->ops, tag->nops, tag, NULL); - gpr_free(ops); - return PyInt_FromLong(errcode); -} -PyObject *pygrpc_Call_cancel(Call *self, PyObject *args, PyObject *kwargs) { - PyObject *py_code = NULL; - grpc_call_error errcode; - int code; - char *details = NULL; - static char *keywords[] = {"code", "details", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Os:start_batch", keywords, - &py_code, &details)) { - return NULL; - } - if (py_code != NULL && details != NULL) { - if (!PyInt_Check(py_code)) { - PyErr_SetString(PyExc_TypeError, "expected integer code"); - return NULL; - } - code = PyInt_AsLong(py_code); - errcode = grpc_call_cancel_with_status(self->c_call, code, details, NULL); - } else if (py_code != NULL || details != NULL) { - PyErr_SetString(PyExc_ValueError, - "if `code` is specified, so must `details`"); - return NULL; - } else { - errcode = grpc_call_cancel(self->c_call, NULL); - } - return PyInt_FromLong(errcode); -} - -PyObject *pygrpc_Call_peer(Call *self) { - char *peer = grpc_call_get_peer(self->c_call); - PyObject *py_peer = PyString_FromString(peer); - gpr_free(peer); - return py_peer; -} -PyObject *pygrpc_Call_set_credentials(Call *self, PyObject *args, - PyObject *kwargs) { - CallCredentials *creds; - grpc_call_error errcode; - static char *keywords[] = {"creds", NULL}; - if (!PyArg_ParseTupleAndKeywords( - args, kwargs, "O!:set_credentials", keywords, - &pygrpc_CallCredentials_type, &creds)) { - return NULL; - } - errcode = grpc_call_set_credentials(self->c_call, creds->c_creds); - return PyInt_FromLong(errcode); -} diff --git a/src/python/grpcio/grpc/_adapter/_c/types/call_credentials.c b/src/python/grpcio/grpc/_adapter/_c/types/call_credentials.c deleted file mode 100644 index 5a15a6e17d..0000000000 --- a/src/python/grpcio/grpc/_adapter/_c/types/call_credentials.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "grpc/_adapter/_c/types.h" - -#define PY_SSIZE_T_CLEAN -#include <Python.h> -#include <grpc/grpc.h> -#include <grpc/grpc_security.h> - - -PyMethodDef pygrpc_CallCredentials_methods[] = { - {"composite", (PyCFunction)pygrpc_CallCredentials_composite, - METH_CLASS|METH_KEYWORDS, ""}, - {"compute_engine", (PyCFunction)pygrpc_CallCredentials_compute_engine, - METH_CLASS|METH_NOARGS, ""}, - {"jwt", (PyCFunction)pygrpc_CallCredentials_jwt, - METH_CLASS|METH_KEYWORDS, ""}, - {"refresh_token", (PyCFunction)pygrpc_CallCredentials_refresh_token, - METH_CLASS|METH_KEYWORDS, ""}, - {"iam", (PyCFunction)pygrpc_CallCredentials_iam, - METH_CLASS|METH_KEYWORDS, ""}, - {NULL} -}; - -const char pygrpc_CallCredentials_doc[] = ""; -PyTypeObject pygrpc_CallCredentials_type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "CallCredentials", /* tp_name */ - sizeof(CallCredentials), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pygrpc_CallCredentials_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - pygrpc_CallCredentials_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - pygrpc_CallCredentials_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0 /* tp_new */ -}; - -void pygrpc_CallCredentials_dealloc(CallCredentials *self) { - grpc_call_credentials_release(self->c_creds); - self->ob_type->tp_free((PyObject *)self); -} - -CallCredentials *pygrpc_CallCredentials_composite( - PyTypeObject *type, PyObject *args, PyObject *kwargs) { - CallCredentials *self; - CallCredentials *creds1; - CallCredentials *creds2; - static char *keywords[] = {"creds1", "creds2", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!:composite", keywords, - &pygrpc_CallCredentials_type, &creds1, - &pygrpc_CallCredentials_type, &creds2)) { - return NULL; - } - self = (CallCredentials *)type->tp_alloc(type, 0); - self->c_creds = - grpc_composite_call_credentials_create( - creds1->c_creds, creds2->c_creds, NULL); - if (!self->c_creds) { - Py_DECREF(self); - PyErr_SetString(PyExc_RuntimeError, "couldn't create composite credentials"); - return NULL; - } - return self; -} - -CallCredentials *pygrpc_CallCredentials_compute_engine( - PyTypeObject *type, PyObject *ignored) { - CallCredentials *self = (CallCredentials *)type->tp_alloc(type, 0); - self->c_creds = grpc_google_compute_engine_credentials_create(NULL); - if (!self->c_creds) { - Py_DECREF(self); - PyErr_SetString(PyExc_RuntimeError, - "couldn't create compute engine credentials"); - return NULL; - } - return self; -} - -/* TODO: Rename this credentials to something like service_account_jwt_access */ -CallCredentials *pygrpc_CallCredentials_jwt( - PyTypeObject *type, PyObject *args, PyObject *kwargs) { - CallCredentials *self; - const char *json_key; - double lifetime; - static char *keywords[] = {"json_key", "token_lifetime", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sd:jwt", keywords, - &json_key, &lifetime)) { - return NULL; - } - self = (CallCredentials *)type->tp_alloc(type, 0); - self->c_creds = grpc_service_account_jwt_access_credentials_create( - json_key, pygrpc_cast_double_to_gpr_timespec(lifetime), NULL); - if (!self->c_creds) { - Py_DECREF(self); - PyErr_SetString(PyExc_RuntimeError, "couldn't create JWT credentials"); - return NULL; - } - return self; -} - -CallCredentials *pygrpc_CallCredentials_refresh_token( - PyTypeObject *type, PyObject *args, PyObject *kwargs) { - CallCredentials *self; - const char *json_refresh_token; - static char *keywords[] = {"json_refresh_token", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:refresh_token", keywords, - &json_refresh_token)) { - return NULL; - } - self = (CallCredentials *)type->tp_alloc(type, 0); - self->c_creds = - grpc_google_refresh_token_credentials_create(json_refresh_token, NULL); - if (!self->c_creds) { - Py_DECREF(self); - PyErr_SetString(PyExc_RuntimeError, - "couldn't create credentials from refresh token"); - return NULL; - } - return self; -} - -CallCredentials *pygrpc_CallCredentials_iam( - PyTypeObject *type, PyObject *args, PyObject *kwargs) { - CallCredentials *self; - const char *authorization_token; - const char *authority_selector; - static char *keywords[] = {"authorization_token", "authority_selector", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss:iam", keywords, - &authorization_token, &authority_selector)) { - return NULL; - } - self = (CallCredentials *)type->tp_alloc(type, 0); - self->c_creds = grpc_google_iam_credentials_create(authorization_token, - authority_selector, NULL); - if (!self->c_creds) { - Py_DECREF(self); - PyErr_SetString(PyExc_RuntimeError, "couldn't create IAM credentials"); - return NULL; - } - return self; -} - diff --git a/src/python/grpcio/grpc/_adapter/_c/types/channel.c b/src/python/grpcio/grpc/_adapter/_c/types/channel.c deleted file mode 100644 index c4db2a0dfd..0000000000 --- a/src/python/grpcio/grpc/_adapter/_c/types/channel.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "grpc/_adapter/_c/types.h" - -#define PY_SSIZE_T_CLEAN -#include <Python.h> -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> - - -PyMethodDef pygrpc_Channel_methods[] = { - {"create_call", (PyCFunction)pygrpc_Channel_create_call, METH_KEYWORDS, ""}, - {"check_connectivity_state", (PyCFunction)pygrpc_Channel_check_connectivity_state, METH_KEYWORDS, ""}, - {"watch_connectivity_state", (PyCFunction)pygrpc_Channel_watch_connectivity_state, METH_KEYWORDS, ""}, - {"target", (PyCFunction)pygrpc_Channel_target, METH_NOARGS, ""}, - {NULL} -}; -const char pygrpc_Channel_doc[] = "See grpc._adapter._types.Channel."; -PyTypeObject pygrpc_Channel_type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "Channel", /* tp_name */ - sizeof(Channel), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pygrpc_Channel_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - pygrpc_Channel_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - pygrpc_Channel_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - (newfunc)pygrpc_Channel_new /* tp_new */ -}; - -Channel *pygrpc_Channel_new( - PyTypeObject *type, PyObject *args, PyObject *kwargs) { - Channel *self; - const char *target; - PyObject *py_args; - ChannelCredentials *creds = NULL; - grpc_channel_args c_args; - char *keywords[] = {"target", "args", "creds", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|O!:Channel", keywords, - &target, &py_args, &pygrpc_ChannelCredentials_type, &creds)) { - return NULL; - } - if (!pygrpc_produce_channel_args(py_args, &c_args)) { - return NULL; - } - self = (Channel *)type->tp_alloc(type, 0); - if (creds) { - self->c_chan = - grpc_secure_channel_create(creds->c_creds, target, &c_args, NULL); - } else { - self->c_chan = grpc_insecure_channel_create(target, &c_args, NULL); - } - pygrpc_discard_channel_args(c_args); - return self; -} -void pygrpc_Channel_dealloc(Channel *self) { - grpc_channel_destroy(self->c_chan); - self->ob_type->tp_free((PyObject *)self); -} - -Call *pygrpc_Channel_create_call( - Channel *self, PyObject *args, PyObject *kwargs) { - Call *call; - CompletionQueue *cq; - const char *method; - const char *host; - double deadline; - char *keywords[] = {"cq", "method", "host", "deadline", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!szd:create_call", keywords, - &pygrpc_CompletionQueue_type, &cq, &method, &host, &deadline)) { - return NULL; - } - call = pygrpc_Call_new_empty(cq); - call->c_call = grpc_channel_create_call( - self->c_chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq->c_cq, method, host, - pygrpc_cast_double_to_gpr_timespec(deadline), NULL); - return call; -} - -PyObject *pygrpc_Channel_check_connectivity_state( - Channel *self, PyObject *args, PyObject *kwargs) { - PyObject *py_try_to_connect; - int try_to_connect; - char *keywords[] = {"try_to_connect", NULL}; - grpc_connectivity_state state; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:connectivity_state", keywords, - &py_try_to_connect)) { - return NULL; - } - if (!PyBool_Check(py_try_to_connect)) { - Py_XDECREF(py_try_to_connect); - return NULL; - } - try_to_connect = Py_True == py_try_to_connect; - Py_DECREF(py_try_to_connect); - state = grpc_channel_check_connectivity_state(self->c_chan, try_to_connect); - return PyInt_FromLong(state); -} - -PyObject *pygrpc_Channel_watch_connectivity_state( - Channel *self, PyObject *args, PyObject *kwargs) { - PyObject *tag; - double deadline; - int last_observed_state; - CompletionQueue *completion_queue; - char *keywords[] = {"last_observed_state", "deadline", - "completion_queue", "tag", NULL}; - if (!PyArg_ParseTupleAndKeywords( - args, kwargs, "idO!O:watch_connectivity_state", keywords, - &last_observed_state, &deadline, &pygrpc_CompletionQueue_type, - &completion_queue, &tag)) { - return NULL; - } - grpc_channel_watch_connectivity_state( - self->c_chan, (grpc_connectivity_state)last_observed_state, - pygrpc_cast_double_to_gpr_timespec(deadline), completion_queue->c_cq, - pygrpc_produce_channel_state_change_tag(tag)); - Py_RETURN_NONE; -} - -PyObject *pygrpc_Channel_target(Channel *self) { - char *target = grpc_channel_get_target(self->c_chan); - PyObject *py_target = PyString_FromString(target); - gpr_free(target); - return py_target; -} diff --git a/src/python/grpcio/grpc/_adapter/_c/types/channel_credentials.c b/src/python/grpcio/grpc/_adapter/_c/types/channel_credentials.c deleted file mode 100644 index 83b1fc0406..0000000000 --- a/src/python/grpcio/grpc/_adapter/_c/types/channel_credentials.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "grpc/_adapter/_c/types.h" - -#define PY_SSIZE_T_CLEAN -#include <Python.h> -#include <grpc/grpc.h> -#include <grpc/grpc_security.h> - - -PyMethodDef pygrpc_ChannelCredentials_methods[] = { - {"google_default", (PyCFunction)pygrpc_ChannelCredentials_google_default, - METH_CLASS|METH_NOARGS, ""}, - {"ssl", (PyCFunction)pygrpc_ChannelCredentials_ssl, - METH_CLASS|METH_KEYWORDS, ""}, - {"composite", (PyCFunction)pygrpc_ChannelCredentials_composite, - METH_CLASS|METH_KEYWORDS, ""}, - {NULL} -}; - -const char pygrpc_ChannelCredentials_doc[] = ""; -PyTypeObject pygrpc_ChannelCredentials_type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "ChannelCredentials", /* tp_name */ - sizeof(ChannelCredentials), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pygrpc_ChannelCredentials_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - pygrpc_ChannelCredentials_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - pygrpc_ChannelCredentials_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0 /* tp_new */ -}; - -void pygrpc_ChannelCredentials_dealloc(ChannelCredentials *self) { - grpc_channel_credentials_release(self->c_creds); - self->ob_type->tp_free((PyObject *)self); -} - -ChannelCredentials *pygrpc_ChannelCredentials_google_default( - PyTypeObject *type, PyObject *ignored) { - ChannelCredentials *self = (ChannelCredentials *)type->tp_alloc(type, 0); - self->c_creds = grpc_google_default_credentials_create(); - if (!self->c_creds) { - Py_DECREF(self); - PyErr_SetString(PyExc_RuntimeError, - "couldn't create Google default credentials"); - return NULL; - } - return self; -} - -ChannelCredentials *pygrpc_ChannelCredentials_ssl( - PyTypeObject *type, PyObject *args, PyObject *kwargs) { - ChannelCredentials *self; - const char *root_certs; - const char *private_key = NULL; - const char *cert_chain = NULL; - grpc_ssl_pem_key_cert_pair key_cert_pair; - static char *keywords[] = {"root_certs", "private_key", "cert_chain", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|zz:ssl", keywords, - &root_certs, &private_key, &cert_chain)) { - return NULL; - } - self = (ChannelCredentials *)type->tp_alloc(type, 0); - if (private_key && cert_chain) { - key_cert_pair.private_key = private_key; - key_cert_pair.cert_chain = cert_chain; - self->c_creds = - grpc_ssl_credentials_create(root_certs, &key_cert_pair, NULL); - } else { - self->c_creds = grpc_ssl_credentials_create(root_certs, NULL, NULL); - } - if (!self->c_creds) { - Py_DECREF(self); - PyErr_SetString(PyExc_RuntimeError, "couldn't create ssl credentials"); - return NULL; - } - return self; -} - -ChannelCredentials *pygrpc_ChannelCredentials_composite( - PyTypeObject *type, PyObject *args, PyObject *kwargs) { - ChannelCredentials *self; - ChannelCredentials *creds1; - CallCredentials *creds2; - static char *keywords[] = {"creds1", "creds2", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!:composite", keywords, - &pygrpc_ChannelCredentials_type, &creds1, - &pygrpc_CallCredentials_type, &creds2)) { - return NULL; - } - self = (ChannelCredentials *)type->tp_alloc(type, 0); - self->c_creds = - grpc_composite_channel_credentials_create( - creds1->c_creds, creds2->c_creds, NULL); - if (!self->c_creds) { - Py_DECREF(self); - PyErr_SetString( - PyExc_RuntimeError, "couldn't create composite credentials"); - return NULL; - } - return self; -} - diff --git a/src/python/grpcio/grpc/_adapter/_c/types/completion_queue.c b/src/python/grpcio/grpc/_adapter/_c/types/completion_queue.c deleted file mode 100644 index d8bb89ca4b..0000000000 --- a/src/python/grpcio/grpc/_adapter/_c/types/completion_queue.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "grpc/_adapter/_c/types.h" - -#define PY_SSIZE_T_CLEAN -#include <Python.h> -#include <grpc/grpc.h> - - -PyMethodDef pygrpc_CompletionQueue_methods[] = { - {"next", (PyCFunction)pygrpc_CompletionQueue_next, METH_KEYWORDS, ""}, - {"shutdown", (PyCFunction)pygrpc_CompletionQueue_shutdown, METH_NOARGS, ""}, - {NULL} -}; -const char pygrpc_CompletionQueue_doc[] = - "See grpc._adapter._types.CompletionQueue."; -PyTypeObject pygrpc_CompletionQueue_type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "CompletionQueue", /* tp_name */ - sizeof(CompletionQueue), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pygrpc_CompletionQueue_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - pygrpc_CompletionQueue_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - pygrpc_CompletionQueue_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - (newfunc)pygrpc_CompletionQueue_new /* tp_new */ -}; - -CompletionQueue *pygrpc_CompletionQueue_new( - PyTypeObject *type, PyObject *args, PyObject *kwargs) { - CompletionQueue *self = (CompletionQueue *)type->tp_alloc(type, 0); - self->c_cq = grpc_completion_queue_create(NULL); - return self; -} - -void pygrpc_CompletionQueue_dealloc(CompletionQueue *self) { - grpc_completion_queue_destroy(self->c_cq); - self->ob_type->tp_free((PyObject *)self); -} - -PyObject *pygrpc_CompletionQueue_next( - CompletionQueue *self, PyObject *args, PyObject *kwargs) { - double deadline; - grpc_event event; - PyObject *transliterated_event; - static char *keywords[] = {"deadline", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "d:next", keywords, - &deadline)) { - return NULL; - } - Py_BEGIN_ALLOW_THREADS; - event = grpc_completion_queue_next( - self->c_cq, pygrpc_cast_double_to_gpr_timespec(deadline), NULL); - Py_END_ALLOW_THREADS; - transliterated_event = pygrpc_consume_event(event); - return transliterated_event; -} - -PyObject *pygrpc_CompletionQueue_shutdown( - CompletionQueue *self, PyObject *ignored) { - grpc_completion_queue_shutdown(self->c_cq); - Py_RETURN_NONE; -} diff --git a/src/python/grpcio/grpc/_adapter/_c/types/server.c b/src/python/grpcio/grpc/_adapter/_c/types/server.c deleted file mode 100644 index 8feab8aab1..0000000000 --- a/src/python/grpcio/grpc/_adapter/_c/types/server.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "grpc/_adapter/_c/types.h" - -#define PY_SSIZE_T_CLEAN -#include <Python.h> -#include <grpc/grpc.h> - - -PyMethodDef pygrpc_Server_methods[] = { - {"request_call", (PyCFunction)pygrpc_Server_request_call, - METH_KEYWORDS, ""}, - {"add_http2_port", (PyCFunction)pygrpc_Server_add_http2_port, - METH_KEYWORDS, ""}, - {"start", (PyCFunction)pygrpc_Server_start, METH_NOARGS, ""}, - {"shutdown", (PyCFunction)pygrpc_Server_shutdown, METH_KEYWORDS, ""}, - {"cancel_all_calls", (PyCFunction)pygrpc_Server_cancel_all_calls, - METH_NOARGS, ""}, - {NULL} -}; -const char pygrpc_Server_doc[] = "See grpc._adapter._types.Server."; -PyTypeObject pygrpc_Server_type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "Server", /* tp_name */ - sizeof(Server), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pygrpc_Server_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - pygrpc_Server_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - pygrpc_Server_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - (newfunc)pygrpc_Server_new /* tp_new */ -}; - -Server *pygrpc_Server_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { - Server *self; - CompletionQueue *cq; - PyObject *py_args; - grpc_channel_args c_args; - char *keywords[] = {"cq", "args", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O:Server", keywords, - &pygrpc_CompletionQueue_type, &cq, &py_args)) { - return NULL; - } - if (!pygrpc_produce_channel_args(py_args, &c_args)) { - return NULL; - } - self = (Server *)type->tp_alloc(type, 0); - self->c_serv = grpc_server_create(&c_args, NULL); - grpc_server_register_completion_queue(self->c_serv, cq->c_cq, NULL); - pygrpc_discard_channel_args(c_args); - self->cq = cq; - Py_INCREF(self->cq); - self->shutdown_called = 0; - return self; -} - -void pygrpc_Server_dealloc(Server *self) { - grpc_server_destroy(self->c_serv); - Py_XDECREF(self->cq); - self->ob_type->tp_free((PyObject *)self); -} - -PyObject *pygrpc_Server_request_call( - Server *self, PyObject *args, PyObject *kwargs) { - CompletionQueue *cq; - PyObject *user_tag; - pygrpc_tag *tag; - Call *empty_call; - grpc_call_error errcode; - static char *keywords[] = {"cq", "tag", NULL}; - if (!PyArg_ParseTupleAndKeywords( - args, kwargs, "O!O", keywords, - &pygrpc_CompletionQueue_type, &cq, &user_tag)) { - return NULL; - } - empty_call = pygrpc_Call_new_empty(cq); - tag = pygrpc_produce_request_tag(user_tag, empty_call); - errcode = grpc_server_request_call( - self->c_serv, &tag->call->c_call, &tag->request_call_details, - &tag->request_metadata, tag->call->cq->c_cq, self->cq->c_cq, tag); - Py_DECREF(empty_call); - return PyInt_FromLong(errcode); -} - -PyObject *pygrpc_Server_add_http2_port( - Server *self, PyObject *args, PyObject *kwargs) { - const char *addr; - ServerCredentials *creds = NULL; - int port; - static char *keywords[] = {"addr", "creds", NULL}; - if (!PyArg_ParseTupleAndKeywords( - args, kwargs, "s|O!:add_http2_port", keywords, - &addr, &pygrpc_ServerCredentials_type, &creds)) { - return NULL; - } - if (creds) { - port = grpc_server_add_secure_http2_port( - self->c_serv, addr, creds->c_creds); - } else { - port = grpc_server_add_insecure_http2_port(self->c_serv, addr); - } - return PyInt_FromLong(port); - -} - -PyObject *pygrpc_Server_start(Server *self, PyObject *ignored) { - grpc_server_start(self->c_serv); - self->shutdown_called = 0; - Py_RETURN_NONE; -} - -PyObject *pygrpc_Server_shutdown( - Server *self, PyObject *args, PyObject *kwargs) { - PyObject *user_tag; - pygrpc_tag *tag; - static char *keywords[] = {"tag", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", keywords, &user_tag)) { - return NULL; - } - tag = pygrpc_produce_server_shutdown_tag(user_tag); - grpc_server_shutdown_and_notify(self->c_serv, self->cq->c_cq, tag); - self->shutdown_called = 1; - Py_RETURN_NONE; -} - -PyObject *pygrpc_Server_cancel_all_calls(Server *self, PyObject *unused) { - if (!self->shutdown_called) { - PyErr_SetString( - PyExc_RuntimeError, - "shutdown must have been called prior to calling cancel_all_calls!"); - return NULL; - } - grpc_server_cancel_all_calls(self->c_serv); - Py_RETURN_NONE; -} diff --git a/src/python/grpcio/grpc/_adapter/_c/types/server_credentials.c b/src/python/grpcio/grpc/_adapter/_c/types/server_credentials.c deleted file mode 100644 index df51a99b6a..0000000000 --- a/src/python/grpcio/grpc/_adapter/_c/types/server_credentials.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "grpc/_adapter/_c/types.h" - -#define PY_SSIZE_T_CLEAN -#include <Python.h> -#include <grpc/grpc.h> -#include <grpc/grpc_security.h> -#include <grpc/support/alloc.h> - - -PyMethodDef pygrpc_ServerCredentials_methods[] = { - {"ssl", (PyCFunction)pygrpc_ServerCredentials_ssl, - METH_CLASS|METH_KEYWORDS, ""}, - {NULL} -}; -const char pygrpc_ServerCredentials_doc[] = ""; -PyTypeObject pygrpc_ServerCredentials_type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "ServerCredentials", /* tp_name */ - sizeof(ServerCredentials), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pygrpc_ServerCredentials_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - pygrpc_ServerCredentials_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - pygrpc_ServerCredentials_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0 /* tp_new */ -}; - -void pygrpc_ServerCredentials_dealloc(ServerCredentials *self) { - grpc_server_credentials_release(self->c_creds); - self->ob_type->tp_free((PyObject *)self); -} - -ServerCredentials *pygrpc_ServerCredentials_ssl( - PyTypeObject *type, PyObject *args, PyObject *kwargs) { - ServerCredentials *self; - const char *root_certs; - PyObject *py_key_cert_pairs; - grpc_ssl_pem_key_cert_pair *key_cert_pairs; - int force_client_auth; - size_t num_key_cert_pairs; - size_t i; - static char *keywords[] = { - "root_certs", "key_cert_pairs", "force_client_auth", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "zOi:ssl", keywords, - &root_certs, &py_key_cert_pairs, &force_client_auth)) { - return NULL; - } - if (!PyList_Check(py_key_cert_pairs)) { - PyErr_SetString(PyExc_TypeError, "expected a list of 2-tuples of strings"); - return NULL; - } - num_key_cert_pairs = PyList_Size(py_key_cert_pairs); - key_cert_pairs = - gpr_malloc(sizeof(grpc_ssl_pem_key_cert_pair) * num_key_cert_pairs); - for (i = 0; i < num_key_cert_pairs; ++i) { - PyObject *item = PyList_GET_ITEM(py_key_cert_pairs, i); - const char *key; - const char *cert; - if (!PyArg_ParseTuple(item, "zz", &key, &cert)) { - gpr_free(key_cert_pairs); - PyErr_SetString(PyExc_TypeError, - "expected a list of 2-tuples of strings"); - return NULL; - } - key_cert_pairs[i].private_key = key; - key_cert_pairs[i].cert_chain = cert; - } - - self = (ServerCredentials *)type->tp_alloc(type, 0); - self->c_creds = grpc_ssl_server_credentials_create( - root_certs, key_cert_pairs, num_key_cert_pairs, force_client_auth, NULL); - gpr_free(key_cert_pairs); - return self; -} diff --git a/src/python/grpcio/grpc/_adapter/_c/utility.c b/src/python/grpcio/grpc/_adapter/_c/utility.c deleted file mode 100644 index 590f7e013a..0000000000 --- a/src/python/grpcio/grpc/_adapter/_c/utility.c +++ /dev/null @@ -1,524 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include <math.h> -#include <string.h> - -#define PY_SSIZE_T_CLEAN -#include <Python.h> -#include <grpc/grpc.h> -#include <grpc/byte_buffer_reader.h> -#include <grpc/support/alloc.h> -#include <grpc/support/slice.h> -#include <grpc/support/time.h> -#include <grpc/support/string_util.h> - -#include "grpc/_adapter/_c/types.h" - -pygrpc_tag *pygrpc_produce_batch_tag( - PyObject *user_tag, Call *call, grpc_op *ops, size_t nops) { - pygrpc_tag *tag = gpr_malloc(sizeof(pygrpc_tag)); - tag->user_tag = user_tag; - Py_XINCREF(tag->user_tag); - tag->call = call; - Py_XINCREF(tag->call); - tag->ops = gpr_malloc(sizeof(grpc_op)*nops); - memcpy(tag->ops, ops, sizeof(grpc_op)*nops); - tag->nops = nops; - grpc_call_details_init(&tag->request_call_details); - grpc_metadata_array_init(&tag->request_metadata); - tag->is_new_call = 0; - return tag; -} - -pygrpc_tag *pygrpc_produce_request_tag(PyObject *user_tag, Call *empty_call) { - pygrpc_tag *tag = gpr_malloc(sizeof(pygrpc_tag)); - tag->user_tag = user_tag; - Py_XINCREF(tag->user_tag); - tag->call = empty_call; - Py_XINCREF(tag->call); - tag->ops = NULL; - tag->nops = 0; - grpc_call_details_init(&tag->request_call_details); - grpc_metadata_array_init(&tag->request_metadata); - tag->is_new_call = 1; - return tag; -} - -pygrpc_tag *pygrpc_produce_server_shutdown_tag(PyObject *user_tag) { - pygrpc_tag *tag = gpr_malloc(sizeof(pygrpc_tag)); - tag->user_tag = user_tag; - Py_XINCREF(tag->user_tag); - tag->call = NULL; - tag->ops = NULL; - tag->nops = 0; - grpc_call_details_init(&tag->request_call_details); - grpc_metadata_array_init(&tag->request_metadata); - tag->is_new_call = 0; - return tag; -} - -pygrpc_tag *pygrpc_produce_channel_state_change_tag(PyObject *user_tag) { - pygrpc_tag *tag = gpr_malloc(sizeof(pygrpc_tag)); - tag->user_tag = user_tag; - Py_XINCREF(tag->user_tag); - tag->call = NULL; - tag->ops = NULL; - tag->nops = 0; - grpc_call_details_init(&tag->request_call_details); - grpc_metadata_array_init(&tag->request_metadata); - tag->is_new_call = 0; - return tag; -} - -void pygrpc_discard_tag(pygrpc_tag *tag) { - if (!tag) { - return; - } - Py_XDECREF(tag->user_tag); - Py_XDECREF(tag->call); - gpr_free(tag->ops); - grpc_call_details_destroy(&tag->request_call_details); - grpc_metadata_array_destroy(&tag->request_metadata); - gpr_free(tag); -} - -PyObject *pygrpc_consume_event(grpc_event event) { - pygrpc_tag *tag; - PyObject *result; - if (event.type == GRPC_QUEUE_TIMEOUT) { - Py_RETURN_NONE; - } - tag = event.tag; - switch (event.type) { - case GRPC_QUEUE_SHUTDOWN: - result = Py_BuildValue("iOOOOO", GRPC_QUEUE_SHUTDOWN, - Py_None, Py_None, Py_None, Py_None, Py_True); - break; - case GRPC_OP_COMPLETE: - if (tag->is_new_call) { - result = Py_BuildValue( - "iOO(ssd)[(iNOOOO)]O", GRPC_OP_COMPLETE, tag->user_tag, tag->call, - tag->request_call_details.method, tag->request_call_details.host, - pygrpc_cast_gpr_timespec_to_double(tag->request_call_details.deadline), - GRPC_OP_RECV_INITIAL_METADATA, - pygrpc_cast_metadata_array_to_pyseq(tag->request_metadata), Py_None, - Py_None, Py_None, Py_None, - event.success ? Py_True : Py_False); - } else { - result = Py_BuildValue("iOOONO", GRPC_OP_COMPLETE, tag->user_tag, - tag->call ? (PyObject*)tag->call : Py_None, Py_None, - pygrpc_consume_ops(tag->ops, tag->nops), - event.success ? Py_True : Py_False); - } - break; - default: - PyErr_SetString(PyExc_ValueError, - "unknown completion type; could not translate event"); - return NULL; - } - pygrpc_discard_tag(tag); - return result; -} - -int pygrpc_produce_op(PyObject *op, grpc_op *result) { - static const int OP_TUPLE_SIZE = 6; - static const int STATUS_TUPLE_SIZE = 2; - static const int TYPE_INDEX = 0; - static const int INITIAL_METADATA_INDEX = 1; - static const int TRAILING_METADATA_INDEX = 2; - static const int MESSAGE_INDEX = 3; - static const int STATUS_INDEX = 4; - static const int STATUS_CODE_INDEX = 0; - static const int STATUS_DETAILS_INDEX = 1; - static const int WRITE_FLAGS_INDEX = 5; - int type; - Py_ssize_t message_size; - char *message; - char *status_details; - gpr_slice message_slice; - grpc_op c_op; - if (!PyTuple_Check(op)) { - PyErr_SetString(PyExc_TypeError, "expected tuple op"); - return 0; - } - if (PyTuple_Size(op) != OP_TUPLE_SIZE) { - char *buf; - gpr_asprintf(&buf, "expected tuple op of length %d", OP_TUPLE_SIZE); - PyErr_SetString(PyExc_ValueError, buf); - gpr_free(buf); - return 0; - } - type = PyInt_AsLong(PyTuple_GET_ITEM(op, TYPE_INDEX)); - if (PyErr_Occurred()) { - return 0; - } - c_op.op = type; - c_op.reserved = NULL; - c_op.flags = PyInt_AsLong(PyTuple_GET_ITEM(op, WRITE_FLAGS_INDEX)); - if (PyErr_Occurred()) { - return 0; - } - switch (type) { - case GRPC_OP_SEND_INITIAL_METADATA: - if (!pygrpc_cast_pyseq_to_send_metadata( - PyTuple_GetItem(op, INITIAL_METADATA_INDEX), - &c_op.data.send_initial_metadata.metadata, - &c_op.data.send_initial_metadata.count)) { - return 0; - } - break; - case GRPC_OP_SEND_MESSAGE: - PyString_AsStringAndSize( - PyTuple_GET_ITEM(op, MESSAGE_INDEX), &message, &message_size); - message_slice = gpr_slice_from_copied_buffer(message, message_size); - c_op.data.send_message = grpc_raw_byte_buffer_create(&message_slice, 1); - gpr_slice_unref(message_slice); - break; - case GRPC_OP_SEND_CLOSE_FROM_CLIENT: - /* Don't need to fill in any other fields. */ - break; - case GRPC_OP_SEND_STATUS_FROM_SERVER: - if (!pygrpc_cast_pyseq_to_send_metadata( - PyTuple_GetItem(op, TRAILING_METADATA_INDEX), - &c_op.data.send_status_from_server.trailing_metadata, - &c_op.data.send_status_from_server.trailing_metadata_count)) { - return 0; - } - if (!PyTuple_Check(PyTuple_GET_ITEM(op, STATUS_INDEX))) { - char *buf; - gpr_asprintf(&buf, "expected tuple status in op of length %d", - STATUS_TUPLE_SIZE); - PyErr_SetString(PyExc_ValueError, buf); - gpr_free(buf); - return 0; - } - c_op.data.send_status_from_server.status = PyInt_AsLong( - PyTuple_GET_ITEM(PyTuple_GET_ITEM(op, STATUS_INDEX), STATUS_CODE_INDEX)); - status_details = PyString_AsString( - PyTuple_GET_ITEM(PyTuple_GET_ITEM(op, STATUS_INDEX), STATUS_DETAILS_INDEX)); - if (PyErr_Occurred()) { - return 0; - } - c_op.data.send_status_from_server.status_details = - gpr_malloc(strlen(status_details) + 1); - strcpy((char *)c_op.data.send_status_from_server.status_details, - status_details); - break; - case GRPC_OP_RECV_INITIAL_METADATA: - c_op.data.recv_initial_metadata = gpr_malloc(sizeof(grpc_metadata_array)); - grpc_metadata_array_init(c_op.data.recv_initial_metadata); - break; - case GRPC_OP_RECV_MESSAGE: - c_op.data.recv_message = gpr_malloc(sizeof(grpc_byte_buffer *)); - break; - case GRPC_OP_RECV_STATUS_ON_CLIENT: - c_op.data.recv_status_on_client.trailing_metadata = - gpr_malloc(sizeof(grpc_metadata_array)); - grpc_metadata_array_init(c_op.data.recv_status_on_client.trailing_metadata); - c_op.data.recv_status_on_client.status = - gpr_malloc(sizeof(grpc_status_code *)); - c_op.data.recv_status_on_client.status_details = - gpr_malloc(sizeof(char *)); - *c_op.data.recv_status_on_client.status_details = NULL; - c_op.data.recv_status_on_client.status_details_capacity = - gpr_malloc(sizeof(size_t)); - *c_op.data.recv_status_on_client.status_details_capacity = 0; - break; - case GRPC_OP_RECV_CLOSE_ON_SERVER: - c_op.data.recv_close_on_server.cancelled = gpr_malloc(sizeof(int)); - break; - default: - return 0; - } - *result = c_op; - return 1; -} - -void pygrpc_discard_op(grpc_op op) { - size_t i; - switch(op.op) { - case GRPC_OP_SEND_INITIAL_METADATA: - /* Whenever we produce send-metadata, we allocate new strings (to handle - arbitrary sequence input as opposed to just lists or just tuples). We - thus must free those elements. */ - for (i = 0; i < op.data.send_initial_metadata.count; ++i) { - gpr_free((void *)op.data.send_initial_metadata.metadata[i].key); - gpr_free((void *)op.data.send_initial_metadata.metadata[i].value); - } - gpr_free(op.data.send_initial_metadata.metadata); - break; - case GRPC_OP_SEND_MESSAGE: - grpc_byte_buffer_destroy(op.data.send_message); - break; - case GRPC_OP_SEND_CLOSE_FROM_CLIENT: - /* Don't need to free any fields. */ - break; - case GRPC_OP_SEND_STATUS_FROM_SERVER: - /* Whenever we produce send-metadata, we allocate new strings (to handle - arbitrary sequence input as opposed to just lists or just tuples). We - thus must free those elements. */ - for (i = 0; i < op.data.send_status_from_server.trailing_metadata_count; - ++i) { - gpr_free( - (void *)op.data.send_status_from_server.trailing_metadata[i].key); - gpr_free( - (void *)op.data.send_status_from_server.trailing_metadata[i].value); - } - gpr_free(op.data.send_status_from_server.trailing_metadata); - gpr_free((char *)op.data.send_status_from_server.status_details); - break; - case GRPC_OP_RECV_INITIAL_METADATA: - grpc_metadata_array_destroy(op.data.recv_initial_metadata); - gpr_free(op.data.recv_initial_metadata); - break; - case GRPC_OP_RECV_MESSAGE: - grpc_byte_buffer_destroy(*op.data.recv_message); - gpr_free(op.data.recv_message); - break; - case GRPC_OP_RECV_STATUS_ON_CLIENT: - grpc_metadata_array_destroy(op.data.recv_status_on_client.trailing_metadata); - gpr_free(op.data.recv_status_on_client.trailing_metadata); - gpr_free(op.data.recv_status_on_client.status); - gpr_free(*op.data.recv_status_on_client.status_details); - gpr_free(op.data.recv_status_on_client.status_details); - gpr_free(op.data.recv_status_on_client.status_details_capacity); - break; - case GRPC_OP_RECV_CLOSE_ON_SERVER: - gpr_free(op.data.recv_close_on_server.cancelled); - break; - } -} - -PyObject *pygrpc_consume_ops(grpc_op *op, size_t nops) { - static const int TYPE_INDEX = 0; - static const int INITIAL_METADATA_INDEX = 1; - static const int TRAILING_METADATA_INDEX = 2; - static const int MESSAGE_INDEX = 3; - static const int STATUS_INDEX = 4; - static const int CANCELLED_INDEX = 5; - static const int OPRESULT_LENGTH = 6; - PyObject *list; - size_t i; - size_t j; - char *bytes; - size_t bytes_size; - PyObject *results = PyList_New(nops); - if (!results) { - return NULL; - } - for (i = 0; i < nops; ++i) { - PyObject *result = PyTuple_Pack(OPRESULT_LENGTH, Py_None, Py_None, Py_None, - Py_None, Py_None, Py_None); - PyTuple_SetItem(result, TYPE_INDEX, PyInt_FromLong(op[i].op)); - switch(op[i].op) { - case GRPC_OP_RECV_INITIAL_METADATA: - PyTuple_SetItem(result, INITIAL_METADATA_INDEX, - list=PyList_New(op[i].data.recv_initial_metadata->count)); - for (j = 0; j < op[i].data.recv_initial_metadata->count; ++j) { - grpc_metadata md = op[i].data.recv_initial_metadata->metadata[j]; - PyList_SetItem(list, j, Py_BuildValue("ss#", md.key, md.value, - (Py_ssize_t)md.value_length)); - } - break; - case GRPC_OP_RECV_MESSAGE: - if (*op[i].data.recv_message) { - pygrpc_byte_buffer_to_bytes( - *op[i].data.recv_message, &bytes, &bytes_size); - PyTuple_SetItem(result, MESSAGE_INDEX, - PyString_FromStringAndSize(bytes, bytes_size)); - gpr_free(bytes); - } else { - PyTuple_SetItem(result, MESSAGE_INDEX, Py_BuildValue("")); - } - break; - case GRPC_OP_RECV_STATUS_ON_CLIENT: - PyTuple_SetItem( - result, TRAILING_METADATA_INDEX, - list = PyList_New(op[i].data.recv_status_on_client.trailing_metadata->count)); - for (j = 0; j < op[i].data.recv_status_on_client.trailing_metadata->count; ++j) { - grpc_metadata md = - op[i].data.recv_status_on_client.trailing_metadata->metadata[j]; - PyList_SetItem(list, j, Py_BuildValue("ss#", md.key, md.value, - (Py_ssize_t)md.value_length)); - } - PyTuple_SetItem( - result, STATUS_INDEX, Py_BuildValue( - "is", *op[i].data.recv_status_on_client.status, - *op[i].data.recv_status_on_client.status_details)); - break; - case GRPC_OP_RECV_CLOSE_ON_SERVER: - PyTuple_SetItem( - result, CANCELLED_INDEX, - PyBool_FromLong(*op[i].data.recv_close_on_server.cancelled)); - break; - default: - break; - } - pygrpc_discard_op(op[i]); - PyList_SetItem(results, i, result); - } - return results; -} - -double pygrpc_cast_gpr_timespec_to_double(gpr_timespec timespec) { - timespec = gpr_convert_clock_type(timespec, GPR_CLOCK_REALTIME); - return timespec.tv_sec + 1e-9*timespec.tv_nsec; -} - -/* Because C89 doesn't have a way to check for infinity... */ -static int pygrpc_isinf(double x) { - return x * 0 != 0; -} - -gpr_timespec pygrpc_cast_double_to_gpr_timespec(double seconds) { - gpr_timespec result; - if (pygrpc_isinf(seconds)) { - result = seconds > 0.0 ? gpr_inf_future(GPR_CLOCK_REALTIME) - : gpr_inf_past(GPR_CLOCK_REALTIME); - } else { - result.tv_sec = (time_t)seconds; - result.tv_nsec = ((seconds - result.tv_sec) * 1e9); - result.clock_type = GPR_CLOCK_REALTIME; - } - return result; -} - -int pygrpc_produce_channel_args(PyObject *py_args, grpc_channel_args *c_args) { - size_t num_args = PyList_Size(py_args); - size_t i; - grpc_channel_args args; - args.num_args = num_args; - args.args = gpr_malloc(sizeof(grpc_arg) * num_args); - for (i = 0; i < args.num_args; ++i) { - char *key; - PyObject *value; - if (!PyArg_ParseTuple(PyList_GetItem(py_args, i), "zO", &key, &value)) { - gpr_free(args.args); - args.num_args = 0; - args.args = NULL; - PyErr_SetString(PyExc_TypeError, - "expected a list of 2-tuple of str and str|int|None"); - return 0; - } - args.args[i].key = key; - if (PyInt_Check(value)) { - args.args[i].type = GRPC_ARG_INTEGER; - args.args[i].value.integer = PyInt_AsLong(value); - } else if (PyString_Check(value)) { - args.args[i].type = GRPC_ARG_STRING; - args.args[i].value.string = PyString_AsString(value); - } else if (value == Py_None) { - --args.num_args; - --i; - continue; - } else { - gpr_free(args.args); - args.num_args = 0; - args.args = NULL; - PyErr_SetString(PyExc_TypeError, - "expected a list of 2-tuple of str and str|int|None"); - return 0; - } - } - *c_args = args; - return 1; -} - -void pygrpc_discard_channel_args(grpc_channel_args args) { - gpr_free(args.args); -} - -int pygrpc_cast_pyseq_to_send_metadata( - PyObject *pyseq, grpc_metadata **metadata, size_t *count) { - size_t i; - Py_ssize_t value_length; - char *key; - char *value; - if (!PySequence_Check(pyseq)) { - return 0; - } - *count = PySequence_Size(pyseq); - *metadata = gpr_malloc(sizeof(grpc_metadata) * *count); - for (i = 0; i < *count; ++i) { - PyObject *item = PySequence_GetItem(pyseq, i); - if (!PyArg_ParseTuple(item, "ss#", &key, &value, &value_length)) { - Py_DECREF(item); - gpr_free(*metadata); - *count = 0; - *metadata = NULL; - return 0; - } else { - (*metadata)[i].key = gpr_strdup(key); - (*metadata)[i].value = gpr_malloc(value_length); - memcpy((void *)(*metadata)[i].value, value, value_length); - Py_DECREF(item); - } - (*metadata)[i].value_length = value_length; - } - return 1; -} - -PyObject *pygrpc_cast_metadata_array_to_pyseq(grpc_metadata_array metadata) { - PyObject *result = PyTuple_New(metadata.count); - size_t i; - for (i = 0; i < metadata.count; ++i) { - PyTuple_SetItem( - result, i, Py_BuildValue( - "ss#", metadata.metadata[i].key, metadata.metadata[i].value, - (Py_ssize_t)metadata.metadata[i].value_length)); - if (PyErr_Occurred()) { - Py_DECREF(result); - return NULL; - } - } - return result; -} - -void pygrpc_byte_buffer_to_bytes( - grpc_byte_buffer *buffer, char **result, size_t *result_size) { - grpc_byte_buffer_reader reader; - gpr_slice slice; - char *read_result = NULL; - size_t size = 0; - grpc_byte_buffer_reader_init(&reader, buffer); - while (grpc_byte_buffer_reader_next(&reader, &slice)) { - read_result = gpr_realloc(read_result, size + GPR_SLICE_LENGTH(slice)); - memcpy(read_result + size, GPR_SLICE_START_PTR(slice), - GPR_SLICE_LENGTH(slice)); - size = size + GPR_SLICE_LENGTH(slice); - gpr_slice_unref(slice); - } - *result_size = size; - *result = read_result; -} diff --git a/src/python/grpcio/grpc/_adapter/_intermediary_low.py b/src/python/grpcio/grpc/_adapter/_intermediary_low.py index 5634c2024d..f87446eae1 100644 --- a/src/python/grpcio/grpc/_adapter/_intermediary_low.py +++ b/src/python/grpcio/grpc/_adapter/_intermediary_low.py @@ -115,16 +115,20 @@ class Call(object): return call def invoke(self, completion_queue, metadata_tag, finish_tag): - err0 = self._internal.start_batch([ + err = self._internal.start_batch([ _types.OpArgs.send_initial_metadata(self._metadata) ], _IGNORE_ME_TAG) - err1 = self._internal.start_batch([ + if err != _types.CallError.OK: + return err + err = self._internal.start_batch([ _types.OpArgs.recv_initial_metadata() ], _TagAdapter(metadata_tag, Event.Kind.METADATA_ACCEPTED)) - err2 = self._internal.start_batch([ + if err != _types.CallError.OK: + return err + err = self._internal.start_batch([ _types.OpArgs.recv_status_on_client() ], _TagAdapter(finish_tag, Event.Kind.FINISH)) - return err0 if err0 != _types.CallError.OK else err1 if err1 != _types.CallError.OK else err2 if err2 != _types.CallError.OK else _types.CallError.OK + return err def write(self, message, tag, flags): return self._internal.start_batch([ @@ -158,7 +162,8 @@ class Call(object): def status(self, status, tag): return self._internal.start_batch([ - _types.OpArgs.send_status_from_server(self._metadata, status.code, status.details) + _types.OpArgs.send_status_from_server( + self._metadata, status.code, status.details) ], _TagAdapter(tag, Event.Kind.COMPLETE_ACCEPTED)) def cancel(self): @@ -192,7 +197,7 @@ class CompletionQueue(object): def get(self, deadline=None): if deadline is None: - ev = self._internal.next() + ev = self._internal.next(float('+inf')) else: ev = self._internal.next(deadline) if ev is None: @@ -248,6 +253,9 @@ class Server(object): def service(self, tag): return self._internal.request_call(self._internal_cq, _TagAdapter(tag, Event.Kind.SERVICE_ACCEPTED)) + def cancel_all_calls(self): + self._internal.cancel_all_calls() + def stop(self): return self._internal.shutdown(_TagAdapter(None, Event.Kind.STOP)) @@ -256,12 +264,12 @@ class ClientCredentials(object): """Adapter from old _low.ClientCredentials interface to new _low.ChannelCredentials.""" def __init__(self, root_certificates, private_key, certificate_chain): - self._internal = _low.ChannelCredentials.ssl(root_certificates, private_key, certificate_chain) + self._internal = _low.channel_credentials_ssl(root_certificates, private_key, certificate_chain) class ServerCredentials(object): """Adapter from old _low.ServerCredentials interface to new _low.ServerCredentials.""" def __init__(self, root_credentials, pair_sequence, force_client_auth): - self._internal = _low.ServerCredentials.ssl( - root_credentials, list(pair_sequence), force_client_auth) + self._internal = _low.server_credentials_ssl( + root_credentials, pair_sequence, force_client_auth) diff --git a/src/python/grpcio/grpc/_adapter/_low.py b/src/python/grpcio/grpc/_adapter/_low.py index 57146aaefe..264c33b484 100644 --- a/src/python/grpcio/grpc/_adapter/_low.py +++ b/src/python/grpcio/grpc/_adapter/_low.py @@ -28,35 +28,76 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from grpc import _grpcio_metadata -from grpc._adapter import _c +from grpc._cython import cygrpc from grpc._adapter import _types _USER_AGENT = 'Python-gRPC-{}'.format(_grpcio_metadata.__version__) -ChannelCredentials = _c.ChannelCredentials -CallCredentials = _c.CallCredentials -ServerCredentials = _c.ServerCredentials +ChannelCredentials = cygrpc.ChannelCredentials +CallCredentials = cygrpc.CallCredentials +ServerCredentials = cygrpc.ServerCredentials + +def server_credentials_ssl(root_credentials, pair_sequence, force_client_auth): + return cygrpc.server_credentials_ssl( + root_credentials, + [cygrpc.SslPemKeyCertPair(key, pem) for key, pem in pair_sequence], + force_client_auth) + +def channel_credentials_ssl( + root_certificates, private_key, certificate_chain): + pair = None + if private_key is not None or certificate_chain is not None: + pair = cygrpc.SslPemKeyCertPair(private_key, certificate_chain) + return cygrpc.channel_credentials_ssl(root_certificates, pair) class CompletionQueue(_types.CompletionQueue): def __init__(self): - self.completion_queue = _c.CompletionQueue() + self.completion_queue = cygrpc.CompletionQueue() def next(self, deadline=float('+inf')): - raw_event = self.completion_queue.next(deadline) - if raw_event is None: + raw_event = self.completion_queue.poll(cygrpc.Timespec(deadline)) + if raw_event.type == cygrpc.CompletionType.queue_timeout: return None - event = _types.Event(*raw_event) - if event.call is not None: - event = event._replace(call=Call(event.call)) - if event.call_details is not None: - event = event._replace(call_details=_types.CallDetails(*event.call_details)) - if event.results is not None: - new_results = [_types.OpResult(*r) for r in event.results] - new_results = [r if r.status is None else r._replace(status=_types.Status(_types.StatusCode(r.status[0]), r.status[1])) for r in new_results] - event = event._replace(results=new_results) - return event + event_type = raw_event.type + event_tag = raw_event.tag + event_call = Call(raw_event.operation_call) + if raw_event.request_call_details: + event_call_details = _types.CallDetails( + raw_event.request_call_details.method, + raw_event.request_call_details.host, + float(raw_event.request_call_details.deadline)) + else: + event_call_details = None + event_success = raw_event.success + event_results = [] + if raw_event.is_new_request: + event_results.append(_types.OpResult( + _types.OpType.RECV_INITIAL_METADATA, raw_event.request_metadata, + None, None, None, None)) + else: + if raw_event.batch_operations: + for operation in raw_event.batch_operations: + result_type = operation.type + result_initial_metadata = operation.received_metadata_or_none + result_trailing_metadata = operation.received_metadata_or_none + result_message = operation.received_message_or_none + if result_message is not None: + result_message = result_message.bytes() + result_cancelled = operation.received_cancelled_or_none + if operation.has_status: + result_status = _types.Status( + operation.received_status_code_or_none, + operation.received_status_details_or_none) + else: + result_status = None + event_results.append( + _types.OpResult(result_type, result_initial_metadata, + result_trailing_metadata, result_message, + result_status, result_cancelled)) + return _types.Event(event_type, event_tag, event_call, event_call_details, + event_results, event_success) def shutdown(self): self.completion_queue.shutdown() @@ -68,7 +109,36 @@ class Call(_types.Call): self.call = call def start_batch(self, ops, tag): - return self.call.start_batch(ops, tag) + translated_ops = [] + for op in ops: + if op.type == _types.OpType.SEND_INITIAL_METADATA: + translated_op = cygrpc.operation_send_initial_metadata( + cygrpc.Metadata( + cygrpc.Metadatum(key, value) + for key, value in op.initial_metadata)) + elif op.type == _types.OpType.SEND_MESSAGE: + translated_op = cygrpc.operation_send_message(op.message) + elif op.type == _types.OpType.SEND_CLOSE_FROM_CLIENT: + translated_op = cygrpc.operation_send_close_from_client() + elif op.type == _types.OpType.SEND_STATUS_FROM_SERVER: + translated_op = cygrpc.operation_send_status_from_server( + cygrpc.Metadata( + cygrpc.Metadatum(key, value) + for key, value in op.trailing_metadata), + op.status.code, + op.status.details) + elif op.type == _types.OpType.RECV_INITIAL_METADATA: + translated_op = cygrpc.operation_receive_initial_metadata() + elif op.type == _types.OpType.RECV_MESSAGE: + translated_op = cygrpc.operation_receive_message() + elif op.type == _types.OpType.RECV_STATUS_ON_CLIENT: + translated_op = cygrpc.operation_receive_status_on_client() + elif op.type == _types.OpType.RECV_CLOSE_ON_SERVER: + translated_op = cygrpc.operation_receive_close_on_server() + else: + raise ValueError('unexpected operation type {}'.format(op.type)) + translated_ops.append(translated_op) + return self.call.start_batch(cygrpc.Operations(translated_ops), tag) def cancel(self, code=None, details=None): if code is None and details is None: @@ -86,14 +156,20 @@ class Call(_types.Call): class Channel(_types.Channel): def __init__(self, target, args, creds=None): - args = list(args) + [(_c.PRIMARY_USER_AGENT_KEY, _USER_AGENT)] + args = list(args) + [ + (cygrpc.ChannelArgKey.primary_user_agent_string, _USER_AGENT)] + args = cygrpc.ChannelArgs( + cygrpc.ChannelArg(key, value) for key, value in args) if creds is None: - self.channel = _c.Channel(target, args) + self.channel = cygrpc.Channel(target, args) else: - self.channel = _c.Channel(target, args, creds) + self.channel = cygrpc.Channel(target, args, creds) def create_call(self, completion_queue, method, host, deadline=None): - return Call(self.channel.create_call(completion_queue.completion_queue, method, host, deadline)) + internal_call = self.channel.create_call( + None, 0, completion_queue.completion_queue, method, host, + cygrpc.Timespec(deadline)) + return Call(internal_call) def check_connectivity_state(self, try_to_connect): return self.channel.check_connectivity_state(try_to_connect) @@ -101,7 +177,8 @@ class Channel(_types.Channel): def watch_connectivity_state(self, last_observed_state, deadline, completion_queue, tag): self.channel.watch_connectivity_state( - last_observed_state, deadline, completion_queue.completion_queue, tag) + last_observed_state, cygrpc.Timespec(deadline), + completion_queue.completion_queue, tag) def target(self): return self.channel.target() @@ -112,7 +189,11 @@ _NO_TAG = object() class Server(_types.Server): def __init__(self, completion_queue, args): - self.server = _c.Server(completion_queue.completion_queue, args) + args = cygrpc.ChannelArgs( + cygrpc.ChannelArg(key, value) for key, value in args) + self.server = cygrpc.Server(args) + self.server.register_completion_queue(completion_queue.completion_queue) + self.server_queue = completion_queue def add_http2_port(self, addr, creds=None): if creds is None: @@ -124,10 +205,11 @@ class Server(_types.Server): return self.server.start() def shutdown(self, tag=None): - return self.server.shutdown(tag) + return self.server.shutdown(self.server_queue.completion_queue, tag) def request_call(self, completion_queue, tag): - return self.server.request_call(completion_queue.completion_queue, tag) + return self.server.request_call(completion_queue.completion_queue, + self.server_queue.completion_queue, tag) def cancel_all_calls(self): return self.server.cancel_all_calls() diff --git a/src/python/grpcio/grpc/_adapter/_types.py b/src/python/grpcio/grpc/_adapter/_types.py index ca0fa066bc..3d5ab33d00 100644 --- a/src/python/grpcio/grpc/_adapter/_types.py +++ b/src/python/grpcio/grpc/_adapter/_types.py @@ -31,6 +31,8 @@ import abc import collections import enum +from grpc._cython import cygrpc + class GrpcChannelArgumentKeys(enum.Enum): """Mirrors keys used in grpc_channel_args for GRPC-specific arguments.""" @@ -40,77 +42,77 @@ class GrpcChannelArgumentKeys(enum.Enum): @enum.unique class CallError(enum.IntEnum): """Mirrors grpc_call_error in the C core.""" - OK = 0 - ERROR = 1 - ERROR_NOT_ON_SERVER = 2 - ERROR_NOT_ON_CLIENT = 3 - ERROR_ALREADY_ACCEPTED = 4 - ERROR_ALREADY_INVOKED = 5 - ERROR_NOT_INVOKED = 6 - ERROR_ALREADY_FINISHED = 7 - ERROR_TOO_MANY_OPERATIONS = 8 - ERROR_INVALID_FLAGS = 9 - ERROR_INVALID_METADATA = 10 + OK = cygrpc.CallError.ok + ERROR = cygrpc.CallError.error + ERROR_NOT_ON_SERVER = cygrpc.CallError.not_on_server + ERROR_NOT_ON_CLIENT = cygrpc.CallError.not_on_client + ERROR_ALREADY_ACCEPTED = cygrpc.CallError.already_accepted + ERROR_ALREADY_INVOKED = cygrpc.CallError.already_invoked + ERROR_NOT_INVOKED = cygrpc.CallError.not_invoked + ERROR_ALREADY_FINISHED = cygrpc.CallError.already_finished + ERROR_TOO_MANY_OPERATIONS = cygrpc.CallError.too_many_operations + ERROR_INVALID_FLAGS = cygrpc.CallError.invalid_flags + ERROR_INVALID_METADATA = cygrpc.CallError.invalid_metadata @enum.unique class StatusCode(enum.IntEnum): """Mirrors grpc_status_code in the C core.""" - OK = 0 - CANCELLED = 1 - UNKNOWN = 2 - INVALID_ARGUMENT = 3 - DEADLINE_EXCEEDED = 4 - NOT_FOUND = 5 - ALREADY_EXISTS = 6 - PERMISSION_DENIED = 7 - RESOURCE_EXHAUSTED = 8 - FAILED_PRECONDITION = 9 - ABORTED = 10 - OUT_OF_RANGE = 11 - UNIMPLEMENTED = 12 - INTERNAL = 13 - UNAVAILABLE = 14 - DATA_LOSS = 15 - UNAUTHENTICATED = 16 + OK = cygrpc.StatusCode.ok + CANCELLED = cygrpc.StatusCode.cancelled + UNKNOWN = cygrpc.StatusCode.unknown + INVALID_ARGUMENT = cygrpc.StatusCode.invalid_argument + DEADLINE_EXCEEDED = cygrpc.StatusCode.deadline_exceeded + NOT_FOUND = cygrpc.StatusCode.not_found + ALREADY_EXISTS = cygrpc.StatusCode.already_exists + PERMISSION_DENIED = cygrpc.StatusCode.permission_denied + RESOURCE_EXHAUSTED = cygrpc.StatusCode.resource_exhausted + FAILED_PRECONDITION = cygrpc.StatusCode.failed_precondition + ABORTED = cygrpc.StatusCode.aborted + OUT_OF_RANGE = cygrpc.StatusCode.out_of_range + UNIMPLEMENTED = cygrpc.StatusCode.unimplemented + INTERNAL = cygrpc.StatusCode.internal + UNAVAILABLE = cygrpc.StatusCode.unavailable + DATA_LOSS = cygrpc.StatusCode.data_loss + UNAUTHENTICATED = cygrpc.StatusCode.unauthenticated @enum.unique class OpWriteFlags(enum.IntEnum): """Mirrors defined write-flag constants in the C core.""" - WRITE_BUFFER_HINT = 1 - WRITE_NO_COMPRESS = 2 + WRITE_BUFFER_HINT = cygrpc.WriteFlag.buffer_hint + WRITE_NO_COMPRESS = cygrpc.WriteFlag.no_compress @enum.unique class OpType(enum.IntEnum): """Mirrors grpc_op_type in the C core.""" - SEND_INITIAL_METADATA = 0 - SEND_MESSAGE = 1 - SEND_CLOSE_FROM_CLIENT = 2 - SEND_STATUS_FROM_SERVER = 3 - RECV_INITIAL_METADATA = 4 - RECV_MESSAGE = 5 - RECV_STATUS_ON_CLIENT = 6 - RECV_CLOSE_ON_SERVER = 7 + SEND_INITIAL_METADATA = cygrpc.OperationType.send_initial_metadata + SEND_MESSAGE = cygrpc.OperationType.send_message + SEND_CLOSE_FROM_CLIENT = cygrpc.OperationType.send_close_from_client + SEND_STATUS_FROM_SERVER = cygrpc.OperationType.send_status_from_server + RECV_INITIAL_METADATA = cygrpc.OperationType.receive_initial_metadata + RECV_MESSAGE = cygrpc.OperationType.receive_message + RECV_STATUS_ON_CLIENT = cygrpc.OperationType.receive_status_on_client + RECV_CLOSE_ON_SERVER = cygrpc.OperationType.receive_close_on_server @enum.unique class EventType(enum.IntEnum): """Mirrors grpc_completion_type in the C core.""" - QUEUE_SHUTDOWN = 0 - QUEUE_TIMEOUT = 1 # if seen on the Python side, something went horridly wrong - OP_COMPLETE = 2 + QUEUE_SHUTDOWN = cygrpc.CompletionType.queue_shutdown + QUEUE_TIMEOUT = cygrpc.CompletionType.queue_timeout + OP_COMPLETE = cygrpc.CompletionType.operation_complete @enum.unique class ConnectivityState(enum.IntEnum): """Mirrors grpc_connectivity_state in the C core.""" - IDLE = 0 - CONNECTING = 1 - READY = 2 - TRANSIENT_FAILURE = 3 - FATAL_FAILURE = 4 + IDLE = cygrpc.ConnectivityState.idle + CONNECTING = cygrpc.ConnectivityState.connecting + READY = cygrpc.ConnectivityState.ready + TRANSIENT_FAILURE = cygrpc.ConnectivityState.transient_failure + FATAL_FAILURE = cygrpc.ConnectivityState.fatal_failure class Status(collections.namedtuple( diff --git a/src/python/grpcio/setup.py b/src/python/grpcio/setup.py index 8ac185bd6b..a948ca1fac 100644 --- a/src/python/grpcio/setup.py +++ b/src/python/grpcio/setup.py @@ -57,19 +57,6 @@ ENABLE_CYTHON_TRACING = os.environ.get( # the installation. INSTALL_TESTS = os.environ.get('GRPC_PYTHON_INSTALL_TESTS', False) -C_EXTENSION_SOURCES = ( - 'grpc/_adapter/_c/module.c', - 'grpc/_adapter/_c/types.c', - 'grpc/_adapter/_c/utility.c', - 'grpc/_adapter/_c/types/call_credentials.c', - 'grpc/_adapter/_c/types/channel_credentials.c', - 'grpc/_adapter/_c/types/server_credentials.c', - 'grpc/_adapter/_c/types/completion_queue.c', - 'grpc/_adapter/_c/types/call.c', - 'grpc/_adapter/_c/types/channel.c', - 'grpc/_adapter/_c/types/server.c', -) - CYTHON_EXTENSION_PACKAGE_NAMES = () CYTHON_EXTENSION_MODULE_NAMES = ( @@ -94,14 +81,6 @@ if not "darwin" in sys.platform: EXTENSION_LIBRARIES += ('rt',) -C_EXTENSION_MODULE = _core.Extension( - 'grpc._adapter._c', sources=list(C_EXTENSION_SOURCES), - include_dirs=list(EXTENSION_INCLUDE_DIRECTORIES), - libraries=list(EXTENSION_LIBRARIES) -) -EXTENSION_MODULES = [C_EXTENSION_MODULE] - - def cython_extensions(package_names, module_names, include_dirs, libraries, build_with_cython=False): file_extension = 'pyx' if build_with_cython else 'c' @@ -185,7 +164,7 @@ else: setuptools.setup( name='grpcio', version='0.11.0b2', - ext_modules=EXTENSION_MODULES + CYTHON_EXTENSION_MODULES, + ext_modules=CYTHON_EXTENSION_MODULES, packages=list(PACKAGES), package_dir=PACKAGE_DIRECTORIES, install_requires=INSTALL_REQUIRES, diff --git a/src/python/grpcio/tests/unit/_adapter/_c_test.py b/src/python/grpcio/tests/unit/_adapter/_c_test.py deleted file mode 100644 index fe020e2a9c..0000000000 --- a/src/python/grpcio/tests/unit/_adapter/_c_test.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import time -import unittest - -from grpc._adapter import _c -from grpc._adapter import _types - - -class CTypeSmokeTest(unittest.TestCase): - - def testCompletionQueueUpDown(self): - completion_queue = _c.CompletionQueue() - del completion_queue - - def testServerUpDown(self): - completion_queue = _c.CompletionQueue() - serv = _c.Server(completion_queue, []) - del serv - del completion_queue - - def testChannelUpDown(self): - channel = _c.Channel('[::]:0', []) - del channel - - -if __name__ == '__main__': - unittest.main(verbosity=2) diff --git a/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py b/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py index 90ad0b9bcb..a6fd82388c 100644 --- a/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py +++ b/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py @@ -115,6 +115,7 @@ class EchoTest(unittest.TestCase): def tearDown(self): self.server.stop() + self.server.cancel_all_calls() self.server_completion_queue.stop() self.client_completion_queue.stop() self.server_completion_queue_thread.join() @@ -286,11 +287,6 @@ class EchoTest(unittest.TestCase): set((server_trailing_metadata_key, server_trailing_binary_metadata_key,))) - server_timeout_none_event = self.server_completion_queue.get(0) - self.assertIsNone(server_timeout_none_event) - client_timeout_none_event = self.client_completion_queue.get(0) - self.assertIsNone(client_timeout_none_event) - self.assertSequenceEqual(test_data, server_data) self.assertSequenceEqual(test_data, client_data) @@ -335,6 +331,7 @@ class CancellationTest(unittest.TestCase): def tearDown(self): self.server.stop() + self.server.cancel_all_calls() self.server_completion_queue.stop() self.client_completion_queue.stop() self.server_completion_queue_thread.join() @@ -410,14 +407,9 @@ class CancellationTest(unittest.TestCase): finish_event = self.client_events.get() self.assertEqual(_low.Event.Kind.FINISH, finish_event.kind) - self.assertEqual(_low.Status(_low.Code.CANCELLED, 'Cancelled'), + self.assertEqual(_low.Status(_low.Code.CANCELLED, 'Cancelled'), finish_event.status) - server_timeout_none_event = self.server_completion_queue.get(0) - self.assertIsNone(server_timeout_none_event) - client_timeout_none_event = self.client_completion_queue.get(0) - self.assertIsNone(client_timeout_none_event) - self.assertSequenceEqual(test_data, server_data) self.assertSequenceEqual(test_data, client_data) diff --git a/src/python/grpcio/tests/unit/_adapter/_low_test.py b/src/python/grpcio/tests/unit/_adapter/_low_test.py index 39b6f247b4..ec46617996 100644 --- a/src/python/grpcio/tests/unit/_adapter/_low_test.py +++ b/src/python/grpcio/tests/unit/_adapter/_low_test.py @@ -80,11 +80,11 @@ class InsecureServerInsecureClient(unittest.TestCase): del self.client_channel self.client_completion_queue.shutdown() - while (self.client_completion_queue.next().type != + while (self.client_completion_queue.next(float('+inf')).type != _types.EventType.QUEUE_SHUTDOWN): pass self.server_completion_queue.shutdown() - while (self.server_completion_queue.next().type != + while (self.server_completion_queue.next(float('+inf')).type != _types.EventType.QUEUE_SHUTDOWN): pass @@ -294,8 +294,12 @@ class HangingServerShutdown(unittest.TestCase): # Now try to shutdown the server and expect that we see server shutdown # almost immediately after calling cancel_all_calls. + + # First attempt to cancel all calls before shutting down, and expect + # our state machine to catch the erroneous API use. with self.assertRaises(RuntimeError): self.server.cancel_all_calls() + shutdown_tag = object() self.server.shutdown(shutdown_tag) pre_cancel_timestamp = time.time() -- GitLab