Пример #1
0
    def _call_before_write_log_iterator(self,
                                        rpc_request,
                                        call_mode=EnumCallMode.Simple,
                                        timeout=None,
                                        trace_info=None):
        """
        远程调用前写日志,并返回要调用的iterator对象
        """
        for _request in rpc_request:
            # 增加调用链信息
            _request.trace_id = trace_info.trace_id
            _request.parent_id = trace_info.call_id
            _request.trace_level = trace_info.trace_level

            if self._logger is not None:
                # 逐个登记调用日志
                _info_dict = self._get_request_info_dict(_request,
                                                         call_mode=call_mode,
                                                         timeout=timeout,
                                                         trace_info=trace_info)
                _info_dict['api_info_type'] = 'STREAM-SEND'
                _info_dict['err_log_msg'] = 'api call chain send log error'
                SimpleGRpcTools.write_api_call_chain_log(
                    self._logger, _info_dict)

            # 返回调用对象
            yield _request
Пример #2
0
    def test(self):
        """
        检测连接是否有效

        @returns {CResult} - 响应对象,判断成功的方法:
            ret.status == msg_pb2.HealthResponse.SERVING
            总共有以下几种状态
            health_pb2.HealthResponse.UNKNOWN
            health_pb2.HealthResponse.SERVICE_UNKNOWN
            health_pb2.HealthResponse.NOT_SERVING
            health_pb2.HealthResponse.SERVING
        """
        _check_result = CResult()
        if self._channel is None:
            # 没有连接
            _check_result.status = msg_pb2.HealthResponse.UNKNOWN
        elif self._test_use_health_check:
            # 使用标准健康检查
            self._health_stub = SimpleGRpcTools.generate_health_check_stub(
                self._channel)
            _check_result = SimpleGRpcTools.health_check_by_stub(
                self._health_stub, self._servicer_name, timeout=self._timeout)
        else:
            # 使用自定义的健康检查
            _check_result = SimpleGRpcTools.simple_grpc_health_check_by_stub(
                self._stub, timeout=self._timeout)
        # 返回结果
        return _check_result
def server_side_stream_call(a, b, *args, **kwargs):
    """
    服务端流模式,真正调用服务端的函数
    """
    # 转换参数
    _para_values = RunTool.get_current_function_parameter_values(is_simple_mode=True)
    _para_obj = SimpleGRpcTools.parameters_to_json(_para_values)
    _req_obj = SimpleGRpcTools.generate_request_obj(
        service_name='service_server_side_stream', para_json=_para_obj.para_json,
        has_para_bytes=_para_obj.has_para_bytes, para_bytes=_para_obj.para_bytes
    )

    # 发送请求, 默认使用全局的日志对象
    _connect_para = SimpleGRpcConnection.generate_connect_para(
        ip='127.0.0.1', port=50051
    )
    _connection = SimpleGRpcConnection(_connect_para)
    _cresult_iterator = _connection.call(_req_obj,
                                         call_mode=EnumCallMode.ServerSideStream)
    _ret = True
    for _cresult in _cresult_iterator:
        if not _cresult.is_success():
            _ret = False

    _connection.close()

    return _ret
Пример #4
0
def client_simple_call_para_server_tsl(a,
                                       b,
                                       *args,
                                       c=10,
                                       d={'d1': 'd1value'},
                                       **kwargs):
    """
    测试简单调用,进行单向认证(客户端验证服务端证书)
    """
    # 转换参数
    _para_values = RunTool.get_current_function_parameter_values(
        is_simple_mode=True)
    _para_obj = SimpleGRpcTools.parameters_to_json(_para_values)
    _req_obj = SimpleGRpcTools.generate_request_obj(
        service_name='service_simple_call_para',
        para_json=_para_obj.para_json,
        has_para_bytes=_para_obj.has_para_bytes,
        para_bytes=_para_obj.para_bytes)
    # 发送请求
    with open(_TEMP_DIR + '/../../simple_grpc/server.crt', 'rb') as f:
        _root_certificates = f.read()
    _connect_para = SimpleGRpcTools.generate_connect_para(
        ip='localhost',
        port=50053,
        is_use_ssl=True,
        root_certificates=_root_certificates)
    _cresult = SimpleGRpcTools.grpc_call(_connect_para, _req_obj)
    _cresult.return_obj = SimpleGRpcTools.json_to_object_by_para_mapping(
        _cresult.return_json, 'client_simple_call_para')
    return _cresult
