'fail','res'=>'','data'=>''); //过滤此次同步前端店铺 if($node = $this->_check_node($shop_id, $method)){ $Ofunc = kernel::single('ome_rpc_func'); $params['to_node_id'] = $node[0]['node_id']; $params['node_type'] = $node[0]['node_type']; $app_xml = $Ofunc->app_xml(); $params['from_api_v'] = $app_xml['api_ver']; $params['to_api_v'] = $Ofunc->fetch_shop_api_v($node[0]['node_id']); }else{ $return_value['res'] = '店铺节点不存在'; return $return_value; } //检查是否过滤指定回写操作 if ($this->_check_request_config($shop_id, $method)) { return false; } //生成日志ID号 $oApi_log = app::get('ome')->model('api_log'); $log_id = $oApi_log->gen_id(); //设置callback异常返回参数为空时的默认值 if($callback && $callback['class'] && $callback['method']){ $rpc_callback = array($callback['class'],$callback['method'],array('log_id'=>$log_id,'shop_id'=>$shop_id)); }else{ $rpc_callback = array('ome_rpc_request','callback',array('log_id'=>$log_id,'shop_id'=>$shop_id)); } if ($queue == true){ //队列发起(此时不记录同步日志,队列后台执行时再记录) $param = array(); $param['api_title'] = $title; $param['params'] = $params; $param['method'] = $method; $param['rpc_callback'] = $rpc_callback; $this->api_queue($method, $param, $addon); }else{ //非队列发起(记录同步日志),并立即发起RPC if (!empty($addon) && is_array($addon)){ $api_params = array_merge($params, $addon); }else{ $api_params = $params; } if (isset($write_log['log_type'])){ $log_type = $write_log['log_type']; }else{ $log_type = ome_rpc_func::method2type($method); } $log_type = $log_type ? $log_type : 'other'; $oApi_log->write_log($log_id,$title,'ome_rpc_request','rpc_request',array($method, $api_params, $rpc_callback),'','request','running','',$addon,$log_type,$addon['bn']); $this->rpc_request($method, $params, $rpc_callback, $time_out,$write_log,$center,$http_method); } return $log_id; } /** * RPC开始请求 * 业务层数据过滤后,开始向上级框架层发起 * @access public * @param string $method RPC远程服务接口名称 * @param array $params 业务参数 * @param int $time_out 发起超时时间(秒) * @return RPC响应结果 */ public function call($method, $params, $shop_id, $time_out=2) { //过滤此次同步前端店铺 if ($node = $this->_check_node($shop_id, $method)) { $params['to_node_id'] = $node[0]['node_id']; $params['node_type'] = $node[0]['node_type']; if(in_array($node[0]['node_type'], ome_shop_type::shopex_shop_type())){ $Ofunc = kernel::single('ome_rpc_func'); $app_xml = $Ofunc->app_xml(); $params['from_api_v'] = $app_xml['api_ver']; $params['to_api_v'] = $Ofunc->fetch_shop_api_v($node[0]['node_id']); } } else { return false; } //检查是否过滤指定回写操作 if ($this->_check_request_config($shop_id, $method)) { return false; } return $this->rpc_request($method, $params, null, $time_out); } /** * RPC开始请求 * 业务层数据过滤后,开始向上级框架层发起 * @access public * @param string $method RPC远程服务接口名称 * @param array $params 业务参数 * @param array $callback 异步返回 * @param int $time_out 发起超时时间(秒) * @param array $write_log 日志记录 * @param Bool $center 请求平台:false矩阵 true:licence中心 * @param String $http_method HTTP请求方式,POST或GET * @return RPC响应结果 */ public function rpc_request($method,$params,$callback,$time_out=5,$write_log=array(),$center=false,$http_method='POST'){ if($center===false){ if (empty($callback)) { //实时请求 $rst = app::get('ome')->matrix()->set_realtime(true) ->set_timeout($time_out) ->call($method, $params); return $rst; } else { if (isset($params['gzip'])){ $gzip = $params['gzip']; }else{ $gzip = false; } $callback_class = $callback[0]; $callback_method = $callback[1]; $callback_params = (isset($callback[2])&&$callback[2])?$callback[2]:array(); if (isset($params[1]['task'])){ $rpc_id = $params[1]['task']; } $rst = app::get('ome')->matrix()->set_callback($callback_class,$callback_method,$callback_params) ->set_timeout($time_out) ->call($method,$params,$rpc_id,$gzip); } }else{ return $this->center_request($method,$params,$write_log,$http_method,$time_out); } } public function center_request($method,$params,$write_log=array(),$http_method='POST',$time_out=10) { $url = MATRIX_RELATION_URL; $sys_params = array( 'app' => $method, 'certi_id' => base_certificate::get('certificate_id'), 'from_node_id' => base_shopnode::node_id('ome'), 'from_api_v' => $params['from_api_v'], 'to_node_id' => $params['to_node_id'], 'to_api_v' => $params['to_api_v'], 'v' => $params['from_api_v'], 'timestamp' => date('Y-m-d H:i:s',time()), 'format' => 'json', ); $query_params = array_merge($sys_params,$params); $query_params['certi_ac'] = self::licence_sign($query_params,'ome'); $log_title = $write_log['log_title']; $original_bn = $write_log['original_bn']; if ($http_method == 'POST'){ $http = kernel::single('base_httpclient'); $response = $http->set_timeout($time_out)->post($url,$query_params,$headers); $response = json_decode($response,true); $rsp = array('rsp'=>'fail','msg'=>'','data'=>''); if (!isset($response['res'])){ $rsp['msg'] = '请求超时'; }else{ $rsp['rsp'] = $response['res']; $rsp['msg'] = $response['msg']; $rsp['data'] = $response['info']; } //$logObj = kernel::single('omeapilog_log'); $log_type = $write_log['log_type']; $log_type = $log_type ? $log_type :'other'; //$status = $rsp['rsp'] == 'success' ? 'success' : 'fail'; //$addon['msg_id'] = $rsp['msg_id']; //$msg = $rsp['msg']; //$logObj->write_action_log($log_title,$method,$query_params,$log_type,$status,$original_bn,$msg='',$addon); return $rsp; }else{ $query_str = array(); foreach ($query_params as $key=>$value){ $query_str[] = $key.'='.$value; } $query_str = implode('&',$query_str); $src = $url.'?'.$query_str; header('Location:'.$src); exit; //echo ''.$log_title.':'.$original_bn.''; } } /** * licence生成加密串 * @access public * @param $params * @return String */ static public function licence_sign($params){ $str = ''; ksort($params); foreach($params as $key => $value){ $str.=$value; } $token = base_certificate::token(); return md5($str.$token); } /** * RPC异步返回数据接收 * @access public * @param object $result 经由框架层处理后的同步结果数据 * @return 返回业务处理结果 */ public function callback($result){ if (is_object($result)){ $callback_params = $result->get_callback_params(); $status = $result->get_status(); $msg = $result->get_result(); $err_msg = $result->get_err_msg(); $data = $result->get_data(); $request_params = $result->get_request_params(); $msg_id = $result->get_msg_id(); }else{ return true; } if($status == 'succ'){ $api_status = 'success'; }else{ $api_status = 'fail'; } if($msg !=''){ $msg = '('.$msg.')'.$err_msg; } $rsp ='succ'; if ($status != 'succ' && $status != 'fail' ){ $msg = 'rsp:'.$status .'res:'. $msg. 'data:'. $data; $rsp = 'fail'; } //错误等级 if (isset($data['error_level']) && !empty($data['error_level'])){ $addon['error_lv'] = $data['error_level']; } $log_id = $callback_params['log_id']; $oApi_log = app::get('ome')->model('api_log'); $oApi_log->update_log($log_id, $msg, $api_status, null, $addon); //$log_detail = $oApi_log->dump($log_id, 'msg_id,params'); //只有接口类型为库存更新时,才调用库存callback函数 return array('rsp'=>$rsp, 'res'=>$msg, 'msg_id'=>$msg_id); } /** * RPC同步返回数据接收 * @access public * @param json array $res RPC响应结果 * @param array $params 同步日志ID */ public function response_log($res, $params){ $response = json_decode($res, true); if (!is_array($response)){ $response = array( 'rsp' => 'running', 'res' => $res, ); } $status = $response['rsp']; $result = $response['res']; if($status == 'running'){ $api_status = 'running'; }elseif ($result == 'rx002'){ //将解除绑定的重试设置为成功 $api_status = 'success'; }else{ $api_status = 'fail'; } $log_id = $params['log_id']; $oApi_log = app::get('ome')->model('api_log'); //更新日志数据 $oApi_log->update_log($log_id, $result, $api_status); if ($response['msg_id']){ //更新日志msg_id及在应用级参数中记录task /* $log_info = $oApi_log->dump($log_id); $log_params = unserialize($log_info['params']); $rpc_key = $params['rpc_key']; $log_params[1]['task'] = $rpc_key; $update_data = array( 'msg_id' => $response['msg_id'], 'params' => serialize($log_params), );*/ $update_data = array( 'msg_id' => $response['msg_id'], ); $update_filter = array('log_id'=>$log_id); $oApi_log->update($update_data, $update_filter); } //只有接口类型为库存更新时,才调用库存callback函数 } /** * 更新库存回写状态 */ function save_stock_callback($log_id,$oApi_log){ $log_info = $oApi_log->dump($log_id,'msg_id,params'); $log_params = unserialize($log_info['params']); if($log_params[2][1]=='stock_update_callback') { $list_quantity = json_decode($log_params[1]['list_quantity'],true); $all_list_quantity = json_decode($log_params[1]['all_list_quantity'],true); $oApiLogToStock = kernel::single('ome_api_log_to_stock'); $oApiLogToStock->save_callback( $all_list_quantity,'success', $params['shop_id'],$response['res'],$log_info ); $oApiLogToStock->save_callback( $list_quantity,$api_status, $params['shop_id'],$response['res'],$log_info ); } } /** * 店铺绑定关系过滤 * 检查店铺(shop_id为空时标识所有店铺)是否可访问远端API接口服务,并返回可用的node_id * @access private * @param string $shop_id 店铺标识ID * @param string $method RPC远程调用接口名称 * @return boolean */ private function _check_node($shop_id,$method){ $node = $this->_get_node($shop_id); if($node){ $request_whitelist = kernel::single('ome_rpc_request_whitelist'); $t_node = $node; foreach($t_node as $k=>$v){ $res = $request_whitelist->check_node($v['node_type'],$method); if(!$res){ unset($node[$k]); } } if($node){ return $node; }else{ return false; } }else{ return false; } } /** * 检查指定店铺及回调方法是否被禁止 * * @param String $shop_id 店铺ID * @param $method 调用方法 * @return boolean true 禁止 false 允许 */ private function _check_request_config($shop_id, $method) { $method = strtolower($method); if ($method == 'store.items.quantity.list.update') { $request_auto_stock = app::get('ome')->getConf('request_auto_stock_' . $shop_id); //如无设置,缺省置为 true if (empty($request_auto_stock)) { $request_auto_stock = 'true'; app::get('ome')->setConf('request_auto_stock_' . $shop_id, 'true'); } //如已经关闭了库存回写功能,返回 true if ($request_auto_stock == 'false') { return true; } } return false; } /** * 通过shop_id获取结点信息 * @access private * @param $shop_id * @return array 店铺绑定的节点数据 */ private function _get_node($shop_id){ $shopObj = app::get('ome')->model('shop'); $node = array(); if(empty($shop_id)){ $shop_info = $shopObj->getList('node_id,node_type', '', 0, -1); if($shop_info){ foreach($shop_info as $v){ if ($v['node_id']){ $node[] = array( 'node_id' => $v['node_id'], 'node_type' => $v['node_type'], ); } } } }else{ $shop_info = $shopObj->dump($shop_id,'node_id,node_type'); if ($shop_info['node_id']){ $node[] = array( 'node_id' => $shop_info['node_id'], 'node_type' => $shop_info['node_type'] ); } } return $node; } /** * RPC同步日志队列 * @access public * @param string $queue_title 队列标题 * @param array $queue_params 队列参数 * @param array $addon 附加参数 * */ public function api_queue($queue_title,$queue_params,$addon=''){ $oQueue = app::get('base')->model('queue'); $queueData = array( 'queue_title'=>$queue_title, 'start_time'=>time(), 'params'=>array( 'sdfdata'=>$queue_params, 'addon' => $addon, ), 'status' => 'hibernate', 'worker'=> __CLASS__.'.run', ); $oQueue->save($queueData); } /** * 执行API同步日志队列 * @param $cursor_id * @param $params */ function run(&$cursor_id,$params){ $oApi_log = app::get('ome')->model('api_log'); if (!is_array($params)){ $params = unserialize($params); } $Sdf = $params['sdfdata']; $addon = $params['addon']; $title = $Sdf['api_title']; $method = $Sdf['method']; $params = $Sdf['params']; $rpc_callback = $Sdf['rpc_callback']; //附加参数 if (!empty($addon) && is_array($addon)){ $api_params = array_merge($params, $addon); }else{ $api_params = $params; } $log_type = ome_rpc_func::method2type($method); $log_id = $rpc_callback[2]['log_id']; $oApi_log->write_log($log_id,$title,'ome_rpc_request','rpc_request',array($method,$api_params,$rpc_callback),'','request','running','',$addon,$log_type,$addon['bn']); kernel::single('ome_rpc_request')->rpc_request($method,$params,$rpc_callback); } /** * * @param $url * @param $params * @param $time_out * * @return String */ function direct_request($url,$params,$time_out=5){ $headers = array( 'Connection'=>$time_out, ); $core_http = kernel::single('base_httpclient'); $res = $core_http->post($url,$params,$headers); $res = 'direct_request:' . $res; kernel::log($res); $res2 = 'direct_request content:' . $url."\n".json_encode($params); kernel::log($res2); return $res; } /** * 返回验证字符串 * * @param $params * * @return String */ function make_sign($post_params){ return base_certificate::getCertiAC($post_params); } }