From cb520b0947faf8be2678bc0f1cb7f1a8656beb03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Tue, 7 Apr 2015 19:37:42 +0800 Subject: [PATCH 01/70] first upload --- README.md | 8 ++++ dubbo_client/__init__.py | 1 + dubbo_client/config.py | 1 + dubbo_client/registry.py | 85 +++++++++++++++++++++++++++++++++++ dubbo_client/rpc.py | 35 +++++++++++++++ dubbo_client/tools.py | 2 + test_dubbo_client/__init__.py | 1 + 7 files changed, 133 insertions(+) create mode 100644 README.md create mode 100644 dubbo_client/__init__.py create mode 100644 dubbo_client/config.py create mode 100644 dubbo_client/registry.py create mode 100644 dubbo_client/rpc.py create mode 100644 dubbo_client/tools.py create mode 100644 test_dubbo_client/__init__.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..9b0c6d6 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +### Python Dubbo Client + +##Python调用Dubbo接口的jsonrpc协议 +请使用dubbo-rpc-jsonrpc + +##在客户端实现负载均衡,服务发现 +通过注册中心的zookeeper,获取服务的注册信息 +然后通过代理实现负载均衡算法,调用服务端 \ No newline at end of file diff --git a/dubbo_client/__init__.py b/dubbo_client/__init__.py new file mode 100644 index 0000000..681fccd --- /dev/null +++ b/dubbo_client/__init__.py @@ -0,0 +1 @@ +__author__ = 'caozupeng' diff --git a/dubbo_client/config.py b/dubbo_client/config.py new file mode 100644 index 0000000..681fccd --- /dev/null +++ b/dubbo_client/config.py @@ -0,0 +1 @@ +__author__ = 'caozupeng' diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py new file mode 100644 index 0000000..ae98d80 --- /dev/null +++ b/dubbo_client/registry.py @@ -0,0 +1,85 @@ +# encoding=utf-8 +import urllib +from urlparse import urlparse, parse_qsl + +from kazoo.protocol.states import KazooState + + +__author__ = 'caozupeng' +from kazoo.client import KazooClient +import logging + +logging.basicConfig() +zk = KazooClient(hosts='172.19.65.33:2181', read_only=True) +service_provides = {} + + +def state_listener(state): + if state == KazooState.LOST: + # Register somewhere that the session was lost + print 'session lost' + elif state == KazooState.SUSPENDED: + # Handle being disconnected from Zookeeper + print 'disconnect from zookeeper' + else: + # Handle being connected/reconnected to Zookeeper + print 'connected' + + +zk.add_listener(state_listener) + + +class JsonProvide(object): + protocol = 'jsonrpc' + location = '' + path = '' + ip = '127.0.0.1' + port = '9090' + + def __init__(self, url): + result = urlparse(url) + self.protocol = result[0] + self.location = result[1] + self.path = result[2] + if self.location.find(':') > -1: + self.ip, self.port = result[1].split(':') + params = parse_qsl(result[4]) + for key, value in params: + # url has a default.timeout property, but it can not add in python object + # so keep the last one + pos = key.find('.') + if pos > -1: + key = key[pos + 1:] + print key + self.__dict__[key] = value + + +def node_listener(event): + print event + + +def add_provider_listener(provide_name): + children = zk.get_children('{0}/{1}/{2}'.format('dubbo', provide_name, 'providers'), watch=node_listener) + for child_node in children: + url = urllib.unquote(child_node).decode('utf8') + if url.startswith('jsonrpc'): + provide = JsonProvide(url) + service_key = service_provides.get(provide.interface) + if service_key: + service_key[provide.location] = provide + else: + service_provides[provide.interface] = {provide.location: provide} + + +zk.start() + +if __name__ == '__main__': + zk.start() + if zk.exists("/dubbo"): + # Print the version of a node and its data + # children = zk.get_children("/dubbo") + # print "There are {0} children".format(len(children)) + # for node in children: + # print node + add_provider_listener('com.ofpay.demo.api.UserProvider') + diff --git a/dubbo_client/rpc.py b/dubbo_client/rpc.py new file mode 100644 index 0000000..fb2b7fa --- /dev/null +++ b/dubbo_client/rpc.py @@ -0,0 +1,35 @@ +import httplib +import json + +from dubbo_client.registry import service_provides, add_provider_listener + + +__author__ = 'caozupeng' + + +def raw_client(service_interface, app_params): + headers = {"Content-type": "application/json-rpc", + "Accept": "text/json"} + provides = service_provides.get(service_interface, ()) + if len(provides) > 0: + location, first = provides.items().pop() + h1 = httplib.HTTPConnection(first.ip, port=int(first.port)) + h1.request("POST", first.path, json.dumps(app_params), headers) + response = h1.getresponse() + return response.read(), None + else: + return None, 'can not find the provide of {0}'.format(service_interface) + + +if __name__ == '__main__': + app_params = { + "jsonrpc": "2.0", + "method": "getUser", + "params": ["A001"], + "id": 1 + } + service_interface = 'com.ofpay.demo.api.UserProvider' + add_provider_listener(service_interface) + ret, error = raw_client(service_interface, app_params) + if not error: + print json.loads(ret, encoding='utf-8') \ No newline at end of file diff --git a/dubbo_client/tools.py b/dubbo_client/tools.py new file mode 100644 index 0000000..bfc1c30 --- /dev/null +++ b/dubbo_client/tools.py @@ -0,0 +1,2 @@ +#encoding=utf-8 +__author__ = 'caozupeng' diff --git a/test_dubbo_client/__init__.py b/test_dubbo_client/__init__.py new file mode 100644 index 0000000..681fccd --- /dev/null +++ b/test_dubbo_client/__init__.py @@ -0,0 +1 @@ +__author__ = 'caozupeng' From 2dd3531e30a617e0717bd5f1dc97048a87fa6b66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Tue, 7 Apr 2015 19:39:48 +0800 Subject: [PATCH 02/70] =?UTF-8?q?=E6=8D=A2=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9b0c6d6..4c656d5 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ ### Python Dubbo Client -##Python调用Dubbo接口的jsonrpc协议 +##Python调用Dubbo接口的jsonrpc协议 请使用dubbo-rpc-jsonrpc -##在客户端实现负载均衡,服务发现 +##在客户端实现负载均衡,服务发现 通过注册中心的zookeeper,获取服务的注册信息 然后通过代理实现负载均衡算法,调用服务端 \ No newline at end of file From b902a898876a9c140a217bed1c71f70022761029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Wed, 8 Apr 2015 11:32:06 +0800 Subject: [PATCH 03/70] =?UTF-8?q?=E5=A2=9E=E5=8A=A0dubbo=20client=E7=9A=84?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/__init__.py | 4 +++ dubbo_client/registry.py | 2 +- dubbo_client/rpc.py | 39 ++++++++++++++++++++++++++++++ test_dubbo_client/test_registry.py | 11 +++++++++ test_dubbo_client/test_rpclib.py | 13 ++++++++++ 5 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 test_dubbo_client/test_registry.py create mode 100644 test_dubbo_client/test_rpclib.py diff --git a/dubbo_client/__init__.py b/dubbo_client/__init__.py index 681fccd..8bf05e7 100644 --- a/dubbo_client/__init__.py +++ b/dubbo_client/__init__.py @@ -1 +1,5 @@ __author__ = 'caozupeng' + +from rpc import ( + DubboClient, +) diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index ae98d80..5be84a7 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -1,4 +1,4 @@ -# encoding=utf-8 +# coding=utf-8 import urllib from urlparse import urlparse, parse_qsl diff --git a/dubbo_client/rpc.py b/dubbo_client/rpc.py index fb2b7fa..ed24b31 100644 --- a/dubbo_client/rpc.py +++ b/dubbo_client/rpc.py @@ -1,5 +1,7 @@ import httplib import json +import random +from pyjsonrpc import HttpClient from dubbo_client.registry import service_provides, add_provider_listener @@ -21,6 +23,43 @@ def raw_client(service_interface, app_params): return None, 'can not find the provide of {0}'.format(service_interface) +class DubboClient(object): + clients = [] + + class _Method(object): + + def __init__(self, client_instance, method): + self.client_instance = client_instance + self.method = method + + def __call__(self, *args, **kwargs): + return self.client_instance.call(self.method, *args, **kwargs) + + def __init__(self, interface): + add_provider_listener(interface) + provides = service_provides.get(interface, ()) + if len(provides) > 0: + for location, provide in provides.items(): + self.clients.append(HttpClient(url="http://{0}{1}".format(location, provide.path))) + + def call(self, method, *args, **kwargs): + client = random.choice(self.clients) + return client.call(method, *args, **kwargs) + + def __call__(self, method, *args, **kwargs): + """ + Redirects the direct call to *self.call* + """ + return self.call(method, *args, **kwargs) + + def __getattr__(self, method): + """ + Allows the usage of attributes as *method* names. + """ + + return self._Method(client_instance=self, method=method) + + if __name__ == '__main__': app_params = { "jsonrpc": "2.0", diff --git a/test_dubbo_client/test_registry.py b/test_dubbo_client/test_registry.py new file mode 100644 index 0000000..b07546a --- /dev/null +++ b/test_dubbo_client/test_registry.py @@ -0,0 +1,11 @@ +from dubbo_client.registry import zk + +__author__ = 'caozupeng' + +if __name__ == '__main__': + if zk.exists("/dubbo"): + # Print the version of a node and its data + children = zk.get_children("/dubbo") + print "There are {0} children".format(len(children)) + for node in children: + print node \ No newline at end of file diff --git a/test_dubbo_client/test_rpclib.py b/test_dubbo_client/test_rpclib.py new file mode 100644 index 0000000..4649c56 --- /dev/null +++ b/test_dubbo_client/test_rpclib.py @@ -0,0 +1,13 @@ +# coding=utf-8 +from dubbo_client import DubboClient + +__author__ = 'caozupeng' + +if __name__ == '__main__': + service_interface = 'com.ofpay.demo.api.UserProvider' + dubbo_client = DubboClient(service_interface) + print dubbo_client.getUser('A003') + print dubbo_client.queryUser( + {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) + print dubbo_client.queryAll() + print dubbo_client.isLimit('MAN', 'Joe') \ No newline at end of file From ba2946b40d627ebd7529c6bf6cb9cacaedd7edfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Wed, 8 Apr 2015 11:57:01 +0800 Subject: [PATCH 04/70] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4c656d5..a3040ca 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,24 @@ -### Python Dubbo Client +Python Dubbo Client +===================================== +实现客户端的负载均衡、自动发现服务功能 +------------------------------------- -##Python调用Dubbo接口的jsonrpc协议 -请使用dubbo-rpc-jsonrpc -##在客户端实现负载均衡,服务发现 +###Python调用Dubbo接口的jsonrpc协议 +请使用dubbo-rpc-jsonrpc 并在dubbo中配置protocol为jsonrpc协议 + +###在客户端实现负载均衡,服务发现 通过注册中心的zookeeper,获取服务的注册信息 -然后通过代理实现负载均衡算法,调用服务端 \ No newline at end of file +然后通过代理实现负载均衡算法,调用服务端 + +### Example +"""Python + service_interface = 'com.ofpay.demo.api.UserProvider' + dubbo_client = DubboClient(service_interface) + print dubbo_client.getUser('A003') + print dubbo_client.queryUser( + {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) + print dubbo_client.queryAll() + print dubbo_client.isLimit('MAN', 'Joe') + print dubbo_client('getUser', 'A005') +""" \ No newline at end of file From 0877f0a531bf1dd3fc9b643fff9c556f1bdb5a63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Wed, 8 Apr 2015 11:58:19 +0800 Subject: [PATCH 05/70] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a3040ca..ef3b19d 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,15 @@ Python Dubbo Client ------------------------------------- -###Python调用Dubbo接口的jsonrpc协议 +### Python调用Dubbo接口的jsonrpc协议 请使用dubbo-rpc-jsonrpc 并在dubbo中配置protocol为jsonrpc协议 -###在客户端实现负载均衡,服务发现 +### 在客户端实现负载均衡,服务发现 通过注册中心的zookeeper,获取服务的注册信息 然后通过代理实现负载均衡算法,调用服务端 ### Example -"""Python +'''Python service_interface = 'com.ofpay.demo.api.UserProvider' dubbo_client = DubboClient(service_interface) print dubbo_client.getUser('A003') @@ -21,4 +21,4 @@ Python Dubbo Client print dubbo_client.queryAll() print dubbo_client.isLimit('MAN', 'Joe') print dubbo_client('getUser', 'A005') -""" \ No newline at end of file +''' \ No newline at end of file From cf4fc7b1a9439403c385c419569c89a9838ce8cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Wed, 8 Apr 2015 11:58:56 +0800 Subject: [PATCH 06/70] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ef3b19d..14949e6 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Python Dubbo Client 然后通过代理实现负载均衡算法,调用服务端 ### Example -'''Python +'''python service_interface = 'com.ofpay.demo.api.UserProvider' dubbo_client = DubboClient(service_interface) print dubbo_client.getUser('A003') From 545cb6cf157839018cf7599f5ff0964131886ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Wed, 8 Apr 2015 11:59:30 +0800 Subject: [PATCH 07/70] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 14949e6..67b5793 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Python Dubbo Client 然后通过代理实现负载均衡算法,调用服务端 ### Example -'''python +'''python service_interface = 'com.ofpay.demo.api.UserProvider' dubbo_client = DubboClient(service_interface) print dubbo_client.getUser('A003') From 63296e1b4360c2f1e7cec6a9c353f78da06bc0f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Wed, 8 Apr 2015 11:59:50 +0800 Subject: [PATCH 08/70] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 67b5793..bce90b7 100644 --- a/README.md +++ b/README.md @@ -20,5 +20,5 @@ Python Dubbo Client {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) print dubbo_client.queryAll() print dubbo_client.isLimit('MAN', 'Joe') - print dubbo_client('getUser', 'A005') + print dubbo_client('getUser', 'A005') ''' \ No newline at end of file From aedce893e91c5b2c13c7b7ac71ead634f769550a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Wed, 8 Apr 2015 12:00:21 +0800 Subject: [PATCH 09/70] =?UTF-8?q?=E5=8E=9F=E6=9D=A5=E4=B8=8D=E6=98=AF?= =?UTF-8?q?=E5=8D=95=E5=BC=95=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bce90b7..0c3801d 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Python Dubbo Client 然后通过代理实现负载均衡算法,调用服务端 ### Example -'''python +```python service_interface = 'com.ofpay.demo.api.UserProvider' dubbo_client = DubboClient(service_interface) print dubbo_client.getUser('A003') @@ -21,4 +21,4 @@ Python Dubbo Client print dubbo_client.queryAll() print dubbo_client.isLimit('MAN', 'Joe') print dubbo_client('getUser', 'A005') -''' \ No newline at end of file +``` \ No newline at end of file From 4cbf4e62dd0f080167a4c72e1080367fe829fafa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Wed, 8 Apr 2015 22:29:46 +0800 Subject: [PATCH 10/70] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- version.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 version.txt diff --git a/version.txt b/version.txt new file mode 100644 index 0000000..6c6aa7c --- /dev/null +++ b/version.txt @@ -0,0 +1 @@ +0.1.0 \ No newline at end of file From e7a761a7d072b2d5742173f05b508f4b3d0e557b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Wed, 8 Apr 2015 22:39:58 +0800 Subject: [PATCH 11/70] =?UTF-8?q?=E6=8A=BD=E7=A6=BBproviders=E5=88=B0commo?= =?UTF-8?q?ns=E5=AF=B9=E8=B1=A1=EF=BC=8C=E6=B3=A8=E5=86=8C=E4=B8=AD?= =?UTF-8?q?=E5=BF=83=E4=BD=BF=E7=94=A8=E7=BA=BF=E7=A8=8B=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?event=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/common.py | 29 ++++++++++ dubbo_client/registry.py | 90 +++++++++++++++++++------------- dubbo_client/rpc.py | 14 ++--- dubbo_client/tools.py | 2 - test_dubbo_client/test_rpclib.py | 16 ++++-- 5 files changed, 103 insertions(+), 48 deletions(-) create mode 100644 dubbo_client/common.py delete mode 100644 dubbo_client/tools.py diff --git a/dubbo_client/common.py b/dubbo_client/common.py new file mode 100644 index 0000000..ff103ba --- /dev/null +++ b/dubbo_client/common.py @@ -0,0 +1,29 @@ +#encoding=utf-8 +from urlparse import urlparse, parse_qsl + +__author__ = 'caozupeng' + + +class ServiceProvider(object): + protocol = 'jsonrpc' + location = '' # ip+port + path = '' # like /com.qianmi.dubbo.UserProvider + ip = '127.0.0.1' + port = '9090' + + def __init__(self, url): + result = urlparse(url) + self.protocol = result[0] + self.location = result[1] + self.path = result[2] + if self.location.find(':') > -1: + self.ip, self.port = result[1].split(':') + params = parse_qsl(result[4]) + for key, value in params: + # url has a default.timeout property, but it can not add in python object + # so keep the last one + pos = key.find('.') + if pos > -1: + key = key[pos + 1:] + print key + self.__dict__[key] = value \ No newline at end of file diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index 5be84a7..fe15119 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -1,9 +1,12 @@ # coding=utf-8 +import Queue +from threading import Thread import urllib -from urlparse import urlparse, parse_qsl from kazoo.protocol.states import KazooState +from dubbo_client.common import ServiceProvider + __author__ = 'caozupeng' from kazoo.client import KazooClient @@ -11,6 +14,11 @@ logging.basicConfig() zk = KazooClient(hosts='172.19.65.33:2181', read_only=True) +""" +所有注册过的服务端将在这里 +格式为{providername:{ip+port:service}} +providername = group_version_servicename +""" service_provides = {} @@ -29,41 +37,16 @@ def state_listener(state): zk.add_listener(state_listener) -class JsonProvide(object): - protocol = 'jsonrpc' - location = '' - path = '' - ip = '127.0.0.1' - port = '9090' - - def __init__(self, url): - result = urlparse(url) - self.protocol = result[0] - self.location = result[1] - self.path = result[2] - if self.location.find(':') > -1: - self.ip, self.port = result[1].split(':') - params = parse_qsl(result[4]) - for key, value in params: - # url has a default.timeout property, but it can not add in python object - # so keep the last one - pos = key.find('.') - if pos > -1: - key = key[pos + 1:] - print key - self.__dict__[key] = value - - def node_listener(event): print event + event_queue.put(event) -def add_provider_listener(provide_name): - children = zk.get_children('{0}/{1}/{2}'.format('dubbo', provide_name, 'providers'), watch=node_listener) - for child_node in children: +def handler_urls(urls): + for child_node in urls: url = urllib.unquote(child_node).decode('utf8') if url.startswith('jsonrpc'): - provide = JsonProvide(url) + provide = ServiceProvider(url) service_key = service_provides.get(provide.interface) if service_key: service_key[provide.location] = provide @@ -71,15 +54,52 @@ def add_provider_listener(provide_name): service_provides[provide.interface] = {provide.location: provide} +def add_provider_listener(provide_name): + #如果已经存在,首先删除原有的服务的集合 + if provide_name in service_provides: + del service_provides[provide_name] + children = zk.get_children('{0}/{1}/{2}'.format('dubbo', provide_name, 'providers'), watch=node_listener) + #全部重新添加 + handler_urls(children) + + +num_worker_threads = 2 + + +def worker(): + while True: + event = event_queue.get() + do_event(event) + event_queue.task_done() + + +event_queue = Queue.Queue() + + +def do_event(event): + # event.path 是类似/dubbo/com.ofpay.demo.api.UserProvider/providers 这样的 + # 如果要删除,必须先把/dubbo/和最后的/providers去掉 + provide_name = event.path[7:event.path.rfind('/')] + if provide_name in service_provides: + del service_provides[provide_name] + if event.state == 'CONNECTED': + children = zk.get_children(event.path, watch=node_listener) + handler_urls(children) + if event.state == 'DELETED': + children = zk.get_children(event.path, watch=node_listener) + handler_urls(children) + +for i in range(num_worker_threads): + t = Thread(target=worker) + t.daemon = False + t.start() + + zk.start() +event_queue.join() if __name__ == '__main__': zk.start() if zk.exists("/dubbo"): - # Print the version of a node and its data - # children = zk.get_children("/dubbo") - # print "There are {0} children".format(len(children)) - # for node in children: - # print node add_provider_listener('com.ofpay.demo.api.UserProvider') diff --git a/dubbo_client/rpc.py b/dubbo_client/rpc.py index ed24b31..01d4e17 100644 --- a/dubbo_client/rpc.py +++ b/dubbo_client/rpc.py @@ -24,7 +24,7 @@ def raw_client(service_interface, app_params): class DubboClient(object): - clients = [] + interface = '' class _Method(object): @@ -36,14 +36,16 @@ def __call__(self, *args, **kwargs): return self.client_instance.call(self.method, *args, **kwargs) def __init__(self, interface): + self.interface = interface add_provider_listener(interface) - provides = service_provides.get(interface, ()) - if len(provides) > 0: - for location, provide in provides.items(): - self.clients.append(HttpClient(url="http://{0}{1}".format(location, provide.path))) def call(self, method, *args, **kwargs): - client = random.choice(self.clients) + provides = service_provides.get(self.interface, ()) + if len(provides) == 0: + return None + location, provide = random.choice(provides.items()) + print 'location is {0}'.format(location) + client = HttpClient(url="http://{0}{1}".format(location, provide.path)) return client.call(method, *args, **kwargs) def __call__(self, method, *args, **kwargs): diff --git a/dubbo_client/tools.py b/dubbo_client/tools.py deleted file mode 100644 index bfc1c30..0000000 --- a/dubbo_client/tools.py +++ /dev/null @@ -1,2 +0,0 @@ -#encoding=utf-8 -__author__ = 'caozupeng' diff --git a/test_dubbo_client/test_rpclib.py b/test_dubbo_client/test_rpclib.py index 4649c56..6bf7e04 100644 --- a/test_dubbo_client/test_rpclib.py +++ b/test_dubbo_client/test_rpclib.py @@ -1,13 +1,19 @@ # coding=utf-8 +import time + from dubbo_client import DubboClient + __author__ = 'caozupeng' if __name__ == '__main__': service_interface = 'com.ofpay.demo.api.UserProvider' dubbo_client = DubboClient(service_interface) - print dubbo_client.getUser('A003') - print dubbo_client.queryUser( - {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) - print dubbo_client.queryAll() - print dubbo_client.isLimit('MAN', 'Joe') \ No newline at end of file + for i in range(1000): + print dubbo_client.getUser('A003') + print dubbo_client.queryUser( + {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) + print dubbo_client.queryAll() + print dubbo_client.isLimit('MAN', 'Joe') + print dubbo_client('getUser', 'A005') + time.sleep(5) From b7edce4826dca7e97004118c5d5b5a5088bc92ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Wed, 8 Apr 2015 22:41:56 +0800 Subject: [PATCH 12/70] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E4=B8=8D=E5=88=B0providers=E7=9A=84=E9=BB=98=E8=AE=A4=E5=80=BC?= =?UTF-8?q?=E4=BB=8Etuple=E5=88=B0dict?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/rpc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo_client/rpc.py b/dubbo_client/rpc.py index 01d4e17..0ac0b81 100644 --- a/dubbo_client/rpc.py +++ b/dubbo_client/rpc.py @@ -40,7 +40,7 @@ def __init__(self, interface): add_provider_listener(interface) def call(self, method, *args, **kwargs): - provides = service_provides.get(self.interface, ()) + provides = service_provides.get(self.interface, {}) if len(provides) == 0: return None location, provide = random.choice(provides.items()) From 5dcf7c994c3003d70d143218e3ae1d82877b8e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 9 Apr 2015 20:16:25 +0800 Subject: [PATCH 13/70] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E7=9A=84=E5=AE=9A=E4=B9=89=E5=92=8C=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/__init__.py | 1 + dubbo_client/registry.py | 4 +- dubbo_client/rpc.py | 13 +++-- dubbo_client/rpcerror.py | 88 ++++++++++++++++++++++++++++++++ test_dubbo_client/test_rpclib.py | 18 ++++--- 5 files changed, 112 insertions(+), 12 deletions(-) create mode 100644 dubbo_client/rpcerror.py diff --git a/dubbo_client/__init__.py b/dubbo_client/__init__.py index 8bf05e7..7feb134 100644 --- a/dubbo_client/__init__.py +++ b/dubbo_client/__init__.py @@ -3,3 +3,4 @@ from rpc import ( DubboClient, ) +from rpcerror import * \ No newline at end of file diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index fe15119..025782a 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -38,7 +38,7 @@ def state_listener(state): def node_listener(event): - print event + # print event event_queue.put(event) @@ -91,7 +91,7 @@ def do_event(event): for i in range(num_worker_threads): t = Thread(target=worker) - t.daemon = False + t.daemon = True t.start() diff --git a/dubbo_client/rpc.py b/dubbo_client/rpc.py index 0ac0b81..6bbd3ba 100644 --- a/dubbo_client/rpc.py +++ b/dubbo_client/rpc.py @@ -1,9 +1,11 @@ import httplib import json import random -from pyjsonrpc import HttpClient +from urllib2 import HTTPError +from pyjsonrpc import HttpClient, JsonRpcError from dubbo_client.registry import service_provides, add_provider_listener +from dubbo_client.rpcerror import NoProvider, ConnectionFail, dubbo_client_errors __author__ = 'caozupeng' @@ -42,11 +44,16 @@ def __init__(self, interface): def call(self, method, *args, **kwargs): provides = service_provides.get(self.interface, {}) if len(provides) == 0: - return None + raise NoProvider('can not find provide', self.interface) location, provide = random.choice(provides.items()) print 'location is {0}'.format(location) client = HttpClient(url="http://{0}{1}".format(location, provide.path)) - return client.call(method, *args, **kwargs) + try: + return client.call(method, *args, **kwargs) + except HTTPError, e: + raise ConnectionFail(None, e.filename) + except JsonRpcError, error: + raise dubbo_client_errors.get(error.code, None) def __call__(self, method, *args, **kwargs): """ diff --git a/dubbo_client/rpcerror.py b/dubbo_client/rpcerror.py new file mode 100644 index 0000000..fae2805 --- /dev/null +++ b/dubbo_client/rpcerror.py @@ -0,0 +1,88 @@ +# coding=utf-8 +__author__ = 'caozupeng' + +dubbo_client_errors = {} + + +class DubboClientError(RuntimeError): + code = None + message = None + data = None + + def __init__(self, message=None, data=None, code=None): + RuntimeError.__init__(self) + self.message = message or self.message + self.data = data + self.code = code or self.code + assert self.code, "Error without code is not allowed." + + def __str__(self): + return "DubboError({code}): {message}".format( + code=self.code, + message=str(self.message) + ) + + def __unicode__(self): + return u"DubboClientError({code}): {message}".format( + code=self.code, + message=self.message + ) + + +class MethodNotFound(DubboClientError): + code = -32601 + message = u"The method does not exist / is not available." + + def __init__(self, message=None, data=None): + DubboClientError.__init__(self, message=message, data=data) + + +class ConnectionFail(DubboClientError): + code = 504 + message = u'connect failed {0}' + + def __init__(self, message=None, data=None): + message = self.message.format(data) + DubboClientError.__init__(self, message=message, data=data) + + +class NoProvider(DubboClientError): + code = 5050 + message = u'No provide name {0}' + provide_name = u'' + + def __init__(self, message=None, data=None): + self.provide_name = data + DubboClientError.__init__(self, message=self.message.format(data), data=data) + + +class InvalidParams(DubboClientError): + code = -32602 + message = u"Invalid method parameter(s)." + + def __init__(self, message=None, data=None): + DubboClientError.__init__(self, message=message, data=data) + + +class InternalError(DubboClientError): + code = -32603 + message = u"Internal JSON-RPC error." + + def __init__(self, message=None, data=None): + DubboClientError.__init__(self, message=message, data=data) + + +class InvalidRequest(DubboClientError): + code = -32600 + message = u"The JSON sent is not a valid Request object." + + def __init__(self, message=None, data=None): + DubboClientError.__init__(self, message=message, data=data) + + +dubbo_client_errors[MethodNotFound.code] = MethodNotFound +dubbo_client_errors[NoProvider.code] = NoProvider +dubbo_client_errors[ConnectionFail.code] = ConnectionFail +dubbo_client_errors[InvalidParams.code] = InvalidParams +dubbo_client_errors[InternalError.code] = InternalError +dubbo_client_errors[InvalidRequest.code] = InvalidRequest diff --git a/test_dubbo_client/test_rpclib.py b/test_dubbo_client/test_rpclib.py index 6bf7e04..2346359 100644 --- a/test_dubbo_client/test_rpclib.py +++ b/test_dubbo_client/test_rpclib.py @@ -1,7 +1,7 @@ # coding=utf-8 import time -from dubbo_client import DubboClient +from dubbo_client import DubboClient, DubboClientError __author__ = 'caozupeng' @@ -10,10 +10,14 @@ service_interface = 'com.ofpay.demo.api.UserProvider' dubbo_client = DubboClient(service_interface) for i in range(1000): - print dubbo_client.getUser('A003') - print dubbo_client.queryUser( - {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) - print dubbo_client.queryAll() - print dubbo_client.isLimit('MAN', 'Joe') - print dubbo_client('getUser', 'A005') + try: + print dubbo_client.getUser('A003') + print dubbo_client.queryUser( + {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) + print dubbo_client.queryAll() + print dubbo_client.isLimit('MAN', 'Joe') + print dubbo_client('getUser', 'A005') + + except DubboClientError, client_e: + print client_e time.sleep(5) From 24f113fd4307d44aad04cb390d6e2e5a1c9e77e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 9 Apr 2015 21:25:54 +0800 Subject: [PATCH 14/70] =?UTF-8?q?=E5=B0=86Registry=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=B8=BA=E4=B8=80=E4=B8=AAClass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/__init__.py | 7 +- dubbo_client/common.py | 2 +- dubbo_client/registry.py | 185 +++++++++++++++-------------- dubbo_client/rpc.py | 38 ++---- test_dubbo_client/test_registry.py | 11 +- test_dubbo_client/test_rpclib.py | 4 +- 6 files changed, 117 insertions(+), 130 deletions(-) diff --git a/dubbo_client/__init__.py b/dubbo_client/__init__.py index 7feb134..0d2608a 100644 --- a/dubbo_client/__init__.py +++ b/dubbo_client/__init__.py @@ -3,4 +3,9 @@ from rpc import ( DubboClient, ) -from rpcerror import * \ No newline at end of file +from rpcerror import * + +from registry import ( + Registry, + ZookeeperRegistry, +) \ No newline at end of file diff --git a/dubbo_client/common.py b/dubbo_client/common.py index ff103ba..2b49e6c 100644 --- a/dubbo_client/common.py +++ b/dubbo_client/common.py @@ -25,5 +25,5 @@ def __init__(self, url): pos = key.find('.') if pos > -1: key = key[pos + 1:] - print key + # print key self.__dict__[key] = value \ No newline at end of file diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index 025782a..d64be6e 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -1,6 +1,4 @@ # coding=utf-8 -import Queue -from threading import Thread import urllib from kazoo.protocol.states import KazooState @@ -10,96 +8,105 @@ __author__ = 'caozupeng' from kazoo.client import KazooClient -import logging -logging.basicConfig() -zk = KazooClient(hosts='172.19.65.33:2181', read_only=True) -""" -所有注册过的服务端将在这里 -格式为{providername:{ip+port:service}} -providername = group_version_servicename -""" -service_provides = {} +class Registry(object): + def add_provider_listener(self, provide_name): + """ + 监听注册中心的服务上下线 + :param provide_name: 类似com.ofpay.demo.api.UserProvider这样的服务名 + :return: 无返回 + """ + pass + + def get_provides(self, provide_name, default=None): + """ + 获取已经注册的服务URL对象 + :param provide_name: com.ofpay.demo.api.UserProvider + :param default: + :return: 返回一个dict的服务集合 + """ + pass + + +class ZookeeperRegistry(Registry): + """ + 所有注册过的服务端将在这里 + 格式为{providername:{ip+port:service}} + providername = group_version_servicename + """ + __service_provides = {} + __connect_state = 'UNCONNECT' + + def __init__(self, hosts): + self.__zk = KazooClient(hosts=hosts, read_only=True) + self.__zk.add_listener(self.__state_listener) + self.__zk.start() + + def __state_listener(self, state): + if state == KazooState.LOST: + # Register somewhere that the session was lost + self.__connect_state = state + elif state == KazooState.SUSPENDED: + # Handle being disconnected from Zookeeper + print 'disconnect from zookeeper' + self.__connect_state = state + else: + # Handle being connected/reconnected to Zookeeper + print 'connected' + self.__connect_state = state + + def __event_listener(self, event): + self.__do_event(event) + + def __handler_urls(self, urls): + for child_node in urls: + url = urllib.unquote(child_node).decode('utf8') + if url.startswith('jsonrpc'): + provide = ServiceProvider(url) + service_key = self.__service_provides.get(provide.interface) + if service_key: + service_key[provide.location] = provide + else: + self.__service_provides[provide.interface] = {provide.location: provide} + + def __do_event(self, event): + # event.path 是类似/dubbo/com.ofpay.demo.api.UserProvider/providers 这样的 + # 如果要删除,必须先把/dubbo/和最后的/providers去掉 + provide_name = event.path[7:event.path.rfind('/')] + if provide_name in self.__service_provides: + del self.__service_provides[provide_name] + if event.state == 'CONNECTED': + children = self.__zk.get_children(event.path, watch=self.__event_listener) + self.__handler_urls(children) + if event.state == 'DELETED': + children = self.__zk.get_children(event.path, watch=self.__event_listener) + self.__handler_urls(children) + + def add_provider_listener(self, provide_name): + """ + 监听注册中心的服务上下线 + :param provide_name: 类似com.ofpay.demo.api.UserProvider这样的服务名 + :return: 无返回 + """ + # 如果已经存在,首先删除原有的服务的集合 + if provide_name in self.__service_provides: + del self.__service_provides[provide_name] + children = self.__zk.get_children('{0}/{1}/{2}'.format('dubbo', provide_name, 'providers'), + watch=self.__event_listener) + # 全部重新添加 + self.__handler_urls(children) + + def get_provides(self, provide_name, default=None): + """ + 获取已经注册的服务URL对象 + :param provide_name: com.ofpay.demo.api.UserProvider + :param default: + :return: 返回一个dict的服务集合 + """ + return self.__service_provides.get(provide_name, default) -def state_listener(state): - if state == KazooState.LOST: - # Register somewhere that the session was lost - print 'session lost' - elif state == KazooState.SUSPENDED: - # Handle being disconnected from Zookeeper - print 'disconnect from zookeeper' - else: - # Handle being connected/reconnected to Zookeeper - print 'connected' - - -zk.add_listener(state_listener) - - -def node_listener(event): - # print event - event_queue.put(event) - - -def handler_urls(urls): - for child_node in urls: - url = urllib.unquote(child_node).decode('utf8') - if url.startswith('jsonrpc'): - provide = ServiceProvider(url) - service_key = service_provides.get(provide.interface) - if service_key: - service_key[provide.location] = provide - else: - service_provides[provide.interface] = {provide.location: provide} - - -def add_provider_listener(provide_name): - #如果已经存在,首先删除原有的服务的集合 - if provide_name in service_provides: - del service_provides[provide_name] - children = zk.get_children('{0}/{1}/{2}'.format('dubbo', provide_name, 'providers'), watch=node_listener) - #全部重新添加 - handler_urls(children) - - -num_worker_threads = 2 - - -def worker(): - while True: - event = event_queue.get() - do_event(event) - event_queue.task_done() - - -event_queue = Queue.Queue() - - -def do_event(event): - # event.path 是类似/dubbo/com.ofpay.demo.api.UserProvider/providers 这样的 - # 如果要删除,必须先把/dubbo/和最后的/providers去掉 - provide_name = event.path[7:event.path.rfind('/')] - if provide_name in service_provides: - del service_provides[provide_name] - if event.state == 'CONNECTED': - children = zk.get_children(event.path, watch=node_listener) - handler_urls(children) - if event.state == 'DELETED': - children = zk.get_children(event.path, watch=node_listener) - handler_urls(children) - -for i in range(num_worker_threads): - t = Thread(target=worker) - t.daemon = True - t.start() - - -zk.start() -event_queue.join() if __name__ == '__main__': - zk.start() - if zk.exists("/dubbo"): - add_provider_listener('com.ofpay.demo.api.UserProvider') + pass diff --git a/dubbo_client/rpc.py b/dubbo_client/rpc.py index 6bbd3ba..888d985 100644 --- a/dubbo_client/rpc.py +++ b/dubbo_client/rpc.py @@ -1,30 +1,15 @@ -import httplib -import json import random from urllib2 import HTTPError + from pyjsonrpc import HttpClient, JsonRpcError -from dubbo_client.registry import service_provides, add_provider_listener + from dubbo_client.rpcerror import NoProvider, ConnectionFail, dubbo_client_errors __author__ = 'caozupeng' -def raw_client(service_interface, app_params): - headers = {"Content-type": "application/json-rpc", - "Accept": "text/json"} - provides = service_provides.get(service_interface, ()) - if len(provides) > 0: - location, first = provides.items().pop() - h1 = httplib.HTTPConnection(first.ip, port=int(first.port)) - h1.request("POST", first.path, json.dumps(app_params), headers) - response = h1.getresponse() - return response.read(), None - else: - return None, 'can not find the provide of {0}'.format(service_interface) - - class DubboClient(object): interface = '' @@ -37,12 +22,13 @@ def __init__(self, client_instance, method): def __call__(self, *args, **kwargs): return self.client_instance.call(self.method, *args, **kwargs) - def __init__(self, interface): + def __init__(self, interface, registry): self.interface = interface - add_provider_listener(interface) + self.registry = registry + self.registry.add_provider_listener(interface) def call(self, method, *args, **kwargs): - provides = service_provides.get(self.interface, {}) + provides = self.registry.get_provides(self.interface, {}) if len(provides) == 0: raise NoProvider('can not find provide', self.interface) location, provide = random.choice(provides.items()) @@ -70,14 +56,4 @@ def __getattr__(self, method): if __name__ == '__main__': - app_params = { - "jsonrpc": "2.0", - "method": "getUser", - "params": ["A001"], - "id": 1 - } - service_interface = 'com.ofpay.demo.api.UserProvider' - add_provider_listener(service_interface) - ret, error = raw_client(service_interface, app_params) - if not error: - print json.loads(ret, encoding='utf-8') \ No newline at end of file + pass \ No newline at end of file diff --git a/test_dubbo_client/test_registry.py b/test_dubbo_client/test_registry.py index b07546a..8cef5b2 100644 --- a/test_dubbo_client/test_registry.py +++ b/test_dubbo_client/test_registry.py @@ -1,11 +1,8 @@ -from dubbo_client.registry import zk +from dubbo_client import ZookeeperRegistry __author__ = 'caozupeng' if __name__ == '__main__': - if zk.exists("/dubbo"): - # Print the version of a node and its data - children = zk.get_children("/dubbo") - print "There are {0} children".format(len(children)) - for node in children: - print node \ No newline at end of file + registry = ZookeeperRegistry('172.19.65.33:2181') + registry.add_provider_listener('com.ofpay.demo.api.UserProvider') + print registry.get_provides('com.ofpay.demo.api.UserProvider') \ No newline at end of file diff --git a/test_dubbo_client/test_rpclib.py b/test_dubbo_client/test_rpclib.py index 2346359..553dce9 100644 --- a/test_dubbo_client/test_rpclib.py +++ b/test_dubbo_client/test_rpclib.py @@ -2,13 +2,15 @@ import time from dubbo_client import DubboClient, DubboClientError +from dubbo_client import ZookeeperRegistry __author__ = 'caozupeng' if __name__ == '__main__': service_interface = 'com.ofpay.demo.api.UserProvider' - dubbo_client = DubboClient(service_interface) + registry = ZookeeperRegistry('172.19.65.33:2181') + dubbo_client = DubboClient(service_interface, registry) for i in range(1000): try: print dubbo_client.getUser('A003') From 286ecdcc930ae2b8b161b3819f0d185a79d718b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 9 Apr 2015 21:31:43 +0800 Subject: [PATCH 15/70] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E5=90=8D=E5=92=8C=E6=8E=92=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/registry.py | 18 ++++++++++-------- test_dubbo_client/test_rpclib.py | 4 ++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index d64be6e..7c86e5f 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -1,13 +1,10 @@ # coding=utf-8 -import urllib - -from kazoo.protocol.states import KazooState - -from dubbo_client.common import ServiceProvider - __author__ = 'caozupeng' +import urllib +from kazoo.protocol.states import KazooState from kazoo.client import KazooClient +from dubbo_client.common import ServiceProvider class Registry(object): @@ -38,8 +35,8 @@ class ZookeeperRegistry(Registry): __service_provides = {} __connect_state = 'UNCONNECT' - def __init__(self, hosts): - self.__zk = KazooClient(hosts=hosts, read_only=True) + def __init__(self, zk_hosts): + self.__zk = KazooClient(hosts=zk_hosts, read_only=True) self.__zk.add_listener(self.__state_listener) self.__zk.start() @@ -57,6 +54,11 @@ def __state_listener(self, state): self.__connect_state = state def __event_listener(self, event): + """ + node provides上下线的监听回调函数 + :param event: + :return: + """ self.__do_event(event) def __handler_urls(self, urls): diff --git a/test_dubbo_client/test_rpclib.py b/test_dubbo_client/test_rpclib.py index 553dce9..61f4a25 100644 --- a/test_dubbo_client/test_rpclib.py +++ b/test_dubbo_client/test_rpclib.py @@ -20,6 +20,6 @@ print dubbo_client.isLimit('MAN', 'Joe') print dubbo_client('getUser', 'A005') - except DubboClientError, client_e: - print client_e + except DubboClientError, client_error: + print client_error time.sleep(5) From 5012e46e52a9b7acb9c91c9cd1c803a689aa9aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 9 Apr 2015 21:38:25 +0800 Subject: [PATCH 16/70] =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=E5=92=8C=E5=86=85=E9=83=A8=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/common.py | 2 +- dubbo_client/registry.py | 29 +++++++++++++++++------------ 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/dubbo_client/common.py b/dubbo_client/common.py index 2b49e6c..d2945ce 100644 --- a/dubbo_client/common.py +++ b/dubbo_client/common.py @@ -4,7 +4,7 @@ __author__ = 'caozupeng' -class ServiceProvider(object): +class ServiceURL(object): protocol = 'jsonrpc' location = '' # ip+port path = '' # like /com.qianmi.dubbo.UserProvider diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index 7c86e5f..5ea57a0 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -4,7 +4,7 @@ import urllib from kazoo.protocol.states import KazooState from kazoo.client import KazooClient -from dubbo_client.common import ServiceProvider +from dubbo_client.common import ServiceURL class Registry(object): @@ -61,16 +61,21 @@ def __event_listener(self, event): """ self.__do_event(event) - def __handler_urls(self, urls): - for child_node in urls: - url = urllib.unquote(child_node).decode('utf8') - if url.startswith('jsonrpc'): - provide = ServiceProvider(url) - service_key = self.__service_provides.get(provide.interface) + def __handler_nodes(self, nodes): + """ + 将zookeeper中查询到的服务节点列表加入到一个dict中 + :param nodes: 节点列表 + :return: 不需要返回 + """ + for child_node in nodes: + node = urllib.unquote(child_node).decode('utf8') + if node.startswith('jsonrpc'): + service_url = ServiceURL(node) + service_key = self.__service_provides.get(service_url.interface) if service_key: - service_key[provide.location] = provide + service_key[service_url.location] = service_url else: - self.__service_provides[provide.interface] = {provide.location: provide} + self.__service_provides[service_url.interface] = {service_url.location: service_url} def __do_event(self, event): # event.path 是类似/dubbo/com.ofpay.demo.api.UserProvider/providers 这样的 @@ -80,10 +85,10 @@ def __do_event(self, event): del self.__service_provides[provide_name] if event.state == 'CONNECTED': children = self.__zk.get_children(event.path, watch=self.__event_listener) - self.__handler_urls(children) + self.__handler_nodes(children) if event.state == 'DELETED': children = self.__zk.get_children(event.path, watch=self.__event_listener) - self.__handler_urls(children) + self.__handler_nodes(children) def add_provider_listener(self, provide_name): """ @@ -97,7 +102,7 @@ def add_provider_listener(self, provide_name): children = self.__zk.get_children('{0}/{1}/{2}'.format('dubbo', provide_name, 'providers'), watch=self.__event_listener) # 全部重新添加 - self.__handler_urls(children) + self.__handler_nodes(children) def get_provides(self, provide_name, default=None): """ From 3e54e8e5bcd2082a5cb76317409f0306589c8639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 9 Apr 2015 21:39:20 +0800 Subject: [PATCH 17/70] =?UTF-8?q?=E9=87=8D=E6=9E=84=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/__init__.py | 2 +- dubbo_client/{rpc.py => rpclib.py} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename dubbo_client/{rpc.py => rpclib.py} (100%) diff --git a/dubbo_client/__init__.py b/dubbo_client/__init__.py index 0d2608a..2364b3f 100644 --- a/dubbo_client/__init__.py +++ b/dubbo_client/__init__.py @@ -1,6 +1,6 @@ __author__ = 'caozupeng' -from rpc import ( +from rpclib import ( DubboClient, ) from rpcerror import * diff --git a/dubbo_client/rpc.py b/dubbo_client/rpclib.py similarity index 100% rename from dubbo_client/rpc.py rename to dubbo_client/rpclib.py From 70da96c832f53a87799b874cc89733db922037e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 9 Apr 2015 21:44:04 +0800 Subject: [PATCH 18/70] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=BC=A9=E5=87=8F?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=96=87=E4=BB=B6=E7=BC=96=E7=A0=81?= =?UTF-8?q?=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/rpclib.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/dubbo_client/rpclib.py b/dubbo_client/rpclib.py index 888d985..001bfb4 100644 --- a/dubbo_client/rpclib.py +++ b/dubbo_client/rpclib.py @@ -1,12 +1,8 @@ +# coding=utf-8 import random from urllib2 import HTTPError - from pyjsonrpc import HttpClient, JsonRpcError - - -from dubbo_client.rpcerror import NoProvider, ConnectionFail, dubbo_client_errors - - +from dubbo_client.rpcerror import NoProvider, ConnectionFail, dubbo_client_errors, InternalError __author__ = 'caozupeng' @@ -32,7 +28,6 @@ def call(self, method, *args, **kwargs): if len(provides) == 0: raise NoProvider('can not find provide', self.interface) location, provide = random.choice(provides.items()) - print 'location is {0}'.format(location) client = HttpClient(url="http://{0}{1}".format(location, provide.path)) try: return client.call(method, *args, **kwargs) @@ -40,6 +35,8 @@ def call(self, method, *args, **kwargs): raise ConnectionFail(None, e.filename) except JsonRpcError, error: raise dubbo_client_errors.get(error.code, None) + except Exception, ue: + raise InternalError(ue.message, None) def __call__(self, method, *args, **kwargs): """ From 3f6709b58f863633bbc137cd958f6e72fe07a8db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 9 Apr 2015 21:44:24 +0800 Subject: [PATCH 19/70] =?UTF-8?q?=E4=BF=AE=E6=94=B9README=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0c3801d..4e034a2 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,18 @@ Python Dubbo Client ### Example ```python service_interface = 'com.ofpay.demo.api.UserProvider' - dubbo_client = DubboClient(service_interface) - print dubbo_client.getUser('A003') - print dubbo_client.queryUser( - {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) - print dubbo_client.queryAll() - print dubbo_client.isLimit('MAN', 'Joe') - print dubbo_client('getUser', 'A005') + registry = ZookeeperRegistry('172.19.65.33:2181') + dubbo_client = DubboClient(service_interface, registry) + for i in range(1000): + try: + print dubbo_client.getUser('A003') + print dubbo_client.queryUser( + {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) + print dubbo_client.queryAll() + print dubbo_client.isLimit('MAN', 'Joe') + print dubbo_client('getUser', 'A005') + + except DubboClientError, client_error: + print client_error + time.sleep(5) ``` \ No newline at end of file From d99977617ef09aabf13d310b3996067b99d4a43d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 9 Apr 2015 21:47:17 +0800 Subject: [PATCH 20/70] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BF=BD=E7=95=A5?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7e99e36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pyc \ No newline at end of file From 944357b614cdcf33d5ff5385a3fd3f1c867a4c64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 9 Apr 2015 21:53:13 +0800 Subject: [PATCH 21/70] =?UTF-8?q?=E4=BE=9D=E8=B5=96=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- req.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 req.txt diff --git a/req.txt b/req.txt new file mode 100644 index 0000000..37c4759 --- /dev/null +++ b/req.txt @@ -0,0 +1,4 @@ +bunch==1.0.1 +kazoo==2.0 +python-jsonrpc==0.7.3 +wsgiref==0.1.2 From b77b51b547350346edce24107fdb799224602b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Fri, 10 Apr 2015 08:59:30 +0800 Subject: [PATCH 22/70] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 ++++++------ test_dubbo_client/test_rpclib.py | 16 ++++++++-------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 4e034a2..b1dd68b 100644 --- a/README.md +++ b/README.md @@ -15,15 +15,15 @@ Python Dubbo Client ```python service_interface = 'com.ofpay.demo.api.UserProvider' registry = ZookeeperRegistry('172.19.65.33:2181') - dubbo_client = DubboClient(service_interface, registry) + user_provider = DubboClient(service_interface, registry) for i in range(1000): try: - print dubbo_client.getUser('A003') - print dubbo_client.queryUser( + print user_provider.getUser('A003') + print user_provider.queryUser( {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) - print dubbo_client.queryAll() - print dubbo_client.isLimit('MAN', 'Joe') - print dubbo_client('getUser', 'A005') + print user_provider.queryAll() + print user_provider.isLimit('MAN', 'Joe') + print user_provider('getUser', 'A005') except DubboClientError, client_error: print client_error diff --git a/test_dubbo_client/test_rpclib.py b/test_dubbo_client/test_rpclib.py index 61f4a25..0db9b5d 100644 --- a/test_dubbo_client/test_rpclib.py +++ b/test_dubbo_client/test_rpclib.py @@ -1,8 +1,8 @@ # coding=utf-8 import time -from dubbo_client import DubboClient, DubboClientError -from dubbo_client import ZookeeperRegistry +from user_provider import DubboClient, DubboClientError +from user_provider import ZookeeperRegistry __author__ = 'caozupeng' @@ -10,15 +10,15 @@ if __name__ == '__main__': service_interface = 'com.ofpay.demo.api.UserProvider' registry = ZookeeperRegistry('172.19.65.33:2181') - dubbo_client = DubboClient(service_interface, registry) + user_provider = DubboClient(service_interface, registry) for i in range(1000): try: - print dubbo_client.getUser('A003') - print dubbo_client.queryUser( + print user_provider.getUser('A003') + print user_provider.queryUser( {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) - print dubbo_client.queryAll() - print dubbo_client.isLimit('MAN', 'Joe') - print dubbo_client('getUser', 'A005') + print user_provider.queryAll() + print user_provider.isLimit('MAN', 'Joe') + print user_provider('getUser', 'A005') except DubboClientError, client_error: print client_error From d6ee5513a308a8d1f595041ad68c041fe2771242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Fri, 10 Apr 2015 11:09:50 +0800 Subject: [PATCH 23/70] =?UTF-8?q?=E6=80=A7=E8=83=BD=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test_dubbo_client/test_performance.py | 37 +++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 test_dubbo_client/test_performance.py diff --git a/test_dubbo_client/test_performance.py b/test_dubbo_client/test_performance.py new file mode 100644 index 0000000..87c07e1 --- /dev/null +++ b/test_dubbo_client/test_performance.py @@ -0,0 +1,37 @@ +# coding=utf-8 +import timeit + +from pyjsonrpc import HttpClient + + +__author__ = 'caozupeng' + + +def test_client_every_new(): + user_provider = HttpClient(url="http://{0}{1}".format('172.19.3.111:38081/', 'com.ofpay.demo.api.UserProvider')) + user_provider.getUser('A003') + user_provider.queryUser( + {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) + # user_provider.queryAll() + user_provider.isLimit('MAN', 'Joe') + user_provider('getUser', 'A005') + + +def test_client(): + user_provider = HttpClient(url="http://{0}{1}".format('172.19.3.111:38081/', 'com.ofpay.demo.api.UserProvider')) + for x in range(10000): + user_provider.getUser('A003') + user_provider.queryUser( + {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) + # user_provider.queryAll() + user_provider.isLimit('MAN', 'Joe') + user_provider('getUser', 'A005') + + +if __name__ == '__main__': + #test_client_every_new 运行10000次, 耗时220.188388109 + #test_client 运行10000次, 耗时215.014229059 + #说明每次new HttpClient和保持一个HttpClient的效率相差不大 + number = 10000 + print u'test_client_every_new 运行{0}次, 耗时{1}'.format(number, timeit.timeit(test_client_every_new, number=number)) + print u'test_client 运行{0}次, 耗时{1}'.format(number, timeit.timeit(test_client, number=1)) \ No newline at end of file From 6286c955ed387a4dd0966fb5bb979e14be16437b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Fri, 10 Apr 2015 17:50:51 +0800 Subject: [PATCH 24/70] =?UTF-8?q?=E6=B7=BB=E5=8A=A0group=E5=92=8Cversion?= =?UTF-8?q?=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/common.py | 2 + dubbo_client/config.py | 7 ++++ dubbo_client/registry.py | 63 +++++++++++++++++++---------- dubbo_client/rpclib.py | 18 ++++++--- test_dubbo_client/test_rawclient.py | 16 ++++++++ test_dubbo_client/test_rpclib.py | 6 +-- 6 files changed, 82 insertions(+), 30 deletions(-) create mode 100644 test_dubbo_client/test_rawclient.py diff --git a/dubbo_client/common.py b/dubbo_client/common.py index d2945ce..3633ac8 100644 --- a/dubbo_client/common.py +++ b/dubbo_client/common.py @@ -10,6 +10,8 @@ class ServiceURL(object): path = '' # like /com.qianmi.dubbo.UserProvider ip = '127.0.0.1' port = '9090' + version = '' + group = '' def __init__(self, url): result = urlparse(url) diff --git a/dubbo_client/config.py b/dubbo_client/config.py index 681fccd..880ec2b 100644 --- a/dubbo_client/config.py +++ b/dubbo_client/config.py @@ -1 +1,8 @@ +# coding=utf-8 __author__ = 'caozupeng' + + +class ReferenceConfig(object): + registry = None + interface = '' + version = '' \ No newline at end of file diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index 5ea57a0..6aa1b9e 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -2,8 +2,10 @@ __author__ = 'caozupeng' import urllib + from kazoo.protocol.states import KazooState from kazoo.client import KazooClient + from dubbo_client.common import ServiceURL @@ -16,7 +18,7 @@ def add_provider_listener(self, provide_name): """ pass - def get_provides(self, provide_name, default=None): + def get_provides(self, provide_name, default=None, **kwargs): """ 获取已经注册的服务URL对象 :param provide_name: com.ofpay.demo.api.UserProvider @@ -29,8 +31,11 @@ def get_provides(self, provide_name, default=None): class ZookeeperRegistry(Registry): """ 所有注册过的服务端将在这里 - 格式为{providername:{ip+port:service}} - providername = group_version_servicename + interface=com.ofpay.demo.DemoService + location = ip:port/url 比如 172.19.20.111:38080/com.ofpay.demo.DemoService2 + providername = servicename|version|group + dict 格式为{interface:{providername:{ip+port:service_url}}} + """ __service_provides = {} __connect_state = 'UNCONNECT' @@ -61,57 +66,71 @@ def __event_listener(self, event): """ self.__do_event(event) - def __handler_nodes(self, nodes): + def __to_key(self, interface, versioin, group): + return '{0}|{1}|{2}'.format(interface, versioin, group) + + def __handler_nodes(self, interface, nodes): """ 将zookeeper中查询到的服务节点列表加入到一个dict中 :param nodes: 节点列表 :return: 不需要返回 """ + # 如果已经存在,首先删除原有的服务的集合 + if interface in self.__service_provides: + del self.__service_provides[interface] for child_node in nodes: node = urllib.unquote(child_node).decode('utf8') if node.startswith('jsonrpc'): service_url = ServiceURL(node) - service_key = self.__service_provides.get(service_url.interface) - if service_key: - service_key[service_url.location] = service_url + key = self.__to_key(service_url.interface, service_url.version, service_url.group) + second_dict = self.__service_provides.get(interface) + if second_dict: + # 获取最内层的nest的dict + inner_dict = second_dict.get(key) + if inner_dict: + inner_dict[service_url.location] = service_url + else: + second_dict[key] = {service_url.location: service_url} else: - self.__service_provides[service_url.interface] = {service_url.location: service_url} + # create the second dict + self.__service_provides[interface] = {key: {service_url.location: service_url}} def __do_event(self, event): # event.path 是类似/dubbo/com.ofpay.demo.api.UserProvider/providers 这样的 # 如果要删除,必须先把/dubbo/和最后的/providers去掉 provide_name = event.path[7:event.path.rfind('/')] - if provide_name in self.__service_provides: - del self.__service_provides[provide_name] if event.state == 'CONNECTED': children = self.__zk.get_children(event.path, watch=self.__event_listener) - self.__handler_nodes(children) + self.__handler_nodes(provide_name, children) if event.state == 'DELETED': children = self.__zk.get_children(event.path, watch=self.__event_listener) - self.__handler_nodes(children) + self.__handler_nodes(provide_name, children) - def add_provider_listener(self, provide_name): + def add_provider_listener(self, interface, **kwargs): """ 监听注册中心的服务上下线 - :param provide_name: 类似com.ofpay.demo.api.UserProvider这样的服务名 + :param interface: 类似com.ofpay.demo.api.UserProvider这样的服务名 :return: 无返回 """ - # 如果已经存在,首先删除原有的服务的集合 - if provide_name in self.__service_provides: - del self.__service_provides[provide_name] - children = self.__zk.get_children('{0}/{1}/{2}'.format('dubbo', provide_name, 'providers'), + version = kwargs.get('version', '') + group = kwargs.get('group', '') + children = self.__zk.get_children('{0}/{1}/{2}'.format('dubbo', interface, 'providers'), watch=self.__event_listener) # 全部重新添加 - self.__handler_nodes(children) + self.__handler_nodes(interface, children) - def get_provides(self, provide_name, default=None): + def get_provides(self, interface, default=None, **kwargs): """ 获取已经注册的服务URL对象 - :param provide_name: com.ofpay.demo.api.UserProvider + :param interface: com.ofpay.demo.api.UserProvider :param default: :return: 返回一个dict的服务集合 """ - return self.__service_provides.get(provide_name, default) + group = kwargs.get('group', '') + version = kwargs.get('version', '') + key = self.__to_key(interface, version, group) + second = self.__service_provides.get(interface, {}) + return second.get(key, default) if __name__ == '__main__': diff --git a/dubbo_client/rpclib.py b/dubbo_client/rpclib.py index 001bfb4..30f2b54 100644 --- a/dubbo_client/rpclib.py +++ b/dubbo_client/rpclib.py @@ -1,13 +1,19 @@ # coding=utf-8 import random from urllib2 import HTTPError + from pyjsonrpc import HttpClient, JsonRpcError + from dubbo_client.rpcerror import NoProvider, ConnectionFail, dubbo_client_errors, InternalError + + __author__ = 'caozupeng' class DubboClient(object): interface = '' + group = '' + version = '' class _Method(object): @@ -18,17 +24,20 @@ def __init__(self, client_instance, method): def __call__(self, *args, **kwargs): return self.client_instance.call(self.method, *args, **kwargs) - def __init__(self, interface, registry): + def __init__(self, interface, registry, **kwargs): self.interface = interface self.registry = registry + self.group = kwargs.get('group', '') + self.version = kwargs.get('version', '') self.registry.add_provider_listener(interface) def call(self, method, *args, **kwargs): - provides = self.registry.get_provides(self.interface, {}) + provides = self.registry.get_provides(self.interface, {}, version=self.version, group=self.group) if len(provides) == 0: raise NoProvider('can not find provide', self.interface) - location, provide = random.choice(provides.items()) - client = HttpClient(url="http://{0}{1}".format(location, provide.path)) + ip_port, service_url = random.choice(provides.items()) + print service_url.location + client = HttpClient(url="http://{0}{1}".format(ip_port, service_url.path)) try: return client.call(method, *args, **kwargs) except HTTPError, e: @@ -48,7 +57,6 @@ def __getattr__(self, method): """ Allows the usage of attributes as *method* names. """ - return self._Method(client_instance=self, method=method) diff --git a/test_dubbo_client/test_rawclient.py b/test_dubbo_client/test_rawclient.py new file mode 100644 index 0000000..179644b --- /dev/null +++ b/test_dubbo_client/test_rawclient.py @@ -0,0 +1,16 @@ +from pyjsonrpc import HttpClient + +__author__ = 'caozupeng' + +def test_client_every_new(): + user_provider = HttpClient(url="http://{0}{1}".format('172.19.3.111:38081/', 'com.ofpay.demo.api.UserProvider2')) + print user_provider.getUser('A003') + print user_provider.queryUser( + {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) + print user_provider.queryAll() + print user_provider.isLimit('MAN', 'Joe') + print user_provider('getUser', 'A005') + + +if __name__ == '__main__': + test_client_every_new() \ No newline at end of file diff --git a/test_dubbo_client/test_rpclib.py b/test_dubbo_client/test_rpclib.py index 0db9b5d..d8b673e 100644 --- a/test_dubbo_client/test_rpclib.py +++ b/test_dubbo_client/test_rpclib.py @@ -1,16 +1,16 @@ # coding=utf-8 import time -from user_provider import DubboClient, DubboClientError -from user_provider import ZookeeperRegistry +from dubbo_client import ZookeeperRegistry, DubboClient, DubboClientError __author__ = 'caozupeng' if __name__ == '__main__': service_interface = 'com.ofpay.demo.api.UserProvider' + # 该对象较重,有zookeeper的连接,需要保存使用 registry = ZookeeperRegistry('172.19.65.33:2181') - user_provider = DubboClient(service_interface, registry) + user_provider = DubboClient(service_interface, registry, version='3.0') for i in range(1000): try: print user_provider.getUser('A003') From 8b97a1481ae803da5ac6fd0f1653d8a0a0b1e9a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Fri, 10 Apr 2015 18:27:26 +0800 Subject: [PATCH 25/70] performance compare --- dubbo_client/rpclib.py | 2 +- test_dubbo_client/test_performance.py | 41 +++++++++++++++++++-------- test_dubbo_client/test_rpclib.py | 6 ++-- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/dubbo_client/rpclib.py b/dubbo_client/rpclib.py index 30f2b54..aeb7d3f 100644 --- a/dubbo_client/rpclib.py +++ b/dubbo_client/rpclib.py @@ -36,7 +36,7 @@ def call(self, method, *args, **kwargs): if len(provides) == 0: raise NoProvider('can not find provide', self.interface) ip_port, service_url = random.choice(provides.items()) - print service_url.location + # print service_url.location client = HttpClient(url="http://{0}{1}".format(ip_port, service_url.path)) try: return client.call(method, *args, **kwargs) diff --git a/test_dubbo_client/test_performance.py b/test_dubbo_client/test_performance.py index 87c07e1..f0d6e41 100644 --- a/test_dubbo_client/test_performance.py +++ b/test_dubbo_client/test_performance.py @@ -2,24 +2,27 @@ import timeit from pyjsonrpc import HttpClient +from dubbo_client import ZookeeperRegistry, DubboClient __author__ = 'caozupeng' +number = 1000 def test_client_every_new(): - user_provider = HttpClient(url="http://{0}{1}".format('172.19.3.111:38081/', 'com.ofpay.demo.api.UserProvider')) - user_provider.getUser('A003') - user_provider.queryUser( - {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) - # user_provider.queryAll() - user_provider.isLimit('MAN', 'Joe') - user_provider('getUser', 'A005') + for x in range(number): + user_provider = HttpClient(url="http://{0}{1}".format('172.19.3.111:38080/', 'com.ofpay.demo.api.UserProvider')) + user_provider.getUser('A003') + user_provider.queryUser( + {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) + # user_provider.queryAll() + user_provider.isLimit('MAN', 'Joe') + user_provider('getUser', 'A005') def test_client(): - user_provider = HttpClient(url="http://{0}{1}".format('172.19.3.111:38081/', 'com.ofpay.demo.api.UserProvider')) - for x in range(10000): + user_provider = HttpClient(url="http://{0}{1}".format('172.19.3.111:38080/', 'com.ofpay.demo.api.UserProvider')) + for x in range(number): user_provider.getUser('A003') user_provider.queryUser( {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) @@ -28,10 +31,24 @@ def test_client(): user_provider('getUser', 'A005') +def test_dubbo(): + service_interface = 'com.ofpay.demo.api.UserProvider' + # 该对象较重,有zookeeper的连接,需要保存使用 + registry = ZookeeperRegistry('172.19.65.33:2181') + user_provider = DubboClient(service_interface, registry, version='2.0') + for x in range(number): + user_provider.getUser('A003') + user_provider.queryUser( + {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) + # user_provider.queryAll() + user_provider.isLimit('MAN', 'Joe') + user_provider('getUser', 'A005') + if __name__ == '__main__': #test_client_every_new 运行10000次, 耗时220.188388109 #test_client 运行10000次, 耗时215.014229059 #说明每次new HttpClient和保持一个HttpClient的效率相差不大 - number = 10000 - print u'test_client_every_new 运行{0}次, 耗时{1}'.format(number, timeit.timeit(test_client_every_new, number=number)) - print u'test_client 运行{0}次, 耗时{1}'.format(number, timeit.timeit(test_client, number=1)) \ No newline at end of file + + print u'test_client_every_new 运行{0}次, 耗时{1}'.format(number, timeit.timeit(test_client_every_new, number=1)) + print u'test_client 运行{0}次, 耗时{1}'.format(number, timeit.timeit(test_client, number=1)) + print u'test_dubbo 运行{0}次, 耗时{1}'.format(number, timeit.timeit(test_dubbo, number=1)) \ No newline at end of file diff --git a/test_dubbo_client/test_rpclib.py b/test_dubbo_client/test_rpclib.py index d8b673e..e56bb32 100644 --- a/test_dubbo_client/test_rpclib.py +++ b/test_dubbo_client/test_rpclib.py @@ -10,13 +10,15 @@ service_interface = 'com.ofpay.demo.api.UserProvider' # 该对象较重,有zookeeper的连接,需要保存使用 registry = ZookeeperRegistry('172.19.65.33:2181') - user_provider = DubboClient(service_interface, registry, version='3.0') + user_provider = DubboClient(service_interface, registry, version='2.0') for i in range(1000): try: print user_provider.getUser('A003') print user_provider.queryUser( {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) - print user_provider.queryAll() + datas = user_provider.queryAll() + for key, user in datas.items(): + print user['name'] print user_provider.isLimit('MAN', 'Joe') print user_provider('getUser', 'A005') From 561aeeba59ee1a8bb8e36f4618d57188c7c5fd0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Fri, 10 Apr 2015 20:05:55 +0800 Subject: [PATCH 26/70] =?UTF-8?q?=E4=BF=AE=E6=94=B9readme=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0version=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b1dd68b..1e565e3 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,18 @@ Python Dubbo Client ### Python调用Dubbo接口的jsonrpc协议 请使用dubbo-rpc-jsonrpc 并在dubbo中配置protocol为jsonrpc协议 +参考 https://github.com/ofpay/dubbo-rpc-jsonrpc ### 在客户端实现负载均衡,服务发现 通过注册中心的zookeeper,获取服务的注册信息 然后通过代理实现负载均衡算法,调用服务端 +支持Version、Group设置 ### Example ```python service_interface = 'com.ofpay.demo.api.UserProvider' registry = ZookeeperRegistry('172.19.65.33:2181') - user_provider = DubboClient(service_interface, registry) + user_provider = DubboClient(service_interface, registry, version='1.0') for i in range(1000): try: print user_provider.getUser('A003') @@ -28,4 +30,9 @@ Python Dubbo Client except DubboClientError, client_error: print client_error time.sleep(5) -``` \ No newline at end of file +``` + +### TODO +优化性能 +支持Retry参数 +支持RoundRobin的调用 \ No newline at end of file From 72b428ebd459e7a5bd0a1a1637f571de7e0bf4a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Fri, 10 Apr 2015 20:40:15 +0800 Subject: [PATCH 27/70] =?UTF-8?q?=E6=B7=BB=E5=8A=A0setup.py=E7=9A=84?= =?UTF-8?q?=E6=94=AF=E6=8C=81=EF=BC=8C=E5=B9=B6=E5=8F=91=E5=B8=83=E7=AC=AC?= =?UTF-8?q?=E4=B8=80=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 ++- README.md | 11 ++++-- dist/dubbo_client-0.1.0-py2.7.egg | Bin 0 -> 19132 bytes setup.py | 56 ++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 dist/dubbo_client-0.1.0-py2.7.egg create mode 100644 setup.py diff --git a/.gitignore b/.gitignore index 7e99e36..2f13ce3 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -*.pyc \ No newline at end of file +*.pyc +build +*.egg-info \ No newline at end of file diff --git a/README.md b/README.md index 1e565e3..8cba883 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,11 @@ Python Dubbo Client 请使用dubbo-rpc-jsonrpc 并在dubbo中配置protocol为jsonrpc协议 参考 https://github.com/ofpay/dubbo-rpc-jsonrpc +### 安装 +下载代码 +python setup.py install + + ### 在客户端实现负载均衡,服务发现 通过注册中心的zookeeper,获取服务的注册信息 然后通过代理实现负载均衡算法,调用服务端 @@ -33,6 +38,6 @@ Python Dubbo Client ``` ### TODO -优化性能 -支持Retry参数 -支持RoundRobin的调用 \ No newline at end of file +优化性能 +支持Retry参数 +支持RoundRobin的调用 \ No newline at end of file diff --git a/dist/dubbo_client-0.1.0-py2.7.egg b/dist/dubbo_client-0.1.0-py2.7.egg new file mode 100644 index 0000000000000000000000000000000000000000..3410de4da98d2d343536769bd2417fde548b3232 GIT binary patch literal 19132 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ࣣ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.0", "python-jsonrpc>=0.7.3"], +) \ No newline at end of file From bbc900bb34592843d6248fb9a915c69f53d856d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Fri, 10 Apr 2015 20:49:26 +0800 Subject: [PATCH 28/70] =?UTF-8?q?pip=E5=AE=89=E8=A3=85=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8cba883..9a9342d 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,10 @@ Python Dubbo Client ### 安装 下载代码 python setup.py install - +Git安装 +pip install git+http://git.dev.qianmi.com/tda/dubbo-client-py.git +或者 +pip install git+https://github.com/ofpay/dubbo-client-py.git ### 在客户端实现负载均衡,服务发现 通过注册中心的zookeeper,获取服务的注册信息 From c3651e91d9a274ae3b3afddcb87ab1f90ce8bb55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Sat, 11 Apr 2015 10:11:28 +0800 Subject: [PATCH 29/70] =?UTF-8?q?=E6=80=A7=E8=83=BD=E6=B5=8B=E8=AF=95profi?= =?UTF-8?q?le?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test_dubbo_client/test_client.txt | Bin 0 -> 65469 bytes test_dubbo_client/test_client_every_new.txt | Bin 0 -> 50184 bytes test_dubbo_client/test_dubbo.txt | Bin 0 -> 106365 bytes test_dubbo_client/test_performance.py | 17 ++++++++++++++--- 4 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 test_dubbo_client/test_client.txt create mode 100644 test_dubbo_client/test_client_every_new.txt create mode 100644 test_dubbo_client/test_dubbo.txt diff --git a/test_dubbo_client/test_client.txt b/test_dubbo_client/test_client.txt new file mode 100644 index 0000000000000000000000000000000000000000..a272ea16e09abeb57acb843a3451f6d09e82389a GIT binary patch literal 65469 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 TqK#~#p7DiHbY%pkQOExQdjlQt literal 0 HcmV?d00001 diff --git a/test_dubbo_client/test_client_every_new.txt b/test_dubbo_client/test_client_every_new.txt new file mode 100644 index 0000000000000000000000000000000000000000..3bbb5151ea3583564e1a31700c0c3c6202a9c751 GIT binary patch literal 50184 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 FzX1DQWr6?z literal 0 HcmV?d00001 diff --git a/test_dubbo_client/test_dubbo.txt b/test_dubbo_client/test_dubbo.txt new file mode 100644 index 0000000000000000000000000000000000000000..860d8bfc705537569445fc91e3c99c276ca92aba GIT binary patch literal 106365 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 literal 0 HcmV?d00001 diff --git a/test_dubbo_client/test_performance.py b/test_dubbo_client/test_performance.py index f0d6e41..2a5eed3 100644 --- a/test_dubbo_client/test_performance.py +++ b/test_dubbo_client/test_performance.py @@ -1,4 +1,6 @@ # coding=utf-8 +import profile +import pstats import timeit from pyjsonrpc import HttpClient @@ -49,6 +51,15 @@ def test_dubbo(): #test_client 运行10000次, 耗时215.014229059 #说明每次new HttpClient和保持一个HttpClient的效率相差不大 - print u'test_client_every_new 运行{0}次, 耗时{1}'.format(number, timeit.timeit(test_client_every_new, number=1)) - print u'test_client 运行{0}次, 耗时{1}'.format(number, timeit.timeit(test_client, number=1)) - print u'test_dubbo 运行{0}次, 耗时{1}'.format(number, timeit.timeit(test_dubbo, number=1)) \ No newline at end of file + # print u'test_client_every_new 运行{0}次, 耗时{1}'.format(number, timeit.timeit(test_client_every_new, number=1)) + # print u'test_client 运行{0}次, 耗时{1}'.format(number, timeit.timeit(test_client, number=1)) + # print u'test_dubbo 运行{0}次, 耗时{1}'.format(number, timeit.timeit(test_dubbo, number=1)) + # profile.run("test_dubbo()", 'test_dubbo.txt') + # p = pstats.Stats('test_dubbo.txt') + # p.sort_stats('time').print_stats() + # profile.run('test_client_every_new()', 'test_client_every_new.txt') + # np = pstats.Stats('test_client_every_new.txt') + # np.sort_stats('time').print_stats() + profile.run('test_client()', 'test_client.txt') + cp = pstats.Stats('test_client.txt') + cp.sort_stats('time').print_stats() \ No newline at end of file From def3a56af911ff2488d29809557418e0d743d09d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Sat, 11 Apr 2015 10:30:30 +0800 Subject: [PATCH 30/70] =?UTF-8?q?=E8=AF=B4=E6=98=8E=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test_dubbo_client/test_performance.py | 30 ++++++++++++++++++++------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/test_dubbo_client/test_performance.py b/test_dubbo_client/test_performance.py index 2a5eed3..1a0b203 100644 --- a/test_dubbo_client/test_performance.py +++ b/test_dubbo_client/test_performance.py @@ -47,19 +47,33 @@ def test_dubbo(): user_provider('getUser', 'A005') if __name__ == '__main__': - #test_client_every_new 运行10000次, 耗时220.188388109 - #test_client 运行10000次, 耗时215.014229059 - #说明每次new HttpClient和保持一个HttpClient的效率相差不大 + """ + 在我的mac 4c8g笔记本上,同时启动服务端和客户端(忽略网络开销) + test_client_every_new 运行1000次,13.380 seconds + test_client 运行1000次, 12.851 seconds + test_dubbo运行1000次 13.559 seconds + 说明 + 1、加上Dubbo的封装,和原生的jsonrpclib差距很小,可以忽略不计 + 2、每次new HttpClient和保持一个HttpClient句柄复用的效率相差不大 + 3、每秒接近300次的调用,对一个业务系统来说绰绰有余 + 大量的应用程序不需要这么快的运行速度,因为用户根本感觉不出来。 + 例如开发一个下载MP3的网络应用程序,C程序的运行时间需要0.001秒, + 而Python程序的运行时间需要0.1秒,慢了100倍,但由于网络更慢,需要等待1秒, + 你想,用户能感觉到1.001秒和1.1秒的区别吗? + 这就好比F1赛车和普通的出租车在北京三环路上行驶的道理一样, + 虽然F1赛车理论时速高达400公里,但由于三环路堵车的时速只有20公里, + 因此,作为乘客,你感觉的时速永远是20公里。 + """ # print u'test_client_every_new 运行{0}次, 耗时{1}'.format(number, timeit.timeit(test_client_every_new, number=1)) # print u'test_client 运行{0}次, 耗时{1}'.format(number, timeit.timeit(test_client, number=1)) # print u'test_dubbo 运行{0}次, 耗时{1}'.format(number, timeit.timeit(test_dubbo, number=1)) # profile.run("test_dubbo()", 'test_dubbo.txt') - # p = pstats.Stats('test_dubbo.txt') - # p.sort_stats('time').print_stats() + p = pstats.Stats('test_dubbo.txt') + p.sort_stats('time').print_stats() # profile.run('test_client_every_new()', 'test_client_every_new.txt') - # np = pstats.Stats('test_client_every_new.txt') - # np.sort_stats('time').print_stats() - profile.run('test_client()', 'test_client.txt') + np = pstats.Stats('test_client_every_new.txt') + np.sort_stats('time').print_stats() + # profile.run('test_client()', 'test_client.txt') cp = pstats.Stats('test_client.txt') cp.sort_stats('time').print_stats() \ No newline at end of file From 94584eebbdf039abd625888b4303cb10f3849bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Sat, 11 Apr 2015 10:32:31 +0800 Subject: [PATCH 31/70] MIT license --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9a9342d..89598ca 100644 --- a/README.md +++ b/README.md @@ -43,4 +43,7 @@ pip install git+https://github.com/ofpay/dubbo-client-py.git ### TODO 优化性能 支持Retry参数 -支持RoundRobin的调用 \ No newline at end of file +支持RoundRobin的调用 + +### Licenses +MIT License \ No newline at end of file From 99ed0ec819e1468af8454320123be3881c58e8a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Sun, 12 Apr 2015 18:40:52 +0800 Subject: [PATCH 32/70] =?UTF-8?q?=E9=87=8D=E6=9E=84=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/registry.py | 8 ++++---- dubbo_client/rpclib.py | 2 +- test_dubbo_client/test_registry.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index 6aa1b9e..5b707ef 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -10,7 +10,7 @@ class Registry(object): - def add_provider_listener(self, provide_name): + def subscribe(self, provide_name): """ 监听注册中心的服务上下线 :param provide_name: 类似com.ofpay.demo.api.UserProvider这样的服务名 @@ -51,11 +51,11 @@ def __state_listener(self, state): self.__connect_state = state elif state == KazooState.SUSPENDED: # Handle being disconnected from Zookeeper - print 'disconnect from zookeeper' + # print 'disconnect from zookeeper' self.__connect_state = state else: # Handle being connected/reconnected to Zookeeper - print 'connected' + # print 'connected' self.__connect_state = state def __event_listener(self, event): @@ -106,7 +106,7 @@ def __do_event(self, event): children = self.__zk.get_children(event.path, watch=self.__event_listener) self.__handler_nodes(provide_name, children) - def add_provider_listener(self, interface, **kwargs): + def subscribe(self, interface, **kwargs): """ 监听注册中心的服务上下线 :param interface: 类似com.ofpay.demo.api.UserProvider这样的服务名 diff --git a/dubbo_client/rpclib.py b/dubbo_client/rpclib.py index aeb7d3f..d09f8cb 100644 --- a/dubbo_client/rpclib.py +++ b/dubbo_client/rpclib.py @@ -29,7 +29,7 @@ def __init__(self, interface, registry, **kwargs): self.registry = registry self.group = kwargs.get('group', '') self.version = kwargs.get('version', '') - self.registry.add_provider_listener(interface) + self.registry.subscribe(interface) def call(self, method, *args, **kwargs): provides = self.registry.get_provides(self.interface, {}, version=self.version, group=self.group) diff --git a/test_dubbo_client/test_registry.py b/test_dubbo_client/test_registry.py index 8cef5b2..740a2aa 100644 --- a/test_dubbo_client/test_registry.py +++ b/test_dubbo_client/test_registry.py @@ -4,5 +4,5 @@ if __name__ == '__main__': registry = ZookeeperRegistry('172.19.65.33:2181') - registry.add_provider_listener('com.ofpay.demo.api.UserProvider') + registry.subscribe('com.ofpay.demo.api.UserProvider') print registry.get_provides('com.ofpay.demo.api.UserProvider') \ No newline at end of file From af62d8972d4a3b33e99ee194beb9663eb86261c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Sun, 12 Apr 2015 18:41:15 +0800 Subject: [PATCH 33/70] zookeeper ip address --- test_dubbo_client/test_rpclib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_dubbo_client/test_rpclib.py b/test_dubbo_client/test_rpclib.py index e56bb32..0168a9c 100644 --- a/test_dubbo_client/test_rpclib.py +++ b/test_dubbo_client/test_rpclib.py @@ -9,7 +9,7 @@ if __name__ == '__main__': service_interface = 'com.ofpay.demo.api.UserProvider' # 该对象较重,有zookeeper的连接,需要保存使用 - registry = ZookeeperRegistry('172.19.65.33:2181') + registry = ZookeeperRegistry('192.168.59.103:2181') user_provider = DubboClient(service_interface, registry, version='2.0') for i in range(1000): try: From 89136a62d9290507f0eefb0e158cafaf9a047d10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Sun, 12 Apr 2015 22:04:30 +0800 Subject: [PATCH 34/70] =?UTF-8?q?=E9=99=A4=E5=8E=BB=E4=B8=8D=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E7=9A=84default=E5=8F=82=E6=95=B0=EF=BC=8C=E8=B4=B4?= =?UTF-8?q?=E5=90=88=E4=B8=9A=E5=8A=A1=E4=BD=BF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/registry.py | 4 ++-- dubbo_client/rpclib.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index 5b707ef..ea775df 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -119,7 +119,7 @@ def subscribe(self, interface, **kwargs): # 全部重新添加 self.__handler_nodes(interface, children) - def get_provides(self, interface, default=None, **kwargs): + def get_provides(self, interface, **kwargs): """ 获取已经注册的服务URL对象 :param interface: com.ofpay.demo.api.UserProvider @@ -130,7 +130,7 @@ def get_provides(self, interface, default=None, **kwargs): version = kwargs.get('version', '') key = self.__to_key(interface, version, group) second = self.__service_provides.get(interface, {}) - return second.get(key, default) + return second.get(key, {}) if __name__ == '__main__': diff --git a/dubbo_client/rpclib.py b/dubbo_client/rpclib.py index d09f8cb..61b8a38 100644 --- a/dubbo_client/rpclib.py +++ b/dubbo_client/rpclib.py @@ -32,7 +32,7 @@ def __init__(self, interface, registry, **kwargs): self.registry.subscribe(interface) def call(self, method, *args, **kwargs): - provides = self.registry.get_provides(self.interface, {}, version=self.version, group=self.group) + provides = self.registry.get_provides(self.interface, version=self.version, group=self.group) if len(provides) == 0: raise NoProvider('can not find provide', self.interface) ip_port, service_url = random.choice(provides.items()) From 2ef7b61d9018370a74217c3caec8a3702e72bfa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Mon, 13 Apr 2015 14:00:02 +0800 Subject: [PATCH 35/70] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/registry.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index ea775df..2501b1d 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -72,6 +72,13 @@ def __to_key(self, interface, versioin, group): def __handler_nodes(self, interface, nodes): """ 将zookeeper中查询到的服务节点列表加入到一个dict中 + zookeeper中保持的节点url类似如下 + jsonrpc://192.168.2.1:38080/com.ofpay.demo.api.UserProvider? + anyhost=true&application=demo-provider&default.timeout=10000&dubbo=2.4.10& + environment=product&interface=com.ofpay.demo.api.UserProvider& + methods=getUser,queryAll,queryUser,isLimit&owner=wenwu&pid=61578& + side=provider×tamp=1428904600188 + 首先将url转为ServiceUrl对象,然保持到缓存中 :param nodes: 节点列表 :return: 不需要返回 """ From 809b66c7f0ddf4fea82019febccfe3cd9e3e8b24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Tue, 14 Apr 2015 11:33:35 +0800 Subject: [PATCH 36/70] =?UTF-8?q?=E6=96=B0=E5=A2=9EApplicationConfig?= =?UTF-8?q?=EF=BC=8C=E6=98=8E=E7=A1=AE=E5=AE=A2=E6=88=B7=E7=AB=AF=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=20=E5=B0=86=E5=AE=A2=E6=88=B7=E7=AB=AF=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E6=B3=A8=E5=86=8C=E5=88=B0zookeeper=E7=9A=84consumers?= =?UTF-8?q?=E4=B8=8B=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/__init__.py | 3 ++ dubbo_client/config.py | 32 ++++++++++++++- dubbo_client/registry.py | 68 ++++++++++++++++++++++++-------- dubbo_client/rpclib.py | 1 + test_dubbo_client/test_rpclib.py | 5 ++- 5 files changed, 90 insertions(+), 19 deletions(-) diff --git a/dubbo_client/__init__.py b/dubbo_client/__init__.py index 2364b3f..ec42361 100644 --- a/dubbo_client/__init__.py +++ b/dubbo_client/__init__.py @@ -8,4 +8,7 @@ from registry import ( Registry, ZookeeperRegistry, +) +from config import ( + ApplicationConfig, ) \ No newline at end of file diff --git a/dubbo_client/config.py b/dubbo_client/config.py index 880ec2b..c19e40b 100644 --- a/dubbo_client/config.py +++ b/dubbo_client/config.py @@ -2,7 +2,37 @@ __author__ = 'caozupeng' +class ApplicationConfig(object): + # 应用名称 + name = 'default' + # 模块版本 + version = '1.0.0' + #应用负责人 + owner = '' + #组织名(BU或部门) + organization = '' + #分层 + architecture = 'web' + #环境,如:dev/test/run + environment = 'run' + + def __init__(self, name, **kwargs): + self.name = name + object_property = dir(ApplicationConfig) + for key, value in kwargs.items(): + if key in object_property: + setattr(self, key, value) + + def __str__(self): + return 'ApplicationConfig is {0}'.format(",".join(k + ':' + v for k, v in vars(self).iteritems())) + + class ReferenceConfig(object): registry = None interface = '' - version = '' \ No newline at end of file + version = '' + + +if __name__ == '__main__': + application_config = ApplicationConfig('test_app', version='2.0.0', owner='caozupeng', error='ssd') + print application_config \ No newline at end of file diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index 2501b1d..d635fe7 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -1,4 +1,8 @@ # coding=utf-8 +import os + +from dubbo_client.config import ApplicationConfig + __author__ = 'caozupeng' import urllib @@ -37,26 +41,30 @@ class ZookeeperRegistry(Registry): dict 格式为{interface:{providername:{ip+port:service_url}}} """ - __service_provides = {} - __connect_state = 'UNCONNECT' + _service_provides = {} + _app_config = ApplicationConfig('default_app') + _connect_state = 'UNCONNECT' + - def __init__(self, zk_hosts): - self.__zk = KazooClient(hosts=zk_hosts, read_only=True) + def __init__(self, zk_hosts, application_config=None): + if application_config: + self._app_config = application_config + self.__zk = KazooClient(hosts=zk_hosts) self.__zk.add_listener(self.__state_listener) self.__zk.start() def __state_listener(self, state): if state == KazooState.LOST: # Register somewhere that the session was lost - self.__connect_state = state + self._connect_state = state elif state == KazooState.SUSPENDED: # Handle being disconnected from Zookeeper # print 'disconnect from zookeeper' - self.__connect_state = state + self._connect_state = state else: # Handle being connected/reconnected to Zookeeper # print 'connected' - self.__connect_state = state + self._connect_state = state def __event_listener(self, event): """ @@ -64,7 +72,7 @@ def __event_listener(self, event): :param event: :return: """ - self.__do_event(event) + self._do_event(event) def __to_key(self, interface, versioin, group): return '{0}|{1}|{2}'.format(interface, versioin, group) @@ -83,14 +91,14 @@ def __handler_nodes(self, interface, nodes): :return: 不需要返回 """ # 如果已经存在,首先删除原有的服务的集合 - if interface in self.__service_provides: - del self.__service_provides[interface] + if interface in self._service_provides: + del self._service_provides[interface] for child_node in nodes: node = urllib.unquote(child_node).decode('utf8') if node.startswith('jsonrpc'): service_url = ServiceURL(node) key = self.__to_key(service_url.interface, service_url.version, service_url.group) - second_dict = self.__service_provides.get(interface) + second_dict = self._service_provides.get(interface) if second_dict: # 获取最内层的nest的dict inner_dict = second_dict.get(key) @@ -100,9 +108,9 @@ def __handler_nodes(self, interface, nodes): second_dict[key] = {service_url.location: service_url} else: # create the second dict - self.__service_provides[interface] = {key: {service_url.location: service_url}} + self._service_provides[interface] = {key: {service_url.location: service_url}} - def __do_event(self, event): + def _do_event(self, event): # event.path 是类似/dubbo/com.ofpay.demo.api.UserProvider/providers 这样的 # 如果要删除,必须先把/dubbo/和最后的/providers去掉 provide_name = event.path[7:event.path.rfind('/')] @@ -113,6 +121,28 @@ def __do_event(self, event): children = self.__zk.get_children(event.path, watch=self.__event_listener) self.__handler_nodes(provide_name, children) + def register(self, interface, **kwargs): + ip = self.__zk._connection._socket.getsockname()[0] + params = { + 'interface': interface, + 'application': self._app_config.name, + 'application.version': self._app_config.version, + 'category': 'consumer', + 'dubbo': 'dubbo-client-py-1.0.0', + 'environment': self._app_config.environment, + 'interface': interface, + 'method': '', + 'owner': self._app_config.owner, + 'side': 'consumer', + 'pid': os.getpid(), + 'version': '1.0' + } + url = 'consumer://{0}/{1}?{2}'.format(ip, interface, urllib.urlencode(params)) + # print urllib.quote(url, safe='') + + consumer_path = '{0}/{1}/{2}'.format('dubbo', interface, 'consumers') + self.__zk.create(consumer_path + '/' + urllib.quote(url, safe=''), ephemeral=True) + def subscribe(self, interface, **kwargs): """ 监听注册中心的服务上下线 @@ -136,10 +166,16 @@ def get_provides(self, interface, **kwargs): group = kwargs.get('group', '') version = kwargs.get('version', '') key = self.__to_key(interface, version, group) - second = self.__service_provides.get(interface, {}) + second = self._service_provides.get(interface, {}) return second.get(key, {}) if __name__ == '__main__': - pass - + zk = KazooClient(hosts='192.168.59.103:2181') + zk.start() + parent_node = '{0}/{1}/{2}'.format('dubbo', 'com.ofpay.demo.api.UserProvider', 'consumers') + nodes = zk.get_children(parent_node) + for child_node in nodes: + node = urllib.unquote(child_node).decode('utf8') + print node + # zk.delete(parent_node+'/'+child_node, recursive=True) diff --git a/dubbo_client/rpclib.py b/dubbo_client/rpclib.py index 61b8a38..1dc3cd5 100644 --- a/dubbo_client/rpclib.py +++ b/dubbo_client/rpclib.py @@ -30,6 +30,7 @@ def __init__(self, interface, registry, **kwargs): self.group = kwargs.get('group', '') self.version = kwargs.get('version', '') self.registry.subscribe(interface) + self.registry.register(interface) def call(self, method, *args, **kwargs): provides = self.registry.get_provides(self.interface, version=self.version, group=self.group) diff --git a/test_dubbo_client/test_rpclib.py b/test_dubbo_client/test_rpclib.py index 0168a9c..b20921a 100644 --- a/test_dubbo_client/test_rpclib.py +++ b/test_dubbo_client/test_rpclib.py @@ -1,15 +1,16 @@ # coding=utf-8 import time -from dubbo_client import ZookeeperRegistry, DubboClient, DubboClientError +from dubbo_client import ZookeeperRegistry, DubboClient, DubboClientError, ApplicationConfig __author__ = 'caozupeng' if __name__ == '__main__': + config = ApplicationConfig('test_rpclib') service_interface = 'com.ofpay.demo.api.UserProvider' # 该对象较重,有zookeeper的连接,需要保存使用 - registry = ZookeeperRegistry('192.168.59.103:2181') + registry = ZookeeperRegistry('192.168.59.103:2181', config) user_provider = DubboClient(service_interface, registry, version='2.0') for i in range(1000): try: From 85069e800fbdc25571acb78ed2ea33d22b024de7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Tue, 14 Apr 2015 13:11:23 +0800 Subject: [PATCH 37/70] =?UTF-8?q?=E4=BF=AE=E6=94=B9readme=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E8=B0=83=E7=94=A8=E8=AF=B4=E6=98=8E=20TODO=E7=9A=84?= =?UTF-8?q?=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 89598ca..de2657f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ Python Dubbo Client ===================================== -实现客户端的负载均衡、自动发现服务功能 +实现客户端的负载均衡、配合Zookeeper自动发现服务功能 ------------------------------------- @@ -23,8 +23,10 @@ pip install git+https://github.com/ofpay/dubbo-client-py.git ### Example ```python + config = ApplicationConfig('test_rpclib') service_interface = 'com.ofpay.demo.api.UserProvider' - registry = ZookeeperRegistry('172.19.65.33:2181') + #registry包含了和zookeeper的连接,该对象需要缓存 + registry = ZookeeperRegistry('192.168.59.103:2181', config) user_provider = DubboClient(service_interface, registry, version='1.0') for i in range(1000): try: @@ -41,9 +43,9 @@ pip install git+https://github.com/ofpay/dubbo-client-py.git ``` ### TODO -优化性能 -支持Retry参数 -支持RoundRobin的调用 +优化性能,将服务上下线的影响降到最小 +支持Retry参数 +支持权重调用 ### Licenses MIT License \ No newline at end of file From 68521bb21d470890f2d93e71b6b489636607379a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Tue, 14 Apr 2015 13:14:58 +0800 Subject: [PATCH 38/70] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup.py | 5 +++-- version.txt | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 8dcfe2d..1d7061f 100644 --- a/setup.py +++ b/setup.py @@ -38,8 +38,8 @@ classifiers = [ #"Development Status :: 1 - Planning", # "Development Status :: 2 - Pre-Alpha", - "Development Status :: 3 - Alpha", - # "Development Status :: 4 - Beta", + # "Development Status :: 3 - Alpha", + "Development Status :: 4 - Beta", # "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Intended Audience :: Developers", @@ -47,6 +47,7 @@ "Operating System :: OS Independent", "Programming Language :: Python :: 2", "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Communications", "Topic :: System :: Networking", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: HTTP Servers", diff --git a/version.txt b/version.txt index 6c6aa7c..a308722 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.1.0 \ No newline at end of file +1.0.0-beta-1 \ No newline at end of file From adfaadd8e7bdc3db9d8b67f21c870dcc38b8178e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Tue, 14 Apr 2015 13:16:23 +0800 Subject: [PATCH 39/70] =?UTF-8?q?Readme=E4=B8=AD=E7=9A=84=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index de2657f..c3ab041 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ Python Dubbo Client 下载代码 python setup.py install Git安装 -pip install git+http://git.dev.qianmi.com/tda/dubbo-client-py.git +pip install git+http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0-beta-1 或者 -pip install git+https://github.com/ofpay/dubbo-client-py.git +pip install git+https://github.com/ofpay/dubbo-client-py.git@1.0.0-beta-1 ### 在客户端实现负载均衡,服务发现 通过注册中心的zookeeper,获取服务的注册信息 From 50b645ac3b12fc5d15a629fc02de790d446ce3a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Tue, 14 Apr 2015 14:10:59 +0800 Subject: [PATCH 40/70] dist update --- README.md | 1 + dist/dubbo_client-1.0.0_beta_1-py2.7.egg | Bin 0 -> 22632 bytes 2 files changed, 1 insertion(+) create mode 100644 dist/dubbo_client-1.0.0_beta_1-py2.7.egg diff --git a/README.md b/README.md index c3ab041..4b6458b 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ pip install git+https://github.com/ofpay/dubbo-client-py.git@1.0.0-beta-1 优化性能,将服务上下线的影响降到最小 支持Retry参数 支持权重调用 +单元测试覆盖率 ### Licenses MIT License \ No newline at end of file diff --git a/dist/dubbo_client-1.0.0_beta_1-py2.7.egg b/dist/dubbo_client-1.0.0_beta_1-py2.7.egg new file mode 100644 index 0000000000000000000000000000000000000000..9407170cdff5eed92d28482264bc78e0ba98e4de GIT binary patch literal 22632 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⪼oI(TuZ2&|m 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%0DU0oZYHrtv1DBO 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 UzO)DkSTH}Em{xn%dWY}+1GaN3CjbBd literal 0 HcmV?d00001 From 839aee0b2b4077cea2feb7802407e5e2e5815ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Tue, 14 Apr 2015 14:12:26 +0800 Subject: [PATCH 41/70] fix download url --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 1d7061f..4584a11 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ VERSION = open("version.txt").readline().strip() HOMEPAGE = "https://github.com/ofpay/dubbo-client-py" DOWNLOAD_BASEURL = "https://github.com/ofpay/dubbo-client-py/raw/master/dist/" -DOWNLOAD_URL = DOWNLOAD_BASEURL + "dubbo-client-%s.tar.gz" % VERSION +DOWNLOAD_URL = DOWNLOAD_BASEURL + "dubbo-client-%s-py2.7.egg" % VERSION setup( From 3cebf1426082a15bfc9fe1fea178108d2bd8c033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Tue, 14 Apr 2015 19:20:23 +0800 Subject: [PATCH 42/70] =?UTF-8?q?=E5=B0=86register=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E6=8F=90=E5=8D=87=E5=88=B0=E7=88=B6=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/registry.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index d635fe7..d7b0a5d 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -14,10 +14,20 @@ class Registry(object): - def subscribe(self, provide_name): + def register(self, interface, **kwargs): + """ + 客户端注册到注册中心,亮出自己的身份 + :param interface: + :param kwargs: + :return: + """ + pass + + def subscribe(self, interface, **kwargs): """ 监听注册中心的服务上下线 :param provide_name: 类似com.ofpay.demo.api.UserProvider这样的服务名 + :param kwargs: version , group :return: 无返回 """ pass From bacf949da98cf5f2e40a5bebcb3e9a8fd0ab755a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Tue, 14 Apr 2015 19:21:02 +0800 Subject: [PATCH 43/70] =?UTF-8?q?test=20=E5=A5=97=E4=BB=B6=E4=BD=BF?= =?UTF-8?q?=E7=94=A8pytest=EF=BC=8C=E4=BB=8E=E5=91=BD=E5=90=8D=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- req.txt | 3 +++ {test_dubbo_client => tests}/__init__.py | 0 {test_dubbo_client => tests}/test_client.txt | Bin .../test_client_every_new.txt | Bin tests/test_config.py | 14 ++++++++++++++ {test_dubbo_client => tests}/test_dubbo.txt | Bin {test_dubbo_client => tests}/test_performance.py | 0 {test_dubbo_client => tests}/test_rawclient.py | 0 {test_dubbo_client => tests}/test_registry.py | 0 {test_dubbo_client => tests}/test_rpclib.py | 0 10 files changed, 17 insertions(+) rename {test_dubbo_client => tests}/__init__.py (100%) rename {test_dubbo_client => tests}/test_client.txt (100%) rename {test_dubbo_client => tests}/test_client_every_new.txt (100%) create mode 100644 tests/test_config.py rename {test_dubbo_client => tests}/test_dubbo.txt (100%) rename {test_dubbo_client => tests}/test_performance.py (100%) rename {test_dubbo_client => tests}/test_rawclient.py (100%) rename {test_dubbo_client => tests}/test_registry.py (100%) rename {test_dubbo_client => tests}/test_rpclib.py (100%) diff --git a/req.txt b/req.txt index 37c4759..9974eb3 100644 --- a/req.txt +++ b/req.txt @@ -1,4 +1,7 @@ bunch==1.0.1 +dubbo-client==1.0.0-beta-1 kazoo==2.0 +py==1.4.26 +pytest==2.7.0 python-jsonrpc==0.7.3 wsgiref==0.1.2 diff --git a/test_dubbo_client/__init__.py b/tests/__init__.py similarity index 100% rename from test_dubbo_client/__init__.py rename to tests/__init__.py diff --git a/test_dubbo_client/test_client.txt b/tests/test_client.txt similarity index 100% rename from test_dubbo_client/test_client.txt rename to tests/test_client.txt diff --git a/test_dubbo_client/test_client_every_new.txt b/tests/test_client_every_new.txt similarity index 100% rename from test_dubbo_client/test_client_every_new.txt rename to tests/test_client_every_new.txt diff --git a/tests/test_config.py b/tests/test_config.py new file mode 100644 index 0000000..42e1539 --- /dev/null +++ b/tests/test_config.py @@ -0,0 +1,14 @@ +# coding=utf-8 +from dubbo_client import ApplicationConfig + +__author__ = 'caozupeng' + + +def test_application_config_new(): + application_config = ApplicationConfig('test_app', version='2.0.0', owner='caozupeng', error='ssd') + assert application_config.architecture == 'web' + assert application_config.name == 'test_app' + assert application_config.environment == 'run' + assert application_config.version == '2.0.0' + assert 'owner' in application_config.__dict__ + assert 'ssd' not in application_config.__dict__ diff --git a/test_dubbo_client/test_dubbo.txt b/tests/test_dubbo.txt similarity index 100% rename from test_dubbo_client/test_dubbo.txt rename to tests/test_dubbo.txt diff --git a/test_dubbo_client/test_performance.py b/tests/test_performance.py similarity index 100% rename from test_dubbo_client/test_performance.py rename to tests/test_performance.py diff --git a/test_dubbo_client/test_rawclient.py b/tests/test_rawclient.py similarity index 100% rename from test_dubbo_client/test_rawclient.py rename to tests/test_rawclient.py diff --git a/test_dubbo_client/test_registry.py b/tests/test_registry.py similarity index 100% rename from test_dubbo_client/test_registry.py rename to tests/test_registry.py diff --git a/test_dubbo_client/test_rpclib.py b/tests/test_rpclib.py similarity index 100% rename from test_dubbo_client/test_rpclib.py rename to tests/test_rpclib.py From 244c71fd4e1b32d4bbada63a423e3dd6b2c03a92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Wed, 15 Apr 2015 21:52:49 +0800 Subject: [PATCH 44/70] =?UTF-8?q?=E5=AE=9E=E7=8E=B0multicast=E7=9A=84?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=E3=80=82=E8=BF=98=E5=B7=AE=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E4=B8=8B=E7=BA=BF=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/__init__.py | 1 + dubbo_client/registry.py | 170 +++++++++++++++++++++++---------------- tests/test_registry.py | 14 +++- tests/test_rpclib.py | 6 +- 4 files changed, 117 insertions(+), 74 deletions(-) diff --git a/dubbo_client/__init__.py b/dubbo_client/__init__.py index ec42361..3d7d41e 100644 --- a/dubbo_client/__init__.py +++ b/dubbo_client/__init__.py @@ -8,6 +8,7 @@ from registry import ( Registry, ZookeeperRegistry, + MulticastRegistry ) from config import ( ApplicationConfig, diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index d7b0a5d..7c42a7d 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -1,10 +1,12 @@ # coding=utf-8 +__author__ = 'caozupeng' import os +import socket +import struct +from threading import Thread from dubbo_client.config import ApplicationConfig - -__author__ = 'caozupeng' import urllib from kazoo.protocol.states import KazooState @@ -14,6 +16,11 @@ class Registry(object): + _service_provides = {} + + def _do_event(self, event): + pass + def register(self, interface, **kwargs): """ 客户端注册到注册中心,亮出自己的身份 @@ -32,51 +39,20 @@ def subscribe(self, interface, **kwargs): """ pass - def get_provides(self, provide_name, default=None, **kwargs): + def get_provides(self, interface, **kwargs): """ 获取已经注册的服务URL对象 - :param provide_name: com.ofpay.demo.api.UserProvider + :param interface: com.ofpay.demo.api.UserProvider :param default: :return: 返回一个dict的服务集合 """ - pass - - -class ZookeeperRegistry(Registry): - """ - 所有注册过的服务端将在这里 - interface=com.ofpay.demo.DemoService - location = ip:port/url 比如 172.19.20.111:38080/com.ofpay.demo.DemoService2 - providername = servicename|version|group - dict 格式为{interface:{providername:{ip+port:service_url}}} - - """ - _service_provides = {} - _app_config = ApplicationConfig('default_app') - _connect_state = 'UNCONNECT' - - - def __init__(self, zk_hosts, application_config=None): - if application_config: - self._app_config = application_config - self.__zk = KazooClient(hosts=zk_hosts) - self.__zk.add_listener(self.__state_listener) - self.__zk.start() - - def __state_listener(self, state): - if state == KazooState.LOST: - # Register somewhere that the session was lost - self._connect_state = state - elif state == KazooState.SUSPENDED: - # Handle being disconnected from Zookeeper - # print 'disconnect from zookeeper' - self._connect_state = state - else: - # Handle being connected/reconnected to Zookeeper - # print 'connected' - self._connect_state = state + group = kwargs.get('group', '') + version = kwargs.get('version', '') + key = self._to_key(interface, version, group) + second = self._service_provides.get(interface, {}) + return second.get(key, {}) - def __event_listener(self, event): + def event_listener(self, event): """ node provides上下线的监听回调函数 :param event: @@ -84,10 +60,10 @@ def __event_listener(self, event): """ self._do_event(event) - def __to_key(self, interface, versioin, group): + def _to_key(self, interface, versioin, group): return '{0}|{1}|{2}'.format(interface, versioin, group) - def __handler_nodes(self, interface, nodes): + def _handler_nodes(self, interface, nodes): """ 将zookeeper中查询到的服务节点列表加入到一个dict中 zookeeper中保持的节点url类似如下 @@ -107,7 +83,7 @@ def __handler_nodes(self, interface, nodes): node = urllib.unquote(child_node).decode('utf8') if node.startswith('jsonrpc'): service_url = ServiceURL(node) - key = self.__to_key(service_url.interface, service_url.version, service_url.group) + key = self._to_key(service_url.interface, service_url.version, service_url.group) second_dict = self._service_provides.get(interface) if second_dict: # 获取最内层的nest的dict @@ -120,16 +96,49 @@ def __handler_nodes(self, interface, nodes): # create the second dict self._service_provides[interface] = {key: {service_url.location: service_url}} + +class ZookeeperRegistry(Registry): + """ + 所有注册过的服务端将在这里 + interface=com.ofpay.demo.DemoService + location = ip:port/url 比如 172.19.20.111:38080/com.ofpay.demo.DemoService2 + providername = servicename|version|group + dict 格式为{interface:{providername:{ip+port:service_url}}} + + """ + _app_config = ApplicationConfig('default_app') + _connect_state = 'UNCONNECT' + + def __init__(self, zk_hosts, application_config=None): + if application_config: + self._app_config = application_config + self.__zk = KazooClient(hosts=zk_hosts) + self.__zk.add_listener(self.__state_listener) + self.__zk.start() + + def __state_listener(self, state): + if state == KazooState.LOST: + # Register somewhere that the session was lost + self._connect_state = state + elif state == KazooState.SUSPENDED: + # Handle being disconnected from Zookeeper + # print 'disconnect from zookeeper' + self._connect_state = state + else: + # Handle being connected/reconnected to Zookeeper + # print 'connected' + self._connect_state = state + def _do_event(self, event): # event.path 是类似/dubbo/com.ofpay.demo.api.UserProvider/providers 这样的 # 如果要删除,必须先把/dubbo/和最后的/providers去掉 provide_name = event.path[7:event.path.rfind('/')] if event.state == 'CONNECTED': - children = self.__zk.get_children(event.path, watch=self.__event_listener) - self.__handler_nodes(provide_name, children) + children = self.__zk.get_children(event.path, watch=self.event_listener) + self._handler_nodes(provide_name, children) if event.state == 'DELETED': - children = self.__zk.get_children(event.path, watch=self.__event_listener) - self.__handler_nodes(provide_name, children) + children = self.__zk.get_children(event.path, watch=self.event_listener) + self._handler_nodes(provide_name, children) def register(self, interface, **kwargs): ip = self.__zk._connection._socket.getsockname()[0] @@ -162,30 +171,53 @@ def subscribe(self, interface, **kwargs): version = kwargs.get('version', '') group = kwargs.get('group', '') children = self.__zk.get_children('{0}/{1}/{2}'.format('dubbo', interface, 'providers'), - watch=self.__event_listener) + watch=self.event_listener) # 全部重新添加 - self.__handler_nodes(interface, children) + self._handler_nodes(interface, children) + + +class MulticastRegistry(Registry): + + class _Loop(Thread): + def __init__(self, address, callback): + Thread.__init__(self) + multicast_group, multicast_port = address.split(':') + self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) + self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) + self.sock.bind(('', int(multicast_port))) + mreq = struct.pack("4sl", socket.inet_aton(multicast_group), socket.INADDR_ANY) + self.sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) + self.callback = callback + + def run(self): + while True: + event = self.sock.recv(10240) + # print event + self.callback(event.rstrip()) + + def __init__(self, address, application_config=None): + if application_config: + self._app_config = application_config + self._Loop(address, self.event_listener).start() + + def _do_event(self, event): + if event.startswith('register'): + url = event[9:] + # print url + service_provide = ServiceURL(url) + self._handler_nodes(service_provide.interface, (url,)) + # print self._service_provides - def get_provides(self, interface, **kwargs): - """ - 获取已经注册的服务URL对象 - :param interface: com.ofpay.demo.api.UserProvider - :param default: - :return: 返回一个dict的服务集合 - """ - group = kwargs.get('group', '') - version = kwargs.get('version', '') - key = self.__to_key(interface, version, group) - second = self._service_provides.get(interface, {}) - return second.get(key, {}) if __name__ == '__main__': - zk = KazooClient(hosts='192.168.59.103:2181') - zk.start() - parent_node = '{0}/{1}/{2}'.format('dubbo', 'com.ofpay.demo.api.UserProvider', 'consumers') - nodes = zk.get_children(parent_node) - for child_node in nodes: - node = urllib.unquote(child_node).decode('utf8') - print node + # zk = KazooClient(hosts='192.168.59.103:2181') + # zk.start() + # parent_node = '{0}/{1}/{2}'.format('dubbo', 'com.ofpay.demo.api.UserProvider', 'consumers') + # nodes = zk.get_children(parent_node) + # for child_node in nodes: + # node = urllib.unquote(child_node).decode('utf8') + # print node # zk.delete(parent_node+'/'+child_node, recursive=True) + # registry = MulticastRegistry('224.5.6.7:1234') + pass \ No newline at end of file diff --git a/tests/test_registry.py b/tests/test_registry.py index 740a2aa..6702682 100644 --- a/tests/test_registry.py +++ b/tests/test_registry.py @@ -1,8 +1,16 @@ -from dubbo_client import ZookeeperRegistry +from dubbo_client import ZookeeperRegistry, MulticastRegistry __author__ = 'caozupeng' -if __name__ == '__main__': +def multicat(): + registry = MulticastRegistry('224.5.6.7:1234') + registry.subscribe('com.ofpay.demo.api.UserProvider') + print registry.get_provides('com.ofpay.demo.api.UserProvider') + +def zookeeper(): registry = ZookeeperRegistry('172.19.65.33:2181') registry.subscribe('com.ofpay.demo.api.UserProvider') - print registry.get_provides('com.ofpay.demo.api.UserProvider') \ No newline at end of file + print registry.get_provides('com.ofpay.demo.api.UserProvider') + +if __name__ == '__main__': + multicat() \ No newline at end of file diff --git a/tests/test_rpclib.py b/tests/test_rpclib.py index b20921a..b94d482 100644 --- a/tests/test_rpclib.py +++ b/tests/test_rpclib.py @@ -1,16 +1,18 @@ # coding=utf-8 import time -from dubbo_client import ZookeeperRegistry, DubboClient, DubboClientError, ApplicationConfig +from dubbo_client import ZookeeperRegistry, DubboClient, DubboClientError, ApplicationConfig, MulticastRegistry __author__ = 'caozupeng' + if __name__ == '__main__': config = ApplicationConfig('test_rpclib') service_interface = 'com.ofpay.demo.api.UserProvider' # 该对象较重,有zookeeper的连接,需要保存使用 - registry = ZookeeperRegistry('192.168.59.103:2181', config) + # registry = ZookeeperRegistry('192.168.59.103:2181', config) + registry = MulticastRegistry('224.5.6.7:1234', config) user_provider = DubboClient(service_interface, registry, version='2.0') for i in range(1000): try: From f252996955398dd02520ed7fe09d00036b62a9f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 16 Apr 2015 08:02:00 +0800 Subject: [PATCH 45/70] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=96=AD=E8=A8=80?= =?UTF-8?q?=EF=BC=8C=E9=A2=84=E9=98=B2=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/rpclib.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dubbo_client/rpclib.py b/dubbo_client/rpclib.py index 1dc3cd5..0901c4e 100644 --- a/dubbo_client/rpclib.py +++ b/dubbo_client/rpclib.py @@ -3,6 +3,7 @@ from urllib2 import HTTPError from pyjsonrpc import HttpClient, JsonRpcError +from dubbo_client.registry import Registry from dubbo_client.rpcerror import NoProvider, ConnectionFail, dubbo_client_errors, InternalError @@ -25,6 +26,7 @@ def __call__(self, *args, **kwargs): return self.client_instance.call(self.method, *args, **kwargs) def __init__(self, interface, registry, **kwargs): + assert isinstance(registry, Registry) self.interface = interface self.registry = registry self.group = kwargs.get('group', '') From d88c65b31168777089de5ecc2866a02f72445a8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 16 Apr 2015 10:23:07 +0800 Subject: [PATCH 46/70] =?UTF-8?q?=E5=B0=86=E4=B8=8E=E5=92=8C=E6=B3=A8?= =?UTF-8?q?=E5=86=8C=E4=B8=AD=E5=BF=83=E7=B1=BB=E5=9E=8B=E6=97=A0=E5=85=B3?= =?UTF-8?q?=E7=9A=84=E4=BB=A3=E7=A0=81=E6=8A=BD=E8=B1=A1=E5=88=B0=E7=88=B6?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/registry.py | 120 ++++++++++++++++++++++++++------------- 1 file changed, 80 insertions(+), 40 deletions(-) diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index 7c42a7d..2ec862a 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -1,4 +1,6 @@ # coding=utf-8 +import time + __author__ = 'caozupeng' import os import socket @@ -16,9 +18,22 @@ class Registry(object): + """ + 所有注册过的服务端将在这里 + interface=com.ofpay.demo.DemoService + location = ip:port/url 比如 172.19.20.111:38080/com.ofpay.demo.DemoService2 + providername = servicename|version|group + dict 格式为{interface:{providername:{ip+port:service_url}}} + + """ _service_provides = {} def _do_event(self, event): + """ + protect方法,处理回调,留给子类实现 + :param event: + :return: + """ pass def register(self, interface, **kwargs): @@ -61,12 +76,40 @@ def event_listener(self, event): self._do_event(event) def _to_key(self, interface, versioin, group): + """ + 计算存放在内存中的服务的key,以接口、版本、分组计算 + :param interface: 接口 类似com.ofpay.demo.DemoProvider + :param versioin: 版本 1.0 + :param group: 分组 product + :return: key 字符串 + """ return '{0}|{1}|{2}'.format(interface, versioin, group) - def _handler_nodes(self, interface, nodes): + def _add_node(self, interface, service_url): + key = self._to_key(service_url.interface, service_url.version, service_url.group) + second_dict = self._service_provides.get(interface) + if second_dict: + # 获取最内层的nest的dict + inner_dict = second_dict.get(key) + if inner_dict: + inner_dict[service_url.location] = service_url + else: + second_dict[key] = {service_url.location: service_url} + else: + # create the second dict + self._service_provides[interface] = {key: {service_url.location: service_url}} + + def _remove_node(self, interface, service_url): + key = self._to_key(service_url.interface, service_url.version, service_url.group) + second_dict = self._service_provides.get(interface) + if second_dict: + inner_dict = second_dict.get(key) + if inner_dict: + del inner_dict[service_url.location] + + def _compare_swap_nodes(self, interface, nodes): """ - 将zookeeper中查询到的服务节点列表加入到一个dict中 - zookeeper中保持的节点url类似如下 + 比较,替换现有内存中的节点信息,节点url类似如下 jsonrpc://192.168.2.1:38080/com.ofpay.demo.api.UserProvider? anyhost=true&application=demo-provider&default.timeout=10000&dubbo=2.4.10& environment=product&interface=com.ofpay.demo.api.UserProvider& @@ -83,29 +126,10 @@ def _handler_nodes(self, interface, nodes): node = urllib.unquote(child_node).decode('utf8') if node.startswith('jsonrpc'): service_url = ServiceURL(node) - key = self._to_key(service_url.interface, service_url.version, service_url.group) - second_dict = self._service_provides.get(interface) - if second_dict: - # 获取最内层的nest的dict - inner_dict = second_dict.get(key) - if inner_dict: - inner_dict[service_url.location] = service_url - else: - second_dict[key] = {service_url.location: service_url} - else: - # create the second dict - self._service_provides[interface] = {key: {service_url.location: service_url}} + self._add_node(interface, service_url) class ZookeeperRegistry(Registry): - """ - 所有注册过的服务端将在这里 - interface=com.ofpay.demo.DemoService - location = ip:port/url 比如 172.19.20.111:38080/com.ofpay.demo.DemoService2 - providername = servicename|version|group - dict 格式为{interface:{providername:{ip+port:service_url}}} - - """ _app_config = ApplicationConfig('default_app') _connect_state = 'UNCONNECT' @@ -129,16 +153,21 @@ def __state_listener(self, state): # print 'connected' self._connect_state = state + def __unquote(self, origin_nodes): + return (urllib.unquote(child_node).decode('utf8') for child_node in origin_nodes if child_node) + def _do_event(self, event): # event.path 是类似/dubbo/com.ofpay.demo.api.UserProvider/providers 这样的 # 如果要删除,必须先把/dubbo/和最后的/providers去掉 + # 将zookeeper中查询到的服务节点列表加入到一个dict中 + # zookeeper中保持的节点url类似如下 provide_name = event.path[7:event.path.rfind('/')] if event.state == 'CONNECTED': children = self.__zk.get_children(event.path, watch=self.event_listener) - self._handler_nodes(provide_name, children) + self._compare_swap_nodes(provide_name, self.__unquote(children)) if event.state == 'DELETED': children = self.__zk.get_children(event.path, watch=self.event_listener) - self._handler_nodes(provide_name, children) + self._compare_swap_nodes(provide_name, self.__unquote(children)) def register(self, interface, **kwargs): ip = self.__zk._connection._socket.getsockname()[0] @@ -160,6 +189,7 @@ def register(self, interface, **kwargs): # print urllib.quote(url, safe='') consumer_path = '{0}/{1}/{2}'.format('dubbo', interface, 'consumers') + self.__zk.ensure_path(consumer_path) self.__zk.create(consumer_path + '/' + urllib.quote(url, safe=''), ephemeral=True) def subscribe(self, interface, **kwargs): @@ -173,51 +203,61 @@ def subscribe(self, interface, **kwargs): children = self.__zk.get_children('{0}/{1}/{2}'.format('dubbo', interface, 'providers'), watch=self.event_listener) # 全部重新添加 - self._handler_nodes(interface, children) + self._compare_swap_nodes(interface, self.__unquote(children)) class MulticastRegistry(Registry): - class _Loop(Thread): def __init__(self, address, callback): Thread.__init__(self) - multicast_group, multicast_port = address.split(':') + self.multicast_group, self.multicast_port = address.split(':') self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) + # in osx we should use SO_REUSEPORT instead of SO_REUSEADDRESS self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) - self.sock.bind(('', int(multicast_port))) - mreq = struct.pack("4sl", socket.inet_aton(multicast_group), socket.INADDR_ANY) + self.sock.bind(('', int(self.multicast_port))) + mreq = struct.pack("4sl", socket.inet_aton(self.multicast_group), socket.INADDR_ANY) self.sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) self.callback = callback def run(self): while True: event = self.sock.recv(10240) - # print event + print event self.callback(event.rstrip()) + def set_mssage(self, msg): + self.sock.sendto(msg, (self.multicast_group, int(self.multicast_port))) + + def __init__(self, address, application_config=None): if application_config: self._app_config = application_config - self._Loop(address, self.event_listener).start() + self.event_loop = self._Loop(address, self.event_listener) + self.event_loop.setDaemon(True) + self.event_loop.start() + # self.event_loop.set_mssage('subscribe provider://172.19.3.111:38081/com.ofpay.demo.api.UserProvider?anyhost=true&application=jsonrpcdemo&category=configurators&check=false&default.timeout=10000&dubbo=2.4.10&environment=product&interface=com.ofpay.demo.api.UserProvider&methods=getUser,queryAll,queryUser,isLimit&owner=wenwu&pid=63590&side=provider×tamp=1429149716694') def _do_event(self, event): if event.startswith('register'): url = event[9:] - # print url - service_provide = ServiceURL(url) - self._handler_nodes(service_provide.interface, (url,)) - # print self._service_provides - + if url.startswith('jsonrpc'): + service_provide = ServiceURL(url) + self._add_node(service_provide.interface, service_provide) + if event.startswith('unregister'): + url = event[11:] + if url.startswith('jsonrpc'): + service_provide = ServiceURL(url) + self._remove_node(service_provide.interface, service_provide) if __name__ == '__main__': # zk = KazooClient(hosts='192.168.59.103:2181') # zk.start() - # parent_node = '{0}/{1}/{2}'.format('dubbo', 'com.ofpay.demo.api.UserProvider', 'consumers') + # parent_node = '{0}/{1}/{2}'.format('dubbo', 'com.ofpay.demo.api.UserProvider', '') # nodes = zk.get_children(parent_node) # for child_node in nodes: # node = urllib.unquote(child_node).decode('utf8') # print node # zk.delete(parent_node+'/'+child_node, recursive=True) - # registry = MulticastRegistry('224.5.6.7:1234') - pass \ No newline at end of file + registry = MulticastRegistry('224.5.6.7:1234') + time.sleep(50) \ No newline at end of file From 11cc8d9dfb6619957071732e2a674f7881ff1117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 16 Apr 2015 17:20:52 +0800 Subject: [PATCH 47/70] =?UTF-8?q?=E5=88=A0=E9=99=A4=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/registry.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index 2ec862a..efa7455 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -178,7 +178,6 @@ def register(self, interface, **kwargs): 'category': 'consumer', 'dubbo': 'dubbo-client-py-1.0.0', 'environment': self._app_config.environment, - 'interface': interface, 'method': '', 'owner': self._app_config.owner, 'side': 'consumer', @@ -235,7 +234,6 @@ def __init__(self, address, application_config=None): self.event_loop = self._Loop(address, self.event_listener) self.event_loop.setDaemon(True) self.event_loop.start() - # self.event_loop.set_mssage('subscribe provider://172.19.3.111:38081/com.ofpay.demo.api.UserProvider?anyhost=true&application=jsonrpcdemo&category=configurators&check=false&default.timeout=10000&dubbo=2.4.10&environment=product&interface=com.ofpay.demo.api.UserProvider&methods=getUser,queryAll,queryUser,isLimit&owner=wenwu&pid=63590&side=provider×tamp=1429149716694') def _do_event(self, event): if event.startswith('register'): From 28bf48cb50a3ab2b03db042a06bddf995e8bea03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 16 Apr 2015 19:32:28 +0800 Subject: [PATCH 48/70] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dzookeeper=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E8=8A=82=E7=82=B9=E7=9A=84bug=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- version.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4b6458b..1c6ffdb 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ Python Dubbo Client 下载代码 python setup.py install Git安装 -pip install git+http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0-beta-1 +pip install git+http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0-beta-2 或者 -pip install git+https://github.com/ofpay/dubbo-client-py.git@1.0.0-beta-1 +pip install git+https://github.com/ofpay/dubbo-client-py.git@1.0.0-beta-2 ### 在客户端实现负载均衡,服务发现 通过注册中心的zookeeper,获取服务的注册信息 diff --git a/version.txt b/version.txt index a308722..e989926 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.0.0-beta-1 \ No newline at end of file +1.0.0-beta-2 \ No newline at end of file From 864a59128f9e6e8bbdeb91134e431546c612f552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 16 Apr 2015 19:34:45 +0800 Subject: [PATCH 49/70] release beta-2 --- dist/dubbo_client-1.0.0_beta_2-py2.7.egg | Bin 0 -> 32345 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 dist/dubbo_client-1.0.0_beta_2-py2.7.egg diff --git a/dist/dubbo_client-1.0.0_beta_2-py2.7.egg b/dist/dubbo_client-1.0.0_beta_2-py2.7.egg new file mode 100644 index 0000000000000000000000000000000000000000..49cd89554eb1d33a53ed869b73a4c1a062800381 GIT binary patch literal 32345 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 literal 0 HcmV?d00001 From be041414839a3b72df3cd463d5b0e8ab1644cc11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Sat, 18 Apr 2015 10:17:34 +0800 Subject: [PATCH 50/70] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- dist/dubbo-client-1.0.0b2.tar.gz | Bin 0 -> 9125 bytes dist/dubbo_client-0.1.0-py2.7.egg | Bin 19132 -> 0 bytes dist/dubbo_client-1.0.0_beta_1-py2.7.egg | Bin 22632 -> 0 bytes ...2.7.egg => dubbo_client-1.0.0b2-py2.7.egg} | Bin 32345 -> 32894 bytes version.txt | 2 +- 6 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 dist/dubbo-client-1.0.0b2.tar.gz delete mode 100644 dist/dubbo_client-0.1.0-py2.7.egg delete mode 100644 dist/dubbo_client-1.0.0_beta_1-py2.7.egg rename dist/{dubbo_client-1.0.0_beta_2-py2.7.egg => dubbo_client-1.0.0b2-py2.7.egg} (79%) diff --git a/README.md b/README.md index 1c6ffdb..f98d845 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ Python Dubbo Client 下载代码 python setup.py install Git安装 -pip install git+http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0-beta-2 +pip install git+http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0b2 或者 -pip install git+https://github.com/ofpay/dubbo-client-py.git@1.0.0-beta-2 +pip install git+https://github.com/ofpay/dubbo-client-py.git@1.0.0b2 ### 在客户端实现负载均衡,服务发现 通过注册中心的zookeeper,获取服务的注册信息 diff --git a/dist/dubbo-client-1.0.0b2.tar.gz b/dist/dubbo-client-1.0.0b2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..1e2ec908564c998f4c053ca800fbe50982ba1b52 GIT binary patch literal 9125 zcma)>MNk|HfJBkt1b26W6C8rOySoMmF2P}t;O_1&!6mo`cW02nT>^tMF#D_ayj6Sa zTOYcr5ARXNA|s>reAR)2THAYga#;Vgv~*#!as0*4Nxs9{`4+ixS+p0^r( zuwH#dry2lmOyi5k-)Ig}MoD>1>vy%Kgdw1MPNH;Au~f4RiQU-P*xuO4-q?^S=He}X zJc?~DBMO8o+{M+J_{c19QWPhdwjKwCz(V+wl~eoadgbo(ECPg zOo8Fr3!gO({$$>jygHY&GI6u*!Z`YMNzrOZ)%Eu$Y5yYy56-|YM+te&j#`00Gh#K#xz9GlLB|aCd=s>L-sM7 z&ZupaWOX}3Eu}nNME0!xLrsGfbas+`s(7mF^~h{mikJ=8l#1#cgqLO=)12g=Qbw*; zSw)?0kPCp$Ll#{+{Y-vfqbAQ`PZgRd*lFj0$OkUgOrch)Cj9ih`|X|U`$ zkz=)bBM=Ea+*yq+R(F`do+OkpIboo8Qk_+jW5AGJsTNc6rRDo|^20#uGj9WdMw8e@ z4O}yAs2QFPSJ*-<^4No``wPCd7!y57%VTUwfbu?;?VZb1iDruLbQ1*IWD&#uJkL0Z z$5@`dlt$7W>nk5e(ht{EDt{MCm(as$g&gOVSnlsUZJG>Xw>P0YGX@vt+L#Nmq>ze~ZZa39%?E)U0{%NG4oMI}8^MAUv&>z z%(wBJIdT1_CF>8ZV8o7Tf<<-4>@(3*kXm(_BQ zWADm;EmcRhHt;#>3!M4j#kBCpyPB7?vqB2CT(i8_vxPAP`+884XQ^537b0=ZV`~*1 zMNTDkiE-y%<08{2503r-N7Lo+p5KoK?m`~1U#$XnNSk4O^?Bn+j%{#F)QX z&KA~_^wz198CZ5=a%2kGiAyZ(TIp5szqYp(6)%l;WyqZBgvat|%uEP*3%k(_!7tD+ zL`57}e9YCePRP;)UqF^eT43sqfSAsnTb!K z9FiYe;gr=@PCNmq<>#xZ^~Z?{5${v;%tiSYT0>bYbl5uP8#s|}h(9qK<3_u$UMr&U zPz6`zH3~|I5~6QvYJMAnITbm#S;<_AGE=|AA~39Unn&>u7k;sRHylV%7#=6*64`=d zB*Qr9Z$pc1%O(5)?XfK|a(2vb00dNcfm3{MRo^dkJg)M5!KPLhua7S_9paNT!?OA8 zv1kDj%+(NNh?K)4P{G|78GAL6=Nx#hqhBRp!8w8E|3bI^EtE42n7W>N>JraspKZNv zS8|c0x>IZhD5kmKSf``8qtG^}_j*fyu`BQDbK7F@KNX1mek#zm6Y-^;Y~E*oBs!@U z;J&J4h{tp~rp9@pC^4hp!HMO0J2*EDXSLUKsYnz8j1*h_c!4!+6BEBn4)QPm*p>o+fG#rEE>on|m8r+cx1_8eerOQK^-3`$C#SSY15Nh3_gn0y z-wIbVC}8-p2)<^nj!XS~H}XK!Fxmd&QUJ2cgH8tgBX?D^I=DC=R^iy2#qt3qO%_(E z_}M7VIozeS9>}h^^thP5L^wswJgq#$t~@-QlNy;yo;@ENc}0a$*NFNZ?in_*cC!X# z3AJrvIxZJ|wAuCc){hBB#%}EF{#bM7Z?A`|^<3cKPOD-8BxDz zWOWxY9QPF#8q-T4tH>{b|WaK^^+0qLd&dbTF>;qvyMnoN3NIn@?;$)5u+4F55U}g z9Qpc(HfHywB77_A%KQ4YLvMlo`sV?*g>H9el+RJO)&M1Hme4;W*zR~01cnr;(D;R% zV3i<&O7RxK^PX>$e4C3gJMMTyX*bO5_&+D+`r1&M$vns2IWe1j)P5P#B9xP)8A}b- z%QM&Iyp90q5`d+_6EN-(UDOde**saY9*YfmZv{+p_+^%I^_D_JBLv7~OqFx7Hd`~I zelWAn)bRqNr1UQm{?s!TC|MZ<*7d;%~i&Q`SyE0W6j!lPwhNzJ!yh=ia1$C2qI_)F);fsdUQ?}fAr}v1(a4X$LTjt z>1We?6|x)dGma#^#K+OE-8j#J1swPhcwy`QY6`NHrTRZIEW$_sYP3!K-247F@_2)u zbFm0SnhOdpw;~1@CZF1mR|tTmeqN*kx$1%(9^?SD@TVpjoGihU;c^ScU8{dQ8hll1 z>dkkzvIR@9zv6l*L^76(PuqXNy-?7lpZ*F0dR;O6_vR!`y@J0TYU` z#AgLGc7C2|y6pVcLAvZI511^e$FU09-!7O{r*C12X1RlvV{2QxA!uG|hvt?LmaM|lBXoWMUy;tr zhS((~G2rx))Cjt{lfXyg>wULPO$&jMM*dkKkqjv<{lvFFs4e3c6P};%&AF52D2j6* zk7+1Yc%H7m!dMA2Yba~1(y*%xJa(u@0L1yl2=u9P44Cl= z@o@=06TT+es4~&HDM=i^sV?yPwRanrCcjI8R3@Udf`j`VLgWg9@4x>XlgU#t=w}er zCi%fg;u`$;W*s7@O zweNG&`s2ySA!~MnJ*k2hP8X+{hDvUIb>r$ArbT>}NsoLjC$uZ>{*fiKxGrq22h!;E z0vGFWl{drG*u3Jr?Nk>Ovnu2eVnN6Y-gg3Dn)qD&!Czl#jI`27wpm*JX~@K1XM`-f zeb!nUCN+y`N=y3so}9%(6Dq#G#42fXdMZCMGvI^FtI))&O=p=@IOd1_^E_s_jQ_61 z0R8k4ZzSNQT|v)!6R(5Wvx#PzD7MXEeEc+I!Az06U|J!D);mvEA51CJemL$7|AW|1 z@`{{J zb~@&<8chL1>1D(J3;Qvo92n`)hJk4U5LS6TZeUA;rWz zB0B(`q!FEGzU9E!l$D@z1oAb}NzV0Oy{4#x-b4vYWF*J+O!;17D_{Sv94Wq`^SnUn zLnI`6(QLTk_%Sh_BEiUoaqOu#nbgxE_2t2O2P?)Y@%`k1xcX*Iu>VzWr$Yg6=W|tIeKA20U+d?&zksSgTc)mB94)K zRI*r2GmF9ooK~ZLU?!oyBzZU+(4RJGEmLr@Vk4J<3m!@qBlukTV7XqeuWKF?6;UJo zj>vR;zd`iF#@Xi*U}@5^bbj(4nN>drTd*~_5Y|tbpA|sfD?#_V+nV*cs)Is`oqdHl zhJPAGO)?7`C-T#e79_YiMI~|bl0mMVSk!21p@qv}swph?gPXj@(~|Q%#9r3S(x$9j z)zeI4g|)xLN;#SL+3V_4s@kX#BnU|Ygb#&$PO^RFYC{D>9Fz1CN7PYdMxs_PR=BIW zKm63GbV;!->@`cQ_Z(5y4)agVF`AkCt`?i`Z5q^KPsNBnPEFPDxTqveFUb8yPrD8t z6FTA6jReMoks*Ajr?vWT?Ye2shAhY&Wu4cb)31%TzJ_8cTLK~tM%<5VAMYe-c+>D6 zkv%0OZ5$Cx{a9Ex2mF>Rfu`G0p6bm+R~3;0&amZrr54Ps;+uYf{smhno5NAkpGLZH z6C^@PtmRon8iHTnV#2sFbZz_KUbpkoejc;pVgT#fq*Eq%3iptn2dSyE6}5!sy8r_R=z?VArn;h_WpZx?n=fEBTL()1?r zdy-tD3lwXTx6#k4C^CR84m;XgN;Ihge3N-29Mse{(~(ZjiUcVZA|ZtE*hwM5XKmIR zux1FRH>o4#D7-|(uE3Bd4c`cPrHTM{yY8os6Rd|^sYIjn%KYC;xG=gd0=jh=|Un0BeqQ42VND=}svt2j3j~&uYarBN1(J>|GpaAKS6< zGEtxBN40n+2B$I7c!9s}Z8soazZKP4EpbOzv?o@tB7PG5`-}9Zg-s(`Sfx-uQpzBX zy?W6}uJuwARKL+M9WB%8iu@+gosBY4ku9#F-vZnHKzF&9*y}n9O2qS!Va35-k^yUq z&d`4OBc_~?_@F`tl$$+PdWx+F&z~-bU-D}NmTcvdOFO+ZUfxRAran6Nkx?|aO* zS}oS*$zo$n>%F*FHD%_8`!=f()O*o{70rzF2%qIYPGmncHtFeSxQ+Qc5q;E{V{CL0`B@p`o9)wUW{x zlJ#F$#yod?#(Wr_01P;xwh(T3Nt#Be7i~BkHqkir`WRZwZ+fvQ_IUo>@(4vo4kMm} zs9{)#zVx%8q={nt8ohnUqqkG5?uO43^@WEW#bbdfxE1W0HJPK$D_tYU^W)Y{h8A)? zP4$#C&4}+8sWA*Bgt8>Ko4*=mOA?;nA3Uc9sR{Vo5p`Qd{1K}%Pm5xH-)0OkH6W85 zq%Q(bY2`e3XXChyW=JBM(#sRA=n=OMR9V1|i?dH~u?waZS2vrA3A z%O6gm?Pm9yCZDb)SFV+3{*fL)@$H7ex7w}`3QwnpJ==#(Mgw)fu_}yqjcg8%-EpJF zz00SD3BhLMQJ8%)FPu z9{21bNqF}oV{Vj(x3%$J)nB+*{;hdCU0sGoq6$ZN)9GtT-PLZ;udZ2uR5=i~(oxC5 z^V?G4hxAwhY}uFy5Ogi~D4!!a8VwjbV!y@G5eJMf8G zX!T$;IuywUkGm>*G7e9s1NHfr3!mWME!ZXYAs;^zaUQNb`7)ZO`l*c$RB0oM0RhwK zfgysBbXT>!T4{Ax?AK(~YX!_Q@mOpwrnCm78*wjscUK?Q(4YekHGE0T*Z2TNfs<_m zyEb;_WZZ9b9)I-Xyv%;>q+peQk}=P|>N6|B1{PP*@lX%rIbnD+CJ5iGHuRS69dLW< z%?$Cjz~V*|TbBNLZxvrxia+KLql&b{&zj$%T<4nGt2$p{GnB0QQLN?2H~YaR!4YDMqbA1BVPz?o5L?!9~*f#wAwCU0y0@hg}lW_h)s z=f|*}1a9n7p16?1upr}%$E@*^tf8f0@+(hmmL* zUPz%tg|<#i<*nB$9MtA2kyxv*vH)f+lr-=G3jftG@~*-+!6+&H)TUeovc@&Pst6^MC%) zIDwVqJP4O%*|*mL*0Soz7`xhs2(c5+QxB9(c1h#f6*ckcC!Sn*kvh{8sY+gDy6;^! zyG=_WkGuyG7__o(+x5Yyweuh*$VoH}HA#hfR-s5C7`^}?uh5Zifpd0HHKOrP7l1}6 z;UyH|4KVm&_J78*6GtfS3cr|03(KRJwI2j9WX?rC0=-rgLVa|^==27m67MTJ*U%6y z6q`dz#p{7;yOghaDNAL7*#%ZAzd|?OSPG$PZU@5&#{lNkA`lcmB@8~y=L795#Qft% z_WY&cBc}dAZ9=iXY+3^(H{OL0H;o&>_DP8Q{LTYg=6lF%ca{@4~q~OdBebA z{=l1!#T9raNxc&6aCW1*@pzzQd(Ri^ETWkz?gs;ax#B3RFrvE zJioX0q?T}52y<3;e%OtLKn#fG`|(at=^4=B#~zu$f8ySxk8FBmyO6nJf2RNCerzFn z;{Cu18Ix0*N108p^$I`X_H^;Aq)vW;NR4CXbFXNS>;3#chf;N#t>1DCWF)ZZuLIBj zCSevYEh+?ro`JnbL>qoP?ko&Qxgb$qkk410v~^}6X$h+}(zi5(t66j#CC_$A zgH!f6bpnXJqq>=}GwyOfGbP$G;ryJyCCR)4;JT_P@kL>(AHOp5)x5!PHs)2FoBmRI zEZn004RJiYIN(yR0-8LKVyiorFb740&xWNIfI>sZ3Q?^6W*-4Dc~CX4yvbfpxwS-kQ&~wD9^kgi z%k)0+>5avb5LqFvdya2Ot?ADwX(eOWM5&-R@)?k$a)P#ok6L3EtD~HZ;RWoOjDmxb zF|V@T(q{G=vQFIVajLlg{q-fE{Dkv03Hr`PyIdFxp~U;-4t3F#FI$95fll0;V?keN z4#mJ z&mwq5OBBo82o%ed3E&zZezrZo#+ZxZ%sLG34TvH9Wbvhqv59d3G&7c-#Uk2`rgzRP zV9yVi;wOYebw#&TW#y`|G;aw1Dv9VQXN-sbJ$G>vXlpx1s%B z)Kywx+T#pTkp0T9NBXq(gTKGJ-b`8}STDn2Er_$BE{8C`$`af#hmY6a9d*&6% z`y%&djdF*FlFix71ah{3aAzUVzY^)-Xkx!*AnTxgMT#fPR_22xH1My;h0xPwkik_| z{?4CEl3Tbyl-&+P-ImMWq$qyn#(~mgG;ye(P%VehMM~*wWy$ksTWb8=Y>Af?E(fT_ ztoKOzj_`;HJor8urZzpMbPPm=Gc@=u+M|?XX41d>2M~FA1_uP5qb?^JUW}U$py2*) z4`}Y{(>H;}_%^wBcwNN3ywGO_eL;nUmA@W=A4o6M$%}Z!pg5%}*sTv7P*kmsriUO@ zer%QRWGd082Jgv5_4R-_+4Dlo3rv?4(M~j#dNJcLs5q)Ne?w{r6f$)MW~rJW)zfHu z+TrHcE#jlWA~9O46&o4|inl>HU%2{fbUaE}l|njiLHcDp;7sD`F>!#Yjk|-y%v3zB z02B=T==DKeQxAj`y!>S{NA@@hjAiw#+TAV2GcUg!(#H7nl+4(zY2JI~0K!cXe^W)C z_kp23`141Z&kmSTO#j1H?6-3sd_5;&GEbdzL9N+)eV1Fdx<>b{2+aCo
O_|~Ak z{`~j~cm^2aSiBrPQ(64(VXsnTJ-Cbdhi|!jiu8DK?Ks^*Or%T3ZoA95KG1e&yY9DX zppG5nLe>h5_C>ur2;hHfrM(N0eV;P=0zMY;crpA5{~Z+mdbBbcrem(U{04o34|Xbq z7`;ylo=yR;ki7VfL3M>MgOaEXq)+_ngseNjkJr-CgE4zM@P*v2eC@RsHuNdK{r%jrPcS2@jRAo7JIi2E4Hov-C%j6nt?T^puPld zqx-2EDVJ9G_1-;8hjz#RhUmbp)~bz$nx>n0x}chpAr_is_Fz=mCae(oH;>At8n@ z!@PdrzQSnlLO0@<7owN0QycU1IOZmG3A>tBQZt%%uG|{g69FPFOVzOlCf~lzt{mO| zPI%OcE&gnM3`m1`U+4OozV$OvOZ7uxpw=nRZ=h(Z4}ZcVK&I$xSb7QdiOhDE-Rpqi z*!C_ClS8)~@r@BK(2g!!8B81$Oi6~5Qq7a@APSPcxa_x~D}m}wcZo|Fn!gbQ<}|`1 z?V~w|J7~VOjyMNL0`v609OAW6$qbX%ppF^k=V55E!Dj?q^aw(f^qy5~-&}^-7Gfrc z>S{<0q-y1Rr;oidRwJ<Hp>>;vSC&!5uMWU2W&F}o#-;i_i zO%}kC{0066uj~cnOmo*IbAHgShc*$FwTH|5oC0#wxfY|fyQ0mz`Lm*W_CpC1Pvy{S zsrjl}SNjX8;Ti8;0Vh$#FTO1I_fM~$7g&BVZ~nlo&4a!MMt!$1yfP{TCV2@|&7{!( TS3KJ&gCe;V_&dY=gMs-Uj_xxY literal 0 HcmV?d00001 diff --git a/dist/dubbo_client-0.1.0-py2.7.egg b/dist/dubbo_client-0.1.0-py2.7.egg deleted file mode 100644 index 3410de4da98d2d343536769bd2417fde548b3232..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19132 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ࣣ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⪼oI(TuZ2&|m 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%0DU0oZYHrtv1DBO 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 UzO)DkSTH}Em{xn%dWY}+1GaN3CjbBd diff --git a/dist/dubbo_client-1.0.0_beta_2-py2.7.egg b/dist/dubbo_client-1.0.0b2-py2.7.egg similarity index 79% rename from dist/dubbo_client-1.0.0_beta_2-py2.7.egg rename to dist/dubbo_client-1.0.0b2-py2.7.egg index 49cd89554eb1d33a53ed869b73a4c1a062800381..7744c7266f8c8bcf87490e78877f21fc0a065cb4 100644 GIT binary patch delta 3558 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 NkO~upBK?oS{{ear1>XPw delta 2984 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 diff --git a/version.txt b/version.txt index e989926..0550047 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.0.0-beta-2 \ No newline at end of file +1.0.0b2 \ No newline at end of file From 4d4498d5da588464eb97321dfeebc9ee2d71474f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Sat, 18 Apr 2015 15:34:04 +0800 Subject: [PATCH 51/70] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=EF=BC=8C=E5=8F=91=E5=B8=83=E5=88=B0pip?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MANIFEST.in | 2 ++ README.md | 6 ++++-- dist/dubbo-client-1.0.0b2.tar.gz | Bin 9125 -> 9362 bytes dist/dubbo-client-1.0.0b3.tar.gz | Bin 0 -> 9119 bytes dist/dubbo-client-1.0.0b4.tar.gz | Bin 0 -> 9358 bytes dist/dubbo_client-1.0.0b2-py2.7.egg | Bin 32894 -> 32933 bytes dist/dubbo_client-1.0.0b3-py2.7.egg | Bin 0 -> 32904 bytes dist/dubbo_client-1.0.0b4-py2.7.egg | Bin 0 -> 32933 bytes tests/test_registry.py | 22 +++++++++++++++++++++- version.txt | 2 +- 10 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 MANIFEST.in create mode 100644 dist/dubbo-client-1.0.0b3.tar.gz create mode 100644 dist/dubbo-client-1.0.0b4.tar.gz create mode 100644 dist/dubbo_client-1.0.0b3-py2.7.egg create mode 100644 dist/dubbo_client-1.0.0b4-py2.7.egg diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..f9e9360 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,2 @@ +include README.md +include version.txt \ No newline at end of file diff --git a/README.md b/README.md index f98d845..38a9b80 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,12 @@ Python Dubbo Client ### 安装 下载代码 python setup.py install +pip安装 +pip install dubbo-client==1.0.0b4 Git安装 -pip install git+http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0b2 +pip install git+http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0b4 或者 -pip install git+https://github.com/ofpay/dubbo-client-py.git@1.0.0b2 +pip install git+https://github.com/ofpay/dubbo-client-py.git@1.0.0b4 ### 在客户端实现负载均衡,服务发现 通过注册中心的zookeeper,获取服务的注册信息 diff --git a/dist/dubbo-client-1.0.0b2.tar.gz b/dist/dubbo-client-1.0.0b2.tar.gz index 1e2ec908564c998f4c053ca800fbe50982ba1b52..a889cffe76d7a496ea9af7a73972521e892a8227 100644 GIT binary patch literal 9362 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 H1cd(sf?!>k literal 9125 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
O_|~Ak z{`~j~cm^2aSiBrPQ(64(VXsnTJ-Cbdhi|!jiu8DK?Ks^*Or%T3ZoA95KG1e&yY9DX zppG5nLe>h5_C>ur2;hHfrM(N0eV;P=0zMY;crpA5{~Z+mdbBbcrem(U{04o34|Xbq z7`;ylo=yR;ki7VfL3M>MgOaEXq)+_ngseNjkJr-CgE4zM@P*v2eC@RsHuNdK{r%jrPcS2@jRAo7JIi2E4Hov-C%j6nt?T^puPld zqx-2EDVJ9G_1-;8hjz#RhUmbp)~bz$nx>n0x}chpAr_is_Fz=mCae(oH;>At8n@ z!@PdrzQSnlLO0@<7owN0QycU1IOZmG3A>tBQZt%%uG|{g69FPFOVzOlCf~lzt{mO| zPI%OcE&gnM3`m1`U+4OozV$OvOZ7uxpw=nRZ=h(Z4}ZcVK&I$xSb7QdiOhDE-Rpqi z*!C_ClS8)~@r@BK(2g!!8B81$Oi6~5Qq7a@APSPcxa_x~D}m}wcZo|Fn!gbQ<}|`1 z?V~w|J7~VOjyMNL0`v609OAW6$qbX%ppF^k=V55E!Dj?q^aw(f^qy5~-&}^-7Gfrc z>S{<0q-y1Rr;oidRwJ<Hp>>;vSC&!5uMWU2W&F}o#-;i_i zO%}kC{0066uj~cnOmo*IbAHgShc*$FwTH|5oC0#wxfY|fyQ0mz`Lm*W_CpC1Pvy{S zsrjl}SNjX8;Ti8;0Vh$#FTO1I_fM~$7g&BVZ~nlo&4a!MMt!$1yfP{TCV2@|&7{!( TS3KJ&gCe;V_&dY=gMs-Uj_xxY diff --git a/dist/dubbo-client-1.0.0b3.tar.gz b/dist/dubbo-client-1.0.0b3.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..3f611d678a1b9c386446b275ad403263df779107 GIT binary patch literal 9119 zcma)>MNk|HfJA}dHn0jiTI+S^qpOzBCg6r^R00xo`Dw{A&GQdtErplG0$DJ6|#F3=SRp|X~ zZm=G#K98Yt(4l!(^y*j2!r09E7sk$_>?^&BOie$Oy7DhSRDfHC>&@`@J3Vfsf=~w3 zaP-C!txB76 z)@CySNPfY~nqR^xPYpyZ6YNy~!5bVMCIBjq5CWU-M}(X3<&;=gSxEHRq^4V#Z_g2I z^C~QC2|yl!Ro;3@lS#)jV(N?}E(S{&%$qjM^-SD%HQl3$E}h5&VKq!|x3&Y9sg$De zkNKMNv>INo%e&4WXqggSkVTX)utpzf!N0{DAWzhfAUOlp@kzTjlj#SHMEoD~QRXU( zw6?L@{Rd=_-%3)frq|h{?wljPrcCrRN6X0`bB^4}xXTLHRNlKt zEI3hh#zY}cNJy>qh-VGz2VMF``l2Lpvs-s9v(02IFUe)T5BH-jpj%E1R{*AI6E#!MM4}m z+_CHA8x&lrpQ;zPC^YeNjrC6GpX#UdR(Xm1;Ur9DK3FM6pI34u8$|d4XKT)xKhYzo z%JGs@ow_#?!NY$dh3Ja{@e2ud66BL~II-*lC^-tEtetQukUXE(n5v7FYD0zE8`4Z(q{)prE`y5Cmv+>z@E0e1^UU4TQAwzvsI)LgN&A zW#?V)!JlWgdVchK?DlwfLLP-?RELv7n2O~^CHHKeZnE
kaklwqIAKLO97)#Z?Ut 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 KIAH$4!2Az^{~wJ2 literal 0 HcmV?d00001 diff --git a/dist/dubbo-client-1.0.0b4.tar.gz b/dist/dubbo-client-1.0.0b4.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..acfa43925c4ea0eec3180bd4d4688806c5b0b05b GIT binary patch literal 9358 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 uL4>a%if97wzzDPr$PVQpPnPIO9| z_$?tzr9+%TDtlz-pKt!t|Nouuy58%)?)$x;=Y5~={l53vx&Yj!0y!+8E4He|lA8@R zLhxxggqwWzJ0Yx-xFiChp~fsPgj%RSc-RO|A2}x26`N~Gj|I zi!qaDpin3{SA#n^5GU7b{SiH_wuFXO`l`PF9+<%!*BsNdAW&ueSi)DO+K*~|L*=dDra7Kk%o1>HYvU5H7T zeXxJPYhSa&3$#P}yR1FZd(EReTJDfm@};aasADiOO*(fIPvE-R6|$+DaIc@@F|+}8 zPsu`bT687}^B!Sz0xNmubG)zKrA$}fQ^WHV`_S{b#eB1K)cE@${pDYE^gG{BM!I=v zi<6SQ!}65TnJ#C~khw3h3S1-kaIN8Eqo~Qp>0v9qcOD2bfUy~p55C5iNm|$S@?1Qb zs)H*qnlY{2I5$3!ragH@UwdVv$9nvOuTO%ae~5$UZ?+Q>p{rpEKASn+BTe+8T>2EH z{i-^bhpF*Fgspt3MU;50Wbz4t(~D^Yd-3bR_`#$m$4TGbip$q5Ix+qMNzN&*s0;x( z(mLF1FrEDE93i)1J*%0+gc)A=)-`4i(xaY6Zm|d7) zVW-DfcvU~sv9wtmu{>zLwCS<+F@Z&SLsbngeiN|E0M{jVm$uoCg7p&0_@$~6GSN*kS*}-oI$>#lIz4zMNUA@uULF0doZFMG&+*V|)HX|7H%8l68 zVO#{`+Ld3W5x@I-QGw|ZRbQP~e-r|XG&G!+H%vO$k z6jZ+Jk3T7b@Ni%X_5b0(@0qF{lrg$~(?r1ZmfwpX63NObH8e4;7vNha3xWOOn^v;> z?$aVdX+V}7?udMoOmeQ0p71BB-`(X^tAoC>(3hxG+GuOr75t3C=I5eU@`f4qfkI;k zqSCf|#H7}DI@oZ-MPV=)AB=r}E}@+$(ETaVgEwTc#RV=H44SmCveGle%ztTo^p@V)nG$7~$)(x!@%AeCv1?@)2^@uDjLk$-w}TXM{%B|5u-D znKxxw0IHdoK&>RiBpK=~OD5SnAWXJyhB{2m2|IUAM=HZia4_2?l7rmXE-q-k&#jQt zk)rYC9KXDO2&Z#p1>fRujmR*_59UXwLZCuOfuM@OVaJH+5NjiHm~)I7#BRnM|3^=o zjX5L_ol@5jJxP&$ItuI|#vVT(CUp@sj#cJ({&|xB^Bf10VwIo;%421?(BRA1y%3pV zlgl7K$p~mL0Y^!qpaAK5NsmJas9+LkRzf`xGs&`uiSWB?z# zzZE378K(}sb>Pq*i~wjCkAzIPcp0D>^S6ow8S!d>krRj7I`M}Q!-8dGBj8Ug*n<@ZH_4pL0tqs}j2lNmC#VBMIPf)2TEoGH3lQc0 z`M=~^Y9cNw?_k%*V%I12OMN+bD1cp`I?&|{8dD^}$~YwFO;U4q=&1oP*hOv_OyZXq z0}xHI0O)~WcA&)13M(lxKt(V|DTo&YXDM<(TNsGBAP!Z>$tO_$y6OizUp9LmzkUW* Opu+`~9pTZ?BL4>NCMatF delta 2256 zcmZ8i2{@Ep8=e_s?8`8+jolzb2w56SjO=^X3dNtbtP_S8S&Bj(C0imyri>O#ACiLo>YsQ1zwi3{-|ITpeLc^)pXEH~de2>(j{1>?D(pq^I5j^eaj@XF zAbJiB;}&L(1yqY3XK+>hQg?tq!~%;u@Iw z*}HbH3egKEVu72j=B)Ok(Wl31{fEr8UOjjmcOj6F*xocd<#)}&^x_Lzu&7?GOMiZ< z5FX=yb+g?e_mMYOGp~w%gtqMRn9YOT$>-BuAc3L&g6nyH9h>37D~`+SA) z2L++sA8t1N)FU>V-R&;^*Zq($QVJNI@si2)G0dUwvUk+O`6y8pLwgcb$zhpva7OC; zT1{1z!tvqpQtAYAv4g5foVIuFZfo2&;&`=N{Nh-QQO$Hz*IVXW&NexlG-VF8_s0$` z=|hLQTDMSR4f90;;4QWLW#=3j`}iSEb3CR`)hxceD)O^QPyb}Qb6r?<=bVY~Xy^UQ z9#9GQUV)$HJAzEIBZ`C>JER-K<~BIPHXN{oFgybLX0?RIF!bF2q@Gd{bl~b`dP_#Z z$4Y)$tVL;-t;X%f`8Cy6Birm8@|yYaSCBzi;-_nYyO)2Yn8{5Q7l$j1Z++#OpLdvM zU@9-?h)(|j3MCAML~!569vM-DV%9hKbZ?#o{UI(enKxeU9}PA!>&& zHuIngCUZ#0R(;h#V@cGaGQ+n$K)3IBKeRWSL0;b!ph~JY&~N&;i5(;;nuDgi3`|qGEdv#}$w9@kFok4vUGpqEyiT3(<)>h@VHO;Yx z50vojW9K?$M{KMdwZ^YgBdk}J?(dg%njg|!JD~n|i8ghyf&R3TJoZd%^=;hpC&uUZ z4k?W%bIy8-CXiR;xDOZa3q4bkdtrHRdE2E0I$OhVj~W_S z3?JpSigx(g>&ED{HqBj{@WU+gA0Ti_PhXl_ZndI%Ju>j9OIW)X=G7ehJkajlg;y4& z(@*&Y+FWHl@O;6y>m>=##TRSNm=DcfeR<>_7v}&%k~dFr*l7lT&l30YqgsH$w}FUA zjTt#?gs@=x44s@i!B6MC4$%Z{G^j5)l;2exv|1PGSlM+*Ji+sdOwSNDT;AJSG`!Sh zCPOj)%6yjH;?zl>!|2H&eqZ7DrqV5aJJCk?TIx>8i6#}o{!_JO+w<+H->v2xM(}&u zVu)!*aRi%)eP_Z0qEc#3-E0v3iNj#r6wRFSaj^?#LXkga0x52>@?ubx`)1C~;Wv2~WO}qu(U?}uE#rz|pCn@~FCR^EiJIM_IiWD>g0*o@NztD#li2pqYu(z;*HK52M8^v0it!8suZhBpap>o7SFwid~3EBVA;*y=uE`+s7zEm0TVuuH_F{xSo?=HdWK z!0Bx5eWEVetk9RL~uP(362^{#3LoZmqY?P0AOD0a}Qn!Jp3ICa$Wno#_AFPTzta*t2ma7jqr&^-!`U7f^G|)Zx8WkG`zCscjF7`+ij^m%dgf#VTvj}ea1Q!A!{#%(0un1Wp YtATzR`=Wf)@JM+;PE*6!#>2dS0~^S`i~s-t diff --git a/dist/dubbo_client-1.0.0b3-py2.7.egg b/dist/dubbo_client-1.0.0b3-py2.7.egg new file mode 100644 index 0000000000000000000000000000000000000000..1a1a31251f30ef7fa821438361ffdfc36c1c8382 GIT binary patch literal 32904 zcmagGQpzC^W5&*ghPHY}R^}!)PV{x9lbIRsaj9*Va04wJ%>Lh%3 z?`!r|!kPQ8m+oJL`mTae;894UWFdk5*U{)bq{;f1a`92{C#hL|))%Y^~B4`R+A}9?C zU9OhC5dj+Sv?k=6{_nqj*9xz`cX7iN%o#14)3}?gCtLHW+$T(yi|%yde55*Oy@M2= z2dSzcUf_$;W;fcPbc}*tsz^gHvd)Rr<7&%i^Z~wM3$s$_9IHe>r zJSrYHnBQe|`$b;jA7oXkx=*EUdc5Cd*FWYR@?0(^#s`tl{`wX9{lA8|z$sSL;1>aU z{m<}v0s{b`{pS!H*;-rM+WbJnL~-3>p8>)9Sqom< zsk%zR8Pci8hjiVUE*XE~L|fD`4HRpLHvLlxW^=Q)z;Q#!X-)DNv8?r?Uz^_GB^*vteZyCI)GiHB<{E+z<@pg@VqR%;cr)f)E%s{YHeS;yFw822bv$d7MUEHFdtvpFx`Jw- zIg9jhb%WTuaZQ(L3MdU@64gl3K=4|Q!Z{VqS*)ab%-J2dXSas4%c+H^BkR}5ucMge z){OqVY!!2|)%U>+^t_B0zE*P85xA{eM@X@9qcuF{Q@Rd%2XVVNJYzUjvQ#elSRA1( z*ho5(NSz7_zXUKC@HlJk7w?i}W`?WzuE{L@?%XU zT5;)9y&GgsFt}g3ebiu=%hUYSRBX?uDUq+O4b0oXK8kAW;3Hb9cTC)_96y{qfHWeg zG-%jFU^#d?2q^%#x~D!p)&(7MyYVN;pq;~&}V^_U$GxH;4&UfdhZkx z0h*Ot^{j`nr8vK~Tis1KBv}E!8SjEfYW+zy&h{^;Xy9SqBpMu0&^jUfB)eD46eM1+ zZ}IwNUhQZ7Q^!MIrT&Gy%I`#NV~?8y%3;Gcli0SZ#N(R}wC=pH#JCK{A_)i?F3T&7 zOI>^L=IzyixHV*f<=G0hsUk8nVs`VrCQ6NND*Mt-&RLTqaVM?AHBPGPO18lTIwYNP zjwz?JJr0ttRa+IGJ!5Y6nBj8OmQh?=dyj%iMe4VC=2dQc}F;8|CG;|7*Q^my=T-Ply>}gDzY&(H~XO?Yb80`c?Oi8XC?LZzEcQ|-5|0@ zfDKLp`NXDE@+~BBqx_m~pcXu$R;%ZfDJiF@APa5p7H0=BXAyVXc zFbhv~!}%=>#EvBiPM!>WnK4(}qitUm($UbJj7Ngq*WMW{_DnB2zMKiYXfu2tIe%GK-{|FiRql_XAUgW#nA{ zV1Ck2f@tpF<80)u2GvNzK`0^h`~w7#l_-J@^|Sc)($3i_S~lDj%nr3fA=AkwWla2y zX04t;f!MFD=-^1fMev@4lrIF}L?pMy@y_fE0)g|i@f>wRpJEU66H+W27**Lclxs4r zYx>qL0zvvp$w6E4GC^c=+|$2}Mc~^Ym-?H3t3hHujM56WmU*LX#T_~jLC37Qy1LZ0 zEZES4-7}K-5g4hnra+X}0qKOrCOu$6o4=F%3OQ6~5uK6gwCmpBvv2KN!oYSQ#4PNl z)XOlecU{!6=PS#^H0@*QBs-bwSPTmFN$7}p~K&}4WpUKLZ7)9|~A;H9V>)%`_4 z$oL_w43;}o4`i3hyA$BICa^cpfb-_yNk_W;{x>LoF(VNMe;0xtCT0s4%Ign7svPPa z$;u{m>ns+a-9=2@FfzNH)$B5y!Kv&OY#OvNT_mSqjKn-53Y1IfB5dMX$>x_4 zpba6#h)RqVcXT|u;i~=sB6tG}JP<0WE7BmTI%`U2CHJ`SyI-xY`zDTeEo{BFyPr|? za)sWN4$QgncLI9p8XCqi#{M4c-xgf5=|b1@5}bnzvwOO=s-=N;w`+<-%Ks!>50t7% zFOIC+RMW&gG&Kv}NKV*SP9N1Z9sbKw4UYL%$zVNvhbzc~u>>+sZZ*ZP1C;4(I?shH zGR~|`00hNol0kwcQZpK9PZo(tCj~h-4nC${6zZIUYq78eG%3xubPCBlf?Y51#27q? zD%$4WzV}AJnvO@D759Km_Zh$VU5Yj({JU1Mx@)^9nrk~<{xL~`OX2%WWE{P#>_V_t z2cir*xHw8M*Oq0GxM+WO?4shzMAIHN`i$7kQQINBPKI7q+3mOixjUA=HUS+-3Hc%0 zfg?sK8fUJb^1Og!n)4U?F!=(;Ku6!hbAGp)7g%b-5m?oII9OfO zIJlSVUaxvgG2LO*{~Z$yv%!Qfg6Ug*AS)SZp~13+2AzC{bAS9%zw` z3)B|wKFug$9HN*wGqcum)?RO|Y$^BXz9ObCxaH-|>a7*l_s{`40&!2CR4z2oLc9TS zIF6#?;_+ch9aoXryf3n6vG(hQj^KGDtay8MkPXNM28WC5**$dJT|2xP3GKUEd|E1A zN=5H)w(LvxtiH|#J0I^`8+cl}%$8DvtTK50TYavg>@TI#adiT10n2LT4B=Cs37KcE z)a9oFQyPVN4xBB%J3k!&eq1~^>(lHceMw(YtXTf>q;FrhvYf5Ymk;rl$!zhr`2h^5 z0*_}Pmp4bK2He&A*X5c_D8O=51%0rq9%yZit!=0FfmJHH2-Bg+0B4vxHM0fQ&7Y>G zB&idzNI1+2@K$=JG^`3K&B>)191OwRI1PI7gY;ANqJf~BKA_!6^xfFp@At*UoptDH z?D4+r+O_lC{*k5QR;|p|z!7%MX|_Oey=K*APSe#{oi2g!k*0CFyUd!!L#8_Ki4v(S zfVL>9nuLIdC9TH$cJ52(T~4<4jfX|Y}|9``+F_TA%aW-gZpaD2xp2b9vUOr{kG@~$8|2mF)VpiMZV;*|TAAn+@jAcKh)lsb z=%hBaITHXKfZG(P%7<8B;%i_elIsFs6$iYxW12BLFN~c_o8~y)ZGWvnVz{qcbwr zD4@?8+1$#(OPTJjab8eQPX+p_{~ag?0Vdang$AND^;e1lV#p1ufrc2BN*tUDGZfRA z1-Azd+$NuiKh2j701`6u!<5!%jC9Z_>PR}5Z4#>xOgtw(@li;s;&Mu`4rktg3WC)y z?Zh`7Oc@Pk$PoHI-g?%1EW=`YexMTQi)$g+C78@y#w|FC;`QsiN-)n?u>B6m?6{dy zb-Tnq5jGG-xVL^EdtG`(U)Or>m&*ad_=MP)se+W@MZu806q;_)F4ep`r^XGO`u>{- z)zkR?<&D?UVrtcusT70I}&vrMCtn??wT+4SGZ-kvC2)#C7gBhEFXI zJXzHQv1Rw_IY#qX{M>F~AR{R}gxVhpb&xbPY}sO#89uiv4!a_C8dx}olWcJIz({I_ zBLA&*KE416a;z`y#3ysNl0P@|PfL9LmGYlUTD4!YuxWHsgQ$6jM5-{VHqF;O7gZAL z*vl?UQ_c8Z4N~}P#QvuPwM)O>AyNg>!N@R5sa;)de6g#1V7p0DE|i7Di2N}DbJ~TC znS|}!F4C(xz>*}&xs1}9zIM6GfRIQ=6@sJhEau(c|WqNoiT!ooK z`UbksJ?}&K3jfkT9eAmF9Ph%Y4HI_?(v1O(B;37ilDgi#e#^D+ME-DeH$)g71~pbt z;;;*L@>FvOQDa`eowPiRO&>*Nyfc_?cNQKeBNr2sm!TrsU7V?UNUb@|YgYE69fT*S zM3|n7y~$upTprepKDj(+;V)9RYhj7zlC@P00Aw~QsNFK8`jqP+wfX|&YPL=?!~0eZ z^}&aT6}#fNG{wK;MLW`^s0Q3cIXKyA(y2H0Z1Yk%oBa38e}@jWpEYEj|AsNwdL}?7 znEa-*7Q9nC!ECoAtxm9pUhM_|U@`Z7?pD=_ry0rO5( zgi3>0l7s@2#AmL}3~YN^5Y^aZm!sdDUwQ4$0~M4Gxmn-*FwRhY1Jb6PPHy6|Tnvo) zku+QRdnkd=zh?cBwpIM{o-3JAfzmcm4wye%3e`|dsD#nUv=MD4j$M(Bf4>~ud`Do| zwve!91)(T>2+al41$nLekq*ec_>lURU})tu=@=(w#R(s=kD2T~kwnSwA2^61Du>tU zFcySUKr>^dB>eRYEwOe5WU%|X&wv#lrNlt0$ME}wQ=lh} zLaVx_2YG#oJrW(7iPy3)n#9e5L=Z#d8A4!@4-9^9>mygiPBm$0^wpC1S52G<;!&R5 zfgdJaAK39)V&fVXNGO6yT1CPiV(7Fhj0C$m0mue|k1IM*6k;_BuwPE^#6?+fBYA8D({$o0n=GXdXI2(1 zg)9pos-l+`!d~WsUcnDqcSAO$?J|!9nSt(O4q%kpHg(zNpZUHhPp2=}&CjACXZyj+|W*?3q|NY{kk#m{Euc%qS*9p+0#C80&(3f5jP4}&)= zCod%Yelm|4#>=no`$9td1IWm$UKMz>u`L4{Sr|O!1}#Y1!)ho+isvq9i@w=GEf?g)!;a&jfUcB3vcSd~cXDq&CMGiZX*rfTeP*TZ>+ z1?q>6sjJKMWUrfke+%tQ<52s?aR3XtS$<|@GOD^JtTQ$ojy>?*j#q>DSJ6YQC_Hft zq+4me$G0fI$qdT)QF8<=BZZ|IXu>86d&QhnbrHY(+UY~t-bs5qrmPqQv&f{bcO)`%gZD#<|e!kQiN^u|U(v6Z_ zA`C-PgKP@eC(MiV$_a6K-IrzxSTbdS{MNy#9B#B^5)ElLzuNrw^Aq^Y;4#djN&C## z)9=>5hfbacnNW;Vd*U1X-vjsaB>I3R1OR|-s{fMj|6fsqQM0DC6N(yUccb1Y88#A7 z(2{CVQyS>_yzZ~;*`EgD*uAAUKPStGNAX(M;z!~_tfuz4WArPj>~yi`3JpNB`1 zqUJOrl=9SV&vDuJr-=*uXCdFmxx)5y*YlJt+hB!G;>F|!x9e8hvwP2W$8L{vlS=od zE5pd390qT0XzV!3u+xi@x_>?7ABcKLk(gd*aox~WVRc=x72%+ofhq)(A&ks0M$mUe z)!zm~s%*1k?+olyWP2>^V^G#rD^p}^uU#0_B(9~51L$YkMke{liPW6=P z;#t|oR{r(1a#bcC*vw0FzdQKWCLe-uE^ow^8I5@6m+Mv$9KWWboTaagp`kKYdSQm| zc%-lUYYbCV$z zn#Ws8q#2uGGsGHW*Ps5RKEm)W(T%vEN)OzfA&UAsoq9}VO%rFm zfF2-LVJ=U;0^u-X-U{|z5)lhJA&R){h`_x1q0>Te={6CqxgmFR51uTaX+tl+d9h|kf$rdo}hQ*#F!KUN=8 z*Yc%H^RdK9+RDK`l+K+#+yD!G3VnK4BI6K5kdE+LorM^gM1sjXzw%t*@>y}vb)LU8 z8Kp|GXs|o#HoUD(j!ia3F4y4Sr}B8wh?~BoX|&@nv(c29*A2hEzOog>Ljy_^_T}q9 zXaqq@^eeDWgZLRb=fvMv(06NnE<*cuy-FXNky{?is_42qpN;`JS<-iEcicK0PC7QX z+A7oaXnI~nd>`0Ro*PF>>@$c@+IcT9b~YF-f-`kd&^(yZ3+^eV-4#$Uy%6+-M{~nW z8n4ovcqej+YgVL9u3pVnpMEVoRfh@XPp9Qv&5tK0wxkeiTsj6xmqJ(r15(9Gwz=(hiHe_TTXr&glAKF-;76g=s96jAwbSC|nRAvcbnne~xbNQe>K~~-477XK zL1z)?44Vu+6jzTCUa_~sfZ~SpwZk=qHekaq7RZ3y*N?V0jlzwc z6<3amdQM>L#x~xcb5x@?)2q_{o_BTbxqghZSQO#=L7JJmAepKZq;Uo zy&iv%rP1kPc)LbFL-bbZ_MNPh>}d7@{x=38kSAzX2n6&vJQj~_K17V2WqQdpn)5C; zqbXAmVsk4c*-C9$f1dPor;(9KpL2aKlN=ecThy0wJ>C>MT%>ib+R9IFyCAekWJHD_ zHGBwzdI41l-eIA^S;!*eypm{Vlr?4jb?o%Hg8lJ8&J9r0vYpcZ|t1iRT4wFp) z`2{=iRM~eQ2kG6wPNNCspk8;%o!S}FCBCZjRq=A}JaT#K*0zIUXXNcT7GG+>OurjX zQg&6A@jTwX>>QXAvW;pkvgB6%GGv6AS53>Y%(9+9Ew^^uBP>b>q8htpV=MU7Cg`wG z5Oan`G;Lo$GSC1ks^HQQkGL&tZlAGbe}>c4K_UN(ptXRzN`|BJLl%Sg0ncp|PQJmu zpJsqotkssY-D})`uB;~cWVE+|y#;60g^AJ!rL?9Nz94&c=1bw1jV8g@g0;g;(xNl$ z<=}E00bMR-X7A0QV78?6DU>x#t#SAhU&BGYiaOCNqr(ZKslxDcZegVl$gFxyg$Ftt zM6m}u8@_dgieO|lXI@VzERYS9IoVk+CB%m0ObmlfDn#olhT~OD<_+S?<1BDk{|Wmu zflrQL7?P~}Scwve1g9mj@KtayTP`;J@2Kz>JtVJqfnuv|2-CtQW* z(hgR~`!BR8xBEuQ&DFtW##p2J2NU-T+i0+&TWM=#OV8ezT5aM2@bd1nsY@xkFl%4)X9N<#iQe=9J?|TS@hh3y><98d}hO+5Y!jH5^L60lV(|56$FmnK{Mf=YJjZ)ie}FU~Hbxg0b$FBM60 zS-9Q$^WY*_&MNPDCkf8n@nphe)BzWVn~dL37|YtaMAX!af&(*3 zBmPDdl`tfaGHwUuj=5nFQUoUxE43#M-Jk5IuYW5ovU-moYz?ZM@$^E&3Gz_DB>u?T zGNz4wZu4laP>$jsgdco zohGJ1oA0?c6J?qBDkb`xvri9T=4lJ8moj~d|IAed1ifE?C2O4Te;68@?;Y}9Z-)E z76XT-1MfRAncxFPrP>1rvHXYiNEREd&96+HT#No}?Ko_R>!PFB+xQBN(B(Uc}#m>K)h=_xf={4p@%G5Rw8AEid> z8~b^Yw^y1&ERb=);d+%tC{+vbqjAQW#}#(#d?^uw1+Iaun?*NEwb6vC%GmGViK}9| zh-5zgFFxe_HZ8=|ez$=>PzCShS~+m|VE&#v(O`Xu{?`eunm1(z^0ou}*qlodBkU|) zfv`Zfch(OjtPD%xr7VF6@#mHr-MAW&!}NW3xI{$9#T;GO*Zr1u3g^EW$k2PhEFI=( z`}D}49v`iU6HfaXbhrIVB?+XkAMt*z`cq%EuqA8|s6Ns#?NF2=*c*sQr6ZNUESi{sJa^lV8vYAI3rEcZcTXcw}D6kf0(N3O?@jWs75>gk+=XA(+g zh6vR8fIpz{FLV>G0a6Sx`n>lZnY+*BW@Df~M_RcKNV&$Y9)2 zZJAlWl=AiL4c#fBBy+snsM?+7nSr^;=cqK7i1$d+y&5rl=LDw#yIIlK*59Cw}j)jaqKW8?i#0=4MeH$0Kx6-JBQ%sU&t(V zDcekqn;Q9BwN)OJj0WYZb<*?E6wDUPPNAcXY9Fjn9?^KwL#b4_8zs*r2|H!Dd`YTerksHz z9~%m4o?`icVk1+FNtqBwlMG!KA+?3WRv_V$1X+Xz#`v&cIND$L{+rYMC^PyZEPX5; zTan>FNioc6U>ds$Sc&N*BA{Pfeei_@kyYe&4X~K76=0{GEh8;b)NfCH zcqw9sh(&?W`5R^$Y4_koQv)KyI^fGx5x6~l^Mp{`O%OFeERgFM&9nQgD{vI_9yC58p&(;jh`9$Bs4J zN3LB>tN?!DhI)74EsEl+x?Yh&cYA*OIB)xVul3D-ZjARTbvpF%gy`H28hNsKp_Gx7 zRhAopkBmHBE5Xk=CL%=7-U+C`p7WGu-3w2EvAmYkf&A8h|3FUI$X?~-s<7Z@);rdz zPuP5y&~?3D-f3xZwYo+hUbq$0PkO%+G(h^hXvDTgU|bNh+kWO+1cZjWFMrqm6nyD-%9m}a!e50_t4~OY=DDMNeXznu7EUVmXtuRj z`CxkJd|~?e!niVl8)J?$+o)Wo0Ekr!MDSR{K-6;nsbEXWb{QH_2*%}zn#^pruZa)s zNct+9-O+?XcNMwDl1v*I^V#9HFahcC))6CWXnqX$DjEP>J-8>qUW_}K$;h`p7YyqH zJz%ITmbl}7k+@n?`N3CW3`ZX?Tem_D2qYT1aQFt3ZA=dTNgfRul9D7*Da$NgVMO9aVN-nRa%@Fj!VZ+!ohE;N=Ne+mD} z|A78is>3NgT$B^bKE?E>*yRfHzip7(8JRdZ*gE`dkWQ*<*{(65_)OQ=RQAyQ8pMBTSVfSZ8b^o#;``+MjGY}^M`b;(5W z7`ZCh@SNvehSlOR!PFuGDbSvY2Nj=nEYfsUrMAdojy?}{%1nBTN#x##JGo9KG!=b$ z-?ds)<@VWg#xXF^0jx&yCKMukOI2juKyk+e&|r1Sd@scC@s{DTly|)o0sueH;fs^VII|tdG|TPoQG-292_Yb?TecTy8z58FvD(Z^GN+OW1o< zel@fhifwN^yX;nmX63C{44G;;nxS1~7WJTn1b1;;A-8s%R}AM?n4@g}(5%D_!lC&J z7Db$0&R7m72%Ifu&FaP9Nx8F8Y(67*S1SszOoPaZbN(BWG|63aFU)VHSRI|3- z5JtdTckNCkqa;BxZAW*%=LQO)hP`oK_dF3 z?)(7zLeqPzo|stc)<&Wrf>hXZYhpH=o|uFmL;%nN zK$L_I0-X!7##y<6*+JOppal;Co-?qlZdl@9kgC+uI48g=Zr0GyL8zWvtEqxTSe87O zHn9#!qpfyKM%AnJZxV-Fx6^B{`XgH2sK_oEm>i;zQNpJ6zQEVXlQ$IjT`J zT)S-I-aDTb%CPB(Xb;aLndH=8Po&ck^O`OJsv>ksdWmNAVf#1Xh{YHwfr-4Edtou+ z(b^L-tN;Q@B3zJm|1ohY)GKkBzDW7dUj(5ZaNzjVq|CU*kUf*9cfgXv>%6cZT#y-+ zz{T><@(=eEXq(+(NxHbffyz8OZJuV2pUD)nOjl#s*);@y0f58{lf%FgN>wqwH|82j zI~6ipRT`FC7P~xk;sfin=hDf&P_X_CtH%MvhHFu{6&r*rU`09Y8a0rKV|a&dbzal! z)Kqr88g`0ga*D0E_BHNE3N!+BEZMfTLWn4qtdL?aK{ky{k|KDCW3R>G zSwZHiL?d!rpXud((qE71k1XQAdfVU!7`?QN|2*hy@= ztt#~}4iPe)N_LVD>pz*Q18R=9qxuKYi&f-u79P4>!yDaJi`PwthyfoOHE>x*gGD0t zSVhFCKhvH-4b%B1TGCVxZnla7WSCP)mgZ=}jun58*H3NZ@iXhM8O>iCNsdaE@_f6X zPP_<tFBaEDa~0h@UEySjmP7=it@w%a zc6x~vvAMpn1~gS#m%gKptnZYJSdQs|r`4dv#BQya)vSz9ZAgq=kj4+^>ziI#^uKUL z7f6N6O=t1{&b$J>KMoJqiwTRw9UXj-)LbLfm@bc`G({Bp)kRE3wD^L(lg=dUSa+qR zyxIrcfILQyymdh?4X#G_40!Ak0hYG>sB#9wuCa`PSNuhYJqcSs4Nf_;%T2BD2s@dq zlq6oFW4Xza!nj(3H($`W@%Hk~BYcc=r9YfhM$qj;-)E1&Gqk|-Fk2=8ReE=dQw}Pd-)B{NH^m2 zA$5R!n=LOSo;=2f#=%-m?@)Gczo>L6uKLiR-3UbC5L$2Rou? zp-r;~0_aJSHYKIMR{jAyS%s6KcvrH-D7?9Vl&bTAT2jLjUUEs&f$>24+cFygJod&O zDszaJvu?ixQghD;!1_39pB#rA>HZE3yU%H!$~w$E_zc);5NHpQ_MDy{VPs$Swxb>( zX}+?!0i_I#vWXi6T&GYP~)PWMDF2ZdPTN77kDLfbX{` zbFHRZV!1$uL%_Kg0Box-%`y=pxu7_21~AvEsW65U6HT52%_~B4$lkD6V0j~ddE2}R z4Y9ja7Rfef0=-HJ~b(4yK(uIAs5{?fHmo%j@FmxV4 zuFFXjH58#Vgmcn*DN_}qLb#gk06qygG{aW9$Y(;ro$ zQ?2#t!A*+SDFI2XW=EJg6p}0kbtBJrPOx6jpj`4)z$y89W9nuRs>G1ns)8ik(mtPNViU0)wDEq0{`+uAd_@C)v zRIO?qyDp57i>$=?7$UOavd4G(LyE@d?)fYnlwsPm5lJ`swNALp~ z0r+8ZBS4+sP+%KK;2dfYRlH)RR!}j}XYxXoutsRk&u5^@5`mqtKHpYoF2Dymf%e2! zpaJ&NI;l*^7rYqbBYqwMC3Bsk^=!Gx2@Xzk>< zVI87s=2-5#6W?f{Q=cR6zFL>AeXXStewD|e39^>az?2L@;&KfdQ0Yf_*c;vkp=L4l z^B_m@a9PeoC>DRR#I?tGLT1hpMrZ7(G2ykNP^HdX@N<^I+ha%6#alV-jMUesJiCs2_h3*y-L67s*es#9FWmoCH>sx&={zzyBcHoZ z8_h{I-X$3>mLjx+r^|c$p0p2N04FVS9DTBOE_AZPc|vEccoC_~#XT5P~8ALR!XVNpj< z0mUAov8UYLz-H0j(if(fVwV`FLoSSFX|=bC^hQKbqcD6-xU#+l+Z19p_yb$vXfRpf z$02Jj8=q&m0c^~^gzIQAg(!om7XdW_REaY7ZP-@@*2qN|eFzCX?*?5`21~x~WCv%s zW2aYV1b+1=@*Gn#&Wqyi5Qiz=0 zI{=e`(on>C2PShW(B^q@bG6d5aq5xj?}mRI>DFEp)2-fCFPC9@d)6pQe!tuR&91p! zipXEC0*4}#0&N8-*hZpTR<*2+WwR^ZQ(~h{O^t954GRvAD0x0K@Km>*IrHbEhA5L0 zu-T{EasDG=&sK#JDWc>%v4+OxBD&X8U8?f&F{#!U;UrJaBbeu369vb=J40VE^rVHz z;G@Jg_*hq2;xos90(RMGGO)s2hfF5?u$Q0~*3-B&o*xu&%;=*sk%+ig&q_~ zsH0T7va-o}Z_xY3US(KC6))Y>^o`Sxd9>Ya-K5&iTT-1}RVu?1SM{T2jqarj4_Js$ zHlGa!XcH5nI@O%SbZ+?0XNI@Cb@ZBU24fYc&l%`#lFh>)gQ&LlFOHNar$=5yA~V`> z>{Ko9>^}GQ8>G^QpN`Id?R@Mv46qKMfXVvYL+;8kv_O=5=IXAHre%TzZ+@+KReBjF z@BAR~93fXL+2io$tK|j$-|0IMY?7 z&&u4!(vi-|&1oM9;NRb#EF&c?{vrRmAM*bR`2O{_ywv~YCRtTW2}KOWXIpPp<=2Gf zYWC*gPdHnZ;AbMQPJt$*qFc9Wp0bpFYEQS5A&DBM9k78Ej1h=sXkMmHr%o0j+8+zq z#r^A${@`JvZlbrM2;Ze++Uxj%v$V&ty(2st)oTAhZLo=AzLA31%#gDxo<=b%pD=}{ zEa}9B=7EQ{G&IA|U2MKiW2|5+fv4YTfpDg5Q_OdiC4t2bu_|h%#lS?VoTynWi?FS? z2?d+YjuMqEmqoIk4g4Za!zmtdAx5K47712~H4=(gd4vj=>9(yP4nnA&PLrS=G*f#@ zXY3K?z!29;S`AY*A@#jow%d7Z(1;RNi;YnUs`=vNnLxjnbu4$hNIl9Kp;BLQ;OS0* z-U}tFksK3Z@uu^mto_f>c#o>-wsNkmD*lGcx7)?l#Z4&l)!Q52KJvQ~w3qvn!M-1Im%0af)-t9)5avbCwB+H^F2hIF@VU&rDgZg_;ZUMKgVKrg8@?}YFc~iC!OIf z1Fcl+#_gyauG#O*H~*VE*Q>Wc~63eDaYiF@)Hp!p`Hv6&^3y zSYkB(2LPzF8Nj`u7VlK?-h!G4b7n-p__#C(3-6pGoTEJy)}VMLH8Ay$flNc9RZZ14 zZ{=(p6AB=%Z~VP#tQX48nAsU%=kQ($Hh&l$E=Dk%#IrNJe9VX+Zkd|+ z5dF56*F~2;!mxR@B{2Dno8Iot$WO?)7)z!G)Dh%ogp$TD5phCm#te~!R)2_akwZ(h zGF%PpRXj1BD-TN%nNav`9;h6u$`S<)0wZoG*x)M24;?+al6PkU@RVVdL^YU1goY)p z7zAgU^74VA=hOXclkv@RO>K>*@0{`$$Fy6v`84im4ynt6PE?ZwJ&X1_(K+x56!-y#TqF3 z4ct)`2n%m?fq@wjRF@d}Tm)&lX#P}b6+#fE&Ow_Z#GpS!VdQ|QUPO0aQHyKS$+#o- zRL3<;g;Eq;{3V~zGfl9mMF|xC#wD9;Q#mzT&x>j}A zH_#HbBE(ka-P+jJ6OJzKtV5@avim+^TW96l+<&^C_19EuN~O};lgRUXv2T}wX| zk3LAjeB@8e0A6r(-d_XNB=o|$2TM}<+fW7>N=Lp3ZlOyaQa7BzGHT~NT>x4z%WU8Y zBZMThF$tA!AaS{95K80JG@=lxvOC|U#5@L1n-jkmCnSNG4PhVaj}|^{vS?8E{sLE(Y|4z?OQcX=$Q;D}Uvd%CsGlTtyP%uldPL};RoB7e1e{L7} zADK~-Q&AKWQTj(+yyM29`uTtE5crZ>k3~R5tWwv8zhuD;n4d_KSp4dG>0etWi*$qo zu>mmmx>y%kMG00~BZ?!DB+RE^MOa&GE<}_@%>XoIzzAB;zrjkwjfIR9!5`6=4pMGA zs9P6a|K!S^(eU7+Q`4YvO{b8&;U|r=NfzM>O;6gLBN)&onxckQtE&|y5Pw;}lF3o~ zBs=4W*XFEooSR|J+UA}1=wvoW_jUFBkDg^-i01q=Ovpd>&ms8#>6w$Qot~A6i;2}g zeUqY;ksOPan;Mm#q~4{HprxZc`cEzW-%9*%TIykLN9$-{YVvRD`%5}h)KHu{0Q={Y z|6FhIk9IqmI6CS5zunLf87oIaJNlPCB37+VMP5#JqLzwQd{Rp7_&?jR%2J?_{Nt_d z$MF9Dyc&r_OF;oKA_y}_U4|jr22c&v_1UN_bof`xd6=y)2TF|7l(flBz8BiSmkmGR^jh9o~COSL2}dV!^Pe z)6?Qilzgy*6A5<*2?hNmcrXwGd6^L9)NBiSV2UNw1Y|js`{VEMZj^3oHA2fpBB4rd zRK!2<>|Npco2e=BK6uDSAlLVA-8dP$jd@`9fvUgfgW~b*;5%o|rvGHgmwNYdplUV+ zsk>%hfD$DHta8G;N=1&@fu}c`k%^d!#Z$`28^WKv(!2Tndk&^}Bv!cdaSjkaBrk$p zSNv9z4+uc~h)${UQ0G9sVz&u$>$hJ8eHbTv=+I1V=Ix+H%euUhXLhtXY$n}k`vzhd z*Q$F^xiSbo!d5H23H5ff8c5VDT*4x_$S^G{z9%9Vg-R3__hEqDzS_*wy<|cdh6X*B zu~>w@dxdh5Rr*bunL&cw9P&U1WH%EFol|iFjBG?4yk?O>GPM7sqcTC!c+|Vrf-tJF z&?Fk6#^kko-LgjcHmb`RgJUJ!S%uJo9wAFA!`L2K-gw<^8g9q5Jw zg+K+_yPEGa>Dw#YHo4cM+J)DOvYAS9Y2haX$pw5$N=Fq{4bs;*tx)*LvmH3;KZT?8 zkIO-Q)ML034U%Q41wxPA$W!rQjjL)nyO5ivwZg5(E=FX{V#DOmzJf`eXN9dbGnrl} z%`VccJDV8Z@46WmgkZy+sjZpTsJejtMzlOw6pc_AdXZU#Xw0#FFip#sH+-P_RbLp6 z6`%4)F>UYEq`&D`G+d(>uPZ&OUGcU22rASz~~;riPD zh2Tx?Ia1?fZoubEdeGE-nFLWI{>>}ciVN+~Nn?bD-VEkfHOI#7_0Yyt|o}da# z4osmQ(bkl*b)t}il6|hy$OXsrlE#}E?{QB>h<6ot)VG3|j5tGbYqRWH%3S*nywTps-?&kn&U7I-<*;m0$Jhq!8jmh<`ZKu^)BIjHy{0J`|M24ut{|w0SGVo-RK-@1sqr5ypy@XcBWm&DD9_;N0e*pYEu_ZVVP zix+O)C)mcN<(3$v@5rn;^XFdG;*e;}&&9$IY%HiGl@Bx*xT@u3mMy=kn}7u zOv6z1@`WUTQ<`;=k;NevnU>N~c~PerWCTrTdDMeF>#;LpRh9OGN+N{gi`(iMaSsh4 z&VndPjJ=c;$NTNZ^`(_*rGxF6cw}0B48E-Oyq{fN{aL5{jI2D*t5{ja%_F^DL;vY|RL;2P}EC>lE%I`koLU)%<2Cv~i>iDBPb+o%Yr zb*}goVUYUxqA@lBdqdM75918r$hdSeD7z{J!va;;6<3LZ8m+5hs5Y4STeTS>J5Y*O z;9^x?L-GgH`N=AGtw|fM1uK&YPrlHU!4DTi<4t5v3MJ{6N;9$<|9a^Opw_UhTl%@!X@O$N1z2 z#orNLI-8BXl87&S&C8iKvsk|ljOI4*u0aNi$bc4~h}zyF$Cq4BiKLMq zXW~fUM`=ifL6Wr>R}oe8G&%^AUV};N!PZzMt6U4p2?QgA8DP8z62Y@VfqXBC*D3(` zW_E#eBnM8H!3H7dPE5fO3N_eFUkWcb@RLDEIt;p#Gv}r>YS?fN8WZOTJ$gMl*=)4b z6*YC^tnZSbNF`9*3fP9L{!0vOatvd9V#eXlt5nSDD!sR4klQolv@@1n1|NaK>!FAG z)2eQ>_V=z+)9-m(X1V9~4qdO%`)0+;D5nz6cw5fcIdj6htMB7c`I<-i$%-sUbq$EP zF2p8cjB9SU->g$6s!>*NLe_Z&NK$K|+dBr3y9_yl$_G^r)m6NkH!&HOlJUAx#l%k8 zS(w(uS+8?EJPzYko7`WEsy~U?BDXH9@mY4`8&^#3$=eqzdS}nlSAUL|vgcmH6^b(Z zIZnWz8!gK*T&5<5@?GVS53aZ;=>hVYJ3d+8=Ud8J56Yt&dDB29^*pzX^u19et}An- zs~r_@v7(*J>SCx{12vn?Ftzaos`W;#H;v?}Y8OvaXKY=<#G*ng%sBvi5N3d(NAl-) ziNkBxfAu(faQ0$(ExQ?!-n#yTiQUA53PY!;upB^YPMAod&j<=J7Vo_-rY(>ay7wR> zQ(#X1azQY<>_J#Djgr#6ot?<0O`1PGlS8pRY{>AzK~s$C%%+I0z${XK=zJWv^5sCy z+s1*D&T(rYsuf3%>@c70$(O>!w;gnBYDc2o*2VXhX&#I3DO$4ku5MM*TpWci9{bJx;#To%5Nr&IVV`I&)WUzbVRyzX+Y3 z7?m`{Yd&#a8`UN5p8Jlvsb`+zExC?MX5?-b_Mv3f#&wDyL!R_r#M?8)=4W#U?kBVP zVugjo(T{E4wZ0fz>WCdEy(r6W$+{jFxrx<{xK&6+AH0^YX2tzRF`)o$xka*A0$krQ zw*OL2cm>YPqUD?}erE}UdaoE0?1Hp_L8Vyci+=MvxW*Hsf(l7-t-O^yY-4Jqidcn( z4>|l%-xQylKUNZd%7YX2JUzHAjPr;?+EVqCXW=@fY+uuH>hh+k2~JTuqQnr4Kb{+KouJ6XbJk>pIczfgkmUo~XAP-rB^lM?uHBot z%;va*c?Zpk{Grv^dkU312>x zV)^Y7Kbl-I?C7c=Y9c?q(3;IfPp4D~n?b0%UkR(4?LllAxsI0#8Ab`OQ$%(8kU!Hp zZthO97>m2T97TMYy%TndGGOssswdS}0OBb6hH7UbJJYg07Ua9Kwe^j633U{@G;?T> z?vF(4_YGeYy;M`H`>MZkv5OqZo0QIxYV~P^7no@_oiXNM-atBT6IB|Ki&fj*v2KSl zA9a6=73W9y#5Hv#PDR+zQ&CA{z-50;ucvaQHV#7}Q!MUtdUG=@5x^1=w zX@u!Vse;)T!J9!bFjPqa>-kC>lqC?Lf@{Q}l?oZ&L_PEZz^4R8<9!yhyxf@5ykB~G6t8bXj+(s6B$VgR z^z`t#wRFEYEVCxI^gAC$AJ@UNVY{y98%- zj5GSaH)dcpQ#I#ylZY0?O2o**5hRjtAZ)O}1P$qnnRM&zBG8pM^vJ)OW=F`-A3_S2 z+1&8ouET81snH5X@|G}u269!zdQ;rBwH7gHBX;mvjlwE8BPsM+YNuIChi+|D@6ENR@^KQ<&2UYbW(2js07@ zk&W@hxT;f(p%jO`$YWVxb=aLXtvAX!u1DYE!g1!pa}+H3mTxCf7{4?(eoTM0OS!wLcSF z3l?$&Q!W;RpzsXVun2R?GX2ckrtwK(4ZSOHRG)6!W6WD{LeERkx@KU8_>{xa-O^ph z5tU8T+WX_73|FsoeztppGj%Iifm0eJ(9V$cetM#~sBhu)%N zJ;$hKAUE%bD6Gz}VE1H&?0rV83{+3YNo|#5=)M#Zo4U2YafMIwgDZ0yQ`6zCfYev< zTQ7fJ*7Ve;Wr3m(_@IvfJNgRGyFaQTIj9wc%XYjO!vXkoH>ELtBu{F%4#DeHh(3b< z7H1|*D}{d6UZrOF+A$h;3F_&=nzNeP-P-nNgGAZMHL`&k(A;#VcMzqF?q=ki&6*eP z^OG8i7Q<6N?^!BX4x~6vdDQL(ifO%43p_0J`?waOYvP%Uob>zVV7p0`%(0p)-@>5o zwi1@<*>@M3gk~LVj*q=dF!D~I`Kc@Du5BtV6-RHvSybD$=BhS(>#^ruh5a9npztagn3R1A|>21d4a=(>#a)%@0lIkAdF})V4*JEIDLEHr03Plrb6IOP-9b}PGu%EqPaW2wQNsUf1SsoFoo2^lH%;hT4Mrh_!@`6#dkT??ca+tqf6KAi0 zN=Mz=_QwgAWT9ieP@1myU6SXfl|;n9uZFcHiPCM0kWt~3#+HH+zxI6_m3VMCS7snh zHpuzbbVuV1%tw5BDd&LY7po{{&KCnKZVOHTFRN7059nuVH2MTf6E zE;pY?#vfwo5C7FWKJ8chA4kL8`zmlE0fY*`7s~HQhKBdUL%kNcc&Woc;1L4*Ks~)W z0xyF6h+!m{nZYa>ft$$E1zvD5wU^cru`w*mgXTAY<>P2sU3*nyBobraOgzLIwXXl!%q?fGs`s5_#O$yn`i92{A z8J>U_d(#zF0au9&k!6@*A@CD#f-5yj%y#Jrb`>BR3GmW*a9#fO82(!K7~1|%E5o3e zQ42u(kKtcb~e}d6EN#u!qC}azlJLH}i0>!3rv_TTx^O3EuZpu$d z$*CRdI!L&1$Ig>Q;Y))yyLBAGg-0T9XNCcF#zLFQ_O1>LGgI$1@jVz?UV@TT1#cx6 zm7@JzpDO*erNU_{iJ&ekxy3$0w~dCWPg^}G(uyz|!ItBQ&Twn6r#bz4*$#<5ra7$N zPebIzujnU;OoX5sPSICjk0ayZ9V!%)mevATCqV-?A`iCB?;Z(Y=OJr5#fX$adNWQx zhCwPPq2vC^&jd3jhME|xG=}qgRmhOkfRt4&o9zBTrW2I~gKtmP*AAbJ4rG(zLS6ex z)aV1uo6oJ=M(u|(JxAh4q~+RDcVyqI4qW65w#qtoy7lRn56(=KmUPPkYi!z%bl3n}jA7A)w!B*Cheo zlmpLz@V=cw-6%wq&4YktE2_?+*2{X}Z4c_uN(v;otyzG)b_;{9FJ(Iom zVL}zp%ha(jrIyMqO=xE`RFJOv499hD1gXxH<&}66uwa7~>lXt950lo~$OcZ+W{oVQ zK?$_AmB=N-kv&{wWf*f;J^CWrmpva$ zC>I<(t5*AbpaZ9AFfd%!ocU!AU-9-|Wn-2#mpTZ|yagA5C07)fUkyDI8g{*5wk_0e z07N8I)b}uN%OER_81RjKo^+^wZv8yCWKTZr|JptOwR`?+_x#uH`LEsc|C!xG2NOsN z0odX60PG%|fA`J?SUjVDSv)J{KBOnnFB{Ai0r{SsSoxI)$*HVFBGUvwiBQ%m#F|1w z?yhSQdw1g*^ZFbo0E-8ggZ|bF%6=2k_cHTf&RkWbK&AfU+1ck|kCn?4tHUFUk_*SZ zP{g6=pi#^p-`cC7jw$p(7(ZCSVuh$K`up`-!;*7BoiPpsWP2l!gF}TgQVM+l51_;A z{bUUV!#L-c4aL8jL)-Z8mN=NQ0_NC z>X$E&G1?u7ogmLhVUFS(eB15z+QOyk$m8UUHg;U%E~Wd6)Z7a`M9HOB)yelD5FF?m z!+A%e`ce4d>4IGSTqww*EmdREOqh021ly7Vbr@4rzSJ=Zlm>*~h3Bt}(fek^1sT`8 zef?&$+iS$7;XcZ7EAg8NjBSk6QhNqVa$9^1ki*A0$Ep;fq2cv1pmWN~VCmOZ&s z0%0w0>PB)k9c+Hk*iY#yHYpYqXWI70ZlFGC(yE@GC~>P zVW#82{f#Un^5M3Zjj+waFV=*7!g?8%^-{i6KpCj( zaGa}bG|SAnr&t&Em4i(+zH)vYn^LKpQNSd}whjA!)Q}C3#~8|T;&X06$qZ+8t)9vP4Db6(#^XS0YJx;d6 zu4v|#;5hmlC$R*(O^Urh9eK5Z>d`LF0rFGFmxArlqM~0hS?p=l>%wN_u-m5xTiC|y zFh-vk4bKgphjNrBE584lI{%MN9lsa|c51-ZG7zwrdN>^D56}7^Bjr?~5hbfGJ(IyN;w8;Ws7fRD5{i9LdXz|31CfbOhw+W{S$vOx0M_dk9AD=6 z2)HVQB5*Z?crHxt+foDr{Aq{~h*DW3ZM$X657z2v$O=9 z>-R)sKj)t}g(YgjB_9@aR1s-k%;YDi&AoF{EtaUO44mi-zoMMJyzyS#J1pxNC?@N! z0=PH}gGAe|BsU7JRu-Ac?x*xReyzPY{vuz-9mmryPFnTT%DcW)IX84$6PjNJ>+kdZXEZtGSqmq+DCx?im$`!#H+qrU zioVa2@P(Xntk~GuOxq%0uWkNQ1rWAK~XrlZ#4rn6}6qDD%Ch|7C9?LGsXBDUGfkHGcPd6X8}k(+_v z=Vj4*U(b^;;&}_D6$H|b!&Ho02T4}T*xvgS&D!c(_hQu4&7kbe9D`a2SoA~+tl-Tt zs3GP8dx+rB_*b!bLuRJz1l|yaNp{|q5Mh$?P^l%YY5N~TRHzqIQu|Bava7h+WoB^F zQ*y!npwRA1drP$}z}|vl!R{lVr%_8NM`O8bQQeWIkl`HKRZBhC+7nJwzR|s}sa1*K zy6|S#8WEbK5SJl!ER0}1GEfp}v|ChIPh#w25ho(eo6Pgq+Y{igT0iLSS^Y?QO~`Ep~Q_Qu=lGO2r9==z)rt^xLf=mzn6VOEun}^|n&(VFEGhtTC zs4mo9@OsrTR|w8X11gVb9g|_0G?o`X7QbN}Y_G;kuA#hxpAf%>ZZ^K&COm|{-Tvoj zj^7Ul!vob8d9Qd!5-IP=cA@=X%;#~Pg3#F|j4q_FU2Kua?rI}D^uEGSo5 zJJ{7S&@5m+;8s^4RPkx1uoi_(Uh#Z!_7wG9h(Su67+q%4%ggR!eg)TIu3VzE4^pGh z#z92py`QvuH!P{P(wWUO`nTND5=)Dy<2?tRAnUOwC8t}9n=kM|h3WO3WY^S+k;BYC zJ1(RtEs=<(LVvfXfE)ONz`!=-Va2{@URYPdtl3ATDl9vWRJcg4wa7eS-;lAl*0&_- z#{XiK0Q)e`+lL=Ue06$>$ioV!+595jA8WpwMxPxVz|VJ?2yXR4mDJ|F-(wyU2XrF~HmwkX=T*6e`kXV; zjmig3R41{WO_mORCUaEm3oq{bT(r;Gdqa_mDKqsF0Thp~qDUE8+(@9S!*nxUS`njs zib;(W5TM7^+O$ut{t?G|>%W64s2cIzYX6dNN+y$V>x#Eh@7RB@Prt#_UX2+$tNOJ3 zf<|urH6zrES2bMfYIjmEYG1;4!I!1-B= z6--)X%&~oneVW8eHT33@5ksWd@6+IKFefx!R!ONQ z{mDMr(#}qWA;Qo`r1RP(Y1p(_+tx;oevUeO(iY~SP(89%4MhepKkNXTr)SaLf9i09 zR6d7K3ZS)bzsH*E&PNI+y{ppxmQ$|RgO1!v$t*MZZof*BT#npW8(9ZUL_wZFM6I(s z3{#T_#^Ptn-M7qJ%yh}x#Tg7&o1^v1FE@8zq}dgSAb291gJ9m*(`6b7QRlmXB%w>i zW($rV!Q%AbDFu}tgA%&{Gsj#Ktu@7wKrST>oM=m97X*g^&}<%6B4G@Hc{x&%Ky2JtU{e38i1?eACzWWzd_bYn8xW}k z_?dWj$=*MC?(S}HH`Dm}Uu6-r;=H1CxLECVI^8)x$hpWOI3XtbA_nPbH*@q{Kn_laYJFjj6 zOMnfUS*>U8&6L&r9P-ie#Y+q+P&vy)OBVIz9996w%+RQtHY)@ri+!*Oo% z5XAQKP~Y%O&^+lb(ps+kJi?W=EWO~z&Z!1yp+;q*Hj4&B)WN0^$vC~)l}tlysR(K% z(We6~)1aR8v+jA)=*on^?Z!7&)DfM^#+Xt|RFtgG)vDm7I3)EL8nHsVWRq_tIq~@cdkft|!w)o) zqT@S#INX$Vy+#40s5Lk*tWU z5uFH~k+q05<>x5vY_f0UayZ50VOnE!I+P+qV|Y`*^*LN7*qAz&;Ap;cA3#298mK5@ zZnp=xkKs%5xSiqVs?vG`JKHY>>ml#O7v)xT+TGDRA$qu@H;*pjoWHaM{RaQVMi{Z$ zHNGkemcY#SELsp0&o;#U*d!ziYsgwecns+pp&^Th_YO5U&K}Yo)m?h*8pR#=`lIv# zXOv4B@K1DB^YhQ-JLqObezEq?VI*{YgP0_`DKQosbLh;uv`0B!jz^)zW2)gYI`;? z^tH}OXh*wor%l=hbWycE8}|DiTs8ESgPInF7bMVhHC3F{@uJ04G+p_ut2ENnL#3Q7 zsnjilOf4;l-QufyKX$e+T?u)d8t0t)=*0{`?Sr|u5HWO=^$+)X7(p>C?8zLj593RJ z?y0z~sBTX|GLvNu`$--GPB|e5mAG*!NEqtV--a3dA+4(HB81Lc; zv~)f^Ov&Dqw@aB48(mo`pGP5MC!?c>ybGq$TN@icV)6p{eoW4?6vI2Dz|xvu)~i(x zkFZ*zPtoLVgQD&@PtsZ5uXx|U$4`2f=y&GUO1zmCZ*fgN zl~-+F9v%f|Eyur^VEVjm*u>;=o8^I;1dDhwR6gb`^$PZl8np{%Xn(KT`g}a3=JdRg=`8~js00uz={qv!!fUVPCSH9oFZ+|M_c}jV3vYsDs`Y#3$ zP`+RDzo8gD#r*CN&qoYCU^f3E=AR=ypE4e#JU=7ykpTjD8~mQ}i;&+P;r9qB2CV;| zLH@_Qd@khq>1~gU6F~Qt-!py@^1Jh=9wAPEGUs0)PqN3JOL^Xp{*h7&*em~u@{5?? z^?G~6BvL)cJa*T5F6Mbxu15+J?Vl;Xi1}SBoJR~O)Bnc&t1-@VDbM?bJThLe{)zF6 zkcR>Hv{vq+^6l>{-*1)cNeSNXYS^Fad0xW)h$4LX1od}8`}5nMS4%$Le#Zag_NTRz z&k@gSBOehG0#6W6DkYy2p4T8g5?%;CA^cL2_?+?dkv^nM{C(y7Sw3a_U5xnj_U9QF zzkVVafZHFoYJaRue2RMbaGw_-J}No;zoC8^D9;VxhuXituYA8Aq2I~+OX#oG@N;?3 z%TXSYffD~A@)w!Uqm~aDoPS^Weq%C!WIl~&J{S2s-}(_KA@?5vf06jReA-81v%;T= zk71hU3ZEyfKJp3_{}bLX0)Ll@`3NLd{xk6Jyv*nFp6A*<(jry=@3ddUJ)a)G&aOs{ zf8l;fPkOHAc^1;68eq-e-2Tfy|GPw>$NSs+Tg7sS7xf6x8FM~tJvzrp+>=lPs_a0>pu^8Kn!e&PJPdG|*K0S|)Ju)J!{>1o2$nQc3kC1ZPUm<^*H_x|$j|6Im-xB~L WzyS+9ARtP>FG5%#AZ6!=Km8wzx!zv@ literal 0 HcmV?d00001 diff --git a/dist/dubbo_client-1.0.0b4-py2.7.egg b/dist/dubbo_client-1.0.0b4-py2.7.egg new file mode 100644 index 0000000000000000000000000000000000000000..a6d546abc7ad5b02766d39eec3e21a7096d5c55c GIT binary patch literal 32933 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 literal 0 HcmV?d00001 diff --git a/tests/test_registry.py b/tests/test_registry.py index 6702682..d83e5a3 100644 --- a/tests/test_registry.py +++ b/tests/test_registry.py @@ -1,16 +1,36 @@ -from dubbo_client import ZookeeperRegistry, MulticastRegistry +from dubbo_client import ZookeeperRegistry, MulticastRegistry, Registry __author__ = 'caozupeng' + def multicat(): registry = MulticastRegistry('224.5.6.7:1234') registry.subscribe('com.ofpay.demo.api.UserProvider') print registry.get_provides('com.ofpay.demo.api.UserProvider') + def zookeeper(): registry = ZookeeperRegistry('172.19.65.33:2181') registry.subscribe('com.ofpay.demo.api.UserProvider') print registry.get_provides('com.ofpay.demo.api.UserProvider') + +def test_registry(): + registry = Registry() + registry._add_node("com.ofpay.demo.api.UserProvider", + "jsonrpc://192.168.2.1:38081/com.ofpay.demo.api.UserProvider2?" + "anyhost=true&application=jsonrpcdemo&default.timeout=10000&" + "dubbo=2.4.10&environment=product&interface=com.ofpay.demo.api.UserProvider&" + "methods=getUser,queryAll,isLimit,queryUser&owner=wenwu&pid=60402&revision=2.0&" + "side=provider×tamp=1429105028153&version=2.0") + registry._add_node("com.ofpay.demo.api.UserProvider", + "jsonrpc://192.168.2.1:38081/com.ofpay.demo.api.UserProvider?" + "anyhost=true&application=jsonrpcdemo&default.timeout=10000&" + "dubbo=2.4.10&environment=product&interface=com.ofpay.demo.api.UserProvider&" + "methods=getUser,queryAll,isLimit,queryUser&owner=wenwu&pid=60402&revision=2.0&" + "side=provider×tamp=1429105028153&version=1.0") + assert registry._service_provides + + if __name__ == '__main__': multicat() \ No newline at end of file diff --git a/version.txt b/version.txt index 0550047..072582d 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.0.0b2 \ No newline at end of file +1.0.0b4 \ No newline at end of file From f2c8f958b07720fb8fb61d8e93d8abde648b9371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Tue, 21 Apr 2015 11:22:01 +0800 Subject: [PATCH 52/70] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=A4=A7=E5=B0=8F=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 4584a11..f3d2321 100644 --- a/setup.py +++ b/setup.py @@ -25,7 +25,7 @@ description = ( "Python Dubbo Client" ), - long_description = open("README.MD").read(), + long_description = open("README.md").read(), keywords = ( "Dubbo, JSON-RPC, JSON, RPC, Client," "HTTP-Client, Remote Procedure Call, JavaScript Object Notation, " From 0aa57ca9ac713437baaae06197bd8fbec5598c21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Tue, 21 Apr 2015 11:30:54 +0800 Subject: [PATCH 53/70] =?UTF-8?q?modify=20version=EF=BC=8Cfix=20lowcase=20?= =?UTF-8?q?filename=20in=20setup.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/dubbo-client-1.0.0b5.tar.gz | Bin 0 -> 9371 bytes dist/dubbo_client-1.0.0b5-py2.7.egg | Bin 0 -> 32954 bytes tests/test_rpclib.py | 5 +++-- version.txt | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 dist/dubbo-client-1.0.0b5.tar.gz create mode 100644 dist/dubbo_client-1.0.0b5-py2.7.egg diff --git a/dist/dubbo-client-1.0.0b5.tar.gz b/dist/dubbo-client-1.0.0b5.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..5c0a555572cbdb8d660b9546004cefdb0b7a9609 GIT binary patch literal 9371 zcmaKxMNk|Ju&sgM?oN>49^BpC-6goYyIZi}?hxGFWpIZK?iO_LFwFhm=I!pSI*Z<& z&8g}>{gEdiA})<`Yr{aS>^wZ#th_8NTv#j}?W~kJeQCw>W~?acNUqN1e!jLd~4gvu!GDoovLInp(tOSY`) zNawqs8`S`E=^V!dDsA>2zP+BbmhO@e66$M?j zy(CxpZYsj72Mp`wrX5N6pz?AqmgQHmu5Q_m8Qv6K&`CFjq+e!*T=(V4fzD zbYu#ttCgj$p|ZP~{8vXK$r{^ZF5CfRte#F3x@vGM*I`Ym05*OzokCUrRHf6npl-r!68%7W4MAuSk!Pru*3X&KPRjW-A2HXi*TUj9ZtoVoqSHrbO#)I{B@qUtF zeUz4Cqsy>Sk#0-^GIiDdm1o$_{$W#iz>1U101UDuDCnPlAAgAPlou?n0lBL$yHa+C z$0GtLr8fJ-a)*t>Cwp;vagG6f$XZJLi(pk= z7B><{a;Ppn?*|j(9pnV#+>OR{Zez|usUZ%35tj`cP!@1GA@afdNc@dkmg-170gk>R zAXU1qJyytHm!BAQPTdgyMcnn<82O$0mse;D5{1ISiVMFQXE9W=T!Ndk3A1*XKd!<2 zjz2juwX@19KNi|=#P+*rqhG7FVYXjz!=Sa5M%n)CBbSaa)DFjuQ#H6?$*CM53j5iw zX`^3Y&1a|cQHVuo;sM|^)YUPd#0B_-R>TFO5zD>$7U9O_4n`4A@l>V;PV5Ft0r6oJ z29p9sY}0VX1*3P*EY_e|*t> z=2>LkXb{-tztHF2e1F0iTpnwUq%ET_EOBu8a+6(T+6#1P@LrlXI^v`ha zRkTy0Od0A~lReO``#y8sk@HD({=yI(0wNm%{}rM#F3)zM}TEuWpqt<4Bi zR1^2zHZd+%kM&?1473to{oy6!VfH3Ai3n~s{pmJmh>c}JV9f&L_$(-AvrCNG&3v+D zzQXgCD+k1Pmgp>1DMs585?{xyNF`pg=$*HnVjB5T z1ux1mDWLa?tFTrtXv{*Iiuy0BM0;3Zv?20)l{}UG&;t$nAp)1s5H|7c^OYeX1Fm~t zYMPL;10U5uU2TWm+$b}2ufA7bn2Ab>EHk^^Je*`H(We~c?FNju5wXk-=CdnGzAIlM zWPO2U&84so0xI-7mGC%nJUY^R$|INq`4F2nX4l!w=Dp;SZ166axT2Jkx;w7s#CJ^* zRJ2T|jEJ^bHx^Orwjee`Td8m8HiVZR4*8r$?F3?fkcm%KM&pdeg+1fZvSgtODr;d} z9Fx625iquVh8t5+-417*Ty~P@q_A$RucrWQZBkm+tWq>?Sri>+z9dg3lc97^(7E)N zOQ(hfKN6Pd#@n0Z#>5p*BkXY^Pt;C6Fqy+&l7H$!&Jg4rLV|1EP7?i&Zs)Yi$4JPH zT!i|Zg99q=cO*fddn8#p*J=8HD}PQG^t4I^wA-Pc?uw^R$pJJ{pMSpE2X+vHKC7Ni z5X8_TrDjjG-8BvWt#6CzZLHts*=*$5404bMBCM_$L3*C=nhD%&ko#QZj#Ss^`UUC< zxcm%&?p4IRyS$Boquyhc|A4?ZATS{535~7P^Ru~U&YfMlT{cBXi%G{SD+c4Y<{)^e zfp~V1r@!;bKi{J|n+&ZX_}bg!i1DWa#t{b-5l_3bpKWf|*X%4&F7l7E`#TOI3X%{^ z#?$GPx!aqzBIAacSYJhr^j@!b{^czoP{Zk(X>5T9KaY1lTlZIxTW2`cYHg%jtjrxJ zy8%@q)3u&DGj-5q7>x<{eJUC^hG^NW*)oSGaMKm}JigR;kx9}uLWx^8WxNlcp$7Vk zMF4)-CTHS_*gzzoL9<^^`my?Isg-(@b2?ul!vQQ+_-t#+6}eFQEMk#I#u2))>6)% zi9;Yr+Uc5nz|#DUWxw>}q#6oBN2XgbI>g~YiJ#ynga~*g-1BfHNX{jR@VDuY^fFE;ie+{cfg6I?u3p znJjRN-n!HAyR?(^3%sxoUY0`7@!1{_Q6IXeESTHokAF%OP#0N-o3J}NQZiLbuRSpi zqD0zZ16>AvZWSON&7H$#R_1r1s}i)Ope|jrnpv9-4c`n0BRhSCVgZNInnD&z-kI8F zR?S;PanulOSr&Y+*(5bAYj)xU`iPr|BX=P2xt!F6O8kIzj9rEOMvj|kOkyknKu1OF z9eyAuJv}fD>D_Z+`&e&~(!xK}+L;PFqrJ9}K;zeH*lW4+@f&&Khwkp_Z5qu`e6TZ- z`|G|r5|?~ZO~1RgK7Ma;s-^jB2#)2FKU)_TGo+W%F5z1RcK2|KRZx-9uOwsY>=p_J zlr>|#?raiV4#`m!WdW`H*52?Qs9lThG@NC?!A{(x85Jce#@1q z$(<+jnJN>OAle&lRdBUapvE8+(53zU+{Fr}-ySI)Cfmptf9}L#PVmLR>%ZI{p3YUA z5=;timIRS11%YpQ3<8Eivw zHZ!_S@%~K7y)e$vk!1jSM+*C30CkFFIHl$s;kX$eN3+gSYZ$m|1Iv}VB*{&e0q(fCc?yo?4(Tpc^@m| zc-okLM<-*L&K3x>eUJ+pH_I>IP$F+y3-z>-3`cZXJoK3D}fkSx05R(%}Up;&s$R{INsSHY%xqhR~P_ z2M&{)&BPL?aO6o)BNE^tcEe#Wlu*`iM8S(A#64>^kt*mo9D0;7XN`g0Ne$0t+v(Vh zcPu*8iD1=;#J6l#AtNH&;(b=Um{@_6cRNj9K}mq9|4=Oa%~M=hBDfmNHF3JU31E~p z7LMCwk!ex7awe3Slx|^Bz+_wPU^DlV3Z`MP0T>fb%eU5cAkzH&SgEtd1bii&ZAKhw z*U{Cdp7AoVo%s7K8R2)$AcyL-n%t@2sQXVl+SE5RHFKwi*DQO~0Z%Zde>XFA}P=u=N6y zp>C}b4r9UKqvlb6cxv+g`w*?;Q#Zucv^K& z((k(s+q$Sxy{IqZw7{zNSZ`oa$3uaD1j`%HL^d|`*w#PX0ir5R%lFyC*2( z&FR_ZGmB?BCf@L$}7+2{BcyB^_F@M ziF?{sb;y7DY8EYm@pSx>at#4*9@wvm7eCqmoe*>HfNKl5@rSJZ;b0J=4L(p z(d)RTV3d|jf|1KlcyCpX$#Ee`Z_f=#uYv0)Bz91~DbR>g~5m629cR>+{A z?{H;VietT@a5&teWSKE}o@k2&M;u_>K3h>rO4Hl-k53V<3ErG%GllglyUuEc?MXlf z;azQS)GjN!z#T++ZuA!~2c-1=zzkRXOU|C4SMo9IY$8|QB5$r&jEt1ojFbqhFYX9? zv{h8POpdfIk!g|;ZMO(>P55*j@Sg2L{tX)olSG9N22LT3viY?S=Jb|H zrNHe@07bj$_Ov2@v{gyKwr&kuo^~ZLn*2DXMS>%<(zo~o#)M5?gCZE1`gZY%(DW%Tix)A~Wk`uS0$qo)h|$75rw5b-2Tr zfuo=rnjdCW+!Qk>$CH+93-07(vi+Bj& z|9%uKE*J;V#2Aotdi^|&u^(M(i}Hyqw|}}% zFD(JVm9&jOMXtjYrheoQo^(CkHB$6>1Sy1#V-~MjN=gZ1NAb-wMQa#rZg0^S@-XzZ zh4;*6kz43*`tp{xJg@(S;fQW*i8J(5Nk68Rqnnk8-JGY*Cd%K&lqI)KmXT&gu^RWA z$pIQNbF(b>uW!Fx6;*pP{x!SE6ZrgrGgjTou$=nEFe!As`n7=HCF0TToZ&j;xKVfz zJZMLm`J4}-3MI$fgs?e7vS=Bl+a1Z_p+QA$9b)~#cl*#1(Z^oasWL{6P@~n0E9PCI zLv;X!u%S-phKE9Q%c93age!jYiG%H~81kchjEFH|q1Dkhyu@>Nmz#$_{L`d_OFgL> z`X3Y;(=`n%?+D}MaG%m}aM`iBPYDP9VyQ0&!H2EP5}w}4>zCuOkzc112cp@Z>9YTP-Us5Cr>a-!Tk{-s=h^=GH`aNx4rmsx6#V8s|Faur zmxDWD`)z{YRLl2=rI}NP z%N)|(45E)tC?I&5^xK;n7e7H^#2&TaLG^xDTQL1W25F@+p@ZqyR-TGdfa8qXbM1;C zT+ImLUp~6Gq=rdJ>PpgAjQtx*oAL?~oywJ+%iy*5DKn*~G^fomx1UuNpWiblsCiksL&(9UBKGH*FzP(eckz;2(hR zC|?7&ih09FBw#xk6DQH4)q9Y%Y zBZpY{wt$K}{JxNER3Zio|1ik=DS9{I01lWmE!ezyT`+T>nt=d@l?3)71zkhuIO=Wf zkd!g=8Fv`A$ccLfQf8;f?3Zjg3C%TkeOS>bL9uzOu> z@N?4>Mqb2Z)tsRqRd}I`za?0t$pH5dwP6MU7i%p3g)h=~o(LaZF#BmAm=-aM z)scY@$bX`*H-csc=AYc%NIghV1+peYaN(U&-ad6e_m-ga);U3+&wkH9(4#bHx}`rA zxd6rEv(WD?s4s@lM!INlP3VFYb7gPFTC#KZ@#$#^okv%dr(t)rpW22G%AM=M#-wk% zFQkZJ&B#wJpbvWAiWIth4;edG^wVsYdcnbAPr`>d<<_u@cWr&$m|I}f{Y}c_!m9Ja zD);_2)(>I?YF&9Q`>)Nix3$LJhVWu?y<+vo{BaxS_lGBo>NY2YU@9&Ma**ms4@8drLyECIic|YK5b2VH; zKFgFPr)|s8m~SUt;szn+$B9>K4ua3(G|<((BuLgILI`{&M%L!O6@|WhynWadwCL7w z504IcUn!#BVGs4JlRHa?2D~dM_VCA{bxX|cXuNFmpXe;k_qhW59=x2uiEkSy&zn?$ zmU|yFD=u0lA3(Hs3v|I>%NMDlzh<^q-Zpzi<9yehy}H_DPMRg>64s89{S}jrn;Rm$ zSWZap8*$he))_9$SGNJ{tYg0Zt72RnX>#RM&4n|6=&+@>oOk&Q zl0r2SL-EOyJ=PEvlq5v|t5=U^jNi(K;UyNlF35b1lKzqtr4;Y^E@)-$M+BF3p#(qN zkUkm^WKK1+l=5pZN(Zn>sOrUPL{b%(29RgjMxxU*A{kGyOB-sQ$YU<{IyyE+zmAdY zD7U)STMb#cP3Y}D**rwxl;I@z_&%ok9gMy&XBC?+RRY&I3&F}mnx{v%vxCOleZg2{ z$KDks{`X zYe`KW-$0XLLn8RtRLliq^MsY2%ny3Ia0eP`fEV#?; z!j&R6uBKm(=S#DM`s-XWzM&NiW7sZ3>-H*@Uc9vizCrsTm9wK+(+}=uBN@17=yVX z`fkH??rOkxkxgCp283QY`0_Y^hg4>O%_l~jmuPb5DkzR`)Agf~~ z0AWi_!yk}_4^gh{$GZ^50u}g=!Eg72srUVj$;xEM)-+uFJRChCiEIRtI)A@Ok+E@| zm3W&*p}d8#G9E+lQq_7#Pb9Cs$)Y}1up|r0R!bVBNH2qOm{yIybwGb#RTzjw2ODeWvd?8UbDo*k%r zWEl|8TBL5+Ur!-@pEemI-fc@ep9^N6s#Q3EF|*4GSOp0BI>hHVEmNY#AcIf##ZZ-S zjl2mEf)5dWQh@N(Lr@}eGBEE#nm);YLlCYY!|(ssD5?wDLx;bPg%l~!{e3kRph2aA zgwSJ+{pauiG6{Gx=$tdWo>N4N>Nrhu&LZgXy5$`6%`;(ZE%3SU&D`mi&m!oq-z_`h zc24Ld^e4W(%jp}jd4L!63!_}Wa=3r)I6V>W_vs`v*=hCn*t!_^dfqkY>!|m4FnnD0 zo)+8+*M0Wf)k`taJ16REK;QkfH6yXBJ@s5!2uyf*DFpf|f9`5bosfO^4mN{yUyGLJ zBXhP2T0n*+RX-6v^3c~qe2xW}=jKn<{TB==CG+Q0bx*JbaFHSOX{z-!cNjq?0Egv1 zrG@VbkuVs4b>|@qu7`W;AA?F3i>D!!=|gYi7g9qILANLHhM4vSe5JLun8xV^POT4keNb&bLxa4&1{wGiO^0f<|>AyI3JS$7%`}?pDe7%@-2R;&>t;>|gp#!GrkxkJn$J$qRkM$S?a93EzH) zF>W^Nz`AehGb8>(IE33@{6eFyE(Q~MG;8kbw4aV>lKw8MkjdYi1;aqU4~On!f_q*8 zM4k8&Vn<4A17)I=McolMpMb<{mDLW5-_}_H+adLm35(wo69tR^p}&q5c;&|S?UnbW zHGUuEoM8W!Xt6iCsUloN5wY#V(9OS^DcS3!K0kPj!Q942i_mw+Cqj#GdNSDhnfwn= zlarI<+Xt^XJ7)&sd`Q4BXu(m_Z~ikR{y2mdUK1b%b55N@NQyci0!*#DX4njK_$a!9 z{Bu$W2>xJ$8cYX4qDr)Axg+NxN>vdch|dJXrwFp=elu|5*7@7POGu2I%r+5F_4F^_ zPud`MnY(bklT2q3if`mMB@JM5f&T;TfpkSkI9=fXkq=}164|j%p2-AaK1=vl{B zNkTTcl~h*iSXI;}9s^@!_C2G?leXIB`q*ouFMJmahM~c!Wc7J(8FOa|?$D1Nb+E*! zfv)~p9AQ$Z#}KhC@Z^H@Ck7JC+oz(290dkc0VGEr_I{6m5>nIFXv>KF6DV2&igpG| z%=ES_fkAB7nevK2@qA#P<5_#2`CjjH>^eO7Y(r`RclZLQ#%$ngpJLalKfaT2~buoh8b#J7U-a#htH5LCVip5-A)V;9?#6lL!POJTzV$VX5; za%3N9HY~V^20UmkXMW(St*vNkXQ}?wBNzDYvRlVCh=Hq)k7CrrF0}P}Y7hFf2cPn` zw}a>rE~ca2+y6U^m`?rZ2p0c)%L&@uSIN$tP8>}j_>iRR{RczrL=1p^J&!A89>=5m z!N3>?XCu4a?odxHFiFNCeYr2DfY_ax3xSu*Futpb+`}kQ3EtP%6qMYETF#su*2UB5 zm!}lg1H*$o#mPBPXGvAIhPwCK<^8EmmHJ>wLY6ak!>+r#jp9Sw+kP-;nC>*)+T)1> zrl(IMz&Fctu*19A4}z}05@mnIlvNV6YA6dYSukY#gfi*ipxEBtm`#v%yY5oJAv%co zH^!YuRL|K+V5_Sceonmo^vv|oUb7rHkre{B?&RE8G-50@o9NMtDZ(V0R_owEUY7HI zHaanC_@sIxkwt=`dm#D~rhRe)Fc$K8a{6bcdge-3z4c|6bAwINL5hNlw_zhVG7d~U zgUnT$r`S3B#HRL**KBBA-TwR`;{BRDOyjc3nR`$uhF!Q9y&fEJ0qb1yd@Kw~z!Aed zJ$YeiQ|r0?{K8P3nTE2$x7r`G{U-_L!pY=cVKMBwk3{JF7s8y$3KXlbN=qVx(%|PM32-u+46ek!kmP?c&Eq(&-Ufu^9LrJXevT z9@cu5#O6{G!+V=U(6F{1_HUk>wVsRoHK9A06VXBx5^_&|*oBm$m0{e$Azc@3P~f=E<^p1NXz9(2X17IM67A3`2KWX)aWE^MZfds`Kf4o4p8jJrz{}kjBDwv z{WA}ngBtP;4Pvzjvf@ZZnuh@S-}WpMgG1V_rr^|hX$?i1cD%T|l%|2^Mzrti8ctkk zN|kS@qEi^wQC5t~C%Fr}&ApQ@L~-X3ysNLZ6v9oG2_nXu5>WSWFC*itBErpr`@=kJ z|4}Vz7KJ6(tjg>*r3Ji79r)@%hb)E(4FMEqiHeHMY}lbZy>E z@piJtJ7w#6iZ$)5>HpIorE(mA@p>|IMk%m_jO=boe`1K03zlMjI+IlIdvBB!Z7L}| z(~m5?Qkjbe(bfx$A0d-JOq*gOp1q7<$yrCgdX=Qs&|? z0rDo_O$|(q@zJ|mY&9K|CqK8fZp*B$Y86@Z{hDg_8;grr*C;m&t>(9E5PG}kdtkQN z!+PW2^PghEgM{G0Ia!F$4kVqhtSGfO0VB|&!LYRrn KU#L4MsQ&?7>7mL1 literal 0 HcmV?d00001 diff --git a/dist/dubbo_client-1.0.0b5-py2.7.egg b/dist/dubbo_client-1.0.0b5-py2.7.egg new file mode 100644 index 0000000000000000000000000000000000000000..de72a930dedc03d35797e920d1f6e213f676ee5a GIT binary patch literal 32954 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

w6WT5Xcf6@%8ckM6yc6JA0vw`@A2kKdjLquDLO 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 -1: key = key[pos + 1:] # print key + if key == 'disabled': + value = value.lower() == 'true' if value else False + self.has_disable_value = True + elif key == 'weight': + value = int(value) if value else 100 + self.has_weight_value = True self.__dict__[key] = value + + def __repr__(self): + return str(self.__dict__) + + def init_default_config(self): + """ + 恢复默认设置,dubbo配置是覆盖形式,如果恢复默认值,那么configurators下的配置会被清空 + :return: + """ + self.disabled = False + self.weight = 100 + + def set_config(self, url_list): + """ + 设置自定义dubbo配置 + :param url_list: + :return: + """ + if not url_list: + return + + param_list = [] + for configuration_url in url_list: + result = urlparse(configuration_url) + params = parse_qsl(result[4]) + param_list.extend(params) + has_disable_value = False + has_weight_value = False + for key, value in param_list: + if key == 'disabled': + self.disabled = value.lower() == 'true' if value else False + has_disable_value = True + if key == 'weight': + self.weight = int(value) if value else 100 + has_weight_value = True + + if not has_disable_value: + self.disabled = False + if not has_weight_value: + self.weight = 100 diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index c3b2671..6a09ba5 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -1,20 +1,21 @@ # coding=utf-8 -import time +import logging.config import os +import os.path +import random import socket import struct -from threading import Thread +import threading +import time import urllib -import logging -import logging.config -import os.path - -from kazoo.protocol.states import KazooState +from threading import Thread from kazoo.client import KazooClient +from kazoo.protocol.states import KazooState -from dubbo_client.config import ApplicationConfig from dubbo_client.common import ServiceURL +from dubbo_client.config import ApplicationConfig +from dubbo_client.rpcerror import NoProvider __author__ = 'caozupeng' @@ -35,7 +36,10 @@ class Registry(object): dict 格式为{interface:{providername:{ip+port:service_url}}} """ - _service_provides = {} + + def __init__(self): + self._service_providers = {} + self._mutex = threading.Lock() def _do_event(self, event): """ @@ -71,7 +75,7 @@ def subscribe(self, interface, **kwargs): """ pass - def get_provides(self, interface, **kwargs): + def get_providers(self, interface, **kwargs): """ 获取已经注册的服务URL对象 :param interface: com.ofpay.demo.api.UserProvider @@ -84,6 +88,40 @@ def get_provides(self, interface, **kwargs): second = self._service_provides.get(interface, {}) return second.get(key, {}) + def get_random_provider(self, interface, **kwargs): + """ + 根据权重和是否禁用获取一个provider + :param interface: + :param kwargs: + :return: + """ + group = kwargs.get('group', '') + version = kwargs.get('version', '') + key = self._to_key(interface, version, group) + second_dict = self._service_providers.get(interface, {}) + service_url_list = [service_url for service_url in second_dict.get(key, {}).itervalues() if + not service_url.disabled and service_url.weight > 0] + if not service_url_list: + raise NoProvider('can not find provider', interface) + + total_weight = 0 + same_weight = True + last_service_url = None + for service_url in service_url_list: + total_weight += service_url.weight + if same_weight and last_service_url and last_service_url.weight != service_url.weight: + same_weight = False + last_service_url = service_url + + if total_weight > 0 and not same_weight: + offset = random.randint(0, total_weight - 1) + for service_url in service_url_list: + offset -= service_url.weight + if offset < 0: + return service_url + + return random.choice(service_url_list) + def event_listener(self, event): """ node provides上下线的监听回调函数 @@ -100,19 +138,19 @@ def configuration_listener(self, event): """ self._do_config_event(event) - def _to_key(self, interface, versioin, group): + def _to_key(self, interface, version, group): """ 计算存放在内存中的服务的key,以接口、版本、分组计算 :param interface: 接口 类似com.ofpay.demo.DemoProvider - :param versioin: 版本 1.0 + :param version: 版本 1.0 :param group: 分组 product :return: key 字符串 """ - return '{0}|{1}|{2}'.format(interface, versioin, group) + return '{0}|{1}|{2}'.format(interface, version, group) def _add_node(self, interface, service_url): key = self._to_key(service_url.interface, service_url.version, service_url.group) - second_dict = self._service_provides.get(interface) + second_dict = self._service_providers.get(interface) if second_dict: # 获取最内层的nest的dict inner_dict = second_dict.get(key) @@ -122,11 +160,11 @@ def _add_node(self, interface, service_url): second_dict[key] = {service_url.location: service_url} else: # create the second dict - self._service_provides[interface] = {key: {service_url.location: service_url}} + self._service_providers[interface] = {key: {service_url.location: service_url}} def _remove_node(self, interface, service_url): key = self._to_key(service_url.interface, service_url.version, service_url.group) - second_dict = self._service_provides.get(interface) + second_dict = self._service_providers.get(interface) if second_dict: inner_dict = second_dict.get(key) if inner_dict: @@ -144,16 +182,59 @@ def _compare_swap_nodes(self, interface, nodes): :param nodes: 节点列表 :return: 不需要返回 """ - # 如果已经存在,首先删除原有的服务的集合 - if interface in self._service_provides: - del self._service_provides[interface] - logger.debug("delete node {0}".format(interface)) - for child_node in nodes: - node = urllib.unquote(child_node).decode('utf8') - logger.debug('child of node is {0}'.format(node)) - if node.startswith('jsonrpc'): - service_url = ServiceURL(node) - self._add_node(interface, service_url) + if self._mutex.acquire(): + # 存在并发问题,需要线程锁 + try: + # 如果已经存在,首先删除原有的服务的集合 + if interface in self._service_providers: + del self._service_providers[interface] + logger.debug("delete node {0}".format(interface)) + for child_node in nodes: + node = urllib.unquote(child_node).decode('utf8') + logger.debug('child of node is {0}'.format(node)) + if node.startswith('jsonrpc'): + service_url = ServiceURL(node) + self._add_node(interface, service_url) + except Exception as e: + logger.warn('swap json-rpc provider error %s', str(e)) + finally: + self._mutex.release() + + def _set_provider_configuration(self, interface, nodes): + """ + 设置provider配置 + :param interface: + :param nodes: + :return: + """ + if not nodes: + return + try: + configuration_dict = {} + for _child_node in nodes: + _node = urllib.unquote(_child_node).decode('utf8') + if _node.startswith('override'): + service_url = ServiceURL(_node) + key = self._to_key(interface, service_url.version, service_url.group) + + if key not in configuration_dict: + configuration_dict[key] = {} + if service_url.location not in configuration_dict[key]: + configuration_dict[key][service_url.location] = [] + configuration_dict[key][service_url.location].append(_node) + + if interface in self._service_providers: + provider_dict = self._service_providers.get(interface) + for provider_key, second_dict in provider_dict.iteritems(): + for service_location, service_url in second_dict.iteritems(): + configuration_service_urls = configuration_dict.get(provider_key, {}).get(service_location) + if not configuration_service_urls: + service_url.init_default_config() + else: + service_url.set_config(configuration_service_urls) + + except Exception as e: + logger.warn('set provider configuration error %s', str(e)) class ZookeeperRegistry(Registry): @@ -161,6 +242,7 @@ class ZookeeperRegistry(Registry): _connect_state = 'UNCONNECT' def __init__(self, zk_hosts, application_config=None): + Registry.__init__(self) if application_config: self._app_config = application_config self.__zk = KazooClient(hosts=zk_hosts) @@ -188,17 +270,27 @@ def _do_event(self, event): # 如果要删除,必须先把/dubbo/和最后的/providers去掉 # 将zookeeper中查询到的服务节点列表加入到一个dict中 # zookeeper中保持的节点url类似如下 - logger.debug("receive event is {0}, event state is {1}".format(event, event.state)) + logger.info("receive event is {0}, event state is {1}".format(event, event.state)) provide_name = event.path[7:event.path.rfind('/')] - if event.state == 'CONNECTED': - children = self.__zk.get_children(event.path, watch=self.event_listener) - self._compare_swap_nodes(provide_name, self.__unquote(children)) - if event.state == 'DELETED': + if event.state in ['CONNECTED', 'DELETED']: children = self.__zk.get_children(event.path, watch=self.event_listener) self._compare_swap_nodes(provide_name, self.__unquote(children)) + configurators_nodes = self._get_provider_configuration(provide_name) + self._set_provider_configuration(provide_name, configurators_nodes) + print self._service_providers def _do_config_event(self, event): - print event + """ + zk的目录路径为 /dubbo/com.qianmi.pc.api.es.item.EsGoodsQueryProvider/configurators + :param event: + :return: + """ + logger.info("receive config event is {0}, event state is {1}".format(event, event.state)) + provide_name = event.path[7:event.path.rfind('/')] + configurators_nodes = self._get_provider_configuration(provide_name) + self._set_provider_configuration(provide_name, configurators_nodes) + + print self._service_providers def register(self, interface, **kwargs): ip = self.__zk._connection._socket.getsockname()[0] @@ -233,11 +325,28 @@ def subscribe(self, interface, **kwargs): providers_children = self.__zk.get_children('{0}/{1}/{2}'.format('dubbo', interface, 'providers'), watch=self.event_listener) logger.debug("watch node is {0}".format(providers_children)) - configurators_children = self.__zk.get_children('{0}/{1}/{2}'.format('dubbo', interface, 'configurators'), - watch=self.configuration_listener) + self.__zk.get_children('{0}/{1}/{2}'.format('dubbo', interface, 'configurators'), + watch=self.configuration_listener) # 全部重新添加 self._compare_swap_nodes(interface, self.__unquote(providers_children)) + configurators_nodes = self._get_provider_configuration(interface) + self._set_provider_configuration(interface, configurators_nodes) + + def _get_provider_configuration(self, interface): + """ + 获取dubbo自定义配置数据,从"/dubbo/{interface}/configurators" 路径下获取配置 + :param interface: + :return: + """ + try: + configurators_nodes = self.__zk.get_children('{0}/{1}/{2}'.format('dubbo', interface, 'configurators'), + watch=self.configuration_listener) + logger.debug("configurators node is {0}".format(configurators_nodes)) + return self.__unquote(configurators_nodes) + except Exception as e: + logger.warn("get provider %s configuration error %s", interface, str(e)) + class MulticastRegistry(Registry): class _Loop(Thread): @@ -262,6 +371,7 @@ def set_mssage(self, msg): self.sock.sendto(msg, (self.multicast_group, int(self.multicast_port))) def __init__(self, address, application_config=None): + Registry.__init__(self) if application_config: self._app_config = application_config self.event_loop = self._Loop(address, self.event_listener) @@ -303,6 +413,6 @@ def _do_event(self, event): # registry = MulticastRegistry('224.5.6.7:1234') registry = ZookeeperRegistry('zookeeper:2181') registry.subscribe('com.ofpay.demo.api.UserProvider') - print registry.get_provides('com.ofpay.demo.api.UserProvider') + print registry.get_providers('com.ofpay.demo.api.UserProvider') time.sleep(500) diff --git a/dubbo_client/rpclib.py b/dubbo_client/rpclib.py index e9e49f3..03e3719 100644 --- a/dubbo_client/rpclib.py +++ b/dubbo_client/rpclib.py @@ -1,11 +1,10 @@ # coding=utf-8 -import random from urllib2 import HTTPError from pyjsonrpc import HttpClient, JsonRpcError from dubbo_client.registry import Registry -from dubbo_client.rpcerror import NoProvider, ConnectionFail, dubbo_client_errors, InternalError, DubboClientError +from dubbo_client.rpcerror import ConnectionFail, dubbo_client_errors, InternalError, DubboClientError __author__ = 'caozupeng' @@ -34,12 +33,9 @@ def __init__(self, interface, registry, **kwargs): self.registry.register(interface) def call(self, method, *args, **kwargs): - provides = self.registry.get_provides(self.interface, version=self.version, group=self.group) - if len(provides) == 0: - raise NoProvider('can not find provide', self.interface) - ip_port, service_url = random.choice(provides.items()) + provider = self.registry.get_random_provider(self.interface, version=self.version, group=self.group) # print service_url.location - client = HttpClient(url="http://{0}{1}".format(ip_port, service_url.path)) + client = HttpClient(url="http://{0}{1}".format(provider.location, provider.path)) try: return client.call(method, *args, **kwargs) except HTTPError, e: diff --git a/tests/test_register_config.py b/tests/test_register_config.py new file mode 100644 index 0000000..57ec186 --- /dev/null +++ b/tests/test_register_config.py @@ -0,0 +1,22 @@ +# coding=utf-8 +import time + +from dubbo_client import ApplicationConfig +from dubbo_client import DubboClient, DubboClientError +from dubbo_client import ZookeeperRegistry + + +def test_config_init(): + config = ApplicationConfig('test_register_config') + service_interface = 'com.ofpay.demo.api.UserProvider' + registry = ZookeeperRegistry('172.19.66.49:2181', config) + user_provider = DubboClient(service_interface, registry, version='1.0.0') + for i in range(10000): + try: + print user_provider.findOne() + except DubboClientError, client_error: + print client_error + time.sleep(1) + +if __name__ == '__main__': + test_config_init() diff --git a/tests/test_registry.py b/tests/test_registry.py index 9a7ef75..180a00c 100644 --- a/tests/test_registry.py +++ b/tests/test_registry.py @@ -6,13 +6,13 @@ def multicat(): registry = MulticastRegistry('224.5.6.7:1234') registry.subscribe('com.ofpay.demo.api.UserProvider') - print registry.get_provides('com.ofpay.demo.api.UserProvider') + print registry.get_providers('com.ofpay.demo.api.UserProvider') def zookeeper(): registry = ZookeeperRegistry('172.19.65.33:2181') registry.subscribe('com.ofpay.demo.api.UserProvider') - print registry.get_provides('com.ofpay.demo.api.UserProvider') + print registry.get_providers('com.ofpay.demo.api.UserProvider') def test_registry(): @@ -29,7 +29,7 @@ def test_registry(): "dubbo=2.4.10&environment=product&interface=com.ofpay.demo.api.UserProvider&" "methods=getUser,queryAll,isLimit,queryUser&owner=wenwu&pid=60402&revision=2.0&" "side=provider×tamp=1429105028153&version=1.0") - assert registry._service_provides + assert registry._service_providers if __name__ == '__main__': From 36dddeff6b2d404ad57f2ab666561b6eced463ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Wed, 18 Apr 2018 17:00:20 +0800 Subject: [PATCH 63/70] Change license to Apache --- AUTHORS.md | 5 + LICENSE | 202 ++++++++++++++++++++++++++++++++++ MANIFEST.in | 2 + README.md | 2 +- dubbo_client/__init__.py | 18 ++- dubbo_client/common.py | 21 +++- dubbo_client/config.py | 20 +++- dubbo_client/registry.py | 20 +++- dubbo_client/rpcerror.py | 20 +++- dubbo_client/rpclib.py | 19 +++- setup.py | 19 ++++ tests/__init__.py | 18 ++- tests/test_config.py | 17 ++- tests/test_kstore_platform.py | 17 ++- tests/test_performance.py | 17 ++- tests/test_rawclient.py | 19 +++- tests/test_register_config.py | 17 +++ tests/test_registry.py | 17 +++ tests/test_rpclib.py | 16 +++ 19 files changed, 471 insertions(+), 15 deletions(-) create mode 100644 AUTHORS.md create mode 100644 LICENSE diff --git a/AUTHORS.md b/AUTHORS.md new file mode 100644 index 0000000..8758df3 --- /dev/null +++ b/AUTHORS.md @@ -0,0 +1,5 @@ +# Original Author and First Commit +* Joe Cao, [@JoeCao](https://github.com/joecao) + +# Contributors (alpha by username) +* jingpeicomp [@jingpeicomp](https://github.com/jingpeicomp) \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8426219 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in index f9e9360..d4a0e7f 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,4 @@ include README.md +include AUTHORS.md +include LICENSE include version.txt \ No newline at end of file diff --git a/README.md b/README.md index c12bc8f..2d52f4b 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ dubbo-client-py支持配置多个zookeeper服务地址 单元测试覆盖率 ### Licenses -MIT License +Apache License ### 感谢 感谢 @jingpeicomp 同学做小白鼠,目前已经正常运行在生产环境数月,谢谢! diff --git a/dubbo_client/__init__.py b/dubbo_client/__init__.py index bcb77cd..c5d518f 100644 --- a/dubbo_client/__init__.py +++ b/dubbo_client/__init__.py @@ -1,4 +1,20 @@ -__author__ = 'caozupeng' +""" + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +""" + from rpclib import ( DubboClient, diff --git a/dubbo_client/common.py b/dubbo_client/common.py index a015eb6..9d6e45f 100644 --- a/dubbo_client/common.py +++ b/dubbo_client/common.py @@ -1,7 +1,22 @@ -# encoding=utf-8 -from urlparse import urlparse, parse_qsl +# coding=utf-8 +""" + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. -__author__ = 'caozupeng' +""" + +from urlparse import urlparse, parse_qsl class ServiceURL(object): diff --git a/dubbo_client/config.py b/dubbo_client/config.py index c14f7a4..df67752 100644 --- a/dubbo_client/config.py +++ b/dubbo_client/config.py @@ -1,5 +1,23 @@ # coding=utf-8 -__author__ = 'caozupeng' + +""" + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +""" + + class ApplicationConfig(object): diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index 6a09ba5..2459455 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -1,4 +1,23 @@ # coding=utf-8 + +""" + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +""" + + import logging.config import os import os.path @@ -17,7 +36,6 @@ from dubbo_client.config import ApplicationConfig from dubbo_client.rpcerror import NoProvider -__author__ = 'caozupeng' # 创建一个logger if os.path.exists('logging.conf'): diff --git a/dubbo_client/rpcerror.py b/dubbo_client/rpcerror.py index 419f86e..f2e95b7 100644 --- a/dubbo_client/rpcerror.py +++ b/dubbo_client/rpcerror.py @@ -1,5 +1,23 @@ # coding=utf-8 -__author__ = 'caozupeng' + +""" + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +""" + + dubbo_client_errors = {} diff --git a/dubbo_client/rpclib.py b/dubbo_client/rpclib.py index 03e3719..1671394 100644 --- a/dubbo_client/rpclib.py +++ b/dubbo_client/rpclib.py @@ -1,4 +1,22 @@ # coding=utf-8 +""" + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +""" + + from urllib2 import HTTPError from pyjsonrpc import HttpClient, JsonRpcError @@ -6,7 +24,6 @@ from dubbo_client.registry import Registry from dubbo_client.rpcerror import ConnectionFail, dubbo_client_errors, InternalError, DubboClientError -__author__ = 'caozupeng' class DubboClient(object): diff --git a/setup.py b/setup.py index 1660372..92b39b5 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,23 @@ #!/usr/bin/env python # coding: utf-8 +""" + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +""" + + """ Python Dubbo Library Client Server - Setup @@ -7,6 +25,7 @@ 2015-4-10 by Joe - https://github.com/JoeCao """ + import os from setuptools import setup, find_packages diff --git a/tests/__init__.py b/tests/__init__.py index 681fccd..ba48d2a 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1 +1,17 @@ -__author__ = 'caozupeng' +# coding=utf-8 +""" + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +""" diff --git a/tests/test_config.py b/tests/test_config.py index 42e1539..9c9953b 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,7 +1,22 @@ # coding=utf-8 +""" + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +""" from dubbo_client import ApplicationConfig -__author__ = 'caozupeng' def test_application_config_new(): diff --git a/tests/test_kstore_platform.py b/tests/test_kstore_platform.py index 1f3d50a..388d4ca 100644 --- a/tests/test_kstore_platform.py +++ b/tests/test_kstore_platform.py @@ -1,9 +1,24 @@ # coding=utf-8 +""" + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +""" import time from dubbo_client import ZookeeperRegistry, DubboClient, DubboClientError, ApplicationConfig -__author__ = 'caozupeng' if __name__ == '__main__': config = ApplicationConfig('test_rpclib') diff --git a/tests/test_performance.py b/tests/test_performance.py index a61ebf1..72ffde8 100644 --- a/tests/test_performance.py +++ b/tests/test_performance.py @@ -1,11 +1,26 @@ # coding=utf-8 +""" + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +""" import pstats from pyjsonrpc import HttpClient from dubbo_client import ZookeeperRegistry, DubboClient -__author__ = 'caozupeng' number = 1000 diff --git a/tests/test_rawclient.py b/tests/test_rawclient.py index 18533e0..85db169 100644 --- a/tests/test_rawclient.py +++ b/tests/test_rawclient.py @@ -1,6 +1,21 @@ -from pyjsonrpc import HttpClient +# coding = utf-8 +""" + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. -__author__ = 'caozupeng' +""" +from pyjsonrpc import HttpClient def test_client_every_new(): diff --git a/tests/test_register_config.py b/tests/test_register_config.py index 57ec186..7976c91 100644 --- a/tests/test_register_config.py +++ b/tests/test_register_config.py @@ -1,4 +1,21 @@ # coding=utf-8 + +""" + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +""" import time from dubbo_client import ApplicationConfig diff --git a/tests/test_registry.py b/tests/test_registry.py index 180a00c..5350c65 100644 --- a/tests/test_registry.py +++ b/tests/test_registry.py @@ -1,3 +1,20 @@ +# coding=utf-8 +""" + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +""" from dubbo_client import ZookeeperRegistry, MulticastRegistry, Registry __author__ = 'caozupeng' diff --git a/tests/test_rpclib.py b/tests/test_rpclib.py index 611c644..bd1a619 100644 --- a/tests/test_rpclib.py +++ b/tests/test_rpclib.py @@ -1,4 +1,20 @@ # coding=utf-8 +""" + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +""" import time from dubbo_client import ZookeeperRegistry, DubboClient, DubboClientError, ApplicationConfig From 169273f3440dd26add1c7382fb039f4d60b1f4ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Wed, 9 May 2018 15:56:51 +0800 Subject: [PATCH 64/70] Modify README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2d52f4b..a2437e1 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Python Dubbo Client ### Python调用Dubbo接口的jsonrpc协议 请使用dubbo-rpc-jsonrpc 并在dubbo中配置protocol为jsonrpc协议 -参考 https://github.com/ofpay/dubbo-rpc-jsonrpc +参考 https://github.com/apache/incubator-dubbo-rpc-jsonrpc ### 安装 下载代码 @@ -16,7 +16,7 @@ pip install dubbo-client==1.0.0b5 Git安装 pip install git+http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0b5 或者 -pip install git+https://github.com/ofpay/dubbo-client-py.git@1.0.0b5 +pip install git+https://github.com/qianmiopen/dubbo-client-py.git@1.0.0b5 ### 在客户端实现负载均衡,服务发现 通过注册中心的zookeeper,获取服务的注册信息 From 4a49e839f643c26e1e2c258ce00df82f3cbfb42d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Wed, 9 May 2018 15:59:43 +0800 Subject: [PATCH 65/70] add new line in README --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a2437e1..0cc33e5 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,9 @@ Python Dubbo Client ### 安装 下载代码 -python setup.py install -pip安装 -pip install dubbo-client==1.0.0b5 +python setup.py install +pip安装 +pip install dubbo-client==1.0.0b5 Git安装 pip install git+http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0b5 或者 @@ -22,8 +22,8 @@ pip install git+https://github.com/qianmiopen/dubbo-client-py.git@1.0.0b5 通过注册中心的zookeeper,获取服务的注册信息 dubbo-client-py支持配置多个zookeeper服务地址 "host": "192.168.1.183:2181,192.168.1.184:2181,192.168.1.185:2181" -然后通过代理实现负载均衡算法,调用服务端 -支持Version、Group设置 +然后通过代理实现负载均衡算法,调用服务端 +支持Version、Group设置 ### Example ```python From ab4869846879d96ecc26bf7a88d81c6fbe121398 Mon Sep 17 00:00:00 2001 From: xly Date: Tue, 28 Aug 2018 12:19:48 +0800 Subject: [PATCH 66/70] Add redme to english --- README.md | 123 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 84 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 0cc33e5..01d1ad1 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,34 @@ -Python Dubbo Client -===================================== -实现客户端的负载均衡、配合Zookeeper自动发现服务功能 -------------------------------------- +## Python Dubbo Client +## Achieve load balancing on the client side、auto discovery service function with Zookeeper +### Python calls the Dubbo interface's jsonrpc protocol +Please use dubbo-rpc-jsonrpc and configure protocol in Dubbo for jsonrpc protocol +*Reference* [https://github.com/apache/incubator-dubbo-rpc-jsonrpc](https://github.com/apache/incubator-dubbo-rpc-jsonrpc) +### Installation -### Python调用Dubbo接口的jsonrpc协议 -请使用dubbo-rpc-jsonrpc 并在dubbo中配置protocol为jsonrpc协议 -参考 https://github.com/apache/incubator-dubbo-rpc-jsonrpc - -### 安装 -下载代码 +Download code python setup.py install -pip安装 -pip install dubbo-client==1.0.0b5 -Git安装 -pip install git+http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0b5 -或者 -pip install git+https://github.com/qianmiopen/dubbo-client-py.git@1.0.0b5 - -### 在客户端实现负载均衡,服务发现 -通过注册中心的zookeeper,获取服务的注册信息 -dubbo-client-py支持配置多个zookeeper服务地址 -"host": "192.168.1.183:2181,192.168.1.184:2181,192.168.1.185:2181" -然后通过代理实现负载均衡算法,调用服务端 -支持Version、Group设置 +pip install +pip install dubbo-client==1.0.0b5 +Git install +pip install git+[http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0b5](http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0b5) +or +pip install git+[https://github.com/qianmiopen/dubbo-client-py.git@1.0.0b5](https://github.com/qianmiopen/dubbo-client-py.git@1.0.0b5) + +### Load balancing on the client side, service discovery +Get the registration information of the service through the zookeeper of the registry. +Dubbo-client-py supports configuring multiple zookeeper service addresses. +"host":"192.168.1.183:2181,192.168.1.184:2181,192.168.1.185:2181" +Then the load balancing algorithm is implemented by proxy, and the server is called. +Support Version and Group settings. ### Example -```python - config = ApplicationConfig('test_rpclib') - service_interface = 'com.ofpay.demo.api.UserProvider' - #registry包含了和zookeeper的连接,该对象需要缓存 - registry = ZookeeperRegistry('192.168.59.103:2181', config) - user_provider = DubboClient(service_interface, registry, version='1.0') - for i in range(1000): + config = ApplicationConfig('test_rpclib') + service_interface = 'com.ofpay.demo.api.UserProvider' + #Contains a connection to zookeeper, which needs caching. + registry = ZookeeperRegistry('192.168.59.103:2181', config) + user_provider = DubboClient(service_interface, registry, version='1.0') + for i in range(1000): try: print user_provider.getUser('A003') print user_provider.queryUser( @@ -44,16 +40,65 @@ dubbo-client-py支持配置多个zookeeper服务地址 except DubboClientError, client_error: print client_error time.sleep(5) -``` - + ### TODO -优化性能,将服务上下线的影响降到最小 -支持Retry参数 -支持权重调用 -单元测试覆盖率 - +Optimize performance, minimize the impact of service upper and lower lines. +Support Retry parameters +Support weight call +Unit test coverage ### Licenses Apache License +### Thanks +Thank @jingpeicomp for being a Guinea pig. It has been running normally for several months in the production environment. Thank you! +## Python Dubbo Client +## Achieve load balancing on the client side、auto discovery service function with Zookeeper +### Python calls the Dubbo interface's jsonrpc protocol +Please use dubbo-rpc-jsonrpc and configure protocol in Dubbo for jsonrpc protocol +*Reference* [https://github.com/apache/incubator-dubbo-rpc-jsonrpc](https://github.com/apache/incubator-dubbo-rpc-jsonrpc) + +### Installation + +Download code +python setup.py install +pip install +pip install dubbo-client==1.0.0b5 +Git install +pip install git+[http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0b5](http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0b5) +or +pip install git+[https://github.com/qianmiopen/dubbo-client-py.git@1.0.0b5](https://github.com/qianmiopen/dubbo-client-py.git@1.0.0b5) + +### Load balancing on the client side, service discovery -### 感谢 -感谢 @jingpeicomp 同学做小白鼠,目前已经正常运行在生产环境数月,谢谢! +Get the registration information of the service through the zookeeper of the registry. +Dubbo-client-py supports configuring multiple zookeeper service addresses. +"host":"192.168.1.183:2181,192.168.1.184:2181,192.168.1.185:2181" +Then the load balancing algorithm is implemented by proxy, and the server is called. +Support Version and Group settings. +### Example + config = ApplicationConfig('test_rpclib') + service_interface = 'com.ofpay.demo.api.UserProvider' + #Contains a connection to zookeeper, which needs caching. + registry = ZookeeperRegistry('192.168.59.103:2181', config) + user_provider = DubboClient(service_interface, registry, version='1.0') + for i in range(1000): + try: + print user_provider.getUser('A003') + print user_provider.queryUser( + {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) + print user_provider.queryAll() + print user_provider.isLimit('MAN', 'Joe') + print user_provider('getUser', 'A005') + + except DubboClientError, client_error: + print client_error + time.sleep(5) + +### TODO +Optimize performance, minimize the impact of service upper and lower lines. +Support Retry parameters +Support weight call +Unit test coverage +### Licenses +Apache License +### Thanks +Thank @jingpeicomp for being a Guinea pig. It has been running normally for several months in the production environment. Thank you! From 9acfd064b6a24f1176452d785388cb1a415eb3e1 Mon Sep 17 00:00:00 2001 From: zhaowei7146 Date: Thu, 8 Nov 2018 10:12:46 +0800 Subject: [PATCH 67/70] The content is duplicated in the README.md and needs to be deleted --- README.md | 52 ---------------------------------------------------- 1 file changed, 52 deletions(-) diff --git a/README.md b/README.md index 01d1ad1..dfbef15 100644 --- a/README.md +++ b/README.md @@ -50,55 +50,3 @@ Unit test coverage Apache License ### Thanks Thank @jingpeicomp for being a Guinea pig. It has been running normally for several months in the production environment. Thank you! -## Python Dubbo Client -## Achieve load balancing on the client side、auto discovery service function with Zookeeper -### Python calls the Dubbo interface's jsonrpc protocol -Please use dubbo-rpc-jsonrpc and configure protocol in Dubbo for jsonrpc protocol -*Reference* [https://github.com/apache/incubator-dubbo-rpc-jsonrpc](https://github.com/apache/incubator-dubbo-rpc-jsonrpc) - -### Installation - -Download code -python setup.py install -pip install -pip install dubbo-client==1.0.0b5 -Git install -pip install git+[http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0b5](http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0b5) -or -pip install git+[https://github.com/qianmiopen/dubbo-client-py.git@1.0.0b5](https://github.com/qianmiopen/dubbo-client-py.git@1.0.0b5) - -### Load balancing on the client side, service discovery - -Get the registration information of the service through the zookeeper of the registry. -Dubbo-client-py supports configuring multiple zookeeper service addresses. -"host":"192.168.1.183:2181,192.168.1.184:2181,192.168.1.185:2181" -Then the load balancing algorithm is implemented by proxy, and the server is called. -Support Version and Group settings. -### Example - config = ApplicationConfig('test_rpclib') - service_interface = 'com.ofpay.demo.api.UserProvider' - #Contains a connection to zookeeper, which needs caching. - registry = ZookeeperRegistry('192.168.59.103:2181', config) - user_provider = DubboClient(service_interface, registry, version='1.0') - for i in range(1000): - try: - print user_provider.getUser('A003') - print user_provider.queryUser( - {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) - print user_provider.queryAll() - print user_provider.isLimit('MAN', 'Joe') - print user_provider('getUser', 'A005') - - except DubboClientError, client_error: - print client_error - time.sleep(5) - -### TODO -Optimize performance, minimize the impact of service upper and lower lines. -Support Retry parameters -Support weight call -Unit test coverage -### Licenses -Apache License -### Thanks -Thank @jingpeicomp for being a Guinea pig. It has been running normally for several months in the production environment. Thank you! From 0947552a7cb6b70aac8146e0804ca5305e745ce4 Mon Sep 17 00:00:00 2001 From: Ian Luo Date: Thu, 25 Apr 2019 11:05:39 +0800 Subject: [PATCH 68/70] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dfbef15..d880bf0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## Python Dubbo Client +## Python Client For Apache Dubbo ## Achieve load balancing on the client side、auto discovery service function with Zookeeper ### Python calls the Dubbo interface's jsonrpc protocol Please use dubbo-rpc-jsonrpc and configure protocol in Dubbo for jsonrpc protocol From de1206f22839b4737277db9158ba701d61fe2af7 Mon Sep 17 00:00:00 2001 From: Huang YunKun Date: Mon, 9 Nov 2020 15:47:55 +0800 Subject: [PATCH 69/70] Create .asf.yaml --- .asf.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .asf.yaml diff --git a/.asf.yaml b/.asf.yaml new file mode 100644 index 0000000..8d84e69 --- /dev/null +++ b/.asf.yaml @@ -0,0 +1,5 @@ +notifications: + commits: commits@dubbo.apache.org + issues: notifications@dubbo.apache.org + pullrequests: notifications@dubbo.apache.org + jira_options: link label link label From 8f53357a4ab19f833eea15a480f3f481ffa6716d Mon Sep 17 00:00:00 2001 From: Hansolo1103 <110121103@nitt.edu> Date: Tue, 20 Feb 2024 20:00:12 +0530 Subject: [PATCH 70/70] Specification of encoding --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 92b39b5..c29c017 100644 --- a/setup.py +++ b/setup.py @@ -44,7 +44,7 @@ description=( "Python Dubbo Client" ), - long_description=open("README.md").read(), + long_description=open("README.md", encoding='utf-8').read(), keywords=( "Dubbo, JSON-RPC, JSON, RPC, Client," "HTTP-Client, Remote Procedure Call, JavaScript Object Notation, "

w6WT5Xcf6@%8ckM6yc6JA0vw`@A2kKdjLquDLO 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 Date: Tue, 21 Apr 2015 11:32:35 +0800 Subject: [PATCH 54/70] fix readme --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 38a9b80..5552131 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,11 @@ Python Dubbo Client 下载代码 python setup.py install pip安装 -pip install dubbo-client==1.0.0b4 +pip install dubbo-client==1.0.0b5 Git安装 -pip install git+http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0b4 +pip install git+http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0b5 或者 -pip install git+https://github.com/ofpay/dubbo-client-py.git@1.0.0b4 +pip install git+https://github.com/ofpay/dubbo-client-py.git@1.0.0b5 ### 在客户端实现负载均衡,服务发现 通过注册中心的zookeeper,获取服务的注册信息 From af51d19dafbafb743e6b221a0488573823520da1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 16 Jul 2015 09:34:50 +0800 Subject: [PATCH 55/70] =?UTF-8?q?=E6=9B=B4=E6=96=B0zookeeper=E5=A4=9A?= =?UTF-8?q?=E4=B8=AA=E6=9C=8D=E5=8A=A1=E5=9C=B0=E5=9D=80=E7=9A=84=E8=AF=B4?= =?UTF-8?q?=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f98d845..3538a65 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ pip install git+https://github.com/ofpay/dubbo-client-py.git@1.0.0b2 ### 在客户端实现负载均衡,服务发现 通过注册中心的zookeeper,获取服务的注册信息 +dubbo-client-py支持配置多个zookeeper服务地址 +"host": "192.168.1.183:2181,192.168.1.184:2181,192.168.1.185:2181", 然后通过代理实现负载均衡算法,调用服务端 支持Version、Group设置 @@ -49,4 +51,4 @@ pip install git+https://github.com/ofpay/dubbo-client-py.git@1.0.0b2 单元测试覆盖率 ### Licenses -MIT License \ No newline at end of file +MIT License From 74abf49232e5adf83064b7114c72407763444950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 16 Jul 2015 13:40:42 +0800 Subject: [PATCH 56/70] add thanks to --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 27c8692..c12bc8f 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,9 @@ pip install git+http://git.dev.qianmi.com/tda/dubbo-client-py.git@1.0.0b5 pip install git+https://github.com/ofpay/dubbo-client-py.git@1.0.0b5 ### 在客户端实现负载均衡,服务发现 -通过注册中心的zookeeper,获取服务的注册信息 -dubbo-client-py支持配置多个zookeeper服务地址 -"host": "192.168.1.183:2181,192.168.1.184:2181,192.168.1.185:2181", +通过注册中心的zookeeper,获取服务的注册信息 +dubbo-client-py支持配置多个zookeeper服务地址 +"host": "192.168.1.183:2181,192.168.1.184:2181,192.168.1.185:2181" 然后通过代理实现负载均衡算法,调用服务端 支持Version、Group设置 @@ -54,3 +54,6 @@ dubbo-client-py支持配置多个zookeeper服务地址 ### Licenses MIT License + +### 感谢 +感谢 @jingpeicomp 同学做小白鼠,目前已经正常运行在生产环境数月,谢谢! From b6c23f9ba77702bfdce8ffae4f076dab5cf8086d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 25 Feb 2016 16:43:40 +0800 Subject: [PATCH 57/70] =?UTF-8?q?=E5=B0=86req=E9=87=8D=E6=96=B0=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E4=B8=BArequirements.txt=EF=BC=8C=E6=9B=B4=E7=AC=A6?= =?UTF-8?q?=E5=90=88=E4=B9=A0=E6=83=AF=20=E5=8E=BB=E6=8E=89=E5=AF=B9?= =?UTF-8?q?=E8=87=AA=E5=B7=B1=E7=9A=84=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- req.txt => requirements.txt | 1 - 1 file changed, 1 deletion(-) rename req.txt => requirements.txt (76%) diff --git a/req.txt b/requirements.txt similarity index 76% rename from req.txt rename to requirements.txt index 9974eb3..11d5b61 100644 --- a/req.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ bunch==1.0.1 -dubbo-client==1.0.0-beta-1 kazoo==2.0 py==1.4.26 pytest==2.7.0 From 8b86353ec310c09ccf907126270cf55825820115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Thu, 25 Feb 2016 17:37:30 +0800 Subject: [PATCH 58/70] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E7=9A=84=E5=BC=82=E5=B8=B8=EF=BC=8C?= =?UTF-8?q?=E7=94=A8=E4=BA=8Ejsonrpc=E4=BC=A0=E9=80=92=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=AB=AF=E7=9A=84=E5=BC=82=E5=B8=B8=E3=80=82=20code=E4=B8=BA-3?= =?UTF-8?q?2000=EF=BC=8C=E9=9C=80=E8=A6=81=E6=9C=8D=E5=8A=A1=E7=AB=AF?= =?UTF-8?q?=E7=9A=84=E6=A1=86=E6=9E=B6=E4=BF=AE=E6=94=B9=E9=85=8D=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/rpcerror.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dubbo_client/rpcerror.py b/dubbo_client/rpcerror.py index fae2805..419f86e 100644 --- a/dubbo_client/rpcerror.py +++ b/dubbo_client/rpcerror.py @@ -80,9 +80,18 @@ def __init__(self, message=None, data=None): DubboClientError.__init__(self, message=message, data=data) +class UserDefinedError(DubboClientError): + code = -32000 + message = u'User defined error happend' + + def __init__(self, message=None, data=None): + DubboClientError.__init__(self, message=message, data=data) + + dubbo_client_errors[MethodNotFound.code] = MethodNotFound dubbo_client_errors[NoProvider.code] = NoProvider dubbo_client_errors[ConnectionFail.code] = ConnectionFail dubbo_client_errors[InvalidParams.code] = InvalidParams dubbo_client_errors[InternalError.code] = InternalError dubbo_client_errors[InvalidRequest.code] = InvalidRequest +dubbo_client_errors[UserDefinedError.code] = UserDefinedError From 6c6a74831f730659239f83a19ced6b6d9ae6fd7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Mon, 7 Mar 2016 19:40:17 +0800 Subject: [PATCH 59/70] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E7=9A=84=E5=A4=84=E7=90=86=E6=96=B9=E5=BC=8F=EF=BC=8C=E5=A1=AB?= =?UTF-8?q?=E5=85=85reason=E5=92=8Cmessage=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/rpclib.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/dubbo_client/rpclib.py b/dubbo_client/rpclib.py index 0901c4e..e9e49f3 100644 --- a/dubbo_client/rpclib.py +++ b/dubbo_client/rpclib.py @@ -3,10 +3,9 @@ from urllib2 import HTTPError from pyjsonrpc import HttpClient, JsonRpcError -from dubbo_client.registry import Registry - -from dubbo_client.rpcerror import NoProvider, ConnectionFail, dubbo_client_errors, InternalError +from dubbo_client.registry import Registry +from dubbo_client.rpcerror import NoProvider, ConnectionFail, dubbo_client_errors, InternalError, DubboClientError __author__ = 'caozupeng' @@ -46,9 +45,15 @@ def call(self, method, *args, **kwargs): except HTTPError, e: raise ConnectionFail(None, e.filename) except JsonRpcError, error: - raise dubbo_client_errors.get(error.code, None) + if error.code in dubbo_client_errors: + raise dubbo_client_errors[error.code](message=error.message, data=error.data) + else: + raise DubboClientError(code=error.code, message=error.message, data=error.data) except Exception, ue: - raise InternalError(ue.message, None) + if hasattr(ue, 'reason'): + raise InternalError(ue.message, ue.reason) + else: + raise InternalError(ue.message, None) def __call__(self, method, *args, **kwargs): """ @@ -64,4 +69,4 @@ def __getattr__(self, method): if __name__ == '__main__': - pass \ No newline at end of file + pass From f6eb732e73addbb7e42c999061b5af651d41c5dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Wed, 30 Mar 2016 10:17:19 +0800 Subject: [PATCH 60/70] =?UTF-8?q?=E5=A2=9E=E5=8A=A0registry=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/__init__.py | 2 +- dubbo_client/common.py | 4 +- dubbo_client/config.py | 10 ++--- dubbo_client/registry.py | 84 +++++++++++++++++++++++++++-------- setup.py | 30 ++++++------- tests/logging.conf | 49 ++++++++++++++++++++ tests/test_kstore_platform.py | 23 ++++++++++ tests/test_performance.py | 8 ++-- tests/test_rawclient.py | 5 ++- tests/test_registry.py | 2 +- tests/test_rpclib.py | 28 ++++++------ 11 files changed, 182 insertions(+), 63 deletions(-) create mode 100644 tests/logging.conf create mode 100644 tests/test_kstore_platform.py diff --git a/dubbo_client/__init__.py b/dubbo_client/__init__.py index 3d7d41e..bcb77cd 100644 --- a/dubbo_client/__init__.py +++ b/dubbo_client/__init__.py @@ -12,4 +12,4 @@ ) from config import ( ApplicationConfig, -) \ No newline at end of file +) diff --git a/dubbo_client/common.py b/dubbo_client/common.py index 3633ac8..bc03749 100644 --- a/dubbo_client/common.py +++ b/dubbo_client/common.py @@ -1,4 +1,4 @@ -#encoding=utf-8 +# encoding=utf-8 from urlparse import urlparse, parse_qsl __author__ = 'caozupeng' @@ -28,4 +28,4 @@ def __init__(self, url): if pos > -1: key = key[pos + 1:] # print key - self.__dict__[key] = value \ No newline at end of file + self.__dict__[key] = value diff --git a/dubbo_client/config.py b/dubbo_client/config.py index c19e40b..c14f7a4 100644 --- a/dubbo_client/config.py +++ b/dubbo_client/config.py @@ -7,13 +7,13 @@ class ApplicationConfig(object): name = 'default' # 模块版本 version = '1.0.0' - #应用负责人 + # 应用负责人 owner = '' - #组织名(BU或部门) + # 组织名(BU或部门) organization = '' - #分层 + # 分层 architecture = 'web' - #环境,如:dev/test/run + # 环境,如:dev/test/run environment = 'run' def __init__(self, name, **kwargs): @@ -35,4 +35,4 @@ class ReferenceConfig(object): if __name__ == '__main__': application_config = ApplicationConfig('test_app', version='2.0.0', owner='caozupeng', error='ssd') - print application_config \ No newline at end of file + print application_config diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index efa7455..062908b 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -1,21 +1,30 @@ # coding=utf-8 import time - -__author__ = 'caozupeng' import os import socket import struct from threading import Thread - -from dubbo_client.config import ApplicationConfig - import urllib +import logging +import logging.config +import os.path from kazoo.protocol.states import KazooState + from kazoo.client import KazooClient +from dubbo_client.config import ApplicationConfig from dubbo_client.common import ServiceURL +__author__ = 'caozupeng' + +# 创建一个logger +if os.path.exists('logging.conf'): + logging.config.fileConfig('logging.conf') +else: + logging.basicConfig() +logger = logging.getLogger('dubbo') + class Registry(object): """ @@ -36,6 +45,14 @@ def _do_event(self, event): """ pass + def _do_config_event(self, event): + """ + protect方法,处理管理台的禁用,倍权,半权等操作 + :param event: + :return: + """ + pass + def register(self, interface, **kwargs): """ 客户端注册到注册中心,亮出自己的身份 @@ -75,6 +92,14 @@ def event_listener(self, event): """ self._do_event(event) + def configuration_listener(self, event): + """ + 监听 + :param event: + :return: + """ + self._do_config_event(event) + def _to_key(self, interface, versioin, group): """ 计算存放在内存中的服务的key,以接口、版本、分组计算 @@ -124,6 +149,7 @@ def _compare_swap_nodes(self, interface, nodes): del self._service_provides[interface] for child_node in nodes: node = urllib.unquote(child_node).decode('utf8') + logger.debug('child of node is {0}'.format(node)) if node.startswith('jsonrpc'): service_url = ServiceURL(node) self._add_node(interface, service_url) @@ -161,6 +187,7 @@ def _do_event(self, event): # 如果要删除,必须先把/dubbo/和最后的/providers去掉 # 将zookeeper中查询到的服务节点列表加入到一个dict中 # zookeeper中保持的节点url类似如下 + logger.debug("receive event is {0}, event state is {1}".format(event, event.state)) provide_name = event.path[7:event.path.rfind('/')] if event.state == 'CONNECTED': children = self.__zk.get_children(event.path, watch=self.event_listener) @@ -169,6 +196,9 @@ def _do_event(self, event): children = self.__zk.get_children(event.path, watch=self.event_listener) self._compare_swap_nodes(provide_name, self.__unquote(children)) + def _do_config_event(self, event): + print event + def register(self, interface, **kwargs): ip = self.__zk._connection._socket.getsockname()[0] params = { @@ -199,10 +229,13 @@ def subscribe(self, interface, **kwargs): """ version = kwargs.get('version', '') group = kwargs.get('group', '') - children = self.__zk.get_children('{0}/{1}/{2}'.format('dubbo', interface, 'providers'), - watch=self.event_listener) + providers_children = self.__zk.get_children('{0}/{1}/{2}'.format('dubbo', interface, 'providers'), + watch=self.event_listener) + logger.debug("watch node is {0}".format(providers_children)) + configurators_children = self.__zk.get_children('{0}/{1}/{2}'.format('dubbo', interface, 'configurators'), + watch=self.configuration_listener) # 全部重新添加 - self._compare_swap_nodes(interface, self.__unquote(children)) + self._compare_swap_nodes(interface, self.__unquote(providers_children)) class MulticastRegistry(Registry): @@ -227,7 +260,6 @@ def run(self): def set_mssage(self, msg): self.sock.sendto(msg, (self.multicast_group, int(self.multicast_port))) - def __init__(self, address, application_config=None): if application_config: self._app_config = application_config @@ -249,13 +281,27 @@ def _do_event(self, event): if __name__ == '__main__': - # zk = KazooClient(hosts='192.168.59.103:2181') - # zk.start() - # parent_node = '{0}/{1}/{2}'.format('dubbo', 'com.ofpay.demo.api.UserProvider', '') - # nodes = zk.get_children(parent_node) - # for child_node in nodes: - # node = urllib.unquote(child_node).decode('utf8') - # print node - # zk.delete(parent_node+'/'+child_node, recursive=True) - registry = MulticastRegistry('224.5.6.7:1234') - time.sleep(50) \ No newline at end of file + zk = KazooClient(hosts='192.168.59.103:2181') + zk.start() + parent_node = '{0}/{1}/{2}'.format('dubbo', 'com.ofpay.demo.api.UserProvider', '') + nodes = zk.get_children(parent_node) + for child_node in nodes: + node = urllib.unquote(child_node).decode('utf8') + print node + configurators_node = '{0}/{1}/{2}'.format('dubbo', 'com.ofpay.demo.api.UserProvider', 'configurators') + nodes = zk.get_children(configurators_node) + for child_node in nodes: + node = urllib.unquote(child_node).decode('utf8') + print node + providers_node = '{0}/{1}/{2}'.format('dubbo', 'com.ofpay.demo.api.UserProvider', 'providers') + nodes = zk.get_children(providers_node) + for child_node in nodes: + node = urllib.unquote(child_node).decode('utf8') + print node + # zk.delete(parent_node+'/'+child_node, recursive=True) + # registry = MulticastRegistry('224.5.6.7:1234') + registry = ZookeeperRegistry('zookeeper:2181') + registry.subscribe('com.ofpay.demo.api.UserProvider') + print registry.get_provides('com.ofpay.demo.api.UserProvider') + + time.sleep(500) diff --git a/setup.py b/setup.py index f3d2321..1660372 100644 --- a/setup.py +++ b/setup.py @@ -8,6 +8,7 @@ """ import os + from setuptools import setup, find_packages THISDIR = os.path.dirname(os.path.abspath(__file__)) @@ -18,25 +19,24 @@ DOWNLOAD_BASEURL = "https://github.com/ofpay/dubbo-client-py/raw/master/dist/" DOWNLOAD_URL = DOWNLOAD_BASEURL + "dubbo-client-%s-py2.7.egg" % VERSION - setup( - name = "dubbo-client", - version = VERSION, - description = ( + name="dubbo-client", + version=VERSION, + description=( "Python Dubbo Client" ), - long_description = open("README.md").read(), - keywords = ( + long_description=open("README.md").read(), + keywords=( "Dubbo, JSON-RPC, JSON, RPC, Client," "HTTP-Client, Remote Procedure Call, JavaScript Object Notation, " ), - author = "Joe Cao", - author_email = "chinalibra@gmail.com", - url = HOMEPAGE, - download_url = DOWNLOAD_URL, - packages = find_packages(), - classifiers = [ - #"Development Status :: 1 - Planning", + author="Joe Cao", + author_email="chinalibra@gmail.com", + url=HOMEPAGE, + download_url=DOWNLOAD_URL, + packages=find_packages(), + classifiers=[ + # "Development Status :: 1 - Planning", # "Development Status :: 2 - Pre-Alpha", # "Development Status :: 3 - Alpha", "Development Status :: 4 - Beta", @@ -53,5 +53,5 @@ "Topic :: Internet :: WWW/HTTP :: HTTP Servers", "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", ], - install_requires = ["kazoo>=2.0", "python-jsonrpc>=0.7.3"], -) \ No newline at end of file + install_requires=["kazoo>=2.0", "python-jsonrpc>=0.7.3"], +) diff --git a/tests/logging.conf b/tests/logging.conf new file mode 100644 index 0000000..aeb83f8 --- /dev/null +++ b/tests/logging.conf @@ -0,0 +1,49 @@ +[loggers] +keys=root, dubbo + +[handlers] +keys=null,console,file + +[formatters] +keys=verbose,simple,default + +[formatter_verbose] +format=%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s +datefmt= +class=logging.Formatter + +[formatter_simple] +format=%(levelname)s %(message)s +datefmt=%Y-%m-%d %H:%M:%S +class=logging.Formatter + +[formatter_default] +format=%(asctime)s %(message)s +datefmt=%Y-%m-%d %H:%M:%S +class=logging.Formatter + +[logger_root] +level=NOTSET +handlers= + +[logger_dubbo] +level=DEBUG +handlers=console,file +propagate=1 +qualname= + +[handler_null] +class=NullHandler +level=DEBUG +args=() + +[handler_console] +class=StreamHandler +level=DEBUG +args=() + +[handler_file] +class=handlers.TimedRotatingFileHandler +level=DEBUG +formatter=default +args=('dubbo.log','D',1,0,'utf8') \ No newline at end of file diff --git a/tests/test_kstore_platform.py b/tests/test_kstore_platform.py new file mode 100644 index 0000000..1f3d50a --- /dev/null +++ b/tests/test_kstore_platform.py @@ -0,0 +1,23 @@ +# coding=utf-8 +import time + +from dubbo_client import ZookeeperRegistry, DubboClient, DubboClientError, ApplicationConfig + +__author__ = 'caozupeng' + +if __name__ == '__main__': + config = ApplicationConfig('test_rpclib') + service_interface = 'com.qianmi.kstore.provider.CustomerAddressProvider' + # 该对象较重,有zookeeper的连接,需要保存使用 + registry = ZookeeperRegistry('zookeeper:2181', config) + # registry = MulticastRegistry('224.5.6.7:1234', config) + user_provider = DubboClient(service_interface, registry, version='1.0') + for i in range(1000): + try: + print user_provider.findAddressByCustomerId(1) + # print user_provider.save(1, 3) + + except DubboClientError, client_error: + print client_error.message + print client_error.data + time.sleep(5) diff --git a/tests/test_performance.py b/tests/test_performance.py index 1a0b203..a61ebf1 100644 --- a/tests/test_performance.py +++ b/tests/test_performance.py @@ -1,16 +1,15 @@ # coding=utf-8 -import profile import pstats -import timeit from pyjsonrpc import HttpClient -from dubbo_client import ZookeeperRegistry, DubboClient +from dubbo_client import ZookeeperRegistry, DubboClient __author__ = 'caozupeng' number = 1000 + def test_client_every_new(): for x in range(number): user_provider = HttpClient(url="http://{0}{1}".format('172.19.3.111:38080/', 'com.ofpay.demo.api.UserProvider')) @@ -46,6 +45,7 @@ def test_dubbo(): user_provider.isLimit('MAN', 'Joe') user_provider('getUser', 'A005') + if __name__ == '__main__': """ 在我的mac 4c8g笔记本上,同时启动服务端和客户端(忽略网络开销) @@ -76,4 +76,4 @@ def test_dubbo(): np.sort_stats('time').print_stats() # profile.run('test_client()', 'test_client.txt') cp = pstats.Stats('test_client.txt') - cp.sort_stats('time').print_stats() \ No newline at end of file + cp.sort_stats('time').print_stats() diff --git a/tests/test_rawclient.py b/tests/test_rawclient.py index 179644b..18533e0 100644 --- a/tests/test_rawclient.py +++ b/tests/test_rawclient.py @@ -2,8 +2,9 @@ __author__ = 'caozupeng' + def test_client_every_new(): - user_provider = HttpClient(url="http://{0}{1}".format('172.19.3.111:38081/', 'com.ofpay.demo.api.UserProvider2')) + user_provider = HttpClient(url="http://{0}{1}".format('zookeeper:38081/', 'com.ofpay.demo.api.UserProvider2')) print user_provider.getUser('A003') print user_provider.queryUser( {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) @@ -13,4 +14,4 @@ def test_client_every_new(): if __name__ == '__main__': - test_client_every_new() \ No newline at end of file + test_client_every_new() diff --git a/tests/test_registry.py b/tests/test_registry.py index d83e5a3..9a7ef75 100644 --- a/tests/test_registry.py +++ b/tests/test_registry.py @@ -33,4 +33,4 @@ def test_registry(): if __name__ == '__main__': - multicat() \ No newline at end of file + multicat() diff --git a/tests/test_rpclib.py b/tests/test_rpclib.py index 2d5e146..611c644 100644 --- a/tests/test_rpclib.py +++ b/tests/test_rpclib.py @@ -1,31 +1,31 @@ # coding=utf-8 import time -from dubbo_client import ZookeeperRegistry, DubboClient, DubboClientError, ApplicationConfig, MulticastRegistry - +from dubbo_client import ZookeeperRegistry, DubboClient, DubboClientError, ApplicationConfig __author__ = 'caozupeng' - if __name__ == '__main__': config = ApplicationConfig('test_rpclib') service_interface = 'com.ofpay.demo.api.UserProvider' # 该对象较重,有zookeeper的连接,需要保存使用 - registry = ZookeeperRegistry('192.168.59.103:2181', config) + registry = ZookeeperRegistry('115.28.74.185:2181', config) # registry = MulticastRegistry('224.5.6.7:1234', config) user_provider = DubboClient(service_interface, registry, version='2.0') for i in range(1000): try: print user_provider.getUser('A003') - print user_provider.getUser(123) - print user_provider.queryUser( - {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) - datas = user_provider.queryAll() - for key, user in datas.items(): - print user['name'] - print user_provider.isLimit('MAN', 'Joe') - print user_provider('getUser', 'A005') - + # print user_provider.getUser(123) + # print user_provider.queryUser( + # {u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'}) + # datas = user_provider.queryAll() + # for key, user in datas.items(): + # print user['name'] + # print user_provider.isLimit('MAN', 'Joe') + # print user_provider('getUser', 'A005') + # print user_provider.notFunc() + # print user_provider.gotException() except DubboClientError, client_error: - print client_error + print client_error.message + print client_error.data time.sleep(5) From 925531bb397238050f2c9f7cfdf91c941b09dd24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E7=A5=96=E9=B9=8F?= Date: Wed, 30 Mar 2016 10:26:02 +0800 Subject: [PATCH 61/70] =?UTF-8?q?=E5=8F=98=E6=9B=B4=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=E4=B8=BA1.0.0b6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dubbo_client/registry.py | 1 + version.txt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dubbo_client/registry.py b/dubbo_client/registry.py index 062908b..c3b2671 100644 --- a/dubbo_client/registry.py +++ b/dubbo_client/registry.py @@ -147,6 +147,7 @@ def _compare_swap_nodes(self, interface, nodes): # 如果已经存在,首先删除原有的服务的集合 if interface in self._service_provides: del self._service_provides[interface] + logger.debug("delete node {0}".format(interface)) for child_node in nodes: node = urllib.unquote(child_node).decode('utf8') logger.debug('child of node is {0}'.format(node)) diff --git a/version.txt b/version.txt index 69127db..7d70f13 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.0.0b5 \ No newline at end of file +1.0.0b6 \ No newline at end of file From 8115ae7463bc9bdd3789cbf876e326a914a81cb3 Mon Sep 17 00:00:00 2001 From: zhaomingliu Date: Tue, 26 Sep 2017 19:53:25 +0800 Subject: [PATCH 62/70] =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=9D=83=E9=87=8D?= =?UTF-8?q?=E5=92=8Cprovider=20disable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +- dist/dubbo-client-1.0.0b2.tar.gz | Bin 9362 -> 0 bytes dist/dubbo-client-1.0.0b3.tar.gz | Bin 9119 -> 0 bytes dist/dubbo-client-1.0.0b4.tar.gz | Bin 9358 -> 0 bytes dist/dubbo-client-1.0.0b5.tar.gz | Bin 9371 -> 0 bytes dist/dubbo_client-1.0.0b2-py2.7.egg | Bin 32933 -> 0 bytes dist/dubbo_client-1.0.0b3-py2.7.egg | Bin 32904 -> 0 bytes dist/dubbo_client-1.0.0b4-py2.7.egg | Bin 32933 -> 0 bytes dist/dubbo_client-1.0.0b5-py2.7.egg | Bin 32954 -> 0 bytes dubbo_client/common.py | 50 ++++++++ dubbo_client/registry.py | 180 ++++++++++++++++++++++------ dubbo_client/rpclib.py | 10 +- tests/test_register_config.py | 22 ++++ tests/test_registry.py | 6 +- 14 files changed, 225 insertions(+), 47 deletions(-) delete mode 100644 dist/dubbo-client-1.0.0b2.tar.gz delete mode 100644 dist/dubbo-client-1.0.0b3.tar.gz delete mode 100644 dist/dubbo-client-1.0.0b4.tar.gz delete mode 100644 dist/dubbo-client-1.0.0b5.tar.gz delete mode 100644 dist/dubbo_client-1.0.0b2-py2.7.egg delete mode 100644 dist/dubbo_client-1.0.0b3-py2.7.egg delete mode 100644 dist/dubbo_client-1.0.0b4-py2.7.egg delete mode 100644 dist/dubbo_client-1.0.0b5-py2.7.egg create mode 100644 tests/test_register_config.py diff --git a/.gitignore b/.gitignore index 2f13ce3..3cb9027 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ *.pyc -build -*.egg-info \ No newline at end of file +.idea +*.log \ No newline at end of file diff --git a/dist/dubbo-client-1.0.0b2.tar.gz b/dist/dubbo-client-1.0.0b2.tar.gz deleted file mode 100644 index a889cffe76d7a496ea9af7a73972521e892a8227..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9362 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 H1cd(sf?!>k diff --git a/dist/dubbo-client-1.0.0b3.tar.gz b/dist/dubbo-client-1.0.0b3.tar.gz deleted file mode 100644 index 3f611d678a1b9c386446b275ad403263df779107..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9119 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 KIAH$4!2Az^{~wJ2 diff --git a/dist/dubbo-client-1.0.0b4.tar.gz b/dist/dubbo-client-1.0.0b4.tar.gz deleted file mode 100644 index acfa43925c4ea0eec3180bd4d4688806c5b0b05b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9358 zcmZ{pV^<{%xQ4TB+n#E&ZA`W&TN8J-&B<MAI}cTx9`0N`Eg z)OIEDYDJSx9B0h%=U?KqKPuD~^ln|(Hr{@CMvA;^X{_UlT2XBS!gIH$XzUep&>IUL zRqTp4UP>fLZ(LUEGiIMCz#xjWB(?mBEZDE8}%xqBmhh1z(LVDA!rennFvzOm9joaA9e@W)8k;&O(52pJnCR0Y!ar% zK~c4Lh+UlMgHJCoW~s~Tmz5?n9*hyjFh7oow&W`)x3B#!*=w1ZU1_s5cf3V3a<(V{ zeiE8Yavwvxv-`nTOH3zN~Y{%6JCETRi3VCdFo5?Crc}pSIAm| zM+H9^Uy@AGA`O+3GEBAfSOJ+P80j$F86Zh)EcCgfWRsMO^j9&JGZXNNgOP{a zEHre8SXK`(H3M4vZX_ZD#`-qEqhRo?jufCFb`)r~_%N6_DWKYP>n4P?e zi0<(8^$l^QFVBwJ5w;tueaVd5KGIy|64Y>*a98jkzO(Mks((zc%m&OdwBe~lFTxFa zZcJ^O<3|F+ilD)U)K$qWl8$;4lnuHpuaIV9Dy6+eS78mUVkk9*2X_};HrT)_^WY$&*}2uy{FRtsae&5B5RSGbQFzA+<$WRSEGA+OB-N6;$Wt8CZ7Bw?Nim+I=-Q=GFOkB{kLyqmTPo%2;XcxY72EzOlI^f~m^ zR3a|FI5aqi{_2?ueqnT26e<(^9atO`0bb)&03Nf&A~m8m6F8qkd=|2`N2D*5{CW9K z@qHA^$K%>dzt2}GN7)gPILB(qCOEU}pSCt}v?2A>x}`GI3L2cKF{sJ@pz5R}nRgSJ zf*53Go+4xYD)!smF<79gM#UCH^^Z1}pPsi%xBQa-Wwe4>5!OoX-b#5BecYogOBc$5 z-CoPm)MIVH1~Ed4+kub-mzQ+cfI|<*hCVwUtGslvn(RrjS?qx}><0s4UuuVrBwyMP z83kiOfenLU!CWwb+&l*xuM?S6#V@NQqN@~f6>jNQq_ z-O~-bNd>CwI4|Z!YlfYD-}`~vQy`J7Z~mR+?LL_9?odM8_rns!l%%56f&Y!r50)YnciZ$ zP&y_d?iV-D3jdXHdO$+sDEx*P-fFMuLy0JKLtcCZ{6@X7VOCIQ1~lIW2Ux)~-+`jr z&(&RWcT5`rFGGQkFQ8@ou0tvxEhG=b7pi$vc9!ra-!VGwZ_V1}TlBpoMY2|6p!z?r zL>-~OWBztXxzyI}>D2Ji%*U2K)>*=^frhYyx?4;g}$KIeEi)g*JF6< zW>8l$a?$>LMm&CUU5i=^G&AWjHVFdu{@J6?ND|j=4<|#@d^*#@T#d6?KiV5ys@V!~ zDnoc^l)Z57p*SJq_#O~mx7EG6)&X6=APZDcj+*{ube%V{JbK)gJT(gWPg{vzDXQW~ z_?~a0Bfc+2$sDUC^4;_`<69yhWcJS9-X)zNOx_}A7Cu)qu0~GKf(yKCwGQ$pR^qO$ zd8-VO-bPcYz5-|oR=L|@pO(}CBUmnXrrhTAcher;96o$kv0l_J3NbIE`fxV^bAJeQ zlW4reCH9C1m7WZbVbh71@OW7@{P@24)_3<)EpFTxByP@zRk43rQ`EoO=xIt~QZrj& z^M9myl{vjwp{@ja0l}x0Z&#yjq_YxVatUV!MODn?ZG${8=4f*t4<)b8VIMY5Af^JU zWC9(~$teH0!phMR)5E~HWHlAK^-gWj*02q!utv+M;YR#OQuyg%2;~|Ur80aEw3R%- z9s|hnt2DG8BACj&y``p4#zW!v7en0N%orzl zc0TfjzN72kjdbTXlc2+YcEu^nn%qCQI)~LmZ7GURg|lsIm8>ZAS0m7_rnoVsq1081 z-BHFKJTsYdhZOX?#8{{@pjXbe4D(gSAuJUWWn@GyTLa-8 z6!B^P_HuKuX9nonape5imZM>L;Hh=7?)Oah&(V-3$h>H~1W~AWh_O=XwId3vtkV@8 zN6IAguos-_XT|OR%;HGO=0;RigduD#wzV+EmiQ=)E1$;1k3U2ZPkWN~P~`Jh;IdKs zcFZDb^Ec&+kQ?@$Oht%lW^fpDEI%^C7usp83?+dTsp!x8Yg=esr~l>Ty7Bfypucfj2#zpZJcM@BPjDY2vsr zawNNIbFCymkO;J~bA$DO%>w%sT}DHR@Wy!?G|=r&_#;+logy4#7LN6no|XN3c|ct8 z*}SIV-+`1j;=c-yl(perA*l4hnH3EpW}4eIAvXlxal;|(_X;7hEF(+3$KE7x;RQj{ zb0^kT3=W)hBOgOuqJHIH#Iy1NYAGoU z7(ERYf@mI%+oQG9(5CtMR9JZ<`J5f$RB0{!r06^J@K=Tj*6mc{ZieA0p4U=m~9N|R^b&!?)F{S z2+G1(6cmPAD5sT3$4U%=u^>I+zY&Kf*X#<+)wKY7Bd=erHcA;F7Wq9XUY*kutWLn^ zYe}>$UyIqX0iwJLE6nvPzMJ;i{scg|7XF5*Lx1sLV=3ixHmb^WAB>7LUn*1+7UMeo z*!|jEyh9lKmzxGDLUfu&J1PlH{vTRGv_?AKrj#rV!mwXGp=MQsfQmn@c=~Y2wSweS zwrjqV>>pM4Iw?X{sl+Dzt|+u*GLp9n-h;QWaskg#`^c{l&F{)d^?b!yCBoVO-jU;l zwQ&|k6ZY7(uW|^v8(UlnN%3fW%#z(2o1GCy*l(Gw1@yiaOpK~^8zLDJ_v(!q5_AFP zw+XUP4Q-wGA_ff)Qas<=DT${X)g>+M%KW>TnoO>u(SWy5w5(kwj(uFwt1LdCT``h} zZr@I<3TT1azPt8Va$7y9q}lPIn%?w*nw_ozUK_%A0~|Bf{Rn<$rJRV|?^zV3DG|wg zh_`N5 zin?y0XviHABcsF&UusUb#R0ph0Sqi1S3dy0p&!3wD!USWdd9Nel&?HxXndrEoFs02Xo z$r2V2^5AvpDI^lU{qFMmbXPL?Tox{$l#onLK1oh0hVziqH`cJUb9CI-mZQl!45K$s z?_$ZuFXrK7c{sNAsu>dU1s}CQ$VQx!go1)HH|Mr0eKpo!dy+2}*DBg0hK(>&4c}eO zZvJ~PPOjcOlErGZI^u}sbt%27KcdkY6D|~5(nqYFz%RlI`g4ATFIBU0 znyjAEWf1a<&O%*rN|6DtAdK5XjASzK;MnUB=_xwRJYv~8 zxaD%0*nKDDRlLH}U5sXiUh;+JOB+{}_%(4N@N2L-0XLPD<^{XlNcFb6{HQVVC3~0^ z1za#H{G(2NkP)jA|1bQA>;>bOFr^pv>l{fWjwV1Kn`PuZ&$}OWDv1ipJ6vsw2629W z^%jZ)sebZ^_GUh5Dux_^)z&3_sFB23n_UhH``jPRot|0BhpovN8MvV+Ts4W%Qfmb^ z(Z;a1_u6nC3{%@)nCGqf4DVyMbc_wBHkq_>-lDztw@^vyTqP}`IS=SYLi!rAX}Vxp zqsh)ONV(Cw=^A+UQ6lOPfO0k!lA?ISTiCtedXkd# z@OT|>F(=`vX!>UQITY6?@ z35a26{fZH1+D<9LiurCVPWEuVhgeVf(#e|{RfWG6$)R*z1$qcQNB3+Z%IN(v-Ehk; znKFY9h6QQ_#=h2)G}hp|*>{(Bthe%KUaBKe$o+~)o>B19$z!d?A*Mew(V#Fc618h7 zHO6C%PYYPC=>LxD!HrqUm-H@6`_M5-BDs9d}}rIGJNUprH-22}>`T--n&x1kOZq>nqo)Gb1bh1U z#oB@|Ry%1)T)&kClLM7IDymE-KG)jI9evi}P1KDttk$xaM@5|VD9Hs~BOl#Q1+M^y zjXfQoKzr)U=K=@~8q!%G7~uB~Y`0QS{0dk5yP$q2H5HOw^(}&T5A| z<%>SoR#BRZMOK@{{q*&~p~fg@EN_^xmrlb~Y2}wv8AeAB%n{$8HR#rxEh?3mu}*JT zuP(8e(Dvrr)7qcDS=K=~ig>VXd~g>0Laojf!b zUb(DT#xngfahy>!<;a+hvCSM!a)Coam~iwT`d)JTKP_y|nGR&*Iv9~N#`wj=%LaJz zVI0c>J=H?YrgxOyJ$KvJu+)bsfDTk6_i1?KH@c6fUCrDt}8k zC5&$twv`nmyYIZ2x{KPDVp;h1a~hv08>JcHv-BWB-6Po+d%`+!*fctzVhc=7%CeF8 zn9nfE_T$u9avKW;6?=n)PWS6@$-=!gymJVF_ci`EF#cudd7!)y`_>`$oTClaY4f~YYgOJ;nAzHUZo~zvl-Iv1FlL@d_g<`fTu=)RFW@vboAmytP>N+h5XxJ zeGdP_h16{Vpi=x6;&XxmPs5c0*_wvXy7q1dxIMNt6(&I*8Q**E#n+24W+3aCs0m`& zvPJ=rcmb#IfCS7x)9sfRPW*(UUq<_jJ?$^0E#{tcZf^KiR;SfD`L1^$F9T=O4|-D< z@y~KBUK~?L(Z_9=w-lBI_(5+j2lbv3Dz5z5=v#p;zBi^DeIpa=pv35o%tJIpsw6q^ z6zeKUGR2n)lF8({3sNXG5VnN>FRGHa1I%Oc`|eHS;M8lfjVCd( zr7$YJW&}umT&A2jJG+@&TX!S9s#_Fj3iQo`udq!x-zCj_yBC@1hNqnIsmxBcen%MKuHp*ZzZWqmqQorIK7G#~zQ+QM#7SX4jE#iBChhj4ex!R|lI ze3APGeHOw( z{k1Zis@rKXkkt|o@w&I9$CaiC`~Pqp}~*!HklENq1y169T``G z^Rj@;IO!G8i!BbMd!#M=mwl}sx<_mM?es544{9=N>Y#KP_9LllW-XTgoGYG7zxsB5 zsP086j$oTCcXZsa-HYsLKZ>T31{|;F%O_6a9EL1?2{Lh|ooAFt?5Cez{FN+L5m#B4 z13^PBdd}fAk+AP4jF$2YSc(`%i#Ss`vw;I(eLeP-Vd^?R{U7kY&4?`E_TPSHQp0yVg8;e98%-ddA z#a1ZQ2m=PqI@%P9>>mH7kyGjy37B76m49RXxUiJV*_Iq4rT;BS*s3~O)Wc$>7r(qmcP>q6=x|iA!A}H zq7qdxm!&}`xWkM+Mbq{B#3l?Fxjs>YPbqM=4uDMa+rmWT%DrFjK$4HynkAAQ`$un( zyhkU&Oa}u2@N)#xUEee-ieb}4)gMWHa^yp~^5ajXn1dJJ#J~7B zee{hDWmN%2-^AyN9;YDMLij@vA4V`gum5dZYHV3|eZ+`-R1{|NZH3fWTu?+cV$_Jp z(s`X5HDp#c@&ibN;ff;^kYL;#pgtu2km!bXQ&(nm&JOva?g5JDzA@%?F)=@APtq5)nN6?ZjiWO3d%90 zVH_Z|6k!5``_A78A+Gq1>+SUi!n5+B&H&O1z&U+T?+4GC{I#YxtH-08ng3kDm3u;5 zJZ%38DGI0nM6W<1!7AKi5abm|_!GqZQ(PZ{`TxEb!yt$cmz~}RMB9Pt>J>5$eF(us z8t;SbBu>r-T&*~6eQ|9Q=KPAck;mVuWqP{OGmCZL?B6q`yIpah^XHMl#Pl%9KRIc& zgLd2U)USKc*)MYQ9%0ijlzQdD@&5VG@sTLdw;k7X%ctjW;p6^BfUBzMrfyFgyT5(c zQK54`Yk-(*y)q|TD|%yHV*Al^bBZs1b5G65bLmG<6@h6wupQ6CPd=fLQXjy6DPCG| zueI1^3F((s2S;0(Y*CU^9mKn?nE^ojX`Q1@c#TbsMs(H{aH)XmFOEVbJ-E->e1? z=ZHXw8Z(3D;TK28@>N|_j%0h!e-A-`aVQdF*HsJuw{waLQtq}_W6CbW$=$w7V-Y7j z=Ugdg?YK~+#`3seNDeu=4*U7a9^h4xj1neGnlc;uK@~GHsn^}j@^x20fl-HX2cB(= z1T0eUWK^(p*WTtK=+&*mK^Pyos}qc{TiVK-BMy}_c+K}!awp~_9FHVg8NTs-Z=v$drj?fn2G4)&F9pfLynm}Ba&6086Zl_p398*_H-Na z56=dIlm|LZ-+8&%k+g zH@TNA)o7tk_-}xWX$Y}@ITH(tLWo;|AX+1QAWpyIw;PQn5n3NDDtP$rzP;x<*sbDe zbD`Vp5eqla?y$9{Wt|nK zFwSDLa-gHcjpaZV3aFlb?%s9utfWEUG_%D6G_Qgz+*LNfwHm~)5LpsI^Ha zJDN2MzyK{hm!rR5V?Pbp8p(gtA0_h+l6soY1N7V+9IzZn7MXvbS zls%l78M3BVeuN8jA#6QwvME*Y#x7!N%s`dd)#KY^6+G0(N#-Kl2<0M_3#2>lPCJ}l zlVV_7P>rL$zu|Er4VXKaS(=qL<|kip7yUTp$SrueNtK?L}lCE{I#G*H!y3o+NLet9JXh2Ol(~3mauHPLC#&B#VD7V$Wk;#hPn7 zI!{L|e_LK=O_YBb&*Lcm#cmc3(sU#zMia0oUCvU|(<7{{gP5Bd2WWH!%zW&lsEB8D zzwKFmo)3erbgD7t^2`Dw=PQvmKze}4n$5LWs>u8p1|GG0sYf=5f`*=+xFqem3PL|H1! zNA;a<YFBx3XNIKm=*yy1Q)p9tw=IiZ@VCv~WX!{JqwJ=f_zY5X=5_}kQ|_bzYlb@gfll&w+hb1{EBz*yZk+y>I~ zogWm&oUX`U{+bh%eXf^Hnw%XfsCfgq!G!wb2XcM7AS~u|e4*Ifa&znnzD7i4?sgF| zls5V8=KFAwOgj6sqGb96xZd3{#J4%(vi(lT0xuFBpR)>vW=r!@!qWX4)cAZw*zrM5 z1UgTq9K0MAze#oZJ-Mo@OG@hNK*?#ugvHr$nD{jRTdBOz2?{oH=4oU=RRVoQX{cE@ zh9O2vIiC?w+Pk(-20eqaq&TCPETF06Fa^|TT1)JMpkeLmR;qgE)GM5I z8Io|(oh&Lsb9wGCyNO0l@ZeAGmw|oAH=SK#3vpKmKj~6+&>|7_t;XF!Pzv zBka6ePS0xDzH&+B@Qv-ZTdj#Vp*Gq?U%28(Q3Gqmm!Ml8yDEW&t73brpLQ}*N_HUO zfVqA%DhTd>FumDIhnS3E#h=RQ#g29mZWGch2f$5 zR>vt$J{ns%*n~{9|H&T!Y7hD@Tmv!NWmx}j_Cfze^TZXuX<$exwFa9=7&`wOSfiW3 zhEhcDZ%8}rNt1uL*qw4}p?lk6lVZGtnAVXPREb`^Xykf$4CPC&Kh)$+lsSe#mG@c5+G}AeBn?Is@^zW>u?q2< z0Ho0j=@OWo4GFcDIrV$s-xotf;iZ3i(@%GP5EDYqGZBupdPkiNXb-|0%}O{a6dR^} zBNZQpEzC;rLG<=cLOd_U#qpvHlQW4_erTr7e5{@g%~Z=z##Pz|XOg4h*!?pL0q^XU uL4>a%if97wzzDPr$PVQp49^BpC-6goYyIZi}?hxGFWpIZK?iO_LFwFhm=I!pSI*Z<& z&8g}>{gEdiA})<`Yr{aS>^wZ#th_8NTv#j}?W~kJeQCw>W~?acNUqN1e!jLd~4gvu!GDoovLInp(tOSY`) zNawqs8`S`E=^V!dDsA>2zP+BbmhO@e66$M?j zy(CxpZYsj72Mp`wrX5N6pz?AqmgQHmu5Q_m8Qv6K&`CFjq+e!*T=(V4fzD zbYu#ttCgj$p|ZP~{8vXK$r{^ZF5CfRte#F3x@vGM*I`Ym05*OzokCUrRHf6npl-r!68%7W4MAuSk!Pru*3X&KPRjW-A2HXi*TUj9ZtoVoqSHrbO#)I{B@qUtF zeUz4Cqsy>Sk#0-^GIiDdm1o$_{$W#iz>1U101UDuDCnPlAAgAPlou?n0lBL$yHa+C z$0GtLr8fJ-a)*t>Cwp;vagG6f$XZJLi(pk= z7B><{a;Ppn?*|j(9pnV#+>OR{Zez|usUZ%35tj`cP!@1GA@afdNc@dkmg-170gk>R zAXU1qJyytHm!BAQPTdgyMcnn<82O$0mse;D5{1ISiVMFQXE9W=T!Ndk3A1*XKd!<2 zjz2juwX@19KNi|=#P+*rqhG7FVYXjz!=Sa5M%n)CBbSaa)DFjuQ#H6?$*CM53j5iw zX`^3Y&1a|cQHVuo;sM|^)YUPd#0B_-R>TFO5zD>$7U9O_4n`4A@l>V;PV5Ft0r6oJ z29p9sY}0VX1*3P*EY_e|*t> z=2>LkXb{-tztHF2e1F0iTpnwUq%ET_EOBu8a+6(T+6#1P@LrlXI^v`ha zRkTy0Od0A~lReO``#y8sk@HD({=yI(0wNm%{}rM#F3)zM}TEuWpqt<4Bi zR1^2zHZd+%kM&?1473to{oy6!VfH3Ai3n~s{pmJmh>c}JV9f&L_$(-AvrCNG&3v+D zzQXgCD+k1Pmgp>1DMs585?{xyNF`pg=$*HnVjB5T z1ux1mDWLa?tFTrtXv{*Iiuy0BM0;3Zv?20)l{}UG&;t$nAp)1s5H|7c^OYeX1Fm~t zYMPL;10U5uU2TWm+$b}2ufA7bn2Ab>EHk^^Je*`H(We~c?FNju5wXk-=CdnGzAIlM zWPO2U&84so0xI-7mGC%nJUY^R$|INq`4F2nX4l!w=Dp;SZ166axT2Jkx;w7s#CJ^* zRJ2T|jEJ^bHx^Orwjee`Td8m8HiVZR4*8r$?F3?fkcm%KM&pdeg+1fZvSgtODr;d} z9Fx625iquVh8t5+-417*Ty~P@q_A$RucrWQZBkm+tWq>?Sri>+z9dg3lc97^(7E)N zOQ(hfKN6Pd#@n0Z#>5p*BkXY^Pt;C6Fqy+&l7H$!&Jg4rLV|1EP7?i&Zs)Yi$4JPH zT!i|Zg99q=cO*fddn8#p*J=8HD}PQG^t4I^wA-Pc?uw^R$pJJ{pMSpE2X+vHKC7Ni z5X8_TrDjjG-8BvWt#6CzZLHts*=*$5404bMBCM_$L3*C=nhD%&ko#QZj#Ss^`UUC< zxcm%&?p4IRyS$Boquyhc|A4?ZATS{535~7P^Ru~U&YfMlT{cBXi%G{SD+c4Y<{)^e zfp~V1r@!;bKi{J|n+&ZX_}bg!i1DWa#t{b-5l_3bpKWf|*X%4&F7l7E`#TOI3X%{^ z#?$GPx!aqzBIAacSYJhr^j@!b{^czoP{Zk(X>5T9KaY1lTlZIxTW2`cYHg%jtjrxJ zy8%@q)3u&DGj-5q7>x<{eJUC^hG^NW*)oSGaMKm}JigR;kx9}uLWx^8WxNlcp$7Vk zMF4)-CTHS_*gzzoL9<^^`my?Isg-(@b2?ul!vQQ+_-t#+6}eFQEMk#I#u2))>6)% zi9;Yr+Uc5nz|#DUWxw>}q#6oBN2XgbI>g~YiJ#ynga~*g-1BfHNX{jR@VDuY^fFE;ie+{cfg6I?u3p znJjRN-n!HAyR?(^3%sxoUY0`7@!1{_Q6IXeESTHokAF%OP#0N-o3J}NQZiLbuRSpi zqD0zZ16>AvZWSON&7H$#R_1r1s}i)Ope|jrnpv9-4c`n0BRhSCVgZNInnD&z-kI8F zR?S;PanulOSr&Y+*(5bAYj)xU`iPr|BX=P2xt!F6O8kIzj9rEOMvj|kOkyknKu1OF z9eyAuJv}fD>D_Z+`&e&~(!xK}+L;PFqrJ9}K;zeH*lW4+@f&&Khwkp_Z5qu`e6TZ- z`|G|r5|?~ZO~1RgK7Ma;s-^jB2#)2FKU)_TGo+W%F5z1RcK2|KRZx-9uOwsY>=p_J zlr>|#?raiV4#`m!WdW`H*52?Qs9lThG@NC?!A{(x85Jce#@1q z$(<+jnJN>OAle&lRdBUapvE8+(53zU+{Fr}-ySI)Cfmptf9}L#PVmLR>%ZI{p3YUA z5=;timIRS11%YpQ3<8Eivw zHZ!_S@%~K7y)e$vk!1jSM+*C30CkFFIHl$s;kX$eN3+gSYZ$m|1Iv}VB*{&e0q(fCc?yo?4(Tpc^@m| zc-okLM<-*L&K3x>eUJ+pH_I>IP$F+y3-z>-3`cZXJoK3D}fkSx05R(%}Up;&s$R{INsSHY%xqhR~P_ z2M&{)&BPL?aO6o)BNE^tcEe#Wlu*`iM8S(A#64>^kt*mo9D0;7XN`g0Ne$0t+v(Vh zcPu*8iD1=;#J6l#AtNH&;(b=Um{@_6cRNj9K}mq9|4=Oa%~M=hBDfmNHF3JU31E~p z7LMCwk!ex7awe3Slx|^Bz+_wPU^DlV3Z`MP0T>fb%eU5cAkzH&SgEtd1bii&ZAKhw z*U{Cdp7AoVo%s7K8R2)$AcyL-n%t@2sQXVl+SE5RHFKwi*DQO~0Z%Zde>XFA}P=u=N6y zp>C}b4r9UKqvlb6cxv+g`w*?;Q#Zucv^K& z((k(s+q$Sxy{IqZw7{zNSZ`oa$3uaD1j`%HL^d|`*w#PX0ir5R%lFyC*2( z&FR_ZGmB?BCf@L$}7+2{BcyB^_F@M ziF?{sb;y7DY8EYm@pSx>at#4*9@wvm7eCqmoe*>HfNKl5@rSJZ;b0J=4L(p z(d)RTV3d|jf|1KlcyCpX$#Ee`Z_f=#uYv0)Bz91~DbR>g~5m629cR>+{A z?{H;VietT@a5&teWSKE}o@k2&M;u_>K3h>rO4Hl-k53V<3ErG%GllglyUuEc?MXlf z;azQS)GjN!z#T++ZuA!~2c-1=zzkRXOU|C4SMo9IY$8|QB5$r&jEt1ojFbqhFYX9? zv{h8POpdfIk!g|;ZMO(>P55*j@Sg2L{tX)olSG9N22LT3viY?S=Jb|H zrNHe@07bj$_Ov2@v{gyKwr&kuo^~ZLn*2DXMS>%<(zo~o#)M5?gCZE1`gZY%(DW%Tix)A~Wk`uS0$qo)h|$75rw5b-2Tr zfuo=rnjdCW+!Qk>$CH+93-07(vi+Bj& z|9%uKE*J;V#2Aotdi^|&u^(M(i}Hyqw|}}% zFD(JVm9&jOMXtjYrheoQo^(CkHB$6>1Sy1#V-~MjN=gZ1NAb-wMQa#rZg0^S@-XzZ zh4;*6kz43*`tp{xJg@(S;fQW*i8J(5Nk68Rqnnk8-JGY*Cd%K&lqI)KmXT&gu^RWA z$pIQNbF(b>uW!Fx6;*pP{x!SE6ZrgrGgjTou$=nEFe!As`n7=HCF0TToZ&j;xKVfz zJZMLm`J4}-3MI$fgs?e7vS=Bl+a1Z_p+QA$9b)~#cl*#1(Z^oasWL{6P@~n0E9PCI zLv;X!u%S-phKE9Q%c93age!jYiG%H~81kchjEFH|q1Dkhyu@>Nmz#$_{L`d_OFgL> z`X3Y;(=`n%?+D}MaG%m}aM`iBPYDP9VyQ0&!H2EP5}w}4>zCuOkzc112cp@Z>9YTP-Us5Cr>a-!Tk{-s=h^=GH`aNx4rmsx6#V8s|Faur zmxDWD`)z{YRLl2=rI}NP z%N)|(45E)tC?I&5^xK;n7e7H^#2&TaLG^xDTQL1W25F@+p@ZqyR-TGdfa8qXbM1;C zT+ImLUp~6Gq=rdJ>PpgAjQtx*oAL?~oywJ+%iy*5DKn*~G^fomx1UuNpWiblsCiksL&(9UBKGH*FzP(eckz;2(hR zC|?7&ih09FBw#xk6DQH4)q9Y%Y zBZpY{wt$K}{JxNER3Zio|1ik=DS9{I01lWmE!ezyT`+T>nt=d@l?3)71zkhuIO=Wf zkd!g=8Fv`A$ccLfQf8;f?3Zjg3C%TkeOS>bL9uzOu> z@N?4>Mqb2Z)tsRqRd}I`za?0t$pH5dwP6MU7i%p3g)h=~o(LaZF#BmAm=-aM z)scY@$bX`*H-csc=AYc%NIghV1+peYaN(U&-ad6e_m-ga);U3+&wkH9(4#bHx}`rA zxd6rEv(WD?s4s@lM!INlP3VFYb7gPFTC#KZ@#$#^okv%dr(t)rpW22G%AM=M#-wk% zFQkZJ&B#wJpbvWAiWIth4;edG^wVsYdcnbAPr`>d<<_u@cWr&$m|I}f{Y}c_!m9Ja zD);_2)(>I?YF&9Q`>)Nix3$LJhVWu?y<+vo{BaxS_lGBo>NY2YU@9&Ma**ms4@8drLyECIic|YK5b2VH; zKFgFPr)|s8m~SUt;szn+$B9>K4ua3(G|<((BuLgILI`{&M%L!O6@|WhynWadwCL7w z504IcUn!#BVGs4JlRHa?2D~dM_VCA{bxX|cXuNFmpXe;k_qhW59=x2uiEkSy&zn?$ zmU|yFD=u0lA3(Hs3v|I>%NMDlzh<^q-Zpzi<9yehy}H_DPMRg>64s89{S}jrn;Rm$ zSWZap8*$he))_9$SGNJ{tYg0Zt72RnX>#RM&4n|6=&+@>oOk&Q zl0r2SL-EOyJ=PEvlq5v|t5=U^jNi(K;UyNlF35b1lKzqtr4;Y^E@)-$M+BF3p#(qN zkUkm^WKK1+l=5pZN(Zn>sOrUPL{b%(29RgjMxxU*A{kGyOB-sQ$YU<{IyyE+zmAdY zD7U)STMb#cP3Y}D**rwxl;I@z_&%ok9gMy&XBC?+RRY&I3&F}mnx{v%vxCOleZg2{ z$KDks{`X zYe`KW-$0XLLn8RtRLliq^MsY2%ny3Ia0eP`fEV#?; z!j&R6uBKm(=S#DM`s-XWzM&NiW7sZ3>-H*@Uc9vizCrsTm9wK+(+}=uBN@17=yVX z`fkH??rOkxkxgCp283QY`0_Y^hg4>O%_l~jmuPb5DkzR`)Agf~~ z0AWi_!yk}_4^gh{$GZ^50u}g=!Eg72srUVj$;xEM)-+uFJRChCiEIRtI)A@Ok+E@| zm3W&*p}d8#G9E+lQq_7#Pb9Cs$)Y}1up|r0R!bVBNH2qOm{yIybwGb#RTzjw2ODeWvd?8UbDo*k%r zWEl|8TBL5+Ur!-@pEemI-fc@ep9^N6s#Q3EF|*4GSOp0BI>hHVEmNY#AcIf##ZZ-S zjl2mEf)5dWQh@N(Lr@}eGBEE#nm);YLlCYY!|(ssD5?wDLx;bPg%l~!{e3kRph2aA zgwSJ+{pauiG6{Gx=$tdWo>N4N>Nrhu&LZgXy5$`6%`;(ZE%3SU&D`mi&m!oq-z_`h zc24Ld^e4W(%jp}jd4L!63!_}Wa=3r)I6V>W_vs`v*=hCn*t!_^dfqkY>!|m4FnnD0 zo)+8+*M0Wf)k`taJ16REK;QkfH6yXBJ@s5!2uyf*DFpf|f9`5bosfO^4mN{yUyGLJ zBXhP2T0n*+RX-6v^3c~qe2xW}=jKn<{TB==CG+Q0bx*JbaFHSOX{z-!cNjq?0Egv1 zrG@VbkuVs4b>|@qu7`W;AA?F3i>D!!=|gYi7g9qILANLHhM4vSe5JLun8xV^POT4keNb&bLxa4&1{wGiO^0f<|>AyI3JS$7%`}?pDe7%@-2R;&>t;>|gp#!GrkxkJn$J$qRkM$S?a93EzH) zF>W^Nz`AehGb8>(IE33@{6eFyE(Q~MG;8kbw4aV>lKw8MkjdYi1;aqU4~On!f_q*8 zM4k8&Vn<4A17)I=McolMpMb<{mDLW5-_}_H+adLm35(wo69tR^p}&q5c;&|S?UnbW zHGUuEoM8W!Xt6iCsUloN5wY#V(9OS^DcS3!K0kPj!Q942i_mw+Cqj#GdNSDhnfwn= zlarI<+Xt^XJ7)&sd`Q4BXu(m_Z~ikR{y2mdUK1b%b55N@NQyci0!*#DX4njK_$a!9 z{Bu$W2>xJ$8cYX4qDr)Axg+NxN>vdch|dJXrwFp=elu|5*7@7POGu2I%r+5F_4F^_ zPud`MnY(bklT2q3if`mMB@JM5f&T;TfpkSkI9=fXkq=}164|j%p2-AaK1=vl{B zNkTTcl~h*iSXI;}9s^@!_C2G?leXIB`q*ouFMJmahM~c!Wc7J(8FOa|?$D1Nb+E*! zfv)~p9AQ$Z#}KhC@Z^H@Ck7JC+oz(290dkc0VGEr_I{6m5>nIFXv>KF6DV2&igpG| z%=ES_fkAB7nevK2@qA#P<5_#2`CjjH>^eO7Y(r`RclZLQ#%$ngpJLalKfaT2~buoh8b#J7U-a#htH5LCVip5-A)V;9?#6lL!POJTzV$VX5; za%3N9HY~V^20UmkXMW(St*vNkXQ}?wBNzDYvRlVCh=Hq)k7CrrF0}P}Y7hFf2cPn` zw}a>rE~ca2+y6U^m`?rZ2p0c)%L&@uSIN$tP8>}j_>iRR{RczrL=1p^J&!A89>=5m z!N3>?XCu4a?odxHFiFNCeYr2DfY_ax3xSu*Futpb+`}kQ3EtP%6qMYETF#su*2UB5 zm!}lg1H*$o#mPBPXGvAIhPwCK<^8EmmHJ>wLY6ak!>+r#jp9Sw+kP-;nC>*)+T)1> zrl(IMz&Fctu*19A4}z}05@mnIlvNV6YA6dYSukY#gfi*ipxEBtm`#v%yY5oJAv%co zH^!YuRL|K+V5_Sceonmo^vv|oUb7rHkre{B?&RE8G-50@o9NMtDZ(V0R_owEUY7HI zHaanC_@sIxkwt=`dm#D~rhRe)Fc$K8a{6bcdge-3z4c|6bAwINL5hNlw_zhVG7d~U zgUnT$r`S3B#HRL**KBBA-TwR`;{BRDOyjc3nR`$uhF!Q9y&fEJ0qb1yd@Kw~z!Aed zJ$YeiQ|r0?{K8P3nTE2$x7r`G{U-_L!pY=cVKMBwk3{JF7s8y$3KXlbN=qVx(%|PM32-u+46ek!kmP?c&Eq(&-Ufu^9LrJXevT z9@cu5#O6{G!+V=U(6F{1_HUk>wVsRoHK9A06VXBx5^_&|*oBm$m0{e$Azc@3P~f=E<^p1NXz9(2X17IM67A3`2KWX)aWE^MZfds`Kf4o4p8jJrz{}kjBDwv z{WA}ngBtP;4Pvzjvf@ZZnuh@S-}WpMgG1V_rr^|hX$?i1cD%T|l%|2^Mzrti8ctkk zN|kS@qEi^wQC5t~C%Fr}&ApQ@L~-X3ysNLZ6v9oG2_nXu5>WSWFC*itBErpr`@=kJ z|4}Vz7KJ6(tjg>*r3Ji79r)@%hb)E(4FMEqiHeHMY}lbZy>E z@piJtJ7w#6iZ$)5>HpIorE(mA@p>|IMk%m_jO=boe`1K03zlMjI+IlIdvBB!Z7L}| z(~m5?Qkjbe(bfx$A0d-JOq*gOp1q7<$yrCgdX=Qs&|? z0rDo_O$|(q@zJ|mY&9K|CqK8fZp*B$Y86@Z{hDg_8;grr*C;m&t>(9E5PG}kdtkQN z!+PW2^PghEgM{G0Ia!F$4kVqhtSGfO0VB|&!LYRrn KU#L4MsQ&?7>7mL1 diff --git a/dist/dubbo_client-1.0.0b2-py2.7.egg b/dist/dubbo_client-1.0.0b2-py2.7.egg deleted file mode 100644 index f6f452ff4094cf717cc957ef8bda02303adae743..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32933 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 APyhe` diff --git a/dist/dubbo_client-1.0.0b3-py2.7.egg b/dist/dubbo_client-1.0.0b3-py2.7.egg deleted file mode 100644 index 1a1a31251f30ef7fa821438361ffdfc36c1c8382..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32904 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 WzyS+9ARtP>FG5%#AZ6!=Km8wzx!zv@ diff --git a/dist/dubbo_client-1.0.0b4-py2.7.egg b/dist/dubbo_client-1.0.0b4-py2.7.egg deleted file mode 100644 index a6d546abc7ad5b02766d39eec3e21a7096d5c55c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32933 zcmagGQY;<{=*T!;YPqd*xc0 zkrAmN4Ge+;00001@SzkhHZ;u75d8OP^RHq2H4_&jBRhR#YYS6bXL@~o3tJ0keSJE6 z57k&kxB&(j(U)u@ZNMienDT0xXc|SN_I{!m+EvWGM-^1TNOpdHzfDg4C&`0s-c3T! zca_jYFk`cVVW`pQ{(}J$OZX96mm0#kWW>nWlh+r4;Npz3R(MGD6t_J4pLvHHJP~>T zu=Bebv*9y!o8Q}!DrPc12O*qxjYKIH_;z_dfC~T9@+YrEvEdS0*6pSpmgmbHds<33n~^=jNi|`0Be`78YKMp z9~%zUB3XxTS03Ml25v&p;L+cxiogse04@+*0LVblgao(&v3ogueYB@@VmX!R}a<6Sd8WHTbdvqG*a-q9~1u z-ELNXk%5{Yw5H_S0UtcS>O|H*y1C&B7mQaeXgo|eQ*8KE9}=f4#P+&yKGR&XKR`+@ zgVj_K|KN+!<}}%&bdG~wsmeewvMz`=;OZ!3_5;3Si?CAYo~p*Yq?Mwy{%Gpx($%3? zJ}I3xTHI&$_(xsgA7xjmdCa73dw$&KG(6=W^Ik0{B?Obt^YBFd{I4M{bdD1<d)na#4AEWIOg!J??t=EB@dh6AIbA2cqlA4to(Y^9SsIr@9FFh~ zY!n?ylx`)3e_O4aES4s9^7kX9dn^=+ULr+hpfM~HGBEQe`2 zrn4+;D4V-D31$P4nP0^*&qM_ z=>M-j*|LT&XO{;m26%)onFa?Gv|boL+5QbP6^YOL zN1|bsPv^zp-07H4d0;8O>L*FZ#Pjxua>S_JG_Jim>Gbv!ttUS`DL&JwSQ0{(%jz2A zO3wkjWp{lregj!>b-t2qrkKo}nBC%_nNqWd%Au@_bKdks!dd%xgOjSJifw3#4oSCy zW5)U7fPi_z=WGUcBDeBbsX2u!8387@kK`0;VX*74kb@zBvd4!zegmUm1|b4 zNk*HUCUI$Pa=ZKP)<8W??wFW0FRsyyjoBg7O0`4LGIAh!@WOIfCJieCwtRyP{?Mmk z{HE2N4D29bYal5MFRDq3GD&EdQQip$oy^LSg&3Po6jk3JmA_GeAi?YUM|2c%_elXb+ zz!oQgLu=O~>BGjxd{dI8unrrDDA17M1__9eKL{@Y;DX#XADl(oVh@mOc1yr=7>Vci z+t>GzN6t_sxyi<~tmB7X6k~1{Zb)+!|hX)u_NsSsco_)>u7Y%lJI(EU4Fe!2Z zn57rG(c+FJV&{q^CvPUc?1Y=$$*!L&>3G;)<`cpGTi+ZOdzLpHf9{lij5)rqN(qp{ zW-Xj2`GrUh*4c+{wr>Z=*Sk4aO{66WAa4E0)NJnTte)1)UVqa1>+8L}qX(0P7e%Q~ zBFp$Mn1;x}J;59bK?fCealEj~ziLXS0A#O7qX?0dHO9oqU=Ft8m7F^hUA z^)rnc+?I76_{*~}&H7oo$j%lzmxIH66FXy~(2xXFT8mxc-u!=>G+zf0hll z)^zW3e?bHQ{$J_t{|1tAjmqXfbeGfOWU-*OMUqdeqM%2kxG;b$stSq%Nm9(m0VD#_ zh;u{cLTA;~c^&gu@kuW44ana&#bF^BNS zhYt&KPLNvQ@6sV2&l{Kn_;u}0;Js;k;*HK$RY1+~EFdBORsq%o_XuYUj5A3#{=uH? zQw~)HRj+sccN@T!0b)=)SSHDgT%^ui}Wwtp&}vBWG?Iv6xlWjamONR zecBAWi3oXEf+dtn~*U>fMdQ_G1!dU;|lR&tbk0CTh9pS0%f_FEpj1? zPBQBd06{UDW|Clu){aLxkVPTVNkcA7f=_4^hqE7*);o8kmcuH2}QvA6PokZ_0|0C3= z3sDXoQW7ncXUDQkTzt4c@u%|IRLcQ2=7QMWNyjmwUY1@?#r?DqxhIakE)g9_8Tm2C zkt0?)24`V_^0JU)mXn8lgnS8Ou(Ro;D0&>G4c^K$V=ejfxBUkuR0yc{Gd3L)_{q_> zOX2&$f*9%V$*IJoH9D8yhtu!!)4lD^O|1lK!~bgvCPv1KS^Tc>0Du7iU?cx8dk#la za|S`n3 zNEjnR8Qdpi;HFJMx+&B~uyhYmqXJYg9k;&5{MPJeIP3HJzHulCq+78OBXV%Zd%E@D z3(KptT#LElTynk&4|@_FYTVg#gbkZKX_2|}Xl|{(SR6^B?($*1D7ey$Be<^jc(lH( zdGsLPvswM#-eJW~;x{77)gxdOmUJWNLq3=S9HyMOGozj1s!8rFZm{Jc`K zl7>FeV%4AGRdbUEb~)LR&%MU5+JSGd3^?L3Cn8j0^!?`1(|Q5 z-0iOlQx=VR37jLbzc?ERep<3H@7v-mb46cSqEzwuY~WD8wwhzWUjXr*#cVm&@(2c0 ziN`yb$CoQy3-0E_bG0EG2Cy1kNgv{-4_a4iXV;~3WSxdC%5*F`$QkZI&1{Kv`@6Y0 zS^7*o3J$Xpyp5hI9jj7WYkFl42SeyCUXxzpDC1nCcrf_3A83CXeLpVm=VN(!Zxgx( zd$K>LZsRg5n5o`ps#H1~ zpgmf;HZkyVMZ4*tgZs*5pVR$b_V+zbS3rkEeWM(HD?1*zcKYR2ntY%%{bpJZbS^*e zjYaRLuh+vV%V7iL0{P=Td*Zm2oQLXax=c9PgKV(9meHl{rV&6X@Y0LZh1}%{V`U$#cApA(x8;jMvB-+N@X0r~OY^{SWwBS*sO+96#|Yfo1d?v)3+dwasB-3+a8eJ1opPT7?U? zcG;UduW+Nxr$(nUj`qf+Np6MQ;qp}ZP@W1V_i}U+joGL639U)-e{7&!(P-nnjaO8s z+gM-AAtp>XrmPuL!}8UZIE=W$;-NvAqNEwAQ~`irF3cL=pq?JRVP1YMqVA~SFf zI_Yg4&O|^*;C4l-ieVO*gjyKMl=?ter9mHwum|HZXuMrZUeEgOJK<8g^t7?4;gUFX z>DxL#Nwv$?&ABhRpJ-I-HKDp?mOp4YD+m(>1`*K$2ms60-YMYWuT0DuEJ`ge=!}fD zis~|Az96>dsv%|hP%z}KglAiI%CxR8sd0m5e#Y{l zdYeAJoqKQL$P2ZhnOjfQ4IG8LJ$XD;8FmWF>uyY8Ln2RwJI~dnL|@NIft5@2aTTP8 zcQ|OOIR{&6z)&inq=&n8#j{z=88g5F5t~m``)V=rZxxZ-p+{wt_~O+=-4=df_}1~l zlT}XK(ilSyH z4%pe`=MR)5$NJVudbV&c{e8Rmyuv?FrSP?)UH2^qn@%S^gqnX$qz0pA+j7JEr&@9o zd)0MirUl=-Q5t`PIN*G+ZspepM4Dg*7#T(xwVRu*A9l4bY!6B59~EJ7q5w?5+zt^F zCJ}r0KN&R~V9AmdT*m3m-}~INP$ zGF;!)!E~rKJ|An&fLwvIh=OW2;8T^uk%eQS-)7fZfbwf1u>;7=xn3(+a z^-K=v@#9s6_b%q*>?a1*>n=s@gP{xeY**Xz;kPb7w2 zD+z0MFpA=*@InY(u=l1v>7e|pFR5QChIVeVu1QjMyvPargz5e>NwmV@k)t@GN<_Ub zV_^gZG&5Fe;+TI}sf`;TgZ=kICalCbB?eLhhCdHZp}q``BN|-FQlXZNFtm*u8uow# zR07+^Yc7lAg1R{(F*v2cmgx-{EX#?#by5L*Zi@E>k6HoD{cs6EZkq-ED7}BbdBg9e zHVrLL@`h3eBsw%x?^O{r$=fB#V1}p*grH(y82rArC$7r98q%lKOb+IUgKlYIFj ze@wc5u+xpCrVT8RFa*=|%EaHq(COD0iS`SEkc|YN*L0vL#O7dtfwpR7hFgy)$N>y_?tFN!Q;wLFh)DsHmMke~6QWDSKb-PZz_u(`rN5R|ikC6snc! zQW6f3o8(tNXTS=S83qOL9zSh^5I`5@Hd>43>;gc|Cop~)FxeN((n+Xpvy?qvSX;Ih zu`Ge8iCtNWcv}p4hdgTE58IM<$UYHd1$j(3f>G+&*5_D!75Je%pTFL;yoiO8L(iWN zokhH~6!1sm^AGEHv$L`BadB4W;9*H4-4ObeyqH_yiA7;{TC5b8h80IB+IYV{4&APu zy^;v{%RXhAtiF953JV_&A|tPRSK`sewGL`#WAIiOwj$|_sG}4sp=T^pZs}1nxu}y0 z2fTSBwd@zhNuj86ZRO~DFV&mog4Llj3G5->q0oxLfYY$HAkezUvz&<4;iVsG%JOv9BF-<0b zSY*JQrYte~5omA%6r4opAJ>x;@osRP0j0%`O`Iiv1L^(+JG)p`WW94+`hdyIr(CG| zU;`=urBo{F+Ty*M0|LLlYf0LFPgsnTnMJvgQOzxJldV z!&>Vjp;hHwc1YH@pwTbFi4#~HBp376uON_3aS^M-&;kp4%YbA?FMWKT>gSfRMa8>w zOCO7-Au!nCchEfgZ|k7ThMbG*tI#g-BvNN~US|hrl11DYdqa?p%ayh;iia529+Z?) z5g3wMWHZ2i5k90hPKc|U{&X|I(iuzS_fAfg2;&vg7)blY^_H=(FW?Kqr*O|^oeMuN z|GR)*It5;2LUB%=sUPrv-?(2U(+4&q008V#{g-(E|JpSew`kcoqo`x{H0h6%VIu(r zuc&pTM9xo;Wi7CX6cRE`<5zH*H!(|^HE}mhO#xAgSOf`JY2U8FOE;kLdwM1- zY0V-+sm$EOAj z_RDZsjctD7gMod9?0|)R0?MX(ZH8>)ts8@yM57@{*7?>Kn!4I>SdMKT@=MLkxq(tc zB0I;#I-sFWzS`6in|Wp7S113*^kXp2)vfp{qcQK|YW+Hb)AvlYi_DD)G*s4FAI!)- zuguLrto(h z&?CfZ%+={PARI=_JE8t7B4QzDL{Zm0QJ6P>bXo{5y=I~fcSP~@yTTa2A@_MYf?Np( zmoD_QV_y`#t<>PW3uW?3^xVqtiwVx-MUv zjnkxAG})c>8s9gjC#IXCR%`Je(s;dTB+OpZH9PQE*=Wiw>POz*-q;EgpaEqF`wMg- zG=m`}2Nc<7LHvzeauXgZ>3g)lmZAN+-(-%>$*oT1RP{Vu&L@DJt?0XSI`15hr=42b z>{RG_wY;t)e~#=aFHNE(4;dt;?R}OQyBdv`!I`=#Xdcbzg$|U`?+YoIUI}_5Vz^Jg@|e9+?`3WGeMJuHI|JXo3Z-NaiHt>xQ$~v7ITknUui=hhCu9!9!|$ zT$jmpIbZ%z0g#87k@DwMU#cP8nmm=PrrPqtJN8gLQfXng=nibL5V}kz+0HPM$9#j; z-<2RjKDXs_;u(1a;>er{g-?eaOK8N3tU1_YKykzQ+2fi)8?xb-2xdYa8pJr5MdQZJ zOQ=Lgza+BtV4EB+IH^;c>sRael(`<#n3u+}{tlSXzM<>(ad0t|_XT*t%3F%5ux_`< z-b^^k*6eaMy4#?iBYLlL|4C6!aWek|AB#l@;tie`1_3>dh{I!B3>9Z*nO!l9;k=K_ zY|avb*xpG^u~uI-SR_5)Yhq+F;M`ouB1eYo5%Z(mOfbWa5N%tivG&*BEetCb9hD_W zix|eBUP4udcU)?85w^^{tRmVQXHDIFn>c@|r2m8u#ib3xN?XY(THR3b(Iox~RulLz z!JI({PUR&+AtO@M9Hm7O2Xzji4(=nZ1tI;qAKo}lqq6(1fB&>2P%6)Ur_%{Kt^`Ls zl?NJ}KiGZscxum6pZR{ACC@GAbt(1SN77N5$*$by7?1eG4%vg>*=aS*uFo{H$7B;k ze#K5YSMfWYCUUq@K z8d{Afpv$Ao>bo5h%8`;ehq8gGGl_WSZ#-&H)gXFfbUb4;Qyh88E2{DZnb(M|^h9Ta zDDh-x!?&qa6^g3i%up>>{upFFpK@ysCvIp^ zUqRv0&QY4o9kdUK^7ApoK`x~oC8no@{>LDA*k#Ig0r#O@DBJ$0#^D7C&&|HM=Wm;! zudnk0Lciyax?YX9Ys@h-z?YI2IzcIlCdabALB^?hxo^+AmAJ}TfAtQf&NtwhJ~6id zM<@rzQ={W4X=(IbjdN@$h ze3M_-3DyxiCt4C%S1^}nDqMRna0(Z}3!8+~?P4BLrSnXzH4ufWeRQIk@nI({FqO+?MVfOWkss#(Fvcz3Wy^Wa{0(e#n+N`AQy zw3@>fnQ%~B@|-1Bj4;ob#Ej-AVyjh+Q5go5rC9PnrMM0>HX|pLb!EY>zV{qh_WA`xk&nlP&2&zyfYVJe9ff=Wf zcqfWZ99BS?w1@J*+%gO;hLeqxK9GPONbxr?xRViGe?Sni0aeL-ex>0Ac`Rg-c;aiF z&_TbneX>xjKnV!O54pV4j8Qu*hz5Zv(2#d>@{?tzU0iHtmN~)Q>qgoeUD+nPSsV6A z7uO_DrN2Re6$j?Nz4Cvw2x=jidH zVdi4fl4m9H%>A2e&;b#5tiz=}TEd*Hz%>{#CZ%J)-gN-^fukEgu0d87uK8OUonIR> zL~eI$>O@i}r(PflT*{+DPhSx(R|}tD!w^d;*KD!uJVzx*4AisMi>a zfkVrY?}M03=nT_oH2 z#ydPz=vS@+6D$*?A>!2Oxe0)HA00&`gr4z0$C0)ON+@B2=AleRYVEZ^EQ~~~fo#BMnX$&! zVSd!zwbn2TWIS+$epN9_^-{ukyh+w+rTr#1eIU63zS;YWpbE*w5sfY)9OSU+OGO=6qYZMmU>-QXcM=St)#J4<&E zERfy3&0{Gm!%9RMOAtcBrIlt6u4dE-eg8c!5z%Q0M>qD(fR(-CvE0%`0gJf8Ic>g!gv#4Q4~CmNzt*IxirOICwzDNum!gi1%OP1uw4ft_!7G%S{T?_C`!YRxU zLAsytM-%}??jp57N}sYd1lB{I^KTx-MnO-t64NxIv1UjC*RW zbDLMveqMcHd!>|QPFGvi`}4eWFn(*h1JTbahZ2LKG_^oBs4tDi`fXD{x7>0L}@{fzJtH z=2H?y#Z2&UinY_QXXFd>=sEjM@Ey$y=Zm})%;Ku?E9@-J ziXS5u2SFEXnQNv$fEUjUijL@luTn+g_VzClLUA`k)B>?UZeq01F0~fU><4pLV7#&5 z*p;yfQemIaQO3@|Jc9|g=LyLwij=tLoE12KC$jc!BEmrv27ytd5Pa&?*t?OCD!=su809POGS*Q==9%ee~z26nXrcfUk zDw`$#bU-w|j#OdjjTpnp*W1p$ND~5yhAslW(R3G+BVbxsHU#9Zw!yR|gWH4#4RYX~ z3c9$@ou^*iMCfHI?1B)pcYi(uw$eaj4>T0hg<&cV?wKiSSy{{bga<0{D^u+4v9GUnDX5}< zNqF!)0K7E=Lq!Ql5)CDeKm?InJCtT-p5=*ArzU0^2br-_e3yZx#$p3AWjZKIDng19 zlVT!{AuoIQ2DS8-+RSx^uDHDRB zBc&Pvxg~9hit)SA&&n~23{J5Tfa-viV@c^wX8@>^OM{UzN__x_Efqp#qZj+cUJLr$ zgnRQmGA*Kk@{8{on-p_oIE{ETAh&%APf+RH6Q5Oy(j|{emVxLlLjWUfT+af2U8Oh| zh!9MW42bsQ5#SHYvIZZKhGkNKS8#|n&<0cY?-1Z7VmH5_z}@{Ceg&KKMO9ldRXRnk zPBFUV{g7p~d`dL4j6@1@VB$r^XPt;LTUV_swp^gkN1ZX3*Vl|d4{ zbCH}&;LYm0YqmLw1E6(oKQ`~{ea0K46thL6qG^-%F1?V~z-i8%2<(^mzWf^g5nWIN zEskQ>m%uK!lc`m8=N(I?7J+7DUzJTgBq_;V(q6=^6Ym|%xfAXrH!wUed5dstv4%wv zuVt0c<$1WPm;*5!(rGl4@3t;DE0{mK+cOgy^@g&3v*RZ)J<;R83l+>0wy9{fDLpl} zuq|%tVne7d9~ZrLpT_rIH`aD2KN@!n)s`2Sm#OsYI=Y%Zh^ms!MJ%|@92GT_n>c7u z6%=d**&(LYW{9;q?&_3!b!RTC$nRg+{3m~=bjlex>u;){5aNFe!~F}J#>?t9c3UC{ zc$;oLX=Icn2#6IaG?8jIi3;5O~`JF0(+RWvEFO9iEbDrQ!*#4H$<3`hQk%gRw_@Yoh&gjmFX zXpnJb$>5v*_;RL=H7VquY-FjbR2%$2uG|1dSy-9`RK~9apWqrlz~95v(y62@6+Cy8 zWfb;n67B(O8KB&@I&x1U0>aR$kBiVYxYB0OBQpJ!1f!4{0Q>fvwCRsk~Py zyHl-cwPU%@TQ4!VNqZ@i(gy__z_5NANNltbja#`zxCU07+o4$tnKXfS>|XCZyGc!D z-=}G>L?*A)wrGuF`7NrfA!U97898W|YrYXJhOh@CSTAs`Gt(2Ip5oCx^*K_Jkp;>& z&e`iCh5zYvl3ct?#n@f1Q|D0Yfuu+ySkIDUS0{{!V#Nw6{u*rC#3Ut(mo)KK5|JHj zp++<+zw?z*;Xi9?s6+@sD%ztPMeo%!@7S*1le!jDn066nksD5#Xx7orT7aF*w%?}O z0OJ@b+ofzT^|<*rQguYl@qW_qDE4O^xq^k4F3;#zug&spn;~-0mqs02j?r+Lh&@gT zapw1|7f|DDfvL6()uX$ek{}u8OtO^)nut^7*y-lET>^eq!wsXwTNBAi=}Nv|H`JLo zVM)&4Q?fk3~G&iF-EP>8WoH zfwv$}QKRqOkSjy$F};JH`$T|ct$$THlVRUP*3diQPpAV4+W-wt1+(jIoyaIVnVhr~ zUXoLV>5Af{dZG`1@TAG^>g^MJtV>k@oOEXJ-DCe(uiy)`;L8YN*-l#4WjCsy@ieo8 zj_4X+ugaPpJ+zDUB2DIC+U}{+IrG6Y_rBOBWR5=sle{6$a>gjLkH*w-$rqt*wK~$| zlk~77qW+I1)}&q-+}v;k_f*2!ZITFb6#f%ZJ@m2sgs3^?j(>iD-8Xghse@+f7WurY5}Yc@l{G5C3OA{%8Gka#TurzYB42NCHywJ| z1nBNYvocOI?jA7rD-rJF+gd+wJxDLaETmbILMqiu)L1QCR3pB~7i@ffzCNC{tV+}k zJ3Ttsr7l8W0IagAr2LyH-y*c#VBy{2={LUg6t7>HVZjZneIrZVw!K?|Z8$jC5xt6R zTRag!&ysa0DFd_%j@Zd6osA^AQzXaXEd-_2T#nR}8&~jBN|TRF1~cAQ*$CjVw+>L5 zL%m(}1|*SMdPe~^CsF(5Ipj$X_h8t4&+}C`VHUyXz}AC7dy#Y&^!*8=`g3-j^Z`i= zR3r>3WnolIrMSL@uqH{ul9zUV6C?76O`9o1b8B<5Le3yyf;o|8tE$eLj6MP~|K9xa za4y0GhHYJTOprL)A}Mk&>k--uIegKSll+q;3YD(j=ZioFCJW|nU4CWh`0N1qafh2Nnw~e{_tm-G|T! zyIXacY>OtyyNocNEhcN6CB?$}-P`+sWh>fSV!clk zBt4qdh?-MyO=`2RJwi9qsuiPsH7;S~l_WD-f3%~}(=Z#MpSceze>J*!jI>#h?Z2hV z>^KatD{)NBw0QB~3*}AN2wMGd+xJ z)NJB5MG$gb^m4px>e^eI396Jtot5ZmQ6RN~DZ~-$3hq$>5fhKsva*$X$2%>&Sl)!* zG5Kz@UfI15!TYAHvyYbINOip@vW;D(C8il!APx|ELkx3NQHk4pv(suoE^E*a{{5p`X`1lPsNb&!>ic|2l6Ed(w}0Wp zWlqxp@N5q9tc*i4Km%bWk~RVrr+Tlof`MfPDVtM23Mv$BzgR5Eu{Z=Kl1xTxFV79@ z7+t%-^3ap?P6M6x5_SLGwsPZVBZI(G5sxOsT22E~It+=+HDpL-5b5b)bQg@8%{0J^ z9L>vRH5aK=^2HM05$gq+wLln?xu?#A*MUNnHupz>vmD+5L#B}951df+io*eThNs8r z&h}y4wFrdgR!Whg8!yc^(dhUd2mdLBm%BqTZ=LK$<)1cMpa%Oeww^Nf)p1;Z#_tAY zc(B6ndwv4HP(8aWSRNWa#VVM!bq~0Z>sE4fIq{ z>|q)Q%H1t&7M&df5sDdh$w@loq8OGo2kR&wL4cn>(;=VP?bMu$4}R)0O@l zau#w4`9@p7ChRM?PL?x>vY7gjP@_OqC=)+M{ncPiT!b;lkkE_n(52tbzuN{bzDn3_U7(AG8xXW*NPTBVrlA82SMf zu!n4r^h35qYlKl((2Q0E7(45McP*@#fc%VZ;bgpUWMQlaeLDNz@;NMvGYnF~&1#@kw&5uTcs930UK{Al25?t2RsFDH%Bre|RD z&v%moCn8>Lilx#-Dfi-yO)bTAZ|8bc6_XRvZLcE9UYsW|FFaF)r@y+wUNQ7#gvsEe z#kcrb*I5#>CV&F>*=RDc!rg{Vr~I*3xC@DDBYCrLBCKBR#Z(My02LUSF&zTJbl#VN zakOR*PA3?sZaW1y-(|SWt`!VjolkHS$+=6H=kEb74JKD2`$S3DkNG_A0F$>1CTtgk z?dvw!IxX&bkNDWZFOxUZxinuM6>-ezqqC5S0+V3>rrxi#Mx;*Mr8t>jy(I`gDveS{ zt957Rkn`Q5_fNdZvWh8Pd88YdWSsKqc-Xm1w_moVxwxrTMI@~oM9&*P$P^v15TR_p z7!J}VB}R9tJB#by@?Xx4?DpvDH{TA$Da~Fo(A%b1ghK{X?Hv9&QJJ0{eHD$$Y{#)z zv%0tcIyh{U&KP+^L>EamuF~&sPM|uTO&=+0twmvUh}Ttui7V>mWGe(yqeb~1xeL2s)&MosQ#om+Y;LSjNmwJEiC4<^ zjD*W7Pln2p&n(f%0(R9<>yT(ziv3kDXM~GLON}ZP9>BshG}m4j4h;nx!+N zJMjc_WQ6NHHAkV8l=jgf*W(gd(2yKUgWZ%YMZ^8h3xQ!DGjR$3RT`L^q`yyN%qWUrdpu1cPr8vd5+kNcnNKeu7b*YEHAhsYnw(B2-;R#J6_ z)n2O3pp{oPy-^xG zGLs9mZr=CGqnI0|z64#LIUgpKWE-13z!lpcmy%Cu5e!R@@Jj=&##CmKM4_g{vfQ6? zQ^ctPj{cEo(|~(G4L&Jje1xkamHmJBI)j;)5fXstp)J;{_ zujFleE6Y?dld8Q5l*y*H=8Ql5`6=ht!k_HO1>b!@MXJn{ZFazJUec=lM2 zTf^+$7R#%l@_>$R-AoOd%u3x~ne_DUr9+r>^7w8ATHg)#mZBJsW7rtpzQ2kc?V6bQ z5u4d4>Y$^!O0~bSB{cbu9@yh;Eq{}BIvz_2q#-Co1F?omDsoY`WR!|QNjyfn%A=*( zSg!~5DV>?!SA?gAtWz{M3mOSfV~K&nfSGU*4s#RchsdFtARRLScwyp_Qkgjp2>}m^ zo*7gRotC}cKXkh-eulki*@_CU`+z)AJ2t*0+x58U*WT2{bk34h-rU@yzYw>=$pj#` z#4e(b9XOuI6eV(QS2kxWGM$%N8<(;YlL!7TQsmsb%E$Z-J<>&X;5PBv5RTkpgS=4g z$6#)nzn>rjt4xNt*D@5ZICLk&mBW`3LoftDJsM(^4#W1huP6<)_gHD03+JW8n?5o( z9YLDoi`7*`BkZv-ZUr!D=2k+ECRt}Yh3yS3Z_dinrJRckBu8jHfJWliwv*#VvMP4x zZ^SEL_m4PlClDewgu>s?ejV$j7I#Ti2vt#ML$Tm+%8C-&29RB}92|15kOH)t?@t+d2+;vg&?%HFPseFI?`>nyiLy=05=pu8?UX6v{Q# zc?Uzo-tu(otDD!dNJaKUb^bcKq^FS-0mvvaCC z^(8nh-QTIN@p8}^3Dmboz8R-DKT@s7BW(0gGV_--? z`ex%$p6vMHZG6rTz80Sdd<&Jm!s`|^{QL*0&unD|5&b1|g1?6Pze(NE)WOBV(e(e6 zf=RjRiP^R$)&=H0s&bm~vDw9Gs+n18Dv8!6);Z=?X0ZQoiZN%zJM`Dt{a>N^=X!zv z(HUiVRV86j<$vVGCw>wxkO4vTH58Dy_j7$I*s4CajQ1WVc~7AbF2^8RG@SP z%>w_s7$yt~^PBXbtJNOF%MK(kIPMDX$o1ky1okYzY4kW2rWxi&Zgy0wi_rqP*R}IM zdY$!0Ecc%wME-04RLK8Nubu7e^{q`^O|Adww=|`!)I^;8%(%=n^*)s(Egj{_e+upY zmg#>JT2BjmS|>v@(|?m@9+@yPBMIt2?7yG<=k9}lgx%TH$yxvZ?fQnOIC&b{@iF?y zIQ4o}1$nutIx1R;X=(M-|7^!POQB}UUvKSy4e$TYtFdT|G!zgcf(UbDK5*`UEE}_; zJ#n}v5c|Q1Y!W_Wyd>Bn;M0a)9~=bRQc&Q*(_@ph`R1}}(=KZ=GHDyg;9AUDJ#?PJ zFsR_;M<}oEeC6 zvQ+;6(cW1`Wz}tcpYHAs>F$#5?oN^JF6or+knS#NB&16~x+AI^3#M90`a|Lkk6?OO9c=Uf4e$l$)w1i;rPL5>dl!A4S5!Pm^{XPA#Gm}=#4 zF|1G?axcINMg{>0i0rpN&|eSE&e*}k*1`Ig1Tb*UY$X6 z-}S|DKM)9*wSL0Jf_Tkw1W`c^Bm%o@VFHAElkaOStKR@ z)4UiYRaxv4@tZ?V!93Xy3UIe?Y_^l)#5P}Ye?OuEtb4a6|6RrjEBWe|LXtyX#y>g{GVkf>L4bu%sq!G=3iTQjXubpiX0 zXnC+G8lf=sBC`n5m}C23nwBqb_(1imzAzjsKIM;M+TN*2f77pMxJEBtU(jY+WucnE zs04S<$_pF}ayyzwwbl?$8k!Y?WyVPbQDy@wa4$(OaCOpYw60#rGzb5v;tX_g-CxH1 z#u!k_1vjV~aaXh6rkGamsusFHRLn-h^|k*C!KMBfH16l&DD3(=MUUzF7@D+R=sI@T zMZ_P&rr4G?gIXoP_{E}@xFXgAik8+qK^2x9m_j|Gttn;eL?H(y`&^}w3y$d}jW;vi z?^2ir#KaUuvoCuoNa&4@;(K*x#IIhBZCv$`C zOuLRz=v#x_Ku*m$-`#QW2-)J{JxTJA0#0MMR%uu`L!bmRF#ueq!oD-QB%|mFhT}UmPYeA=! z!@Kk011e{`C}R7GWniA7LeI=48(HI)Q$7B^t`uuhoId)HGyg-*I9Y1a>1olFi*2X*hI^#d4IfwP-TFqqau>fFXCD zMq}somISDA9@ZUHM`7usO%bLb+mhP13+rAk=-WftG<$DP-uf#lNS=Xa^~B8mtbj9S z@`+Tw$dKZ1pM?3uu|(f_emS%Z#FPtIXUbciT>>Qq7q2~=?z#>9c{Ae2MC}=ER|?x% zWI!m~>agvuImTVl#@B2;yi-6gw1d}8k9MU(GMYS7!0VnPNa6b~_2fyh@I&|!wgD^x z3g9=M1H5qZ|MdNB*qf+riz|xOKU&Tp=~-f!hN0@^3rPT{H0vTGi$g3jEv2LKqE0c$ z2%66Fs0Vx2V`s#wD(wfAL=n zHQ1q1GR4G5!@jk)Q4vtnoap`1G zc2x?71*)zqt`Y?`T35wTZ7}n91o9P=8B4`I)LJYk^9bE3|6u{$J3PnJr0!q0dUQ>w1dwFVD+JxYp zAvb&wdI9%?1awU2FApTV+JU{}xkpQn@yQR0zazYKHXC~-5nobi;N=g3SGQ=I(W~j2 zlg2r5XEb{FrP0Hsagq1if$Igg^&J5?9=MAWo`>V&J3%9l>Y6OG6wfq~qQQ5epYlEj z$Q2dg)bVDlMsBJTlGm>gVtz z*Q{K--jhhBEAO9(fh>zZsy7=$tCFy5VoeBVgnyeXDTR0$okw~cAslRnlU2Z+azJCs{eYB#Q6Fb>}7riKE zv3?yG&28XagA5jt0WCfewY^1-FS(u)Nh3eb#F4;{(vS*+Bx^6OBC6;maX4xBE74MNbJn1Uk|YOtBU6kcxN zCxei57<4CR&P{35u;CmuCe9Ih^m=r%*=VUNYU;*W-z7njN}#wEunkxJml)XO7{>U- zjKiH*shHJOdT+@fw`a&{XDqu6J_3c;Ll5<*Ro!Oo?_H;+-}AQ2a?kA@x?Z98&5D&# zP9>c2ww$qZ=7e`w-^Zi!HIMX@6W zcMKqR8FB`d52_rht9UnWVlpfx<8`BoiJh{uFs+HRUgvmt9LB3QxxW@we-g1pZe3R6 zv+TwO{v0o5&%J~z6lL~voPa+!T9#wDOic{syUHOSTyam*1LQMz ze6qgJx0JOWlt(r4rh!cAd2Si$d!tBPSLR4pJ1X8{MLU<(#Zb2fYBrl;YU2x3>y27( z8p%`DE}rJq*t&#?MTJ(Fa{%@y%mBBKK&U2RBxI1zQxzo~DZwU8kRBsR zi#dH-sS``4naIR{oE39%-25h>STx?~G+e7%Wqb95VJU91{~5ob)iocXc+c^Re5l!G ztghOvb&pLuUIEf>i85c46f@)k`^p~+$J$b4s9{PUJZ(4X+aK595ASg3vR-ILz%x$= z1R_cQv*&JDq4e1Xl?jQ!);l#{_8O9cehErw*$B6u65EKdgeJV_N zHz!_617-##=IYS>*or?%Lkh&Yut|hAG+z#MU;wQEn;?wSVtaBH6$6!m<-!?&Mu~!p zpzFf-kT=sIIXl54E!y2;D&!lSQGvJ$>`$Dq6JH4IZzB)3Tk&-oTo?MXOM~i)^NSJ} zRm=!`oP4D_=QC-Y4X&JZ=C0g+QZ5js0DDrtza->l8tTJn6lNw`YpY&*l!?PiFJQ3JZy&AKSibeKEGw5j#+NQI_43bv-U} z6RR6>tB{I5cr9Peiu;XXLIK)xi)66`xV~d-|D~Mp3Y?im%Q;>A&JqaqUNI)v1!)0; zO0mor{pNRYjVDG06_Vmwc`JF?#?(j^u?haZFZ<29v_MibGn;+-ly98Ru49y^ zINX1cxREl|{#lqKC9OzAbe^Yo6Mm+fi0c ziUrN}!o{}UlaG`EMj9$$wm*bA{`cniufKUxHW(TG8K#R7De&k`*pd>1U&9aBwg4!- zR$B9xits{Q_7a7xFJYoc3?t54H~Lzy->2o2V(sF-&SJglh&xZY3d2%}np2cvrUw7| z*6B6yn1{7Re>AcF3U)#9G|eAXtEiYC! zOio1SIaR7LN*P($Jcg|8@~p>do&ENya`6I>rm}~PkW!;Oe;}X+UcR``aeLAk>tS+f z8*egk1AfdNz}LTfsXg{pF_cvpk^{WdbcztOEy#X=R5neKRb-_?agV-{19WNC!j1pd_i0bqqf2MWZ+?`}G7I%9&iuf{nC+rkuz~Z@7PpYi| z#8LDO)y_nAre%FB$aiIH>l^P9>L_$+=FlMBABooQ8@?ubsis!eC1>Fw<;0W6Z(4fppv^sx%@OtG2si-410w>i!ln^0uZbIg(LU93#^BhUI|TC$ny8 zhDB#vN(KAN4<8oquj|>k=aN})15XyGLfMgGN33~r^ne!|Az*<@^lygQKS?CYvf-$L zNFPVvo6QN!>*JZ6Ru4lsK$T%CB6o(rkToqdX_%L}oSQ^tM;6o+1pB@rXoSvF?iSmd zm%TN*FMhG{s;Y&>hMn|-b6Kgn>U%wP+iVTe2-A;J1+y=LH-lnesFDKK^OZIzOCUf6 z*N8zY6*9budguj!PYI05RUGzn_8=Op6{Sbuse;ZG+9}`C7KTB$(YXyW_uE6|BrYJw zAx#N$78)p_cd+bp(uxM!r3Ogu;1P2frz0&n$282jjEU0d>Xv7#h+w210ddeagK-%! zA@!jTB=qSQg)U*53-)`1G##6F-rnH2sfQs;3m9lO`I(3ZQ;74MtniO|A7!EUy0>3(roW=(AAcRq|hu7hX8c4xH@5iN+7h>?XONF?7t z*kFMP8qyat>DJptpeu3ck$*MKj*y{0gcK~Zx#7QEhuN4@qZN$gEn)l&8~a z-8n6A>?jBRNu$}3Dh&&!FsBpNPU=Y-`?q!@8{>&_Ri_w3DGqy)$Fjicusds7Z-%g@1eray}nEq8Z&%ux8-DxASbLb~L$1gJ4{1t1fU!pW zAB;6aRi#BaG(jX@-WJ-beHd8(Y;y8zeQ=AY-5y0=#T{GN!iE)$muX(hB0hl>qLkSXsmCQ z50xNQ1@Ov+9lAInMH&6pZL=YamN9G&y+y}*j#14(Zr%}5Se;+N?#T+-`;1r_sGg3K z+A7D;eJLb1b!&m+3ZLc&SLQUPro&qSsjuR8Vf40!1J2K_3Bj^c9|We^fIp()YF4CXEn9E zwe8OaiL#SxWCJyzx#>>tAW9kC&B!^MH80%fCp8o;hNphsvsADgNO7FG#dSc9SZZV>MU4g+bkIB`njk?=Cb6%{tf|AA6Tz#|eIw8Bt~%e!aW(_ZnlN3U%ep%vDUMc#5-S>Zh8 zfg)@6yT{;PL<+RXSrj)uGURp3Md z2o-=Yl;4pI4ey7CdM$GCQip-SBLwz=dU|yPUIh6O!$>eQgIO{HH<6_ayx?MLFRdeD zV_234&2Iq9r|09Vt|KLBr{vQEHG=S`WQRbJEJ)#^x|XC$=_PY-3jK7|i{AVe!ab=u zd?kx%?90v(ncWU<5X2aPg8rrd1fzA5 z$P@Wc$QCYl$UQLxicRBagCx4=BU@kHl%JB4Q#;mmkZ|FSohOUJmj-Qi>o|l9k3`L~h%eAHM$i7#} z3y!A=z>kquNf0Sg(JComdxB~hWkVdZ6Hf4*1#4xF!5t~NO*hoXlHr&}r{C!(eUL4t zUEZ#ocENT$*`nJOPv4`+ifB^Fr!ZgxV*?o5?EmaY_MYeVqoB5(pnqYz-ij7k%crUfws01xnwx9hl|XtCpmIu05wXfl2I~U zr$nwlo-h$44;gLRyXse6yjP+}Uqt(|=Yt95f}>~EYM&2u;4}>ehRd2Wzs%t)-u|m> z%(CWE2cem_;3BZ(iURYip=UzFt~boKh58MEh=hvz9_DQsWTg=UzOm1f_SMg=p9h!h z$*28ayXU`l&wuTn|JptOwR`?QvwP@Z0!bkNJDeVX-GlS*-q`?)XY?;kXxyI20W;iuvPPdll3%g+2)52P;^t5YUzC%a^9$_n>;1A1F3sD2Ht_w9dg+IFrB0x(=Z8Z)w@0KWkJ= z@wV)~bM&>e{$xVckBQ`sRgq5vbrKlL{RT+=@&z(Ry92Qk%dKelvlwjgeYv&tOSz zi;n?v_&Dd7HBPx@8d=#ukOvo z)F(|^)zgz)sl-?te!uMr7h4E-V?Gr!Pb&Lx|1!x0b}yE7qjPt|gARukoK{JP9)9!1 zU>C7T+(h@?Iww5u`WSI~pJ|GWX)7$9+I2O|bR4+9k%dG)-1f2&wpsYanvhReFQamN zHZNQZ8u$6FhWwEW_r+ZcHM7G+Ql8?Xgf;6sdZAtfk+!<{lqSjku@9p?zMd-MeSI7UblqzYxW-S zz4$$AFlbk@l-`i!25kb}xiW@p@Z0yEpF@(h89?I#94%3i_Sk@{^?-U7z&6%p1@7hh zoV{eFe`YT4;qN%zWru&KsZ&aY!rDs?jo znB>^DVc(A$vT5oJhO%dlFXdZLuSKQ~_q~jo=y|m?b6#YKnY383xiz3OJ2Whr-h3$J zhBBY?BVF651}gM)yZKg%bB)A2I&gN6lkKo8nz)8p;TpPDqosg=3IVe z;@h3Eo<+v;cT6Mn#Z|U}Yg2_4Q_bhzh10$59O$S@1n17}gHA)TKb|f$sKlnKGn-nMn zgYxgsDqd~7k$~glqDy<67R)wk4c!<7(U|E-p{c4M8fFHjQd}^uR`VeS&($c`B2j4dV(Q09Y#Hgx7JEdl5HJ<-_D`R7exiJEZ9hXox~MA{cK`3Y)s z@0?VNCF&{zC;Gy#D5o!PychQl%X$Wi$-1imF3!Rr(Y7nejY6xHMW(X*DZP$gYcGz! z$d_@)@wAJRR{gZ{t}j*24c%5bf=G^uV1n(Mdd_jO6fb2@t?JAgZ1UV*_n8xbftLD& z=9j_x`+WZyO-^~%!ig?Qx-#iy?qJ1@UZl37@AD*lA?F+`Hg-1Cwg}j(n?w97wesos zdh{|5RAi&m0A-nHGzthEQn3NDabyx|(;hUciS9eS4*CPly@d7fiWjr9w2}=6CLFvK z7gc;jjNZ0epWXB<>m$;0ZT9jbaJ_UMrA2n+X5jaES@ho5^CXOT-a=^wfwbc=730=HlGQS{ z_x?n)wz}567&Ub>C_6L9pcVoaJ&^({cykPDh`GQXA~-buRV?0+nJGJgH-ur5op&Wf zn4~;ZYDsI_{>Km%>cy1Q{?fPXDsFa}8JzT#T(CbVwENQDQY{Oxx1dccdv~IEQxCQV+KFgwvF7bnk0wRU)`9yxFxzgyty3Wk?+hBUq0Nltdcs78TZ$ z82ebniAeJ%^ZYeArJ!`+8Q2t2xf=5@Bs`n#^#Vl>w!XF==*PHgSV7XjSaUr1k9f#u zuXyLW`zzC6FC`^biy}|db1z|Nmjf0qLy_Tiw};Y6F(6jOO29sn_66}2b8WIDb-ba6 z@0G6UyrQNc(?kCRbkW1+VR+zkbYJF7nAI|>3w0N~UUkeBf-};9$|G9GWEdum<;9Q1 zZx{#LtMQU+DDU7W#IK>7jjy)}58-dO|2eng_rt;PK=l>i1Q?`tQp-zmd=ws%6AV@V zCdq|F8!cZyBpx6ke5euzMI4U|O%%w*ojEXuj>gsX6X37=bwQYQlKaR-d{-k)XLsIh zIv)uawQbuVZCNznFtvH@p!B-i;?&Wqxj z4bji|Sp!*jm%yGvX~4FDaFX?D2j?9^^lkCmJMrr5q*0O!r8BEBahb4G*6}pXymPL6 zlSKWo24^<0CR8dZEW8=e?@Y)J11S>=%2n15cC`#N3z!eM)fEU;e3~h&MIn<{JYSqW zMST}ykP;_GmznhPvb&gH!F8A`muT&S)F`xZ5RrNBC+*%1ORBAOX7h~xEw{A9(jw}3 z&p{{1dhAKb>DJ=r3w%&vdVMF^HML^oF!Rrj3u#JAB%-O%-|Z>j2EHILunl=wvG17| z*3~d;_7SNH%Z?)zE|P04GEdkyWbCc=ElIlZzgQ)}K8*AB;fE1lo!(*6jF^ou!yX{d zvG;(!$H8J8enksga)t@hN(K%I53Z5ie!_wF0UkW^u)=9Jzlit8n(wC3X9oxH^Iax_ zTfI;vwR!LNn1{px-N=GXD}>;ARj#2v=Ztit@_`f8No;46rGuZz92NV*i~Bwo?Q{0t zP^4nYOua+^#pA0eQbrax66oqM-AtEO#3-L)QX>Tf=yA0+?Nh6N#IfG`@1P2*Mtry0 zzvP>e$t2vm;;qy>_TTH%Z}7BNW5&*^J}tkXkz0Sw2=(Gs4VOCkK?qn|SF(M5gms+S zOF%PmJQ0uARk$K~c8y1)v28)YFK;<;e%4|IlU5mXyS&SwmIUN>3#M3qfX;lmjjdfz zW4*ANBUDSgTaqB8_tUk-I__%HZ76Vmj==>r>w8j4LnoPJ>?yOPp0n&}L(4*$WKH_I zGb>%6Ch<}Yy?JEB5GnTiH253L2~C$(QmRRRvQM_Ovr}P+Fticrymm<%HZ9h+wUMKr zqt2f6jCrVHkE~TgkpavPJHY1YS+w_`BHbXB&*75-XzknYvF5t-k%CF@s+BB0)Z~G&_?dF|E%O#LU9xs@2E*0nX#Mib z&D|Gib_F5`p2+4PnD_N`nMOj?`EDRd=u)xSg5yW9I6ZhuL8Zr_#4frcU z%Z%pQ#xrsD%2LGmQ$sb$kTUkMHleH=u>lR?8s_Si^kEuFqEs|fQ85X*^j*NH>n{RW zyI%GPi&GI=X+S1qs!C?S2n@5#M7(-xQ zj#MNN8#fl1)W0es{^sRLC7LiFP^k0(!g@8y-FITg}KG^&{>Q4E%K8k_x{TT z0vBrk+7rxU8tR3)OWb@(tqu47v%N^4>>v}7+OW7jhVnr@#ong>zR8qWi>yCd~|&A5l+{ zm=0ZjB+VwgkfW`|02#yu$iP(Ud$$YBZ2fZQ7Tt)^BLN2gjcPuJ7R}oGXGsXK#pBf% zfYBEX7=6zI>;H^CLsjL!k}~i6EL%bi`$LsEpfOK6!WE~TQyT*Lif<{1C6BU_)Z@VH)S1pvf$oM?|GiA{+NbSmrrZA z{ZY$LEpS#A12SH)Bv2Z|hQt;F9s*({D>IfpPBD3y))<`* zrO412-V|_s4wnfwrj8{zn(y2Pkk6V1DvFrf?E&s%_>w$sXSlhlwBEqZ_DjKf$b0cc zxfPvucl1t(9`5MPql-A_FKt1;!GEz4Myz&?uZn^tF!Mc&76iq!4RJp<3CY45vKA2@ zL%K$2$l~F>Lk*6zhjd4Emma%DamT&>D1E@VA{6g7fl&HBA&fo8EdHRW%Mv82F?$8G zeD~ZGZ!2?zP>hhVeaqHcFG7p9*;y|)my?*fBz0^_L!E93MjLT=r_L=MXD~zirv2Vp z6+KaYnPF&Z7{xT~);^XnrKyqcy>h?Wo(&9rt#cCE(Qe#nlePg}RBg|O{k{iR4SnUH zrbXce2{c_z6(@DPXfYK{S3c`1jr8{_t!+jn`Pz(!uGRNz~_|l(yENv$BA2L1-cw`>6AGZ{oUB7&917+Nd zF?RHY{A!83$#qLo>`?53)aA`3_!}Na2ap?_E)tT2=mz^BsfA{GSgqnn)6B)tTWD0W zaMnzTkD<|rZZmNUAL*#K4&p?1K1(geyEpD#>S7BygfL zNWMLYCVZ>GgtT$4}bRoj<`M}b+(@oy%WK5rW~F}d7kd7vi2 zBAyJDk2y=df_tU9gcI$u-aZlMd0<5gdN5AY;_LC`?| zeBvr#>-5)^@AvTAp9*-MQXZVF=ck|kiva|b@7MfqD27ilzdPac5rYqy&A*8G=e*CS zj0Y*t50HFhfB@bGzi0d+;Gqv|1mG03weID+au!y(Awqqj9-NO?r^F{ zh!da&`WMKP?6K!ko;Rz1q?7{o%73E#BIb9E;2trFRL?Pwt+$?wdETP ze%B}G5d+HfzcK&nn)6)B^JXHCj2EnbV*DcHVZc4Dm3yds`}@lGTjhFEg7>=u_vd<^ z*S9~S2wy%y{ax+;{PyRSl#jQc^FO)$Xf4kCll}Q4b&P^8&<2B}hX5 z7t}8U<+%a;Q2Y1y1sEv5W&I`eS8MpWyyxX8kH{Q}-^u$8@)w!Uqm~aDoPS^Weg`st zWIl~&J{S2s-}(_~EcYJ)f06jReA-9itiqp(k71hU3ZEyfKJvO0{}bLX0)Ll@`3U4w z{xk6Jyv*nFp6A*<(n?kT@3ddUJ)a)G&aNqqf8l;fPkOHAc^1;68UoGV-2Tfy|GPw> z$NLxmx&Nt zzrp+>=lPs_a0>pu^8H3ke&PJPdGe}(*M-aOw1J`%(oeop|100%7afPg3gzX)Lg@eAjNKm8xtwFImH diff --git a/dist/dubbo_client-1.0.0b5-py2.7.egg b/dist/dubbo_client-1.0.0b5-py2.7.egg deleted file mode 100644 index de72a930dedc03d35797e920d1f6e213f676ee5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32954 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