Пример #5
0
def server_bidirectional_stream_call_one_by_one():
    """
    双向流模式,客户端处理,一个请求对应一个响应的情况
    通过队列传递交互传递参数
    """
    # 清空队列
    TEMP_QUEUE.queue.clear()

    # 处理
    _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1',
                                                          port=50051)
    with SimpleGRpcTools.generate_channel(_connect_para) as channel:
        # # 注意队列一定要先传入一个值
        TEMP_QUEUE.put(None)
        _cresult_iterator = SimpleGRpcTools.grpc_call_by_channel(
            channel,
            bidirectional_stream_one_by_one_generator(),
            call_mode=EnumCallMode.BidirectionalStream)
        for _cresult in _cresult_iterator:
            # 放入队列
            s = _cresult.return_json
            TEMP_QUEUE.put(s)
            if not _cresult.is_success():
                return False
    return True
    def _mutiple_thread_fun(self, i, connect, result: list):
        """
        多线程处理
        """
        _i = i + 1

        # 参数处理
        _para_obj = SimpleGRpcTools.parameters_to_json([['', _i]], is_support_bytes=True)
        _req_obj = SimpleGRpcTools.generate_request_obj(
            service_name='service_mutiple_thread', para_json=_para_obj.para_json,
            has_para_bytes=_para_obj.has_para_bytes, para_bytes=_para_obj.para_bytes
        )

        # 通知外面执行是否成功
        result[i] = False

        # 访问服务
        _cresult: CResult = connect.call(_req_obj)

        self.assertTrue(
            _cresult.is_success(), msg='_mutiple_thread_fun [%d] error: %s' % (i, str(_cresult))
        )

        self.assertTrue(
            _cresult.return_json == str(_i), msg='_mutiple_thread_fun [%d] return error: %s' % (i, str(_cresult.return_json))
        )

        # 通知外面执行是否成功
        result[i] = True
def client_simple_call_para_double_tsl(a, b, *args, c=10, d={'d1': 'd1value'}, **kwargs):
    """
    测试简单调用,进行双向认证(服务端验证客户端证书,客户端验证服务端证书)
    """
    # 转换参数
    _para_values = RunTool.get_current_function_parameter_values(is_simple_mode=True)
    _para_obj = SimpleGRpcTools.parameters_to_json(_para_values)
    _req_obj = SimpleGRpcTools.generate_request_obj(
        service_name='service_simple_call_para', para_json=_para_obj.para_json,
        has_para_bytes=_para_obj.has_para_bytes, para_bytes=_para_obj.para_bytes
    )
    # 发送请求
    with open(_TEMP_DIR + '/../../simple_grpc/client.pem', 'rb') as f:
        _client_private_key = f.read()
    with open(_TEMP_DIR + '/../../simple_grpc/client.crt', 'rb') as f:
        _client_certificate_chain = f.read()
    with open(_TEMP_DIR + '/../../simple_grpc/server.crt', 'rb') as f:
        _root_certificates = f.read()

    # 发送请求, 默认使用全局的日志对象
    _connect_para = SimpleGRpcConnection.generate_connect_para(
        ip='localhost', port=50052, is_use_ssl=True,
        root_certificates=_root_certificates,
        private_key=_client_private_key,
        certificate_chain=_client_certificate_chain
    )
    _connection = SimpleGRpcConnection(_connect_para)
    _cresult = _connection.call(_req_obj)
    _connection.close()

    _cresult.return_obj = SimpleGRpcTools.json_to_object_by_para_mapping(
        _cresult.return_json,
        'client_simple_call_para'
    )
    return _cresult
Пример #8
0
    def test_error(self):
        """
        测试错误信息
        """
        if not TEST_FLAG['test_error']:
            return

        print("测试错误信息")
        print("测试错误信息 - 连接失败")
        _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1',
                                                              port=60051)
        _cresult = SimpleGRpcTools.grpc_call(
            _connect_para, SimpleGRpcTools.generate_request_obj('test'))
        self.assertTrue(
            _cresult.code == '20408'
            and grpc.StatusCode.UNAVAILABLE.name == _cresult.i18n_msg_paras[0],
            '测试错误信息失败 - 连接失败 ')

        print("测试错误信息 - 服务名不存在")
        _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1',
                                                              port=50051)
        _cresult = SimpleGRpcTools.grpc_call(
            _connect_para, SimpleGRpcTools.generate_request_obj('test', ''))
        self.assertTrue(_cresult.code == '11403', '测试错误信息失败 - 服务名不存在 ')

        print("测试错误信息 - 超时")
        _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1',
                                                              port=50051)
        _cresult = SimpleGRpcTools.grpc_call(
            _connect_para,
            SimpleGRpcTools.generate_request_obj('service_simple_overtime'),
            timeout=0.1)
        self.assertTrue(_cresult.code == '30403', '测试错误信息失败 - 超时')
