def serialize_remote_exception(failure_info, log_failure=True): """Prepares exception data to be sent over rpc. Failure_info should be a sys.exc_info() tuple. """ tb = traceback.format_exception(*failure_info) failure = failure_info[1] if log_failure: LOG.error("Returning exception %s to caller", six.text_type(failure)) LOG.debug(tb) kwargs = {} if hasattr(failure, 'kwargs'): kwargs = failure.kwargs # NOTE(matiu): With cells, it's possible to re-raise remote, remote # exceptions. Lets turn it back into the original exception type. cls_name = six.text_type(failure.__class__.__name__) mod_name = six.text_type(failure.__class__.__module__) if (cls_name.endswith(_REMOTE_POSTFIX) and mod_name.endswith(_REMOTE_POSTFIX)): cls_name = cls_name[:-len(_REMOTE_POSTFIX)] mod_name = mod_name[:-len(_REMOTE_POSTFIX)] data = { 'class': cls_name, 'module': mod_name, 'message': six.text_type(failure), 'tb': tb, 'args': failure.args, 'kwargs': kwargs } json_data = jsonutils.dumps(data) return json_data
def unquote_version(self, req, group_id, objtype, entity, body=None): """区服包引用指定资源引用删除""" body = body or {} if objtype != common.GAMESERVER: raise InvalidArgument('Version unquote just for %s' % common.GAMESERVER) package_id = int(body.get('package_id')) group_id = int(group_id) entity = int(entity) session = endpoint_session() query = model_query(session, AppEntity, filter=AppEntity.entity == entity) quote = None with session.begin(): _entity = query.one() if _entity.objtype != objtype: raise InvalidArgument('Objtype not match') if _entity.group_id != group_id: raise InvalidArgument('Group id not match') versions = jsonutils.loads_as_bytes(_entity.versions) if _entity.versions else {} str_key = str(package_id) if str_key in versions: quote = versions.pop(str_key) cdnquote_controller.delete(req, quote.get('quote_id')) _entity.versions = jsonutils.dumps(versions) if versions else None session.flush() return resultutils.results(result='%s entity version unquote success' % objtype, data=[dict(version=quote.get('version') if quote else None, quote_id=quote.get('quote_id') if quote else None)])
def order(session, client, serial, uid, oid, money, cid, chapter, ext=None, order_time=None): query = model_query(session, User, filter=User.uid == uid) coin, gift = client.translate(money) with session.begin(): user = query.one() order = Order(oid=oid, uid=uid, sandbox=client.sandbox, currency=client.currency, platform=client.name, money=money, serial=serial, time=order_time or int(time.time()), cid=cid, chapter=chapter, coins=user.coins, gifts=user.gifts, coin=coin, gift=gift, ext=jsonutils.dumps(ext) if ext else None) session.add(order) return coin + gift
def quote_version(self, req, group_id, objtype, entity, body=None): """区服包引用指定资源版本""" body = body or {} if objtype != common.GAMESERVER: raise InvalidArgument('Version quote just for %s' % common.GAMESERVER) package_id = int(body.get('package_id')) rversion = body.get('rversion') group_id = int(group_id) entity = int(entity) session = endpoint_session() query = model_query(session, Group, filter=Group.group_id == group_id) query = query.options(joinedload(Group.packages, innerjoin=False)) group = query.one() resource_id = None for package in group.packages: if package.package_id == package_id: resource_id = package.resource_id if not resource_id: raise InvalidArgument('Entity can not find package or package resource is None') query = model_query(session, AppEntity, filter=AppEntity.entity == entity) query = query.options(joinedload(AppEntity.areas, innerjoin=False)) with session.begin(): _entity = query.one() if _entity.objtype != objtype: raise InvalidArgument('Objtype not match') if _entity.group_id != group_id: raise InvalidArgument('Group id not match') if not model_count_with_key(session, PackageArea.package_id, filter=and_(PackageArea.package_id == package_id, PackageArea.area_id.in_([area.area_id for area in _entity.areas]) )): raise InvalidArgument('Entity area not in package areas') versions = jsonutils.loads_as_bytes(_entity.versions) if _entity.versions else {} str_key = str(package_id) if str_key in versions: quote = versions.get(str_key) if quote.get('version') != rversion: body = {'version': rversion} quote.update(body) cdnquote_controller.update(req, quote.get('quote_id'), body=body) else: qresult = cdnresource_controller.vquote(req, resource_id, body={'version': rversion, 'desc': '%s.%d' % (common.NAME, entity)}) quote = qresult['data'][0] quote = dict(version=rversion, quote_id=quote.get('quote_id')) versions.setdefault(str_key, quote) _entity.versions = jsonutils.dumps(versions) session.flush() return resultutils.results(result='set entity version quote success', data=[dict(resource_id=resource_id, version=rversion, quote_id=quote.get('quote_id'))])
def record(session, order, serial, extdata, on_transaction_call=None): uid = order.uid query = session.query(User).filter(User.uid == uid).with_for_update() try: with session.begin(): user = query.one() if on_transaction_call: extdata = on_transaction_call(extdata) recharge = RechargeLog( oid=order.oid, sandbox=order.sandbox, uid=uid, coins=user.coins, gifts=user.gifts, coin=order.coin, gift=order.gift, money=order.money, currency=order.currency, platform=order.platform, time=order.time, ftime=int(time.time()), cid=order.cid, chapter=order.chapter, serial=serial if serial else order.serial, ext=jsonutils.dumps(extdata) if extdata else None, ) user.coins += order.coin user.gifts += order.gift session.add(recharge) except DBDuplicateEntry: LOG.warning('Duplicate esure notify') d = DuplicateRecharge(oid=order.oid, uid=order.uid, coin=order.coin, gift=order.gift, money=order.money, currency=order.currency, time=int(time.time()), status=common.NOTCHCEK, serial=order.serial) try: session.add(d) except DBError: LOG.error('Recodr duplicate recharge order fail')
def add_agent(self, body): agent = Agent() try: agent.host = validators['type:hostname'](body.pop('host')) agent.agent_type = body.pop('agent_type', None) if agent.agent_type is None or len(agent.agent_type) > 64: raise ValueError('Agent type info over size') if body.get('ports_range', None) is not None: agent.ports_range = jsonutils.dumps(body.pop('ports_range')) agent.memory = int(body.pop('memory')) agent.cpu = int(body.pop('cpu')) agent.disk = int(body.pop('disk')) endpoints = validateutils.validate_endpoints(body.pop('endpoints', [])) except KeyError as e: raise InvalidArgument('Can not find argument: %s' % e.message) except ValueError as e: raise InvalidArgument('Argument value type error: %s' % e.message) agent.create_time = timeutils.realnow() session = self.session() with self._lock_all_agents(): host_filter = and_(Agent.host == agent.host, Agent.status > manager_common.DELETED) if model_count_with_key(session, Agent.host, filter=host_filter) > 0: raise exceptions.AgentHostExist('Agent with host %s alreday eixst' % agent.host) agent_id = model_autoincrement_id(session, Agent.agent_id) with session.begin(): agent.agent_id = agent_id # if agent.endpoints: # for endpoint in agent.endpoints: # endpoint.agent_id = agent_id session.add(agent) session.flush() if endpoints: for endpoint in endpoints: session.add(AgentEndpoint(agent_id=agent_id, endpoint=endpoint)) session.flush() # add new agent_id to cache all agent_id # if not self.client.sadd(self.ALL_AGENTS_KEY, str(agent.agent_id)): if not self.client.zadd(self.ALL_AGENTS_KEY, int(time.time()), str(agent.agent_id)): raise exceptions.CacheStoneError('Cant not add agent_id to redis, key %s' % self.ALL_AGENTS_KEY) _endpoints = [e.endpoint for e in agent.endpoints] LOG.info('New anget with endpoints %s' % ','.join(_endpoints)) return agent
def SimpleFlowSqliteConverter(): sqlite3.register_adapter(list, jsonutils.dumps) sqlite3.register_adapter(tuple, lambda x: jsonutils.dumps(list(x))) sqlite3.register_adapter(set, lambda x: jsonutils.dumps(list(x))) sqlite3.register_adapter(dict, jsonutils.dumps)
def swallow(self, req, entity, body=None): """合服内部接口,一般由agent调用 用于新实体吞噬旧实体的区服和数据库""" body = body or {} entity = int(entity) uuid = body.get('uuid') if not uuid: raise InvalidArgument('Merger uuid is None') session = endpoint_session() query = model_query(session, MergeTask, filter=MergeTask.uuid == uuid) query = query.options(joinedload(MergeTask.entitys, innerjoin=False)) glock = get_gamelock() rpc = get_client() with session.begin(): etask = query.one_or_none() if not etask: raise InvalidArgument('Not task exit with %s' % uuid) # 新实体不匹配 if etask.entity != body.get('entity'): raise InvalidArgument('New entity not %d' % etask.entity) # 找到目标实体 appentity = None for _entity in etask.entitys: if _entity.entity == entity: if _entity.status != common.MERGEING: if _entity.status != common.SWALLOWING: raise InvalidArgument( 'Swallow entity find status error') if not _entity.databases or not _entity.areas: raise InvalidArgument( 'Entity is swallowing but database or ares is None' ) LOG.warning('Entit is swallowing, return saved data') return resultutils.results( result='swallow entity is success', data=[ dict(databases=jsonutils.loads_as_bytes( _entity.databases), areas=jsonutils.loads_as_bytes( _entity.areas)) ]) _query = model_query(session, AppEntity, filter=AppEntity.entity == entity) _query = _query.options( joinedload(AppEntity.databases, innerjoin=False)) appentity = _query.one_or_none() break if not appentity: raise InvalidArgument('Can not find app entity?') if appentity.objtype != common.GAMESERVER: raise InvalidArgument('objtype error, entity not %s' % common.GAMESERVER) if appentity.status != common.MERGEING: raise InvalidArgument('find status error, when swallowing') databases = self._database_to_dict(appentity) areas = [area.to_dict() for area in appentity.areas] if not databases or not areas: LOG.error('Entity no areas or databases record') return resultutils.results( result='swallow entity fail, ' 'target entity can not found database or areas', resultcode=manager_common.RESULT_ERROR) with glock.grouplock(group=appentity.group_id): # 发送吞噬命令到目标区服agent metadata, ports = self._entityinfo(req=req, entity=entity) target = targetutils.target_agent_by_string( metadata.get('agent_type'), metadata.get('host')) target.namespace = common.NAME rpc_ret = rpc.call(target, ctxt={'agents': [ appentity.agent_id, ]}, msg={ 'method': 'swallow_entity', 'args': dict(entity=entity) }) if not rpc_ret: raise RpcResultError('swallow entity result is None') if rpc_ret.get('resultcode') != manager_common.RESULT_SUCCESS: raise RpcResultError('swallow entity fail %s' % rpc_ret.get('result')) # 修改实体在合服任务中的状态,存储areas以及databases appentity.status = common.SWALLOWING _entity.status = common.SWALLOWING _entity.areas = jsonutils.dumps(areas) _entity.databases = jsonutils.dumps(databases) session.flush() return resultutils.results( result='swallow entity is success', data=[dict(databases=databases, areas=areas)])
def serialize_msg(raw_msg): # NOTE(russellb) See the docstring for _RPC_ENVELOPE_VERSION for more # information about this format. msg = jsonutils.dumps(raw_msg) return msg