环境
python 3.x
核心脚本
# DubboRequest.py
# -*- coding: utf-8 -*-
# @Time : 2021/06/02 10:11
# @Author : 软件测试技术
from Setting import config
import re
from loguru import logger
from functools import lru_cache
from kazoo.client import KazooClient
from urllib.parse import unquote
import telnetlib
import json
import urllib
import random
import sys
import os
from functools import reduce
sys.path.append(
reduce(lambda x, _: os.path.dirname(x), list(range(1, 4)), __file__))
@lru_cache(maxsize=10)
class Dubbo(telnetlib.Telnet):
prompt = 'dubbo>'
coding = 'utf-8'
def __init__(self, host=None, port=0, timeout=10):
super().__init__(host, port, timeout)
self.write(b'\n')
def command(self, flag, str_=""):
data = self.read_until(flag.encode())
self.write(str_.encode() + b"\n")
return data
def invoke(self, service_name, method_name, arg):
arg_str = None
if isinstance(arg, (dict, list)):
arg_str = json.dumps(arg)
if isinstance(arg, tuple):
arg_str = str(arg).replace("(", "").replace(")", "")
command_str = "invoke {0}.{1}({2})".format(service_name, method_name,
arg_str)
self.command(Dubbo.prompt, command_str)
data = self.command(Dubbo.prompt, "")
data = data.decode("utf-8", errors='ignore').split('\n')
return data
@logger.catch
def queryDTO(self, service_name, method_name):
command_str = f"ls -l {service_name}"
self.command(Dubbo.prompt, command_str)
data = self.command(Dubbo.prompt, "")
data = data.decode("utf-8", errors='ignore').split('\n')
print('Dto', data)
for i in data:
if method_name in i:
p = re.compile(r'[(](.*?)[)]', re.S) # 最小匹配
dto = re.findall(p, i)
if len(dto) == 1:
return dto[0]
else:
logger.info(
f"error>>>{service_name}.{method_name}`s dto not find!")
class DubboUtils(object):
def __init__(self, zk_service, interface):
self.zk_service = zk_service
self.interface = interface
@lru_cache(maxsize=10)
def _get_dubbo(self, server_name):
"""
获取单个dubbo服务的,这里可能要根据,
:param server_name:服务名
:return:{"service": service, "paths": paths, "method": method}
"""
zk = KazooClient(hosts="{}".format(self.zk_service))
zk.start()
urls = []
service_list = zk.get_children("dubbo")
for i in service_list:
if server_name in i:
try:
# 获取服务发布方
providers = zk.get_children(
"/dubbo/{}/providers".format(i))
if providers:
for provider in providers:
url = urllib.parse.unquote(provider)
if url.startswith('dubbo:'):
urls.append(url.split('dubbo://')[1])
except Exception as e:
logger.error(e)
paths = []
for i in urls:
try:
path, temp = i.split('/', 1)
service = temp.split('?')[0]
method = temp.split('methods=')[1].split('&')[0].split(',')
paths.append(path)
except Exception as e:
logger.error(e)
return None
services = {"service": service, "paths": paths, "method": method}
return services
@logger.catch
def requests_dubbo(self, method, param):
"""
请求dubbo接口
:param method: dubbo接口的方法
:param param: 请求参数
:return:
"""
res = self._get_dubbo(self.interface)
if res == None:
return {"result": "fail", "data": "该service查询不到对应的信息"}
else:
methods = res.get("method")
if method not in methods:
raise NameError(f"{method} not in {methods}")
paths = res.get("paths")
if len(paths) > 1:
paths = paths[random.randint(0, len(paths) - 1)]
# paths = paths[-1]
else:
paths = paths[0]
ip, port = paths.split(":")
con = Dubbo(ip, port)
# param['class'] = con.queryDTO(self.interface,method)
logger.info(
f"StratRun >>> ADDRESS:{ip} - PORT:{port} - SERVICE:{self.interface} -METHOD:{method}, PARAMS:\n {json.dumps(param, ensure_ascii=False)} "
)
result = con.invoke(service_name=self.interface,
method_name=method,
arg=param)
logger.info(f"RESULT>>> {','.join(result)}")
try:
return {"result": "success", "data": json.loads(result[0])}
except Exception as e:
return {"result": e, "data": result}
class DubboRun:
def __init__(self):
self.zkAddress = "你们的zk地址"
def run(self, service, dubboApi, dto, params):
"""
service-> 服务
dubboApi->方法
dto-> 入参类型 (不写这个参数 可能导致找不到该method的错误)
params-> 入参
"""
params["class"] = dto
myDubbo = DubboUtils(self.zkAddress, service)
res = myDubbo.requests_dubbo(dubboApi, params)
return res
if __name__ == '__main__':
x = DubboRun()
service = "com.xxx.xxxx.product.xxxxx.xxx.xxxxxxxxxxxxxxxxx"
dto = "com.xxxx.xxxx.xxxx.xx.xxx.xxxxxxxx"
dubboApi = "xxxxxxx"
params = {"test": True, "logId": "test202020"}
x.run(service=service,dubboApi=dubboApi,dto=dto,params=params)
执行结果
2021-07-27 14:53:23.735 | INFO | dubbo_req:requests_dubbo:133 - StratRun >>> ADDRESS:172.1xx.1xx.8x - PORT:20880 - SERVICE:com.xxxxxxxx.xxxxx.xxxx.xxx.xx.xxxxxxxx-METHOD:querySignListByPage, PARAMS:
{"applyType": "ORG", "traceLogId": "apiTest2012070201"}
2021-07-27 14:53:24.213 | INFO | dubbo_req:requests_dubbo:137 - RESULT>>> {"result":{"currentPage":1,"dataList":[{"applyChannel":"","applyCode":"ssfdfdsfsdafasfdsdfasdfsdaffasdgf","beginDate":"2017-10-27 09:56:36","contractEntity":"","createdAt":"2017-10-27 09:56:36","endDate":"2020-08-01 00:00:00","id":"3631"}],"pageSize":1,"totalRows":1},"success":true}
,elapsed: 406 ms.
,dubbo>
—over—