def bidirectional_stream_single_request(a, b, *args, **kwargs):
    """
    双向流模式,产生请求对象的函数
    """
    # 转换参数
    _para_values = RunTool.get_current_function_parameter_values(is_simple_mode=True)
    _para_obj = SimpleGRpcTools.parameters_to_json(_para_values)
    _req_obj = SimpleGRpcTools.generate_request_obj(
        service_name='service_bidirectional_stream', para_json=_para_obj.para_json,
        has_para_bytes=_para_obj.has_para_bytes, para_bytes=_para_obj.para_bytes
    )
    return _req_obj
Пример #10
0
def client_side_stream_call():
    """
    客户端流模式,真正调用服务端的函数
    """
    # 发送请求
    _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1',
                                                          port=50051)
    _cresult = SimpleGRpcTools.grpc_call(
        _connect_para,
        client_side_stream_generator(),
        call_mode=EnumCallMode.ClientSideStream)
    _cresult.return_obj = SimpleGRpcTools.json_to_object_by_para_mapping(
        _cresult.return_json, 'service_client_side_stream')
    return _cresult
Пример #11
0
def server_bidirectional_stream_call_n_by_one():
    """
    双向流模式,客户端处理,多个请求对应一个响应的情况
    """
    # 处理
    _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1',
                                                          port=50051)
    with SimpleGRpcTools.generate_channel(_connect_para) as channel:
        _cresult_iterator = SimpleGRpcTools.grpc_call_by_channel(
            channel,
            bidirectional_stream_n_by_one_generator(),
            call_mode=EnumCallMode.BidirectionalStream)
        for _cresult in _cresult_iterator:
            # 打印
            print('bidirectional_stream_n_by_one client get: ' +
                  _cresult.return_json)
            if not _cresult.is_success():
                return False
    return True
def get_client_simple_call_para(a,
                                b,
                                *args,
                                c=10,
                                d={'d1': 'd1value'},
                                **kwargs):
    """
    测试简单调用,直接返回参数
    """
    # 转换参数
    _para_values = RunTool.get_current_function_parameter_values(
        is_simple_mode=True)
    _para_obj = SimpleGRpcTools.parameters_to_json(_para_values)
    _req_obj = SimpleGRpcTools.generate_request_obj(
        service_name='service_simple_call_para',
        para_json=_para_obj.para_json,
        has_para_bytes=_para_obj.has_para_bytes,
        para_bytes=_para_obj.para_bytes)
    return _req_obj
Пример #13
0
    def __init__(self, connect_para):
        """
        构造函数

        @param {NullObj} connect_para - 具体参数见SimpleGRpcConnection.generate_connect_para函数的定义

        @throws {ConnectionError} - 如果连接时需要检查有效性,当检查失败时抛出该异常
        """
        # 内部变量初始化
        self._trace_info_dict = dict()

        # 初始化参数
        self._connect_para = connect_para
        self._fill_connect_para(self._connect_para)
        self._test_on_connect = connect_para.test_on_connect
        self._test_use_health_check = connect_para.test_use_health_check
        self._servicer_name = connect_para.servicer_name
        self._logger = connect_para.logger
        self._log_level = connect_para.log_level
        self._timeout = connect_para.timeout

        # 日志处理
        if self._logger is None and connect_para.is_use_global_logger:
            # 使用全局logger
            self._logger = RunTool.get_global_logger()

        # 进行连接
        self._channel = SimpleGRpcTools.generate_channel(self._connect_para)
        self._stub = SimpleGRpcTools.generate_call_stub(self._channel)

        # 检查连接有效性
        if self._test_on_connect:
            _check_result = self.test()
            if _check_result.status != msg_pb2.HealthResponse.SERVING:
                # 连接失败,打印日志后抛出异常
                if self._logger is not None:
                    self._logger.log(
                        self._log_level, '[EX:%s]%s%s\n%s' %
                        (_check_result.error,
                         'SimpleGRpcConnection init error: ',
                         _check_result.msg, _check_result.trace_str))
                raise ConnectionError(_check_result.msg)
