def get_app_token(): """ get app token configmap: SC_MANAGE_SVC SC_MANAGE_API """ app_token_key = get_hash_key(key_type="app") service_conf = get_settings_value("SERVICE_CONF") sc_manage_svc = get_cm_value("SC_MANAGE_SVC") sc_manage_api = get_cm_value("SC_MANAGE_API") try: cache_app_token = cache.get(app_token_key) if cache_app_token: return cache_app_token["app_token"]["token"] else: data = { "name": service_conf["NAME"], "secret": service_conf["SECRET"] } app_token = rest_client.post(service_address=sc_manage_svc, api_path=sc_manage_api, json=data) cache.set(app_token_key, {'app_token': app_token}, timeout=app_token["expires_in"] - 120) logger.info("sparrowcloud get app token: {}".format( app_token["token"])) return app_token["token"] except Exception as ex: raise Exception( 'sparrowcloud/get_app_token error, no token available in cache and app_manage_error, ' 'message:{}'.format(ex.__str__()))
def send_task_v3(message_code, *args, **kwargs): """ 发送实时任务 参数: message_code 消息代码 *args **kwargs configmap : SC_TASK_PROXY: xxxxx-svc:8000 SC_TASK_PROXY_API: "/api/xxxxxxxxxx/producer/send/" """ sc_task_proxy = get_cm_value("SC_TASK_PROXY") sc_task_proxy_api = get_cm_value("SC_TASK_PROXY_API") task_sender = TaskSender(sc_message_sender_svc=sc_task_proxy, sc_message_sender_api=sc_task_proxy_api) error_message = None try: task_result = task_sender.send_task(exchange=None, routing_key=None, message_code=message_code, delay=False, *args, **kwargs) return task_result except Exception as ex: error_message = ex.__str__() raise Exception("消息发送失败,失败原因{}, 消息内容message_code={},消息参数{}{}".format( error_message, message_code, args, kwargs))
def send_task_v2(message_code, retry_times=3, *args, **kwargs): """ 发送实时任务 参数: message_code 消息代码 *args **kwargs configmap : SC_TASK_PROXY: xxxxx-svc:8000 SC_TASK_PROXY_API: "/api/xxxxxxxxxx/producer/send/" """ sc_task_proxy = get_cm_value("SC_TASK_PROXY") sc_task_proxy_api = get_cm_value("SC_TASK_PROXY_API") task_sender = TaskSender(sc_message_sender_svc=sc_task_proxy, sc_message_sender_api=sc_task_proxy_api) # 发送任务出现异常时的初始重试时间间隔 interval_time = 1 error_message = None for _ in range(retry_times): try: task_result = task_sender.send_task(exchange=None, routing_key=None, message_code=message_code, delay=False, *args, **kwargs) return task_result except Exception as ex: time.sleep(interval_time) error_message = ex.__str__() raise Exception("消息发送失败,失败原因{},重试次数{},消息内容message_code={},消息参数{}{}".format( error_message, retry_times, message_code, args, kwargs))
def register(schema): ''' configmap : SC_SCHEMA_SVC SC_SCHEMA_API ''' sc_schema_svc = get_cm_value("SC_SCHEMA_SVC") sc_schema_api = get_cm_value("SC_SCHEMA_API") try: r = rest_client.post(sc_schema_svc, sc_schema_api, json=schema) print("schema 注册成功 resp body={}".format(r)) except HTTPException as ex: print("schema 注册失败. message={} ".format(ex.detail))
def send_message(msg_data, code_type, content_type="text", msg_sender=None, *args, **kwargs): """ # ConfigMap: SC_LY_MESSAGE SC_LY_MESSAGE_API """ if msg_sender is None: msg_sender = get_service_name() sc_ly_message = get_cm_value("SC_LY_MESSAGE") sc_ly_message_api = get_cm_value("SC_LY_MESSAGE_API") data = { "shop_id": kwargs.pop("shop_id", None), "msg_sender": msg_sender, "code_type": code_type, "user_id_list": kwargs.pop("user_id_list", []), # msg数据格式是动态变化,由发送者根据服务要求填充发送该类型数据的必要数据 # "msg": { # "content_type": content_type, # "data": msg_data # } } # 把kwargs里面剩余的有关数据放入msg中,发送的数据由服务发送者决定,此处不做校验 msg = {"content_type": content_type, "data": msg_data} if kwargs.get("nickname"): msg.update({"nickname": kwargs.pop("nickname")}) if kwargs.get("title"): msg.update({"title": kwargs.pop("title")}) data.update({"msg": msg}) try: res = rest_client.post(sc_ly_message, sc_ly_message_api, json=data, *args, **kwargs) logging.info( "sparrow_cloud ly_message send_message, data:{}, code_type:{}". format(data, code_type)) return res except HTTPException as ex: logging.error( "sparrow_cloud ly_message send_message error: {}".format(ex)) raise HTTPException(ex)
def get_user_token(user_id): """ get user token :param user_id: configmap: SC_MANAGE_SVC SC_MANAGE_API """ user_token_key = get_hash_key(key_type="user", user_id=user_id) service_conf = get_settings_value("SERVICE_CONF") sc_manage_svc = get_cm_value("SC_MANAGE_SVC") sc_manage_api = get_cm_value("SC_MANAGE_API") try: if os.environ.get("SC_SKIP_TOKEN_CACHE", "").title() != "True": cache_user_token = cache.get(user_token_key) if cache_user_token: return cache_user_token # 跳过缓存或者缓存数据空 data = { "name": service_conf["NAME"], "secret": service_conf["SECRET"], "uid": user_id } res = requests_client.post(service_address=sc_manage_svc, api_path=sc_manage_api, json=data) if res.status_code < 200 or res.status_code >= 300: raise Exception( f"请求app_manage服务出错,状态码:{res.status_code},数据:{res.text}") cache.set(user_token_key, res.text, timeout=res.json().get("expires_in", 7200)) return res.text except Exception as ex: logger.error( f"sparrowcloud/get_user_token error, no token available in cache and app_manage_error,\ 'message:{ex.__str__()}, return static token") return json.dumps({ "iss": "sparrow_cloud", "uid": user_id, "type": "user" })
def send_log(data): """ :param data: dict :return:True, False """ if not isinstance(data, dict): raise TypeError("参数类型错误:except=%s, get=%s" % ("dict", type(data))) data["service_name"] = get_service_name() service_log_svc = get_cm_value("SC_SERVICE_LOG_SVC") service_log_api = get_cm_value("SC_SERVICE_LOG_API") try: response = post(service_log_svc, service_log_api, data=data) logging.info( "sparrow_cloud: service log sent successfully, message:{}".format( response)) return True except HTTPException as ex: logging.error( "sparrow_cloud: Service log sending failed, message:{}".format( ex.__str__())) return False
def access_verify(user_id, app_name, resource_code): """ access control verify """ if all([user_id, app_name, resource_code]): sc_access_control_svc = get_cm_value("SC_ACCESS_CONTROL_SVC") sc_access_control_api = get_cm_value("SC_ACCESS_CONTROL_API") params = { "user_id": user_id, "app_name": app_name, "resource_code": resource_code } try: response = rest_client.get(sc_access_control_svc, api_path=sc_access_control_api, params=params) if response['has_perm']: return True except HTTPException as ex: if ex.status_code == 400 or ex.status_code == 403: logger.info("sparrow_cloud log : access verify failed. user:{}, message:{}".format(user_id, ex.detail)) return False return True return False
def send_message(msg, code_list, channel="dingtalk", message_type="text", *args, **kwargs): """ 群发消息机器人 client configmap: SC_MESSAGE_ROBOT SC_MESSAGE_ROBOT_API """ if not isinstance(msg, str) and not isinstance(code_list, list): raise TypeError( "参数类型错误:msg type not string or code_list type not list") sc_message_robot = get_cm_value("SC_MESSAGE_ROBOT") sc_message_robot_api = get_cm_value("SC_MESSAGE_ROBOT_API") data = { "msg": msg, "group_code_list": code_list, "channel": channel, "message_type": message_type } try: res = rest_client.post(sc_message_robot, sc_message_robot_api, data=data, *args, **kwargs) logging.info( "sparrow_cloud ding_talk send_message: msg:{}, group_code_list:{}". format(msg, code_list)) return res except HTTPException as ex: logging.error( "sparrow_cloud ding_talk send_message error: {}".format(ex)) raise HTTPException(ex)
def send_task(exchange, routing_key, message_code, retry_times=3, *args, **kwargs): """ 发送实时任务 参数: exchange/routing_key/message_code, 创建消息服务时返回的配置信息 *args **kwargs configmap : SC_MESSAGE_SENDER_SVC: "xxxxxxx-svc:8000" SC_MESSAGE_SENDER_API: "/api/sparrow_task/producer/send/" """ sc_message_sender_svc = get_cm_value("SC_MESSAGE_SENDER_SVC") sc_message_sender_api = get_cm_value("SC_MESSAGE_SENDER_API") task_sender = TaskSender(sc_message_sender_svc=sc_message_sender_svc, sc_message_sender_api=sc_message_sender_api) # 发送任务出现异常时的初始重试时间间隔 interval_time = 1 error_message = None for _ in range(retry_times): try: task_result = task_sender.send_task(exchange=exchange, routing_key=routing_key, message_code=message_code, *args, **kwargs) return task_result except Exception as ex: time.sleep(interval_time) error_message = ex.__str__() raise Exception("消息发送失败,失败原因{},重试次数{},消息内容message_code={},消息参数{}{}".format( error_message, retry_times, message_code, args, kwargs))
import os import json import logging from django.conf import settings from sparrow_cloud.restclient.exception import HTTPException from sparrow_cloud.utils.get_cm_value import get_cm_value from sparrow_cloud.utils.get_settings_value import get_settings_value from sparrow_cloud.restclient import rest_client logger = logging.getLogger(__name__) sc_distributed_lock_svc = get_cm_value("SC_SPARROW_DISTRIBUTED_LOCK_SVC") sc_distributed_lock_api = get_cm_value("SC_SPARROW_DISTRIBUTED_LOCK_API") def add_lock(key: str, expire_time: int, *args, **kwargs): """ # ConfigMap: SC_SPARROW_DISTRIBUTED_LOCK_SVC SC_SPARROW_DISTRIBUTED_LOCK_API """ service_conf = get_settings_value("SERVICE_CONF") service_name = service_conf.get("NAME", None) service_secret = service_conf.get("SECRET", None) if not service_name or not service_secret: raise Exception( "NAME or SECRET is not configured in SERVICE_CONF settings") data = { "service_name": service_name, "secret": service_secret,
from django.http import JsonResponse import logging from sparrow_cloud.middleware.base.base_middleware import MiddlewareMixin from sparrow_cloud.utils.get_cm_value import get_cm_value from sparrow_cloud.restclient import rest_client logger = logging.getLogger(__name__) SC_SPARROW_DISTRIBUTED_LOCK_SVC = get_cm_value( "SC_SPARROW_DISTRIBUTED_LOCK_SVC") SC_SPARROW_DISTRIBUTED_LOCK_FRONT_API = get_cm_value( "SC_SPARROW_DISTRIBUTED_LOCK_FRONT_API") class CheckLockMiddleware(MiddlewareMixin): def process_request(self, request): # key = request.headers.get("Sc-Lock") key = request.META.get("HTTP_SC_LOCK") # key不存在或者值为空,跳过锁检查,放行 if not key: return try: response = rest_client.put(SC_SPARROW_DISTRIBUTED_LOCK_SVC, SC_SPARROW_DISTRIBUTED_LOCK_FRONT_API, json={ "key": key, "opt": "incr" }) res = response.get("code") # 只有当锁存在且其值为0(表示锁未被使用)时,code才会返回0 if res == 0:
def rabbitmq_consumer(queue): """ SparrowRabbitmpConsumer 参数: queue # settings里面queue_conf 配置 configmap 配置: SC_BROKER_USERNAME: 用户名 SC_BROKER_PASSWORD: 密码 SC_BROKER_VIRTUAL_HOST: VIRTUAL_HOST SC_BROKER_SERVICE_SVC: 依赖服务 SC_BACKEND_SERVICE_SVC: 依赖服务 SC_BACKEND_SERVICE_API: api SC_CONSUMER_RETRY_TIMES: 错误重试次数,默认3次 SC_CONSUMER_INTERVAL_TIME: 错误重试间隔,默认3秒 SC_CONSUMER_HEARTBEAT: 消费者与rabbitmq心跳检测间隔,默认600秒 QUEUE_CONF_1 = { "QUEUE": "ORDER_PAY_SUC_ALL", "TARGET_FUNC_MAP": { "ORDER_PAY_SUC_ONLINE": "" } } ps: QUEUE_CONF_1 # 队列的配置 QUEUE # 队列名称 TARGET_FUNC_MAP # 队列消费的任务(字典中的键为message code, 对应的值为执行该消息的任务函数路径字符串) """ queue_conf = get_settings_value(queue) retry_times = get_cm_value('SC_CONSUMER_RETRY_TIMES') interval_time = get_cm_value('SC_CONSUMER_INTERVAL_TIME') consumer_heartbeat = get_cm_value('SC_CONSUMER_HEARTBEAT') virtual_host = get_cm_value("SC_BROKER_VIRTUAL_HOST") host = get_cm_value("SC_BROKER_SERVICE_HOST") port = get_cm_value("SC_BROKER_SERVICE_PORT") username = get_cm_value("SC_BROKER_USERNAME") password = get_cm_value('SC_BROKER_PASSWORD') backend_service_svc = get_cm_value('SC_BACKEND_SERVICE_SVC') backend_service_api = get_cm_value('SC_BACKEND_SERVICE_API') message_broker_conf = { "host": host, "port": port, "username": username, "password": password, "virtual_host": virtual_host, } while True: try: consumer = RabbitMQConsumer( queue=queue_conf.get('QUEUE', None), message_broker_conf=message_broker_conf, message_backend_svc=backend_service_svc, message_backend_api=backend_service_api, retry_times=int(retry_times), interval_time=int(interval_time), heartbeat=int(consumer_heartbeat) ) consumer.target_func_map = queue_conf.get('TARGET_FUNC_MAP', None) consumer.consume() except KeyboardInterrupt: break except: # 如果遇到exception不退出,过几秒重试一下 time.sleep(int(interval_time))
from json import loads from sparrow_cloud.utils.get_cm_value import get_cm_value from sparrow_cloud.middleware.base.base_middleware import MiddlewareMixin sc_method_map = get_cm_value("SC_METHOD_MAP") METHOD_MAP = tuple(loads(sc_method_map).values()) if not METHOD_MAP: METHOD_MAP = ('PUT', 'DELETE') class MethodConvertMiddleware(MiddlewareMixin): """解决阿里云不支持put/delete 请求方式的问题""" def process_request(self, request): if 'HTTP_METHOD' in request.META: method = request.META['HTTP_METHOD'].upper() if method in METHOD_MAP: setattr(request, 'method', method)