1# Copyright 2017 gRPC authors.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Common interfaces and implementation."""
15
16import abc
17import collections
18
19import six
20
21
22def _fuss(tuplified_metadata):
23    return tuplified_metadata + ((
24        'grpc.metadata_added_by_runtime',
25        'gRPC is allowed to add metadata in transmission and does so.',
26    ),)
27
28
29FUSSED_EMPTY_METADATA = _fuss(())
30
31
32def fuss_with_metadata(metadata):
33    if metadata is None:
34        return FUSSED_EMPTY_METADATA
35    else:
36        return _fuss(tuple(metadata))
37
38
39def rpc_names(service_descriptors):
40    rpc_names_to_descriptors = {}
41    for service_descriptor in service_descriptors:
42        for method_descriptor in service_descriptor.methods_by_name.values():
43            rpc_name = '/{}/{}'.format(service_descriptor.full_name,
44                                       method_descriptor.name)
45            rpc_names_to_descriptors[rpc_name] = method_descriptor
46    return rpc_names_to_descriptors
47
48
49class ChannelRpcRead(
50        collections.namedtuple('ChannelRpcRead', (
51            'response',
52            'trailing_metadata',
53            'code',
54            'details',
55        ))):
56    pass
57
58
59class ChannelRpcHandler(six.with_metaclass(abc.ABCMeta)):
60
61    @abc.abstractmethod
62    def initial_metadata(self):
63        raise NotImplementedError()
64
65    @abc.abstractmethod
66    def add_request(self, request):
67        raise NotImplementedError()
68
69    @abc.abstractmethod
70    def close_requests(self):
71        raise NotImplementedError()
72
73    @abc.abstractmethod
74    def take_response(self):
75        raise NotImplementedError()
76
77    @abc.abstractmethod
78    def cancel(self, code, details):
79        raise NotImplementedError()
80
81    @abc.abstractmethod
82    def termination(self):
83        raise NotImplementedError()
84
85    @abc.abstractmethod
86    def is_active(self):
87        raise NotImplementedError()
88
89    @abc.abstractmethod
90    def time_remaining(self):
91        raise NotImplementedError()
92
93    @abc.abstractmethod
94    def add_callback(self, callback):
95        raise NotImplementedError()
96
97
98class ChannelHandler(six.with_metaclass(abc.ABCMeta)):
99
100    @abc.abstractmethod
101    def invoke_rpc(self, method_full_rpc_name, invocation_metadata, requests,
102                   requests_closed, timeout):
103        raise NotImplementedError()
104
105
106class ServerRpcRead(
107        collections.namedtuple('ServerRpcRead', (
108            'request',
109            'requests_closed',
110            'terminated',
111        ))):
112    pass
113
114
115REQUESTS_CLOSED = ServerRpcRead(None, True, False)
116TERMINATED = ServerRpcRead(None, False, True)
117
118
119class ServerRpcHandler(six.with_metaclass(abc.ABCMeta)):
120
121    @abc.abstractmethod
122    def send_initial_metadata(self, initial_metadata):
123        raise NotImplementedError()
124
125    @abc.abstractmethod
126    def take_request(self):
127        raise NotImplementedError()
128
129    @abc.abstractmethod
130    def add_response(self, response):
131        raise NotImplementedError()
132
133    @abc.abstractmethod
134    def send_termination(self, trailing_metadata, code, details):
135        raise NotImplementedError()
136
137    @abc.abstractmethod
138    def add_termination_callback(self, callback):
139        raise NotImplementedError()
140
141
142class Serverish(six.with_metaclass(abc.ABCMeta)):
143
144    @abc.abstractmethod
145    def invoke_unary_unary(self, method_descriptor, handler,
146                           invocation_metadata, request, deadline):
147        raise NotImplementedError()
148
149    @abc.abstractmethod
150    def invoke_unary_stream(self, method_descriptor, handler,
151                            invocation_metadata, request, deadline):
152        raise NotImplementedError()
153
154    @abc.abstractmethod
155    def invoke_stream_unary(self, method_descriptor, handler,
156                            invocation_metadata, deadline):
157        raise NotImplementedError()
158
159    @abc.abstractmethod
160    def invoke_stream_stream(self, method_descriptor, handler,
161                             invocation_metadata, deadline):
162        raise NotImplementedError()
163