Пример #14
0
def client_simple_throw_excepiton():
    """
    测试简单调用,抛出异常
    """
    # 转换参数
    _para_values = RunTool.get_current_function_parameter_values(
        is_simple_mode=True)
    _para_obj = SimpleGRpcTools.parameters_to_json(_para_values)
    _req_obj = SimpleGRpcTools.generate_request_obj(
        service_name='service_simple_throw_excepiton',
        para_json=_para_obj.para_json,
        has_para_bytes=_para_obj.has_para_bytes,
        para_bytes=_para_obj.para_bytes)
    # 发送请求
    _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1',
                                                          port=50051)
    _cresult = SimpleGRpcTools.grpc_call(_connect_para, _req_obj)
    _cresult.return_obj = SimpleGRpcTools.json_to_object_by_para_mapping(
        _cresult.return_json, 'client_simple_throw_excepiton')
    return _cresult
Пример #15
0
    def _call_after_write_log(self,
                              cresult,
                              start_time,
                              call_mode=EnumCallMode.Simple,
                              timeout=None,
                              trace_info=None):
        """
        登记返回结果日志
        """
        if self._logger is not None:
            # 登记返回结果日志
            _info_dict = self._get_cresult_info_dict(cresult,
                                                     start_time,
                                                     call_mode=call_mode,
                                                     timeout=timeout,
                                                     trace_info=trace_info)
            _info_dict['err_log_msg'] = 'api call chain back log error'
            SimpleGRpcTools.write_api_call_chain_log(self._logger, _info_dict)

        return cresult
Пример #16
0
def client_simple_call_para(a, b, *args, c=10, d={'d1': 'd1value'}, **kwargs):
    """
    测试简单调用,直接返回参数
    """
    # 转换参数
    _para_values = RunTool.get_current_function_parameter_values(
        is_simple_mode=True)
    _para_obj = SimpleGRpcTools.parameters_to_json(_para_values)
    _req_obj = SimpleGRpcTools.generate_request_obj(
        service_name='service_simple_call_para',
        para_json=_para_obj.para_json,
        has_para_bytes=_para_obj.has_para_bytes,
        para_bytes=_para_obj.para_bytes)
    # 发送请求
    _connect_para = SimpleGRpcTools.generate_connect_para(
        conn_str='127.0.0.1:50051')
    _cresult = SimpleGRpcTools.grpc_call(_connect_para, _req_obj)
    _cresult.return_obj = SimpleGRpcTools.json_to_object_by_para_mapping(
        _cresult.return_json, 'client_simple_call_para')
    return _cresult
Пример #17
0
    def _call_after_write_log_iterator(self,
                                       cresult_iterator,
                                       start_time,
                                       call_mode=EnumCallMode.Simple,
                                       timeout=None,
                                       trace_info=None):
        for _cresult in cresult_iterator:
            if self._logger is not None:
                # 逐个登记返回结果日志
                _info_dict = self._get_cresult_info_dict(_cresult,
                                                         start_time,
                                                         call_mode=call_mode,
                                                         timeout=timeout,
                                                         trace_info=trace_info)
                _info_dict['err_log_msg'] = 'api call chain back log error'
                SimpleGRpcTools.write_api_call_chain_log(
                    self._logger, _info_dict)

            # 返回结果对象
            yield _cresult
def client_simple_throw_excepiton():
    """
    测试简单调用,抛出异常
    """
    # 转换参数
    _para_values = RunTool.get_current_function_parameter_values(
        is_simple_mode=True)
    _para_obj = SimpleGRpcTools.parameters_to_json(_para_values)
    _req_obj = SimpleGRpcTools.generate_request_obj(
        service_name='service_simple_throw_excepiton',
        para_json=_para_obj.para_json,
        has_para_bytes=_para_obj.has_para_bytes,
        para_bytes=_para_obj.para_bytes)
    # 发送请求, 默认使用全局的日志对象
    _connect_para = SimpleGRpcConnection.generate_connect_para(
        conn_str='127.0.0.1:50051')
    _connection = SimpleGRpcConnection(_connect_para)
    _cresult = _connection.call(_req_obj)
    _connection.close()
    _cresult.return_obj = SimpleGRpcTools.json_to_object_by_para_mapping(
        _cresult.return_json, 'client_simple_throw_excepiton')
    return _cresult
Пример #19
0
def server_side_stream_call(a, b, *args, **kwargs):
    """
    服务端流模式,真正调用服务端的函数
    """
    # 转换参数
    _para_values = RunTool.get_current_function_parameter_values(
        is_simple_mode=True)
    _para_obj = SimpleGRpcTools.parameters_to_json(_para_values)
    _req_obj = SimpleGRpcTools.generate_request_obj(
        service_name='service_server_side_stream',
        para_json=_para_obj.para_json,
        has_para_bytes=_para_obj.has_para_bytes,
        para_bytes=_para_obj.para_bytes)
    _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1',
                                                          port=50051)
    with SimpleGRpcTools.generate_channel(_connect_para) as channel:
        _cresult_iterator = SimpleGRpcTools.grpc_call_by_channel(
            channel, _req_obj, call_mode=EnumCallMode.ServerSideStream)
        for _cresult in _cresult_iterator:
            if not _cresult.is_success():
                return False
    return True
Пример #20
0
    def test_health_check(self):
        """
        测试服务健康状态
        """
        if not TEST_FLAG['test_health_check']:
            return

        print("测试服务健康状态")
        _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.1',
                                                              port=50051)
        print("测试服务健康状态 - 服务中")
        _resp_obj = SimpleGRpcTools.health_check(_connect_para,
                                                 'servicer_simple_call')
        self.assertTrue(
            _resp_obj.status == health_pb2.HealthCheckResponse.SERVING,
            '测试服务健康状态失败 - 服务中')

        print("测试服务健康状态 - 停止服务")
        self.server_no_ssl_no_zoo.set_service_status(
            'servicer_simple_call', health_pb2.HealthCheckResponse.NOT_SERVING)
        _resp_obj = SimpleGRpcTools.health_check(_connect_para,
                                                 'servicer_simple_call')
        self.assertTrue(
            _resp_obj.status == health_pb2.HealthCheckResponse.NOT_SERVING,
            '测试服务健康状态失败 - 停止服务')

        # 恢复服务
        self.server_no_ssl_no_zoo.set_service_status(
            'servicer_simple_call', health_pb2.HealthCheckResponse.SERVING)

        print("测试服务健康状态 - 服务不存在")
        _connect_para = SimpleGRpcTools.generate_connect_para(ip='127.0.0.2',
                                                              port=50051)
        _resp_obj = SimpleGRpcTools.health_check(_connect_para,
                                                 'servicer_simple_call')
        self.assertTrue(
            _resp_obj.status == health_pb2.HealthCheckResponse.UNKNOWN,
            '测试服务健康状态失败 - 服务不存在')
Пример #21
0
    def reconnect(self):
        """
        重新连接

        @returns {CResult} - 响应对象,判断成功的方法:
            ret.status == msg_pb2.HealthResponse.SERVING
            总共有以下几种状态
            health_pb2.HealthResponse.UNKNOWN
            health_pb2.HealthResponse.SERVICE_UNKNOWN
            health_pb2.HealthResponse.NOT_SERVING
            health_pb2.HealthResponse.SERVING
        """
        # 先关闭连接
        self.close()

        # 进行连接
        self._channel = SimpleGRpcTools.generate_channel(self._connect_para)
        self._stub = SimpleGRpcTools.generate_call_stub(self._channel)

        # 检查连接有效性
        if self._test_on_connect:
            _check_result = self.test()
            if not _check_result.is_success(
            ) or _check_result.status != msg_pb2.HealthResponse.SERVING:
                # 连接失败,打印日志后抛出异常
                if self._logger is not None:
                    self._logger.log(
                        self._log_level, '[EX:%s]%s%s, service status:%s\n%s' %
                        (_check_result.error,
                         'SimpleGRpcConnection reconnect error: ',
                         _check_result.msg, _check_result.status,
                         _check_result.trace_str))
            return _check_result
        else:
            # 不检查的情况,直接返回成功,连接状态为SERVING
            _check_result = CResult('00000')
            _check_result.status = msg_pb2.HealthResponse.SERVING
            return _check_result
Пример #22
0
    def _call_before_write_log(self,
                               rpc_request,
                               call_mode=EnumCallMode.Simple,
                               timeout=None,
                               trace_info=None):
        """
        远程调用前写日志,并返回要调用的参数
        """
        # 增加调用链信息
        rpc_request.trace_id = trace_info.trace_id
        rpc_request.parent_id = trace_info.call_id
        rpc_request.trace_level = trace_info.trace_level

        if self._logger is not None:
            # 登记调用日志
            _info_dict = self._get_request_info_dict(rpc_request,
                                                     call_mode=call_mode,
                                                     timeout=timeout,
                                                     trace_info=trace_info)
            _info_dict['err_log_msg'] = 'api call chain send log error'
            SimpleGRpcTools.write_api_call_chain_log(self._logger, _info_dict)

        return rpc_request
def client_simple_call_para(a, b, *args, c=10, d={'d1': 'd1value'}, **kwargs):
    """
    测试简单调用,直接返回参数
    """
    # 转换参数
    _para_values = RunTool.get_current_function_parameter_values(is_simple_mode=True)
    _para_obj = SimpleGRpcTools.parameters_to_json(_para_values)
    _req_obj = SimpleGRpcTools.generate_request_obj(
        service_name='service_simple_call_para', para_json=_para_obj.para_json,
        has_para_bytes=_para_obj.has_para_bytes, para_bytes=_para_obj.para_bytes
    )
    # 发送请求, 默认使用全局的日志对象
    _connect_para = SimpleGRpcConnection.generate_connect_para(
        conn_str='127.0.0.1:50051', servicer_name='servicer_simple_call',
        test_on_connect=True, test_use_health_check=False
    )
    _connection = SimpleGRpcConnection(_connect_para)
    _cresult = _connection.call(_req_obj)
    _connection.close()
    _cresult.return_obj = SimpleGRpcTools.json_to_object_by_para_mapping(
        _cresult.return_json,
        'client_simple_call_para'
    )
    return _cresult
Пример #24
0
    def call(self,
             rpc_request,
             call_mode=EnumCallMode.Simple,
             timeout=None,
             metadata=None,
             credentials=None,
             wait_for_ready=None,
             compression=None,
             **kwargs):
        """
        执行gRPC远程调用

        @param {msg_pb2.RpcRequest|request_iterator} rpc_request - 请求对象或产生请求对象的迭代器(iterator),应与call_mode匹配
        @param {EnumCallMode} call_mode=EnumCallMode.Simple - 调用服务端的模式
        @param {number} timeout=None - 超时时间,单位为秒
        @param {object} metadata=None - Optional :term:`metadata` to be transmitted to the
            service-side of the RPC.
        @param {object} credentials=None - An optional CallCredentials for the RPC. Only valid for
            secure Channel.
        @param {object} wait_for_ready=None - This is an EXPERIMENTAL argument. An optional
            flag to enable wait for ready mechanism
        @param {object} compression=None - An element of grpc.compression, e.g.
            grpc.compression.Gzip. This is an EXPERIMENTAL option.
        @param {**kwargs} kwargs - 动态参数,用于支持调用链信息

        @returns {CResult|iterator} - 执行结果CResult或执行结果的迭代器(iterator),与call_mode匹配
            CResult对象有以下3个属性:
            return_json - 返回值的json字符串
            has_return_bytes - 是否有返回字节数组
            return_bytes - 返回的字节数组
        """
        _start_time = datetime.datetime.now()  # 开始处理时间
        _trace_info = self._get_trace_info(**kwargs)  # 获取调用链信息
        _request = None
        _timeout = timeout
        if timeout is None or timeout <= 0:
            _timeout = self._connect_para.timeout

        # 发送之前记录日
        if call_mode in [EnumCallMode.Simple, EnumCallMode.ServerSideStream]:
            _request = self._call_before_write_log(rpc_request=rpc_request,
                                                   call_mode=call_mode,
                                                   timeout=_timeout,
                                                   trace_info=_trace_info)
        else:
            _request = self._call_before_write_log_iterator(
                rpc_request=rpc_request,
                call_mode=call_mode,
                timeout=_timeout,
                trace_info=_trace_info)

        # 执行调用
        _cresult_call = SimpleGRpcTools.grpc_call_by_stub(
            self._stub,
            rpc_request=_request,
            call_mode=call_mode,
            timeout=_timeout,
            metadata=metadata,
            credentials=credentials,
            wait_for_ready=wait_for_ready,
            compression=compression)

        # 接收响应后记录日志
        if call_mode in [EnumCallMode.Simple, EnumCallMode.ClientSideStream]:
            _cresult = self._call_after_write_log(_cresult_call,
                                                  _start_time,
                                                  call_mode=call_mode,
                                                  timeout=_timeout,
                                                  trace_info=_trace_info)
        else:
            _cresult = self._call_after_write_log_iterator(
                _cresult_call,
                _start_time,
                call_mode=call_mode,
                timeout=_timeout,
                trace_info=_trace_info)

        # 返回结果
        return _cresult
Пример #25
0
    def setUpClass(cls):
        """
        启动测试类执行的初始化,只执行一次
        """
        # 初始化日志类
        DebugTool.set_debug(False)
        try:
            # 删除临时日志
            FileTool.remove_files(path=_TEMP_DIR + '/log/',
                                  regex_str='test_case*')
        except:
            pass

        cls.logger = simple_log.Logger(
            conf_file_name=_TEMP_DIR +
            '/../../simple_grpc/test_simple_grpc.json',
            logger_name=simple_log.EnumLoggerName.ConsoleAndFile,
            config_type=simple_log.EnumLoggerConfigType.JSON_FILE,
            logfile_path=_TEMP_DIR + '/log/test_case_asyn.log',
            is_create_logfile_by_day=True,
        )
        cls.logger.setLevelWithHandler(simple_log.DEBUG)

        # 设置json转换对象的参数映射

        # 日志处理函数
        def _asyn_logging_fun(levelno, topic_name, msg):
            print('haha:%s, %s, %s' % (str(levelno), topic_name, msg))

        # 异步日志
        cls._asyn_logger = CallChainTool.create_call_chain_logger(
            logger=cls.logger,
            asyn_logging=True,
            asyn_logging_fun=_asyn_logging_fun,
            asyn_deal_msg_fun=SimpleGRpcTools.api_call_chain_asyn_deal_msg_fun)

        # 服务端处理类,可以多个服务公用
        cls.servicer_simple_call = SimpleGRpcServicer(logger=cls._asyn_logger)
        cls.servicer_simple_call.add_service(EnumCallMode.Simple,
                                             'service_simple_call_para',
                                             service_simple_call_para)
        cls.servicer_simple_call.add_service(
            EnumCallMode.Simple, 'service_simple_call_no_para_no_return',
            service_simple_call_no_para_no_return)
        cls.servicer_simple_call.add_service(EnumCallMode.Simple,
                                             'service_simple_call_return',
                                             service_simple_call_return)
        cls.servicer_simple_call.add_service(EnumCallMode.Simple,
                                             'service_simple_throw_excepiton',
                                             service_simple_throw_excepiton)
        cls.servicer_simple_call.add_service(EnumCallMode.Simple,
                                             'service_simple_overtime',
                                             service_simple_overtime)
        cls.servicer_simple_call.add_service(EnumCallMode.ClientSideStream,
                                             'service_client_side_stream',
                                             service_client_side_stream)
        cls.servicer_simple_call.add_service(EnumCallMode.ServerSideStream,
                                             'service_server_side_stream',
                                             service_server_side_stream)
        cls.servicer_simple_call.add_service(EnumCallMode.BidirectionalStream,
                                             'service_bidirectional_stream',
                                             service_bidirectional_stream)

        # 初始化并启动服务,简单服务,无SSL,无服务发现
        cls.server_no_ssl_no_zoo_opts = SimpleGRpcServer.generate_server_opts(
            ip='127.0.0.1',
            port=50051,
            max_workers=10,
            max_connect=100,
            is_health_check=True)
        cls.server_no_ssl_no_zoo = SimpleGRpcServer(
            server_name='ServerNoSslNoZoo',
            logger=cls.logger,
            log_level=simple_log.INFO)

        cls.server_no_ssl_no_zoo.start_server(
            server_opts=cls.server_no_ssl_no_zoo_opts,
            servicer_list={'servicer_simple_call': cls.servicer_simple_call},
            is_wait=True)

        # 初始化并启动服务,简单服务,无服务发现,TSL双向认证模式
        _private_key_certificate_chain_pair = SimpleGRpcTools.get_private_key_certificate_chain_pair(
            _TEMP_DIR + '/../../simple_grpc/server.pem',
            _TEMP_DIR + '/../../simple_grpc/server.crt')
        with open(_TEMP_DIR + '/../../simple_grpc/client.crt', 'rb') as f:
            # 根证书
            _root_certificates = f.read()

        cls.server_double_ssl_no_zoo_opts = SimpleGRpcServer.generate_server_opts(
            ip='localhost',
            port=50052,
            max_workers=10,
            max_connect=100,
            is_use_ssl=True,
            private_key_certificate_chain_pairs=(
                _private_key_certificate_chain_pair, ),
            root_certificates=_root_certificates)
        cls.server_double_ssl_no_zoo = SimpleGRpcServer(
            server_name='ServerDoubleSslNoZoo',
            logger=cls.logger,
            log_level=simple_log.INFO)
        cls.server_double_ssl_no_zoo.start_server(
            server_opts=cls.server_double_ssl_no_zoo_opts,
            servicer_list={'servicer_simple_call': cls.servicer_simple_call},
            is_wait=True)

        # 初始化并启动服务,简单服务,无服务发现,TSL单向认证模式(仅验证服务端证书)
        cls.server_server_ssl_no_zoo_opts = SimpleGRpcServer.generate_server_opts(
            ip='localhost',
            port=50053,
            max_workers=10,
            max_connect=100,
            is_use_ssl=True,
            private_key_certificate_chain_pairs=(
                _private_key_certificate_chain_pair, ),
            root_certificates=None)
        cls.server_server_ssl_no_zoo = SimpleGRpcServer(
            server_name='ServerServerSslNoZoo',
            logger=cls.logger,
            log_level=simple_log.INFO)
        cls.server_server_ssl_no_zoo.start_server(
            server_opts=cls.server_server_ssl_no_zoo_opts,
            servicer_list={'servicer_simple_call': cls.servicer_simple_call},
            is_wait=True)
    def test_connect_pool(self):
        """
        测试连接池
        """
        print("开始测试连接池")

        _connect_para = SimpleGRpcConnection.generate_connect_para(
            conn_str='127.0.0.1:50051',
            servicer_name='servicer_simple_call',
            test_on_connect=False,
            test_use_health_check=False)
        # 建立连接池
        _pool = SimpleGRpcConnectionPool(_connect_para,
                                         name='ConnectionPool',
                                         maxsize=3,
                                         minsize=0,
                                         realse_free_time=5,
                                         test_on_get=True,
                                         test_on_free=True,
                                         test_while_idle=True,
                                         test_idle_time=5,
                                         validation_query='',
                                         get_connection_timeout=1,
                                         logger=self._asyn_logger,
                                         init_break_if_connect_error=True)

        print("测试连接池-获取连接并执行")
        # 尝试获取连接
        _connection = _pool.get_connection()
        _back_server = service_simple_call_para('a1', 'b1')
        _req_obj = get_client_simple_call_para('a1', 'b1')
        _back_client = _connection.call(_req_obj)
        _back_client.return_obj = SimpleGRpcTools.json_to_object_by_para_mapping(
            _back_client.return_json, 'client_simple_call_para')

        self.assertTrue(
            _back_client.is_success(),
            msg=
            '测试连接池-获取连接并执行失败,执行RPC失败: code=%s, msg=%s, error=%s, i18n_msg_paras=%s'
            % (_back_client.code, _back_client.msg, _back_client.error,
               str(_back_client.i18n_msg_paras)))
        self.assertTrue(compare_object_by_json(_back_server,
                                               _back_client.return_obj),
                        msg='测试连接池-获取连接并执行, 执行参数不一致')

        print('测试连接池-获取连接超时')
        _c1 = _pool.get_connection()
        _c2 = _pool.get_connection()

        try:
            _c3 = _pool.get_connection()
            self.assertTrue(False, msg='测试连接池-获取连接超时失败,应抛出超时')
        except TimeoutError:
            pass
        except Exception as e:
            self.assertTrue(False, msg='测试连接池-获取连接超时失败,未期望的异常:%s' % str(e))

        self.assertTrue(3 == _pool.current_size,
                        msg='测试连接池-获取连接超时-当前连接池大小错误:%d' % _pool.current_size)

        print('测试连接池-释放连接')
        _pool.free_connection(_connection)
        _c3 = _pool.get_connection()  # 这样c3可用获取连接并使用
        self.assertTrue(3 == _pool.current_size,
                        msg='测试连接池-释放连接-当前连接池大小错误:%d' % _pool.current_size)

        print('测试连接池-自动释放连接')
        _pool.free_connection(_c1)
        _pool.free_connection(_c2)
        _pool.free_connection(_c3)
        time.sleep(10)
        self.assertTrue(0 == _pool.current_size,
                        msg='测试连接池-自动释放连接-当前连接池大小错误:%d' % _pool.current_size)