diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/message_log_api.h b/eventmesh-sdks/eventmesh-sdk-c/include/message_log_api.h new file mode 100644 index 0000000000..8c2eb9516d --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/message_log_api.h @@ -0,0 +1,55 @@ +// 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. + +#ifndef __MESSAGE_LOG_API_H_ +#define __MESSAGE_LOG_API_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "rmb_define.h" +#include "rmb_pub.h" + +#define LOG_MSG_COM_CONSUMERID "consumerId" +#define LOG_MSG_COM_LOGNAME "logName" +#define LOG_MSG_COM_TIMESTAMP "logTimestamp" +#define LOG_MSG_COM_CONTENT "content" +#define LOG_MSG_COM_LOGTYPE "logType" +#define LOG_MSG_COM_LANG "lang" +#define LOG_MSG_COM_ID "id" +#define LOG_MSG_COM_PROCESSID "processId" +#define LOG_MSG_COM_THREADID "threadId" +#define LOG_MSG_COM_CONSUMERSVRID "consumerSvrId" +#define LOG_MSG_COM_LEVEL "level" +#define LOG_MSG_COM_EXTFIELDS "extFields" + +#define LOG_INFO_LEVEL "info" +#define LOG_DEBUG_LEVEL "debug" +#define LOG_WARN_LEVEL "warn" +#define LOG_ERROR_LEVEL "error" +#define LOG_FATAL_LEVEL "fatal" + +//应用可以调用此接口上传log日志 + int rmb_log_for_common (StContext * pStContext, const char *iLogLevel, + const char *cLogName, const char *content, + const char *extFields); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_access_config.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_access_config.h new file mode 100644 index 0000000000..3df3ded354 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_access_config.h @@ -0,0 +1,45 @@ +// 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. + +#ifndef RMB_ACCESS_CONFIG_H_ +#define RMB_ACCESS_CONFIG_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + + int rmb_get_wemq_proxy_list_num (); + + int rmb_get_wemq_proxy_list_used (); + +//int wemq_proxy_load_servers(char* url, long timeout, const char* path); + int wemq_proxy_load_servers (const char *url, long timeout); + + int wemq_proxy_get_server (char *host, size_t size, unsigned int *port); + + void wemq_proxy_goodbye (const char *host, unsigned int port); + + void wemq_proxy_to_black_list (const char *host, unsigned int port); + + int wemq_proxy_ip_is_connected (); + + void split_str (char *ips, char ipArray[][50], int *len); + +#ifdef __cplusplus +} +#endif + +#endif /* RMB_ACCESS_CONFIG_H_ */ diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_cfg.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_cfg.h new file mode 100644 index 0000000000..3ce38bd837 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_cfg.h @@ -0,0 +1,60 @@ +// 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. + +#ifndef RMB_CFG_H_ +#define RMB_CFG_H_ + +#include "rmb_define.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define CFG_STRING (int)1 +#define CFG_INT (int)2 +#define CFG_LONG (int)3 +#define CFG_DOUBLE (int)4 +#define CFG_LINE (int)5 +#define CFG_SHORT (int)6 + +#define US 0x1f + +#define MAX_CONFIG_LINE_LEN 1023 + + void RMB_TLib_Cfg_GetConfig (char *sConfigFilePath, ...); + +#define Rmb_TLib_Cfg_GetConfig(sConfigFilePath,fmt,args...) RMB_TLib_Cfg_GetConfig(sConfigFilePath,fmt,## args) + +/** + * Function: rmb_load_config + * Description: rmb load configure + * Return: + * 0: success + * -1: failed + */ + int rmb_load_config (const char *configPath); + + const char *rmb_get_host_ip (); + + void rmb_get_config_python (RmbPythonConfig * config); + + const char *getRmbLastError (); + +#ifdef __cplusplus +} +#endif + +#endif /* RMB_CFG_H_ */ diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_common.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_common.h new file mode 100644 index 0000000000..8bdf7745ba --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_common.h @@ -0,0 +1,269 @@ +// 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. + +#ifndef _RMB_COMMON_H_ +#define _RMB_COMMON_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include +#include +#include + + extern unsigned int g_uiSendMsgSeq; + extern unsigned int g_uiRecvMsgSeq; +//extern unsigned int g_iSendReq = 0; +#define MAX_SEND_MSG_SEQ 65535 + extern unsigned int DEFAULT_WINDOW_SIZE; +#define CURRENT_WINDOW_SIZE (((g_uiRecvMsgSeq) <= (g_uiSendMsgSeq)) ? ((g_uiSendMsgSeq) - (g_uiRecvMsgSeq)) : (MAX_SEND_MSG_SEQ - (g_uiRecvMsgSeq) + (g_uiSendMsgSeq))) + + static int cmpQueueStr (const void *a, const void *b) + { + return strcmp (((StQueueName *) a)->cQueueName, + ((StQueueName *) b)->cQueueName); + } + + static int cmpQueueNodeStr (const void *a, const void *b) + { + return strcmp (((StQueueNode *) a)->cQueueName, + ((StQueueNode *) b)->cQueueName); + } + + static int cmpServiceStatusStr (const void *a, const void *b) + { +// if (((StServiceStatus*)a)->ulGetTimes == 0) +// { +// return 1; +// } +// if (((StServiceStatus*)b)->ulGetTimes == 0) +// { +// return -1; +// } +// if (((StServiceStatus*)a)->ulGetTimes < ((StServiceStatus*)b)->ulGetTimes) +// { +// return 1; +// } + int iRet = + strcmp (((StServiceStatus *) a)->strServiceId, + ((StServiceStatus *) b)->strServiceId); + if (iRet != 0) + { + return iRet; + } + iRet = + strcmp (((StServiceStatus *) a)->strScenarioId, + ((StServiceStatus *) b)->strScenarioId); + if (iRet != 0) + { + return iRet; + } + iRet = + strcmp (((StServiceStatus *) a)->strTargetOrgId, + ((StServiceStatus *) b)->strTargetOrgId); + if (iRet != 0) + { + return iRet; + } + if (((StServiceStatus *) a)->cFlagForOrgId < + ((StServiceStatus *) a)->cFlagForOrgId) + { + return -1; + } + else if (((StServiceStatus *) a)->cFlagForOrgId > + ((StServiceStatus *) a)->cFlagForOrgId) + { + return 1; + } + return 0; + } + + static int cmpBroadNodeStr (const void *a, const void *b) + { + int iRet = + strcmp (((StBroadcastNode *) a)->strServiceId, + ((StBroadcastNode *) b)->strServiceId); + if (iRet != 0) + return iRet; + + iRet = + strcmp (((StBroadcastNode *) a)->strScenarioId, + ((StBroadcastNode *) b)->strScenarioId); + if (iRet != 0) + return iRet; + +// iRet = strcmp(((StBroadcastNode*)a)->cConsumerSysId, ((StBroadcastNode*)b)->cConsumerSysId); +// if (iRet != 0) +// return iRet; + + return 0; + } + +/* +typedef struct StQueueTree +{ + char queueName[30]; + struct StQueueTree *pLeft; + struct StQueueTree *pRight; +}StQueueTree; + +static StQueueTree* InsertQueue(StQueueTree* pRoot, const char *cQueuName) +{ + StQueueTree* pCurNode = pRoot; + StQueueTree* pTmp; + StQueueTree* pNewNode = (StQueueTree*)malloc(sizeof(StQueueTree)); + strncpy(pNewNode->queueName, cQueuName, sizeof(pNewNode->queueName)); + pNewNode->pLeft = NULL; + pNewNode->pRight = NULL; + + if(pCurNode == NULL) + { + return pNewNode; + } + else + { + while(pCurNode != NULL) + { + pTmp = pCurNode; + if( strcmp(cQueuName, pTmp->queueName) > 0) + { + pCurNode = pCurNode->pRight; + } + else + { + pCurNode = pCurNode->pLeft; + } + } + + if(strcmp(cQueuName, pTmp->queueName) > 0) + { + pTmp->pRight = pNewNode; + } + else + { + pTmp->pLeft = pNewNode; + } + } + return pRoot; +} + +static StQueueTree* FindQueue(StQueueTree* pRoot, const char *cQueuName) +{ + int iRet = 1; + StQueueTree *pCurNode = pRoot; + while (iRet != 0) + { + if (pCurNode == NULL) + { + return NULL; + } + iRet = strcmp(cQueuName, pCurNode->queueName); + if( iRet > 0) + { + pCurNode = pCurNode->pRight; + } + else if( iRet < 0) + { + pCurNode = pCurNode->pLeft; + } + else + { + return pCurNode; + } + } + return NULL; +} + +typedef struct StQueueName StQueueName; + +static int rmb_partition(StQueueName* pQueueList,int low,int high) +{ + StQueueName tmpQueueName; + strcpy(tmpQueueName.cQueueName, (pQueueList + low)->cQueueName); + while(low < high) + { + if(lowcQueueName, tmpQueueName.cQueueName) >= 0) + { + --high; + } + strcpy((pQueueList+low)->cQueueName, (pQueueList+high)->cQueueName); + + if(lowcQueueName, tmpQueueName.cQueueName) <= 0) + { + ++low; + } + strcpy((pQueueList+high)->cQueueName, (pQueueList+low)->cQueueName); + } + strcpy((pQueueList + low)->cQueueName, tmpQueueName.cQueueName); + return low; +} + +static void rmb_quick_sort(StQueueName* pQueueList,int low,int high) +{ + if(lowcQueueName, cQueueName); + if ( iRet == 0) + { + return (pQueueList + m); + } + else if (iRet < 0) + { + if (i == m) + { + return NULL; + } + i = m; + } + else if (iRet > 0) + { + if (j == m) + { + return NULL; + } + j = m; + } + } + return NULL; +} +*/ +#ifdef __cplusplus +} +#endif + +#endif /* _RMB_COMMON_H_ */ diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_context.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_context.h new file mode 100644 index 0000000000..e4677db3fd --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_context.h @@ -0,0 +1,66 @@ +// 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. + +#ifndef RMB_CONTEXT_H_ +#define RMB_CONTEXT_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "rmb_define.h" + + int rmb_context_init (StContext * pStContext); + + int rmb_context_add_rsp_socket (StContext * pStContext, + const char *cLocalIp, + unsigned short usReplyPort); + + int rmb_context_add_req_socket (StContext * pStContext, + const char *cLocalIp, + unsigned short usReqPort); + + int rmb_context_add_broadcast_socket (StContext * pStContext, + const char *cLocalIp, + unsigned short usBroadcastPort); + + int rmb_context_add_req_mq_fifo (StContext * pStContext, + const char *strFiFoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, void *func_argv); + int rmb_context_add_rr_rsp_mq_fifo (StContext * pStContext, + const char *strFiFoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv); + int rmb_context_add_broadcast_mq_fifo (StContext * pStContext, + const char *strFiFoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv); + + int rmb_context_enqueue (StContext * pStContext, + const enum RmbMqIndex uiMsgType, const char *data, + unsigned int uiDataLen); + +#ifdef __cplusplus +} +#endif + +#endif /* RMB_CONTEXT_H_ */ diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_define.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_define.h new file mode 100644 index 0000000000..20f8ea6f13 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_define.h @@ -0,0 +1,1264 @@ +// 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. + +#ifndef RMB_DEFINE_H_ +#define RMB_DEFINE_H_ +#ifdef __cplusplus +extern "C" +{ +#endif + +/* +rmb_define.h +RMB基本定义 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include "rmb_mq.h" +#include "rmb_log.h" +#include "rmb_errno.h" +#include "wemq_fifo.h" + +#include "wemq_topic_list.h" +#include "wemq_proto.h" + +#include +#include +#include +#include +#include + +#define RMBVERSION "2.2.0" +#define RMBVERSIONFORBIZ "00002200" + static const char rmbVersion[20] = "2.2.0"; + +#define DEFAULT_MSG_MAX_LIVE_TIME 14400000 +#define RR_ASYNC_MSG_MAX_LIVE_TIME 60000 +#define DEFAULT_DCN_LENGTH 3 +#define DEFAULT_SERVICE_ID_LENGTH 8 +#define DEFAULT_SCENE_ID_LENGTH 2 + +#define MAX_FLOWS_IN_A_SESSION 200 //the max flow numbers in one session +#define MAX_QUEUE_SESSIONS_IN_A_CONTEXT 1 //the max session numbers in one context +//#define MAX_LENTH_IN_A_MSG 2150000 //packages buf for send and receive +#define MAX_LENTH_IN_A_MSG 2625825 //packages buf for send and receive +#define MAX_PROPERTY_NUMS 50 //the max numbers for property +#define MAX_PROPERTY_LENTH 255 //the max length for one property +#define MAX_RMB_CONTEXT 2 //the max numbers of context -- solace threads + +#define MAX_SYSHEADER_LENGTH 20 +//流控比中每个topic最大的计数 +#define MAX_TOPIC_COUNT 1000000 +//#define MAX_APPHEADER_LENGTH 50000 +//0.9.12 保持和java一致 +//0.9.16,由于c会加\0,所以字节数需要加1 +//#define MAX_APPHEADER_LENGTH 525000 +//#define MAX_APPHEADER_LENGTH 525001 +#define MAX_APPHEADER_LENGTH (1 << 19) +#define MAX_PROPERTY_SIZE 50 +#define MAX_RET_MSG_SIZE 512 +//0.9.16,由于c会加\0,所以字节数需要加1 +//#define MAX_MSG_CONTENT_SIZE 2100000 +//#define MAX_MSG_CONTENT_SIZE 2100001 +#define MAX_MSG_CONTENT_SIZE (1 << 21) +#define MAX_MSG_ATTACHMENT_SIZE 2048 + +#define MAX_COMMON_SIZE 20 + +#define MAX_LOG_BUF_SIZE 20000 + +#define MAX_SERVICE_STATUS_CACHE_NUMS 1000 +#define MAX_GSL_REQ_BUF_SIZE 100 +#define MAX_GSL_RSP_BUF_SIZE 100 + +#define MAX_GSL_RSP_TOPIC_GROUP_SIZE 256 + +#define GSL_DEFAULT_DCN "GSL" +#define GSL_DEFAULT_SERVICE_ID "12300009" +#define GSL_DEFAULT_SCENE_ID "01" +#define GSL_DEFAULT_COMMON_ORGID "10006" + +#define MAX_RMB_WORKER_NUMS 400 +#define MAX_RMB_PROXY_NUMS 10 + +//for config center +#define WEMQ_ACCESS_SERVER "dynamicKey/v1/wemqAccessServer.json" +#define DYNAMIC_KEY_NAME "dynamicKey/v1" + +#define RMB_REQ_SINGLE "querySingle" +#define RMB_WHITE_LIST_RCV "whitelist-rcv" +#define RMB_WHITE_LIST_SND "whitelist-snd" +#define WEMQ_PROXY_SERVERS "wemq.proxy.servers" + +//#define RMB_WHITE_LIST_RCV_MAX 200 +//#define RMB_WHITE_LIST_SND_MAX 200 +#define RMB_TOPIC_PER_SYS_MAX 10000 +#define MAX_LISTEN_TOPIC_NUM 1000 + +#define RMB_MAX_NORMAL_SESSIONS_IN_A_CONTEXT_FOR_WEMQ 100 //the max normal session in context only for wemq proxy mode + +#define TCP_BUF_SIZE (3<<20) + + enum RmbGslSubcmd + { + GSL_SUBCMD_QUERY_SERVICE = 0x1, + GSL_SUBCMD_NEW_QUERY_SERVICE = 0x11, + GSL_SUBCMD_QUERY_TOPICGROUP = 0x02, + }; + + enum RmbMsgSource + { + RMB_MSG_FROM_SOLACE = 1, + RMB_MSG_FROM_WEMQ = 2, + }; + + enum RmbTargetOrgIdCommitType + { + RMB_COMMIT_BY_OWN = 0, + RMB_COMMIT_BY_API = 1, + }; + + enum RmbFlagForMsgInit + { + RMBMSG_DEST_HAS_SET = 0, + + }; + + enum EVENT_OR_SERVICE_CALL + { + RMB_EVENT_CALL = 0, + RMB_SERVICE_CALL = 1, + }; + + enum RMB_SVR_MODE + { + RMB_OLD_MODE = 0, + RMB_PROXY_WORKER = 1, + }; + + enum RMB_PROXY_MQ_TYPE + { + RMB_PROXY_MQ_RECEIVE = 1, + RMB_PROXY_MQ_SEND = 2, + RMB_PROXY_MQ_RR = 3, + }; + + enum RMB_LOG_POINT + { + RMB_LOG_START_CALL = 0, + RMB_LOG_ENTRY = 1, + RMB_LOG_EXIT = 2, + RMB_LOG_END_CALL = 3, + RMB_LOG_ON_ERROR = 4, + RMB_LOG_OTHER = 5, + }; + + //proxy-worker模式下使用 + typedef struct StMqFifoArg + { + char *_fiFoPath; + unsigned int _shmKey; + unsigned int _shmSize; + } StMqFifoArg; + + enum RMB_MSG_MODE + { + RMB_MSG_SOLACE = 0, + RMB_MSG_WEMQ = 1, + }; + + enum RMB_RSP_CODE + { + RMB_CODE_TIME_OUT = -1, + RMB_CODE_SUSS, + RMB_CODE_OTHER_FAIL, + RMB_CODE_AUT_FAIL, + RMB_CODE_DYED_MSG, + }; + +//**************************for wemq define******************************** +#define MAX_WEMQ_KFIFO_LENGTH (1UL << 16) +#define GETMSGID(buf,msgId) ({\ + char *p = (buf);\ + p += 2 * sizeof(int);\ + p += 3 * sizeof(char);\ + p += sizeof(StSystemHeader);\ + p += 2 * sizeof(StDestination);\ + (msgId) = *((unsigned long*)(p));\ +}) + +#define IS_DYED_MSG "IS_DYED_MSG" +#define MSG_HEAD_COMMAND_STR "command" +#define MSG_HEAD_SEQ_INT "seq" +#define MSG_HEAD_CODE_INT "code" +#define MSG_HEAD_MSG_STR "msg" + +#define MSG_HEAD_TYPE_INT "type" +#define MSG_HEAD_STATUS_INT "status" +#define MSG_HEAD_MSG_STR "msg" +#define MSG_HEAD_TIME_LINT "time" +#define MSG_HEAD_TIMESTAMP_LINT "timestamp" +#define MSG_HEAD_DEST_JSON "dest" +#define MSG_HEAD_DEST_SCENARIO_STR "scenario" +#define MSG_HEAD_DEST_SERVICE_STR "service" +#define MSG_HEAD_DEST_DCN_STR "dcn" +#define MSG_HEAD_DEST_ORGANIZATION_STR "organization" +#define MSG_HEAD_REDIRECT_OBJ "redirect" + +#define MSG_HEAD_SUB_BYPASS_TOPIC "topic" + +#define MSG_HEAD_IDC "idc" +#define MSG_HEAD_IP "ip" + +#define MSG_BODY_TOPIC_LIST_JSON "topicList" +#define MSG_BODY_TOPIC_STR "topic" +#define MSG_BODY_PROPERTY_JSON "properties" +#define MSG_BODY_PROPERTY_MSG_TYPE_STR "msgType" +#define MSG_BODY_PROPERTY_TTL_INT "TTL" +#define MSG_BODY_PROPERTY_SEQ_STR "SEQ" +#define MSG_BODY_PROPERTY_RR_REQUEST_UNIQ_ID_STR "RR_REQUEST_UNIQ_ID" +#define MSG_BODY_PROPERTY_KEYS_STR "keys" +#define MSG_BODY_PROPERTY_REPLYTO_STR "REPLY_TO" +#define MSG_BODY_PROPERTY_BORN_TIME_STR "BORN_TIME" +#define MSG_BODY_PROPERTY_STORE_TIME_STR "STORE_TIME" +#define MSG_BODY_PROPERTY_LEAVE_TIME_STR "LEAVE_TIME" +#define MSG_BODY_PROPERTY_ARRIVE_TIME_STR "ARRIVE_TIME" + +#define MSG_BODY_BYTE_BODY_JSON "body" +#define MSG_BODY_BYTE_BODY_APPHEADER_CONTENT_JSON "appHeaderContent" +#define MSG_BODY_BYTE_BODY_APPHEADER_NAME_STR "appHeaderName" +#define MSG_BODY_BYTE_BODY_CONTENT_STR "body" +#define MSG_BODY_BYTE_BODY_CREATETIME_LINT "createTime" +#define MSG_BODY_BYTE_BODY_SYSTEM_HEADER_CONTENT_JSON "sysHeaderContent" + +#define MSG_BODY_RMB_TRACE_LOG_JSON "rmbTraceLog" +#define MSG_BODY_RMB_TRACE_LOG_LOG_POINT_STR "logPoint" +#define MSG_BODY_RMB_TRACE_LOG_ERR_CODE_STR "errCode" +#define MSG_BODY_RMB_TRACE_LOG_ERR_MSG_STR "errMsg" +#define MSG_BODY_RMB_TRACE_LOG_MESSAGE_STR "message" +#define MSG_BODY_RMB_TRACE_LOG_EXTFIELDS_STR "extFields" + +#define MSG_BODY_SYSTEM_JSON "sysHeader" +#define MSG_BODY_SYSTEM_BIZ_STR "bizSeqNo" +#define MSG_BODY_SYSTEM_SEQNO_STR "consumerSeqNo" +#define MSG_BODY_SYSTEM_SVRID_STR "consumerSvrId" +#define MSG_BODY_SYSTEM_ORGSYS_STR "orgSysId" +#define MSG_BODY_SYSTEM_CSMID_STR "consumerId" +#define MSG_BODY_SYSTEM_TIME_LINT "tranTimestamp" +#define MSG_BODY_SYSTEM_CSMDCN_STR "consumerDCN" +#define MSG_BODY_SYSTEM_ORGSVR_STR "orgSvrId" +#define MSG_BODY_SYSTEM_ORGID_STR "organizationId" +#define MSG_BODY_SYSTEM_VER_STR "version" +#define MSG_BODY_SYSTEM_UNIID_STR "uniqueId" +#define MSG_BODY_SYSTEM_CONLEN_INT "contentLength" +#define MSG_BODY_SYSTEM_MSGTYPE_INT "messageType" +#define MSG_BODY_SYSTEM_RRTYPE_INT "rrType" +#define MSG_BODY_SYSTEM_ACK_SEQ "ack_seq" +#define MSG_BODY_SYSTEM_RECVTYPE_INT "receiveMode" +#define MSG_BODY_SYSTEM_SENDTIME_LINT "sendTimestamp" +#define MSG_BODY_SYSTEM_RECVTIME_LINT "receiveTimestamp" +#define MSG_BODY_SYSTEM_REPLYTIME_LINT "replyTimestamp" +#define MSG_BODY_SYSTEM_REPLYRECEIVETIME_LINT "replyReceiveTimestamp" +#define MSG_BODY_SYSTEM_APITYPE_INT "apiType" +#define MSG_BODY_SYSTEM_LOGICTYPE_INT "logicType" +#define MSG_BODY_SYSTEM_SOCOID_STR "solCorrelationId" +#define MSG_BODY_SYSTEM_EXTFIELDS_STR "extFields" +#define MSG_BODY_SYSTEM_API_VERSION "rmbVersion" +#define MSG_BODY_SYSTEM_REQ_IP "req_ip" +#define MSG_BODY_SYSTEM_REQ_SYS "req_sys" +#define MSG_BODY_SYSTEM_REQ_DCN "req_dcn" +#define MSG_BODY_SYSTEM_REQ_IDC "req_idc" +#define MSG_BODY_SYSTEM_RSP_IP "rsp_ip" +#define MSG_BODY_SYSTEM_RSP_SYS "rsp_sys" +#define MSG_BODY_SYSTEM_RSP_DCN "rsp_dcn" +#define MSG_BODY_SYSTEM_RSP_IDC "rsp_idc" + +#define MSG_BODY_APP_JSON "appHeader" + +#define MSG_BODY_DEST_JSON "destinationContent" +#define MSG_BODY_DEST_NAME_STR "name" +#define MSG_BODY_DEST_TYPE_STR "type" +#define MSG_BODY_DEST_SORE_STR "serviceOrEventId" +#define MSG_BODY_DEST_SCENARIO_STR "scenario" +#define MSG_BODY_DEST_ANY_DCN_STR "anyDCN" +#define MSG_BODY_DEST_DCN_STR "dcnNo" +#define MSG_BODY_DEST_ORGID_STR "organizationId" +#define MSG_BODY_DEST_ORGFLAG_INT "organizationIdInputFlag" + +#define MSG_BODY_TTL_LINT "timeToLive" +#define MSG_BODY_CONTENT_STR "content" +#define MSG_BODY_REPLYTO_STR "replyTo" +#define MSG_BODY_CREATETIME_LINT "createTime" +#define MSG_BODY_DELIVERYTIME_INT "deliveryTimes" +#define MSG_BODY_RESENT_BOOL "resent" +#define MSG_BODY_COID_STR "correlationId" +#define MSG_BODY_DUP_BOOL "duplicated" +#define MSG_BODY_SYN_BOOL "syn" +#define LOG_ERROR_POINT "ON_ERROR" + + typedef struct StRmbMsg StRmbMsg; + + typedef struct StWemqThreadMsg + { + unsigned int m_iCmd; + + unsigned int m_iHeaderLen; + unsigned int m_iBodyLen; + char *m_pHeader; + char *m_pBody; + } StWemqThreadMsg; + +#define RMB_MAX_UNIQUE_NUMS 2048 + + typedef struct StUniqueIdList + { + char unique_id[50]; + char biz_seq[50]; + unsigned int timeout; + unsigned int flag; + unsigned long timeStamp; + } StUniqueIdList; + + typedef struct StUniqueIdList DataType; + + typedef struct array + { + DataType *Data; + int size, max_size; + void (*Constructor) (struct array *); //构造函数 + void (*Input) (DataType, struct array *); //输入数据 + int (*get_array_size) (struct array *); //获取arr的大小 + int (*return_index_value) (struct array *, int); + void (*Destructor) (struct array *); //析构函数 + } Array; + +#define RMB_MAX_ERR_MSG_FROM_ACCESS 1024 + +//wemq msg 最多4m +#define WEMQ_MSG_MSX_LENGTH (1 << 22) + + typedef struct stContextProxy + { + pthread_t mainThreadId; + pthread_t coThreadId; + + char *mPubRRBuf; + + //for rr + pthread_mutex_t rrMutex; + pthread_cond_t rrCond; + int iFlagForRR; + + //for event msg, wait for ack + pthread_mutex_t eventMutex; + pthread_cond_t eventCond; + int iFlagForEvent; + long iSeqForEvent; + + //for add listen + pthread_mutex_t regMutex; + pthread_cond_t regCond; + int iFlagForReg; + //for add listen result check + int iResultForReg; + + //for pub session connect + pthread_mutex_t pubMutex; + pthread_cond_t pubCond; + int iFlagForPub; + int iFlagForPublish; + + //for sub session connect + pthread_mutex_t subMutex; + pthread_cond_t subCond; + int iFlagForSub; + +// myhash_t* rrHashTable; + void *pubContext; + void *subContext; + + StRmbMsg *pReplyMsg; + + //StUniqueIdList *pUniqueListForRRAsyncNew; + //StUniqueIdList *pUniqueListForRRAsyncOld; + + Array pUniqueListForRRAsyncNew; + Array pUniqueListForRRAsyncOld; + + StUniqueIdList stUnique; + + //StUniqueIdList stUniqueListForRRAsync[RMB_MAX_UNIQUE_NUMS]; + //StUniqueIdList stUniqueListForRRAsyncOld[RMB_MAX_UNIQUE_NUMS]; + + //Array stUniqueListForRRAsync; + //Array stUniqueListForRRAsyncOld; + + int iFlagForRun; + unsigned long ulGoodByeTime; + unsigned long ulLastClearRRAysncMsgTime; + unsigned long ulLastPrintOldListIsEmpty; + int iFlagForRRAsync; + + //for goodbye + pthread_mutex_t goodByeMutex; + pthread_cond_t goodByeCond; + int iFlagForGoodBye; + + StWemqTopicList stTopicList; + STRUCT_WEMQ_KFIFO (StWemqThreadMsg, MAX_WEMQ_KFIFO_LENGTH) pubFifo; + STRUCT_WEMQ_KFIFO (StWemqThreadMsg, MAX_WEMQ_KFIFO_LENGTH) subFifo; + } stContextProxy; + + typedef struct StThreadArgs + { + stContextProxy *pStContextProxy; + int contextType; + } StThreadArgs; + +#define WEMQ_FIFO_SIZE (2 << 20) + + typedef struct WemqThreadCtx + { + STRUCT_WEMQ_KFIFO (StWemqThreadMsg, WEMQ_FIFO_SIZE) * m_ptFifo; + stContextProxy *m_ptProxyContext; + + //int m_iThreadId; + char *m_pRecvBuff; + char *m_pSendBuff; + + //cache msg which from user thread; + StWemqThreadMsg m_stWemqThreadMsg; + StWemqThreadMsg m_stHeartBeat; + StWemqThreadMsg m_stHelloWord; + StWemqThreadMsg m_stListen; + + int m_iWemqThreadMsgHandled; + +// StWemqHeader m_stWemqHeader; + StWeMQMSG m_stWeMQMSG; + StWemqTopicList *m_ptTopicList; + + //for epoll + int m_iEpollFd; + struct epoll_event m_stEv; + struct epoll_event *m_ptEvents; + + int m_iFlagForSeverBreak; + + SSL_CTX *sslCtx; + + int m_iSockFd; + SSL *ssl; + + int m_iSockFdNew; + SSL *sslNew; + + int m_iSockFdOld; + SSL *sslOld; + + int m_iLastState; + int m_iState; + int m_contextType; + + int m_iHeartBeatCount; + unsigned int m_uiHeartBeatCurrent; + struct timeval stTimeNow; + struct timeval stTimeLast; + struct timeval stTimeLastRecv; + + // proxy server 地址 + char m_cProxyIP[100]; + char m_cProxyIPOld[100]; + unsigned int m_uiProxyPort; + unsigned int m_uiProxyPortOld; + int m_iLocalPort; // socket local port + + pthread_t m_threadID; // current thread's ID + +// bool m_lRedirect; + int m_lRedirect; + char m_cRedirectIP[100]; + int m_iRedirectPort; + + } WemqThreadCtx; +//************************************************************************* + +//**************************rmb msg define********************************* + + enum RmbDestinationType + { + RMB_DEST_TOPIC = 0, + RMB_DEST_QUEUE, + }; + +#define RMB_SYSTEMHEADER_EXTFIELDS_MAX_LEN 1024 * 2 // 2K +#define RMB_SYSTEMHEADER_PROPERTY_MAX_LEN 1024 * 2 // 2K + + typedef struct StSystemHeader + { + char cBizSeqNo[50]; //全局唯一业务流水号 + char cConsumerSeqNo[50]; //服务消费者系统调用流水号 + char cOrgSysId[10]; //交易原始发起方系统编号 + char cConsumerSysId[10]; //服务消费者系统编号 + char cConsumerSysVersion[10]; //服务消费者的系统版本号 + char cConsumerSvrId[50]; //服务消费者服务器标示(服务器名或IP地址) + char cRmbVersion[10]; //rmb版本号 + + char cOrgSvrId[50]; + char cUniqueId[50]; //unique id + char cConsumerDcn[10]; //服务消费者所在DCN + unsigned long ulTranTimeStamp; //交易发起时间戳 + char cAppHeaderClass[50]; //类名 + char cOrgId[10]; //法人号 + int flag; + + unsigned long ulSendTime; //发送时间 + unsigned long ulReceiveTime; //接收时间 + unsigned long ulReplyTime; //回包时间 + unsigned long ulReplyReceiveTime; //回包接收时间 + + unsigned long ulMessageDate; + + int iReceiveMode; + + int iContentLength; + char cExtFields[RMB_SYSTEMHEADER_EXTFIELDS_MAX_LEN]; + char cProperty[RMB_SYSTEMHEADER_PROPERTY_MAX_LEN]; + int iSetSysVersionFlag; + } StSystemHeader; + +#define REQ_BORN_TIMESTAMP "req_born_timestamp" +#define REQ_STORE_TIMESTAMP "req_store_timestamp" +#define REQ_LEAVE_TIMESTAMP "req_leave_timestamp" +#define REQ_ARRIVE_TIMESTAMP "req_arrive_timestamp" + +#define RSP_BORN_TIMESTAMP "rsp_born_timestamp" +#define RSP_STORE_TIMESTAMP "rsp_store_timestamp" +#define RSP_LEAVE_TIMESTAMP "rsp_leave_timestamp" +#define RSP_ARRIVE_TIMESTAMP "rsp_arrive_timestamp" + + typedef struct StAppHeader + { + char cTransCode[8]; // + char cSourceChannelType[32]; // + char cWordStationId[4]; // + } StAppHeader; + + typedef struct StDestination + { + int iDestType; //target type: 0: topic 1: queue + char cDestName[200]; + } StDestination; + + typedef struct StFlow StFlow; + +//包类型分类 + enum C_RMB_PKG_TYPE + { + ALL_TYPE_RMB = 0, //所有类型 + QUEUE_PKG = 1, //queue上的消息,一般为请求 + RR_TOPIC_PKG = 2, //RR的回包 + BROADCAST_TOPIC_PKG = 3, //广播包 + MANAGE_TOPIC_PKG = 4, //RMB内部管理topic包 + NEW_LOGIC_RECEIVE = 5, + NEW_LOGIC_SEND = 6, + }; + +//包来源分类 + enum C_RMB_LOGIC_TYPE + { + REQ_PKG_IN = 1, + RSP_PKG_IN = 2, + EVENT_PKG_IN = 3, + REQ_PKG_OUT = 4, + RSP_PKG_OUT = 5, + EVENT_PKG_OUT = 6, + + REQ_PKG_IN_WEMQ = 7, + RSP_PKG_IN_WEMQ = 8, + EVENT_PKG_IN_WEMQ = 9, + REQ_PKG_OUT_WEMQ = 10, + RSP_PKG_OUT_WEMQ = 11, + EVENT_PKG_OUT_WEMQ = 12, + MANAGE_PKG_IN_WEMQ = 13, + }; + + enum C_RMB_MESSAGE_TYPE + { + RMB_REQ_MSG = 1, + RMB_RSP_MSG = 2, + RMB_EVENT_MSG = 3, + }; + +//rmb转发包的方式 + enum UDP_OR_MQ + { + MSG_IPC_UDP = 0, + MSG_IPC_MQ = 1, + }; + + enum RMB_API_YPE + { + JAVA_TYPE = 1, + C_TYPE = 2, + JAVA_TYPE_WEMQ = 3, + C_TYPE_WEMQ = 4, + }; + + enum RMB_CONTEXT_TYPE + { + RMB_CONTEXT_TYPE_SUB = 0, + RMB_CONTEXT_TYPE_PUB = 1 + }; + +//typedef struct StRmbMsg + struct StRmbMsg + { + //sessionIndex for wemq + unsigned int uiSessIndex; + unsigned int uiFlowIndex; + + //pkg type + char cPkgType; //收到包的类型 + char cLogicType; //消息来源 + char cApiType; //apiType, enum RMB_API_YPE + StSystemHeader sysHeader; + StDestination dest; + StDestination replyTo; + unsigned long ulMsgId; + unsigned long ulMsgLiveTime; + char isDyedMsg[10]; + + //for receive msg + //char cServiceId[8]; + //char cScenario[2]; + + //char cAppHeader[MAX_APPHEADER_LENGTH]; + char *cAppHeader; + int iMallocAppHeaderLength; + int iAppHeaderLen; + + //char cContent[MAX_MSG_CONTENT_SIZE]; + char *cContent; + int iMallocContentLength; + int iContentLen; + + char cCorrId[MAX_COMMON_SIZE]; + int iCorrLen; + + //msg src + int iEventOrService; //0 event;1 service + char strTargetDcn[10]; + char strServiceId[10]; + char strScenarioId[5]; + + //for gsl + char strTargetOrgId[10]; + int iFLagForOrgId; + + //for flag check + int flag; + + int iMsgMode; //pub:send msg to wemq or solace sub:recv msg from wemq or solace + + char strLogBuf[1024]; +//}StRmbMsg; + }; + +//************for mq + typedef void (*rmb_callback_func) (const char *, const int, void *); + typedef int (*rmb_callback_func_v2) (const char *, const int, void *); +#define MAX_MQ_NUMS 10 +#define MAX_FIFO_PATH_NAME_LEN 200 +#define MAX_MQ_PKG_SIZE 10000000 +//static const unsigned int C_RMB_MQ_HEAD_SIZE = 2 * sizeof(unsigned int); +#define C_RMB_MQ_HEAD_SIZE 2 * sizeof(unsigned int) +#define C_RMB_MQ_PKG_HEAD_SIZE 2 * sizeof(unsigned int) +//static const unsigned int C_RMB_MQ_PKG_HEAD_SIZE = 2 * sizeof(unsigned int); + + typedef struct StRmbMq + { + unsigned int uiShmkey; + unsigned long ulShmId; + unsigned int uiShmSize; + + //head + tail + real data + char *pMqData; + unsigned int *pHead; + unsigned int *pTail; + + //real data + char *pBlock; + unsigned int uiBlockSize; + + } StRmbMq; + + typedef struct StRmbFifo + { + int iFd; + char strPath[MAX_FIFO_PATH_NAME_LEN]; + } StRmbFifo; + + typedef struct StRmbQueue + { + unsigned int uiSize; + + //head + tail + real data + char *pData; + unsigned int *pHead; + unsigned int *pTail; + + //real data + char *pBlock; + unsigned int uiBlockSize; + } StRmbQueue; + + typedef struct StRmbPipe + { + int fd[2]; + int r_fd; + int w_fd; + } StRmbPipe; + + typedef struct StMqInfo + { + StRmbMq *mq; + StRmbFifo *fifo; + + //for wemq + StRmbQueue *que; + StRmbPipe *pipe; + + int iIndex; //offset in vector + int iMsgType; //iPkgType,1 queue msg;2 rr topic msg;3 broadcast msg;4 manage msg + + rmb_callback_func func; + rmb_callback_func_v2 funcForNew; + void *args; + + //for epoll + int active; + + //for notify num + int iCount; + unsigned int uiLastCheckTime; + + int iMergeNotifyFLag; //0:not marge 1:marge + int iNotifyFactor; //the factor of notify + + pthread_mutex_t queMutex; + } StMqInfo; + + enum RmbMqIndex + { + req_mq_index = 1, + rr_rsp_mq_index = 2, + broadcast_mq_index = 3, + manage_mq_index = 4, + +// wemq_req_mq_index = 5, +// wemq_rr_rsp_mq_index = 6, +// wemq_broadcast_mq_index = 7, +// wemq_manage_mq_index = 8, + }; + +//for mq notify + typedef struct StRmbMqFifoNotify + { + StMqInfo vecMqInfo[MAX_MQ_NUMS]; + int iMqNum; + + StMqInfo *mqIndex[MAX_MQ_NUMS]; //see define of RmbMqIndex + //for select + fd_set readFd; + fd_set tmpReadFd; + struct timeval tv; + int iMaxFd; + + //for epoll + int iEpollFd; + + char *pBuf; + unsigned int uiBufLen; + + } StRmbMqFifoNotify; + +/////////////////////////////// + + typedef struct StContext StContext; + +//*************************context************************ + +//context的基本定义 + struct StContext + { + // for solace + unsigned int uiInitFlag; + + //for receive msgs + StRmbMsg *pReceiveMsg; + StRmbMsg *pReceiveMsgForRR; + StRmbMsg *pReceiveMsgForBroadCast; + + StRmbMsg *pReceiveWemqMsg; + StRmbMsg *pReceiveWemqMsgForRR; + StRmbMsg *pReceiveWemqMsgForBroadCast; + + //for receive msgs + char *pPkg; + unsigned int uiPkgLen; + + //for wemq + char *pWemqPkg; + unsigned int uiWemqPkgLen; + + char *pWemqPkgForRRAsync; + unsigned int uiWemqPkgForRRAsyncLen; + + //********UDP************* + //for rev req or broadcast + int iSocketForReq; + struct sockaddr_in tmpReqAddr; + + //for rev reply + int iSocketForRsp; + struct sockaddr_in tmpReplyAddr; + + //for rev broadcast + int iSocketForBroadcast; + struct sockaddr_in tmpBroadcastAddr; + + //*******MQ*************** + StRmbMqFifoNotify fifoMq; + + unsigned int uiNowTime; + + //sub or pub + void *pFather; + + //****for wemq + unsigned int uiInitWemqFlag; + + //for wemq proxy + stContextProxy *pContextProxy; + //sub or pub; + int contextType; + }; + +//********broadcast********* + typedef struct StBroadcastNode + { + char strServiceId[10]; + char strScenarioId[5]; + char cConsumerSysId[10]; + char cReserve[2]; + } StBroadcastNode; + +//********queue节点*********** + typedef struct StQueueNode + { + char cQueueName[30]; + int iQueueSize; + int iQueueUnackSize; + + } StQueueNode; + + typedef struct StQueueName + { + char cQueueName[30]; + } StQueueName; + + typedef struct StServiceStatus + { + char strTargetOrgId[10]; + char strServiceId[10]; + char strScenarioId[5]; + char cFlagForOrgId; + + char cResult; + char cRouteFlag; + char strTargetDcn[10]; + unsigned long ulGetTimes; + unsigned long ulInvalidTime; + } StServiceStatus; + + typedef struct StRmbConfig + { + char strConfigFile[500]; + + char cConsumerSysId[10]; + char cConsumerSysVersion[10]; + char cConsumerSvrId[100]; + char cOrgSvrId[50]; + //char cUniqueId[100]; + char cConsumerDcn[10]; + + //主机名 + char cHostName[100]; + char cHostIp[50]; + unsigned int uiPid; + + //log + int iLogLevel; + //RmbLogFile stLog; + char logFileName[200]; + int iLogFileNums; + int iLogFileSize; + int iLogShiftType; + + StRmbLog gRmbLog; + + //for solace api init + unsigned int uiIsInitSolaceApi; + //solace + int iSwitchForSolaceLog; + char strSolaceLog[100]; + int iSolaceLogLevel; + + //for connect success timeout + int createConnectionTimeOut; + + //debug switch + int iDebugSwitch; + + //queue config + StQueueNode queueNodeList[5000]; + int iQueueListSize; + + StBroadcastNode broadNodeList[5000]; + int iBroadListSize; + + //for browser + pthread_mutex_t configMutex; + pthread_cond_t configCond; + int iFlag; + + //for mergeq for gsl + pthread_mutex_t mergeqForGslMutex; + pthread_cond_t mergeqForGslCond; + int iFlagForMerge; + int iMergeQueue; + //for merge queue + pthread_mutex_t mergeQueueMutex; + + //for log + pthread_mutex_t configLog; + + //for send white list +// pthread_mutex_t sendWhiteListMutex; + + //for debug print + char *pLogBuf; + + //for manage session + int iManageFlag; //0 表示还没有, 1表示有 + + StQueueName fullQueueList[3000]; //queue + int iFullNums; + + //for flag + int iFlagForReq; //0:UDP,1:MQ + int iFlagForRRrsp; //0:UDP,1:MQ + int iFlagForBroadCast; //0:UDP,1:MQ + int iFlagForManage; //0:UDP,1:MQ + + //每次处理的个数 + int iEveryTimeProcessNum; + + //提醒的try间隔 + int iNotifyCheckSpan; + + //for req mq + char strFifoPathForReq[128]; + unsigned int uiShmKeyForReq; + unsigned int uiShmSizeForReq; + + //for rsp + char strFifoPathForRRrsp[128]; + unsigned int uiShmKeyForRRrsp; + unsigned int uiShmSizeForRRrsp; + + //for broadcast + char strFifoPathForBroadcast[128]; + unsigned int uiShmKeyForBroadcast; + unsigned int uiShmSizeForBroadcast; + + //flag + //是否合并通知的开关 + int iFLagForMergeNotify; + + //orgId + char strOrgId[10]; + + //last error + char _lastError[300]; + + //是否允许发送的开关 + int iFlagForPublish; + unsigned long ulLastStopTime; + unsigned long ulLastAllowTime; + char cLastMsg[50]; + + //rmb的启动时间 + unsigned long ulStartTime; //rmb init time + + //RR info + unsigned int uiSendRRMsgNums; + unsigned int uiSendRRMsgError; + + //Event info + unsigned int uiSendEventMsg; + unsigned int uiSendEventMsgError; + + //AyncRR + unsigned int uiSendAyncRRMsg; + unsigned int uiSendAyncRRMsgError; + + //receiveMsg + unsigned int uiReceiveServiceReqMsg; + unsigned int uiReceiveAyncRRReply; + unsigned int uiReceiveEventMsg; + + StServiceStatus serviceStatusList[MAX_SERVICE_STATUS_CACHE_NUMS]; + int iCacheServiceNums; + + int iCacheTimeoutTime; + int iCacheSuccTimeoutTime; //gsl query success, timeout default is 600s + int iCacheFailedTimeoutTime; //gsl query failed, timeout default is 30s + + //timtout + unsigned long ulNowTtime; + + //exit timtout + unsigned long ulExitTimeOut; + + //for rmb proxy worker + int iRmbMode; + + int iWorkerSendBufSize; + + //for reload cfg + //signal1 + int iSwitchForSignal1; + //signal2 + int iSwitchForSignal2; + + //for ack + int ackTimers; + int ackThresHold; + + //for query timeout + int iQueryTimeout; + + //for sub broadcast LVQ + unsigned int uiIsBroadcastLVQ; + + //for msg trans by solace timeout :daxin + int iCommonTimeOut; + //for rmb period stat log + int iStatPeriod; + //get group topic status time + int iGetGroupTopicTime; + //get send white list time + int iGetSendWhiteListTime; + + //for clean merge q thread + pthread_t pid_merge; + int flag_merge; + + // logServer log switch for user + int iLogserverSwitch; + //logServer log switch for api + int iApiLogserverSwitch; + //rmb mode: wemq + char cRmbMode[10]; + int iConnWemq; + + //gsl control + int iReqGsl; + + //for config center + char cConfigIp[256]; + int iConfigPort; + int iConfigTimeout; + int configIpPosInArr; + char ConfigAddr[512]; +// char cWemqSavePath[1024]; + + int tlsOnoff; + + //local IDC config + char cRegion[10]; + + int iFlagForLoop; + + //for proxyContext + int iProxyContextNums; + void *pProxyContext; + + //for mode worker heart beat; + int heartBeatPeriod; + int heartBeatTimeout; + + //for get access ip + int getAccessIpPeriod; + + //for access ack + int accessAckTimeOut; + + //for rr async + int rrAsyncTimeOut; + + //for access goodbye + int goodByeTimeOut; + + // wemq-access 配置中心服务器 + int iWemqUseHttpCfg; // 是否启用Http配置中心 + //for default tcp + char cWemqProxyIp[100]; + unsigned int cWemqProxyPort; + int iWemqTcpConnectRetryNum; // 连接wemq-access重试次数 + int iWemqTcpConnectDelayTime; // 每次重连间隔时间(ms) + + int iWemqTcpConnectTimeout; // 每次TCP连接超时时间 + int iWemqTcpSocketTimeout; // TCP socket 超时时间 + + //for topic + int iNormalTimeout; // 监听topic超时时间(ms), default is:120000 + + //for wemq user/passwd + char cWemqUser[100]; + char cWemqPasswd[100]; + + int mqIsEmpty; + + char strDepartMent[20]; + } StRmbConfig; + + typedef struct RmbPythonConfig + { + //for req mq + char strFifoPathForReq[128]; + unsigned int uiShmKeyForReq; + unsigned int uiShmSizeForReq; + + //for rsp + char strFifoPathForRRrsp[128]; + unsigned int uiShmKeyForRRrsp; + unsigned int uiShmSizeForRRrsp; + + //for broadcast + char strFifoPathForBroadcast[128]; + unsigned int uiShmKeyForBroadcast; + unsigned int uiShmSizeForBroadcast; + } RmbPythonConfig; + + enum MQ_STATUS + { + MQ_INIT = 0, + MQ_IS_NOT_EMPTY, + MQ_IS_EMPTY + }; + +//灰度完成queue的场景ID +#define GRAY_COMPLETE_SCENE "FR" + + enum TOPIC_STATUS + { + QUEUE_NOT_GRAY = 0, + QUEUE_GRAY_INIT, + QUEUE_GRAY_NOT_COMPLETE, + QUEUE_GRAY_COMPLETE + }; + + typedef struct StRmbListenQueueInfo + { + char cDcn[5]; + char cServiceId[10]; + char cScenarioId[5]; + } st_rmb_queue_info; + +//rmb topic info + typedef struct StRmbTopicInfo + { + char cServiceId[10]; + char cScenarioId[5]; + char cTopicGroup[32]; + char cTopicStatus[3]; + int flag; + } StRmbTopicInfo; + + extern StRmbConfig *pRmbStConfig; + extern char cManageTopic[30]; + extern char cQueueFullTopic[30]; + extern char cLogLevelTopic[30]; +///////////////add by wan + extern char cPublishCheck[30]; +///////////////////////////// + extern StContext *g_pStContextArry[MAX_RMB_CONTEXT]; +#define LOGRMB(loglevel,fmt, args...) {LogRmb(loglevel, "[%s:%d(%s)]["fmt"]", __FILE__, __LINE__, __FUNCTION__, ## args);\ + if(loglevel==RMB_LOG_ERROR) snprintf(pRmbStConfig->_lastError, sizeof(pRmbStConfig->_lastError)-1, fmt, ## args);} + +//****common tool******* +#define RMB_MGS_PRINT_P(p) p->cConsumerSysId,p->cConsumerSysId,p->cConsumerSysId, +#define RMB_MAX(a,b) (a>b)?a:b +#define RMB_MIN(a,b) (a len){return -1;} +#define RMB_LEN_CHECK(a,len); if(strlen(a) != len){rmb_errno=RMB_ERROR_ARGV_LEN_ERROR;return rmb_errno;} + +//#define RMB_CHECK_POINT_NULL(a,b); if((void*)a == NULL) {LOGRMB(RMB_LOG_ERROR,"%s is NULL!", b);return -1;} +#define RMB_CHECK_POINT_NULL(a,b); if((void*)a == NULL) {LOGRMB(RMB_LOG_ERROR,"%s is NULL!", b);rmb_errno=RMB_ERROR_ARGV_NULL;return RMB_ERROR_ARGV_NULL;} +//end +#define RMB_MEMSET(a); memset(&a, 0, sizeof(a)); + +#define RMB_ADD_SESSION_PROPERTY(a,b,c); sprintf(a->cSessionProps[a->uiPropIndex], "%s", b);\ + a->vecPSessProps[a->uiPropIndex] = a->cSessionProps[a->uiPropIndex];\ + a->uiPropIndex++;\ + sprintf(a->cSessionProps[a->uiPropIndex], "%s", c);\ + a->vecPSessProps[a->uiPropIndex] = a->cSessionProps[a->uiPropIndex];\ + a->uiPropIndex++; + +#define RMB_ADD_FLOW_PROPERTY(a,b,c); sprintf(a->cFlowProps[a->uiPropIndex], "%s", b);\ + a->vecPFlowProps[a->uiPropIndex] = a->cFlowProps[a->uiPropIndex];\ + a->uiPropIndex++;\ + sprintf(a->cFlowProps[a->uiPropIndex], "%s", c);\ + a->vecPFlowProps[a->uiPropIndex] = a->cFlowProps[a->uiPropIndex];\ + a->uiPropIndex++; + +#define RMB_ADD_FLOW_PROPERTY_INT(a,b,c); sprintf(a->cFlowProps[a->uiPropIndex], "%s", b);\ + a->vecPFlowProps[a->uiPropIndex] = a->cFlowProps[a->uiPropIndex]; \ + a->uiPropIndex++; \ + sprintf(a->cFlowProps[a->uiPropIndex], "%d", c);\ + a->vecPFlowProps[a->uiPropIndex] = a->cFlowProps[a->uiPropIndex];\ + a->uiPropIndex++; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_errno.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_errno.h new file mode 100644 index 0000000000..6f7d7aa9fe --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_errno.h @@ -0,0 +1,137 @@ +// 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. + +#ifndef __RMB_ERRNO_H__ +#define __RMB_ERRNO_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + + extern int *rmb_error (void) __attribute__ ((__const__)); + +#define rmb_errno (*rmb_error()) + + struct rmb_err_msg + { + int err_no; + const char *err_msg; + }; + +#define RMB_MAX_ERR_NUMS 500 +#define RMB_ERROR_BASE_BEGIN 10000 + +//错误码列表 +#define RMB_ERROR_ARGV_NULL 10001 //参数为空 +#define RMB_ERROR_ARGV_LEN_ERROR 10002 //参数长度错误 +#define RMB_ERROR_MALLOC_FAIL 10003 //申请内存失败 +#define RMB_ERROR_INIT_CONTEXT_FAIL 10004 //初始化context失败 +#define RMB_ERROR_MSG_MISSING_PART 10005 //发送RMB消息必要字段缺少 +#define RMB_ERROR_RR_INTERFACE_CAN_NOT_SEND_EVENT_MSG 10006 //RMB同步接口不允许发送异步消息 +#define RMB_ERROR_EVENT_INTERFACE_CAN_NOT_SEND_RR_MSG 10007 //RMB异步接口不允许发送同步消息 +#define RMB_ERROR_NOW_CAN_NOT_SEND_MSG 10008 //现在禁止发送消息 +#define RMB_ERROR_QUEUE_FULL 10009 //该topic已queue满,不允许发送 +#define RMB_ERROR_GSL_SERVICE_ID_NULL 10010 //GSL服务id为空 +#define RMB_ERROR_GSL_SERVICE_ID_ERROR 10011 //GSL服务id路由失败 +#define RMB_ERROR_GSL_SVR_ERROR 10012 //GSL服务器返回失败 +#define RMB_ERROR_REQ_GSL_ERROR 10013 //请求GSL服务失败 +#define RMB_ERROR_MSG_UUID_FAIL 10014 //RMB消息生成UUID失败 +#define RMB_ERROR_MSG_SET_SYSTEMHEADER_FAIL 10015 //RMB消息初始化为SOLACE消息时设置systemHeader失败 +#define RMB_ERROR_SEND_GET_SESSION_FAIL 10016 //发送消息时,获取可用session失败 +#define RMB_ERROR_SEND_EVENT_MSG_FAIL 10017 //发送异步消息失败 +#define RMB_ERROR_SEND_RR_MSG_FAIL 10018 //发送同步消息失败 +#define RMB_ERROR_SEND_RR_MSG_TIMEOUT 10019 //发送同步消息超时 +#define RMB_ERROR_REPLY_TO_NULL 10020 //RR请求消息缺少replyTo,不允许reply +#define RMB_ERROR_REPLY_FAIL 10021 //回复消息失败 +#define RMB_ERROR_SESSION_CONNECT_FAIL 10022 //session连接失败--->连接session失败,请检查rmb配置文件是否正确 +#define RMB_ERROR_SESSION_RECONNECT_FAIL 10023 //session重连失败 +#define RMB_ERROR_SESSION_DESTORY_FAIL 10024 //session销毁失败 +#define RMB_ERROR_SESSION_NUMS_LIMIT 10025 //该类型session连接数已达上限 +#define RMB_ERROR_LISTEN_QUEUE_NOT_EXIST 10026 //监听queue失败,不存在该queue +#define RMB_ERROR_LISTEN_QUEUE_FAIL 10027 //监听queue失败 +#define RMB_ERROR_FLOW_DESTORY_FAIL 10028 //flow销毁失败 +#define RMB_ERROR_LISTEN_TOPIC_FAIL 10029 //监听topic失败 +#define RMB_ERROR_INIT_MQ_FAIL 10030 //初始化消息通信MQ失败 +#define RMB_ERROR_INIT_FIFO_FAIL 10031 //初始化通知FIFO失败 +#define RMB_ERROR_INIT_UDP_FAIL 10032 //初始化UDP失败 +#define RMB_ERROR_INIT_EPOLL_FAIL 10033 //初始化Epoll失败 +#define RMB_ERROR_MQ_NUMS_LIMIT 10034 //添加MQ数量超过上限 +#define RMB_ERROR_ENQUEUE_MQ_FAIL 10035 //消息入队MQ失败 +#define RMB_ERROR_DEQUEUE_MQ_FAIL 10036 //消息出队MQ失败 +#define RMB_ERROR_MSG_2_BUF_FAIL 10037 //RMB消息转为Buf失败 +#define RMB_ERROR_BUF_2_MSG_FAIL 10038 //Buf转RMB消息失败 +#define RMB_ERROR_MSG_SET_CONTENT_TOO_LARGE 10039 //RMB消息设置Content过大 +#define RMB_ERROR_MSG_SET_APPHEADER_TOO_LARGE 10040 //RMB消息设置AppHeader过大 +#define RMB_ERROR_MSG_TTL_0 10041 //RMB消息设置存活时间必须大于0 +#define RMB_ERROR_RCV_MSG_GET_CONTENT_FAIL 10042 //RMB接收消息获取Content失败 +#define RMB_ERROR_RCV_MSG_GET_BINARY_FAIL 10043 //RMB接收消息获取BinaryAttachment失败 +#define RMB_ERROR_RCV_MSG_CONTENT_TOO_LARGE 10044 //RMB接收消息Content过大 +#define RMB_ERROR_RCV_MSG_APPHEADER_TOO_LARGE 10045 //RMB接收消息AppHeader过大 +#define RMB_ERROR_MANAGE_MSG_PKG_ERROR 10046 //RMB管理消息包格式错误 +#define RMB_ERROR_MANAGE_MSG_PKG_CHECK_FAIL 10047 //RMB管理消息鉴权失败 +#define RMB_ERROR_CONTEXT_CREATE_FAIL 10048 //CONTEXT创建失败 +#define RMB_ERROR_FIFO_PARA_ERROR 10049 //FIFO参数错误 +#define RMB_ERROR_SHM_PARA_ERROR 10050 //SHM参数错误 +#define RMB_ERROR_SEND_FIFO_NOTIFY_ERROR 10051 //fifo发送通知失败 +#define RMB_ERROR_FLOW_NUMS_LIMIT 10052 //flow数目限制 +#define RMB_ERROR_MSG_GET_SYSTEMHEADER_ERROR 10053 //消息systemHeader错误 +#define RMB_ERROR_RMB_MSG_2_SOLACE_MSG_ERROR 10054 //copy rmb msg 2 solace msg error +#define RMB_ERROR_SOLACE_MSG_2_RMB_MSG_ERROR 10055 //copy solace msg 2 rmb msg error +#define RMB_ERROR_NO_AVAILABLE_SESSION 10056 //没有可用的session +#define RMB_ERROR_NO_BROADCAST_SESSION 10057 //没有可用的添加广播的session +#define RMB_ERROR_NO_AVAILABLE_CONTEXT 10058 //没有可用的context +#define RMB_ERROR_SET_FLOW_PROPETY 10059 //设置flow属性错误 +#define RMB_ERROR_ACK_MSG_FAIL 10060 //ack消息失败 +#define RMB_ERROR_LOGIC_NOTIFY_INIT 10061 //logic进程notify初始化失败 +#define RMB_ERROR_SESSION_ADD_FAIL 10062 //增加session失败 +#define RMB_ERROR_WORKER_NUMS_LIMIT 10063 //worker数量限制 +#define RMB_ERROR_BUF_NOT_ENOUGH 10064 //buf不够存储 +#define RMB_ERROR_STOP_FLOW_ERROR 10065 //停止flow收消息失败 +#define RMB_ERROR_DEQUEUE_MQ_EMPTY 10066 //消息队列出队为空 +#define RMB_ERROR_REMOVE_TOPIC_FAIL 10067 //删除监听topic失败 + +//proxy add +#define RMB_NOT_REGISTER_WORKER 10068 //worker还未注册 +#define RMB_SEND_MSG_ERROR_TYPE 10069 //发送消息错误的类型 +#define RMB_MSG_DECODE_ERROR 10070 //worker到proxy消息decode错误 +#define RMB_WORKER_BUF_FULL 10071 //worker满了 + +#define RMB_ERROR_CREATE_THREAD_FAIL 10072 //创建线程失败 +#define RMB_ERROR_ENCODE_FAIL 10073 //Encode失败 +#define RMB_ERROR_DECODE_FAIL 10074 //Decode失败 +#define RMB_ERROR_RR_RSP_NOTIFY_ERROR 10075 //RR回包唤醒错误 +#define RMB_ERROR_WORKER_REGISTER_ERROR 10076 //注册worker失败 +#define RMB_ERROR_WORKER_WINDOW_FULL 10077 //worker发送队列已满; +#define RMB_ERROR_WORKER_PUT_FIFO_ERROR 10078 //put msg into fifo error + +#define RMB_ERROR_START_CALL_FAIL 10079 +#define RMB_ERROR_END_CALL_FAIL 10080 +#define RMB_ERROR_ENTRY_FAIL 10081 +#define RMB_ERROR_EXIT_FAIL 10082 +#define RMB_ERROR_TOPIC_COUNT_TOO_LARGE 10083 //流控比时,topic个数超过最大个数 +#define RMB_ERROR_CLIENT_GOODBYE_TIMEOUT 10084 //客户端退出超时 + + void init_error (); + + const char *get_rmb_last_error (); + + void rmb_reset_error (); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_http_client.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_http_client.h new file mode 100644 index 0000000000..c916285e1c --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_http_client.h @@ -0,0 +1,38 @@ +// 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. + +#ifndef __RMB_HTTP_CLIENT_H +#define __RMB_HTTP_CLIENT_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + struct rmb_http_buffer + { + size_t len; + char *data; + }; + +// timeout: ms + int rmb_http_easy_get (const char *url, void *buffer, long timeout); +//int rmb_http_easy_post(char* url, char* post_data, size_t len, void* buffer, size_t size, size_t* used, long timeout); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_list.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_list.h new file mode 100644 index 0000000000..0dd1c016d9 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_list.h @@ -0,0 +1,564 @@ +// 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. + +/** + * copy from linux_list.h + */ + +#ifndef RMB_LIST_H_ +#define RMB_LIST_H_ + +#include + +/* + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ + +typedef struct rmb_st_list +{ + struct st_list *prev, *next; + void *data; +} RMB_LIST; + +struct rmb_list_head +{ + struct rmb_list_head *next, *prev; +}; + +#define RMB_LIST_HEAD_INIT(name) { &(name), &(name) } + +#define RMB_LIST_HEAD(name) \ + struct rmb_list_head name = RMB_LIST_HEAD_INIT(name) + +static inline void RMB_INIT_LIST_HEAD (struct rmb_list_head *list) +{ + list->next = list; + list->prev = list; +} + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __rmb_list_add (struct rmb_list_head *newNode, + struct rmb_list_head *prev, + struct rmb_list_head *next) +{ + next->prev = newNode; + newNode->next = next; + newNode->prev = prev; + prev->next = newNode; +} + +/** + * list_add - add a new entry + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static inline void rmb_list_add (struct rmb_list_head *newNode, + struct rmb_list_head *head) +{ + __rmb_list_add (newNode, head, head->next); +} + +/** + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static inline void rmb_list_add_tail (struct rmb_list_head *newNode, + struct rmb_list_head *head) +{ + __rmb_list_add (newNode, head->prev, head); +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __rmb_list_del (struct rmb_list_head *prev, + struct rmb_list_head *next) +{ + next->prev = prev; + prev->next = next; +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty() on entry does not return true after this, the entry is + * in an undefined state. + */ +static inline void rmb_list_del (struct rmb_list_head *entry) +{ + __rmb_list_del (entry->prev, entry->next); + entry->next = NULL; + entry->prev = NULL; +} + +/** + * list_replace - replace old entry by new one + * @old : the element to be replaced + * @new : the new element to insert + * + * If @old was empty, it will be overwritten. + */ +static inline void rmb_list_replace (struct rmb_list_head *old, + struct rmb_list_head *newNode) +{ + newNode->next = old->next; + newNode->next->prev = newNode; + newNode->prev = old->prev; + newNode->prev->next = newNode; +} + +static inline void rmb_list_replace_init (struct rmb_list_head *old, + struct rmb_list_head *newNode) +{ + rmb_list_replace (old, newNode); + RMB_INIT_LIST_HEAD (old); +} + +/** + * list_del_init - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +static inline void rmb_list_del_init (struct rmb_list_head *entry) +{ + __rmb_list_del (entry->prev, entry->next); + RMB_INIT_LIST_HEAD (entry); +} + +/** + * list_move - delete from one list and add as another's head + * @list: the entry to move + * @head: the head that will precede our entry + */ +static inline void rmb_list_move (struct rmb_list_head *list, + struct rmb_list_head *head) +{ + __rmb_list_del (list->prev, list->next); + rmb_list_add (list, head); +} + +/** + * list_move_tail - delete from one list and add as another's tail + * @list: the entry to move + * @head: the head that will follow our entry + */ +static inline void rmb_list_move_tail (struct rmb_list_head *list, + struct rmb_list_head *head) +{ + __rmb_list_del (list->prev, list->next); + rmb_list_add_tail (list, head); +} + +/** + * list_is_last - tests whether @list is the last entry in list @head + * @list: the entry to test + * @head: the head of the list + */ +static inline int rmb_list_is_last (const struct rmb_list_head *list, + const struct rmb_list_head *head) +{ + return list->next == head; +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static inline int rmb_list_empty (const struct rmb_list_head *head) +{ + return head->next == head; +} + +/** + * list_empty_careful - tests whether a list is empty and not being modified + * @head: the list to test + * + * Description: + * tests whether a list is empty _and_ checks that no other CPU might be + * in the process of modifying either member (next or prev) + * + * NOTE: using list_empty_careful() without synchronization + * can only be safe if the only activity that can happen + * to the list entry is list_del_init(). Eg. it cannot be used + * if another CPU could re-list_add() it. + */ +static inline int rmb_list_empty_careful (const struct rmb_list_head *head) +{ + struct rmb_list_head *next = head->next; + return (next == head) && (next == head->prev); +} + +/** + * list_is_singular - tests whether a list has just one entry. + * @head: the list to test. + */ +static inline int rmb_list_is_singular (const struct rmb_list_head *head) +{ + return !rmb_list_empty (head) && (head->next == head->prev); +} + +static inline void __rmb_list_cut_position (struct rmb_list_head *list, + struct rmb_list_head *head, + struct rmb_list_head *entry) +{ + struct rmb_list_head *new_first = entry->next; + list->next = head->next; + list->next->prev = list; + list->prev = entry; + entry->next = list; + head->next = new_first; + new_first->prev = head; +} + +/** + * list_cut_position - cut a list into two + * @list: a new list to add all removed entries + * @head: a list with entries + * @entry: an entry within head, could be the head itself + * and if so we won't cut the list + * + * This helper moves the initial part of @head, up to and + * including @entry, from @head to @list. You should + * pass on @entry an element you know is on @head. @list + * should be an empty list or a list you do not care about + * losing its data. + * + */ +static inline void rmb_list_cut_position (struct rmb_list_head *list, + struct rmb_list_head *head, + struct rmb_list_head *entry) +{ + if (rmb_list_empty (head)) + return; + if (rmb_list_is_singular (head) && (head->next != entry && head != entry)) + return; + if (entry == head) + RMB_INIT_LIST_HEAD (list); + else + __rmb_list_cut_position (list, head, entry); +} + +static inline void __rmb_list_splice (const struct rmb_list_head *list, + struct rmb_list_head *prev, + struct rmb_list_head *next) +{ + struct rmb_list_head *first = list->next; + struct rmb_list_head *last = list->prev; + + first->prev = prev; + prev->next = first; + + last->next = next; + next->prev = last; +} + +/** + * list_splice - join two lists, this is designed for stacks + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void rmb_list_splice (const struct rmb_list_head *list, + struct rmb_list_head *head) +{ + if (!rmb_list_empty (list)) + __rmb_list_splice (list, head, head->next); +} + +/** + * list_splice_tail - join two lists, each list being a queue + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void rmb_list_splice_tail (struct rmb_list_head *list, + struct rmb_list_head *head) +{ + if (!rmb_list_empty (list)) + __rmb_list_splice (list, head->prev, head); +} + +/** + * list_splice_init - join two lists and reinitialise the emptied list. + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * The list at @list is reinitialised + */ +static inline void rmb_list_splice_init (struct rmb_list_head *list, + struct rmb_list_head *head) +{ + if (!rmb_list_empty (list)) + { + __rmb_list_splice (list, head, head->next); + RMB_INIT_LIST_HEAD (list); + } +} + +/** + * list_splice_tail_init - join two lists and reinitialise the emptied list + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * Each of the lists is a queue. + * The list at @list is reinitialised + */ +static inline void rmb_list_splice_tail_init (struct rmb_list_head *list, + struct rmb_list_head *head) +{ + if (!rmb_list_empty (list)) + { + __rmb_list_splice (list, head->prev, head); + RMB_INIT_LIST_HEAD (list); + } +} + +/** +* container_of - cast a member of a structure out to the containing structure +* @ptr: the pointer to the member. +* @type: the type of the container struct this is embedded in. +* @member: the name of the member within the struct. +* +*/ + +#define rmb_container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define rmb_list_entry(ptr, type, member) \ + rmb_container_of(ptr, type, member) + +/** + * list_first_entry - get the first element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + * + * Note, that list is expected to be not empty. + */ +#define rmb_list_first_entry(ptr, type, member) \ + rmb_list_entry((ptr)->next, type, member) + +/** + * list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop cursor. + * @head: the head for your list. + */ +#define rmb_list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); \ + pos = pos->next) + +/** + * __list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop cursor. + * @head: the head for your list. + * + * This variant differs from list_for_each() in that it's the + * simplest possible list iteration code, no prefetching is done. + * Use this for code that knows the list to be very short (empty + * or 1 entry) most of the time. + */ +#define __rmb_list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) + +/** + * list_for_each_prev - iterate over a list backwards + * @pos: the &struct list_head to use as a loop cursor. + * @head: the head for your list. + */ +#define rmb_list_for_each_prev(pos, head) \ + for (pos = (head)->prev; pos != (head); \ + pos = pos->prev) + +/** + * list_for_each_safe - iterate over a list safe against removal of list entry + * @pos: the &struct list_head to use as a loop cursor. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define rmb_list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +/** + * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry + * @pos: the &struct list_head to use as a loop cursor. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define rmb_list_for_each_prev_safe(pos, n, head) \ + for (pos = (head)->prev, n = pos->prev; \ + pos != (head); \ + pos = n, n = pos->prev) + +/** + * list_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define rmb_list_for_each_entry(pos, head, member) \ + for (pos = rmb_list_entry((head)->next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = rmb_list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_for_each_entry_reverse - iterate backwards over list of given type. + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define rmb_list_for_each_entry_reverse(pos, head, member) \ + for (pos = rmb_list_entry((head)->prev, typeof(*pos), member); \ + &pos->member != (head); \ + pos = rmb_list_entry(pos->member.prev, typeof(*pos), member)) + +/** + * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() + * @pos: the type * to use as a start point + * @head: the head of the list + * @member: the name of the list_struct within the struct. + * + * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). + */ +#define rmb_list_prepare_entry(pos, head, member) \ + ((pos) ? : rmb_list_entry(head, typeof(*pos), member)) + +/** + * list_for_each_entry_continue - continue iteration over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Continue to iterate over list of given type, continuing after + * the current position. + */ +#define rmb_list_for_each_entry_continue(pos, head, member) \ + for (pos = rmb_list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = rmb_list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_for_each_entry_continue_reverse - iterate backwards from the given point + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Start to iterate over list of given type backwards, continuing after + * the current position. + */ +#define rmb_list_for_each_entry_continue_reverse(pos, head, member) \ + for (pos = rmb_list_entry(pos->member.prev, typeof(*pos), member); \ + &pos->member != (head); \ + pos = rmb_list_entry(pos->member.prev, typeof(*pos), member)) + +/** + * list_for_each_entry_from - iterate over list of given type from the current point + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Iterate over list of given type, continuing from current position. + */ +#define rmb_list_for_each_entry_from(pos, head, member) \ + for (; &pos->member != (head); \ + pos = rmb_list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define rmb_list_for_each_entry_safe(pos, n, head, member) \ + for (pos = rmb_list_entry((head)->next, typeof(*pos), member), \ + n = rmb_list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = rmb_list_entry(n->member.next, typeof(*n), member)) + +/** + * list_for_each_entry_safe_continue + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Iterate over list of given type, continuing after current point, + * safe against removal of list entry. + */ +#define rmb_list_for_each_entry_safe_continue(pos, n, head, member) \ + for (pos = rmb_list_entry(pos->member.next, typeof(*pos), member), \ + n = rmb_list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = rmb_list_entry(n->member.next, typeof(*n), member)) + +/** + * list_for_each_entry_safe_from + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Iterate over list of given type from current point, safe against + * removal of list entry. + */ +#define rmb_list_for_each_entry_safe_from(pos, n, head, member) \ + for (n = rmb_list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = rmb_list_entry(n->member.next, typeof(*n), member)) + +/** + * list_for_each_entry_safe_reverse + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Iterate backwards over list of given type, safe against removal + * of list entry. + */ +#define rmb_list_for_each_entry_safe_reverse(pos, n, head, member) \ + for (pos = rmb_list_entry((head)->prev, typeof(*pos), member), \ + n = rmb_list_entry(pos->member.prev, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = rmb_list_entry(n->member.prev, typeof(*n), member)) + +#endif /* RMB_LIST_H_ */ diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_log.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_log.h new file mode 100644 index 0000000000..5ebae8fcf8 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_log.h @@ -0,0 +1,121 @@ +// 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. + +#ifndef _RMB_LOG_H_ +#define _RMB_LOG_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum RMB_LOG_TYPE +{ + RMB_LOG_TYPE_NORMAL = 0, //不需要滚动 + RMB_LOG_TYPE_CYCLE, //按大小滚动 + RMB_LOG_TYPE_DAILY, //按日期滚动 + RMB_LOG_TYPE_DAILY_AND_CYCLE, //按日期和大小一起滚动 + RMB_LOG_TYPE_CYCLE_BY = 6, //按大小滚动 +}; + +enum RMB_LOG_LEVEL +{ + RMB_LOG_FATAL = 0, + RMB_LOG_ERROR, + RMB_LOG_WARN, + RMB_LOG_INFO, + RMB_LOG_DEBUG, + RMB_LOG_ALL +}; + +typedef struct StRmbLogPara +{ + int _logLevel; + int _shiftType; + char _path[256]; + int _maxFileSize; + int _maxFileNum; +} StRmbLogPara; + +typedef struct StRmbLog +{ + FILE *_pStatFile; + FILE *_pLogFile; + char _logStatFileName[300]; + int _fd; + //int _fileOpen; //表示文件是否打开 + char _logFileName[300]; //next shift, 当前日志文件需要rename的名字 + char _logBaseFileName[280]; //当前写的日志名字 + time_t _lastShiftTime; + int _curFileNums; //当前日志数 + int _curFileNo; //当前第几个日志或者当天第几个日志,circle删除看这个 + + int _curFileSize; //当前日志大小 + + int _toDeleteFileNo; //for circle + char _toDeleteFileName[300]; //for daily + time_t _toDeleteTime; //删除哪天的日志 + StRmbLogPara _para; + + //pthread_spinlock_t logSpinLock = SPIN_LOCK_UNLOCKED; //自旋锁 + pthread_mutex_t rmbLogMutex; //临界区 + struct timeval stLogTv; + struct stat gRmbSb; + + //for file lock + struct flock logFileLock; + struct flock logStateLock; +} StRmbLog; + +typedef struct StDayInfo +{ + unsigned int _curFileNo; //当前天,下一个rename的名字 + unsigned int _deleteFileNo; //当前天,马上要被delete的序号 + time_t _dayTime; //代表当前天的时间 + unsigned int _curFileNum; //当前天的日志个数 + + char _baseFileName[280]; + char _logFileName[300]; +} StDayInfo; + +int ReloadCfg (int logLevel, int shiftType, const char *path, int maxFileSize, + int maxFileNum); +int GetCurFileNumFromStatFile (); +int SetCurFileNumToStatFile (); +int InitRmbLogFile (int logLevel, int shiftType, const char *path, + int maxFileSize, int maxFileNum); +int OpenRmbLog (); +int FindNextDeleteLog (); +int LogRmb (int logLevel, const char *format, ...); +int ShiftRmbLog (FILE * file); +int GetCurStateFromRmbLogByCirCle (); +int GetCurStateFromRmbLogByDaily (); +int GetCurStateFromRmbLogByDaily_V2 (); +int GetCurStateFromRmbLogByDaily_V3 (); +int GetCurStateFromRmbLogByDaily_V4 (); +int GetDayInfo (StDayInfo * dayInfo, time_t * curTime); +int GetDayInfoWithBreak (StDayInfo * dayInfo, time_t * curTime); +int GetRmbNowLongTime (); + +void _Log_Thread_func (void *args); +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_mq.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_mq.h new file mode 100644 index 0000000000..0aebc9532d --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_mq.h @@ -0,0 +1,282 @@ +// 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. + +#ifndef RMB_MQ_H_ +#define RMB_MQ_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rmb_define.h" +#include "rmb_msg.h" +#include "rmb_sub.h" + +//typedef void (*rmb_callback_func)(const char*, const int, const int type, void*); +//typedef int(*rmb_callback_func_v2)(const char*, const int, void*); +//#define MAX_MQ_NUMS 10 +//#define MAX_FIFO_PATH_NAME_LEN 200 +//#define MAX_MQ_PKG_SIZE 10000000 +////static const unsigned int C_RMB_MQ_HEAD_SIZE = 2 * sizeof(unsigned int); +//#define C_RMB_MQ_HEAD_SIZE 2 * sizeof(unsigned int) +//#define C_RMB_MQ_PKG_HEAD_SIZE 2 * sizeof(unsigned int) +////static const unsigned int C_RMB_MQ_PKG_HEAD_SIZE = 2 * sizeof(unsigned int); + +//*************************for mq***************************** +//typedef struct StRmbMq +//{ +// unsigned int uiShmkey; +// unsigned long ulShmId; +// unsigned int uiShmSize; +// +// //head + tail + real data +// char* pMqData; +// unsigned int *pHead; +// unsigned int *pTail; +// +// //real data +// char *pBlock; +// unsigned int uiBlockSize; +// +//}StRmbMq; + +//mq init + int rmb_mq_init (StRmbMq * pMq, const unsigned int shmKey, + const unsigned int shmSize, const int bCreate, + const int bReadOnly); + +//mq_enqueue + int rmb_mq_enqueue (StRmbMq * pMq, const char *data, unsigned int uiDataLen, + unsigned int uiFLow); + +//mq_dequeue + int rmb_mq_dequeue (StRmbMq * pMq, char *buf, unsigned int uiBufSize, + unsigned int *pDataLen, unsigned int *pFlowId); + +//mq_try_deuque + int rmb_mq_try_dequeue (StRmbMq * pMq, char *buf, unsigned int uiBufSize, + unsigned int *pDataLen, unsigned int *pFlowId); + +//mq_get_stat + int rmb_mq_get_stat (StRmbMq * pMq); + +//*************************for fifo***************************** +//typedef struct StRmbFifo +//{ +// int iFd; +// char strPath[MAX_FIFO_PATH_NAME_LEN]; +//}StRmbFifo; + +//fifo init +//return -1 exist error + int rmb_fifo_init (StRmbFifo * pFifo, const char *pPath); + +//fifo + int rmb_fifo_send (StRmbFifo * pFifo); + +//clear notify + int rmb_fifo_clear_flag (StRmbFifo * pFifo); + +//*************************for queue****************************** +//typedef struct StRmbQueue +//{ +// unsigned int uiSize; +// +// //head + tail + real data +// char* pData; +// unsigned int *pHead; +// unsigned int *pTail; +// +// //real data +// char *pBlock; +// unsigned int uiBlockSize; +//}StRmbQueue; + +//queue init + int rmb_queue_init (StRmbQueue * pQue, const unsigned int size); + +//enqueue + int rmb_queue_enqueue (StRmbQueue * pQue, const char *data, + unsigned int uiDataLen, unsigned int uiFLow); + +//dequeue + int rmb_queue_dequeue (StRmbQueue * pQue, char *buf, unsigned int uiBufSize, + unsigned int *pDataLen, unsigned int *pFlowId); + +//try deuque + int rmb_queue_try_dequeue (StRmbQueue * pQue, char *buf, + unsigned int uiBufSize, unsigned int *pDataLen, + unsigned int *pFlowId); + +//get stat + int rmb_queue_get_stat (StRmbQueue * pQue); + +//*************************for pipe***************************** +//typedef struct StRmbPipe +//{ +// int fd[2]; +// int r_fd; +// int w_fd; +//}StRmbPipe; + +//pipe init +//return -1 exist error + int rmb_pipe_init (StRmbPipe * pPipe); + +//pipe + int rmb_pipe_send (StRmbPipe * pPipe); + +//clear notify + int rmb_pipe_clear_flag (StRmbPipe * pPipe); + +//*************************for mq & notify*********************** +//typedef struct StMqInfo +//{ +// StRmbMq* mq; +// StRmbFifo* fifo; +// +// //for wemq +// StRmbQueue *que; +// StRmbPipe *pipe; +// +// int iIndex; //offset in vector +// int iMsgType; //iPkgType,1 queue msg;2 rr topic msg;3 broadcast msg;4 manage msg +// +// rmb_callback_func func; +// rmb_callback_func_v2 funcForNew; +// void* args; +// +// //for epoll +// int active; +// +// //for notify num +// int iCount; +// unsigned int uiLastCheckTime; +// +// int iMergeNotifyFLag; //0:not marge 1:marge +// int iNotifyFactor; //the factor of notify +//}StMqInfo; + +//enum RmbMqIndex +//{ +// req_mq_index = 1, +// rr_rsp_mq_index = 2, +// broadcast_mq_index = 3, +// manage_mq_index = 4, +// +// wemq_req_mq_index = 5, +// wemq_rr_rsp_mq_index = 6, +// wemq_broadcast_mq_index = 7, +// wemq_manage_mq_index = 8, +//}; +// +////for mq notify +//typedef struct StRmbMqFifoNotify +//{ +// StMqInfo vecMqInfo[MAX_MQ_NUMS]; +// int iMqNum; +// +// StMqInfo* mqIndex[MAX_MQ_NUMS]; //see define of RmbMqIndex +// //for select +// fd_set readFd; +// fd_set tmpReadFd; +// struct timeval tv; +// int iMaxFd; +// +// //for epoll +// int iEpollFd; +// +// char* pBuf; +// unsigned int uiBufLen; +// int type; +// +//}StRmbMqFifoNotify; + +//******************************************************function******************************s + + int rmb_notify_init (StRmbMqFifoNotify * pMqNotify); + +//notify add + int rmb_notify_add (StRmbMqFifoNotify * pMqNotify, StRmbMq * mq, + StRmbFifo * fifo, const enum RmbMqIndex iMsgType, + rmb_callback_func func, void *func_argv); + +//enqueue +//-1:error argv +//-2:not enough space +//-3:enquque error +//-4:notify send failed + int rmb_notify_enqueue_by_type (StRmbMqFifoNotify * pMqNotify, + const enum RmbMqIndex uiMsgType, + const unsigned int uiCurTime, + const char *data, unsigned int uiDataLen); + +//enqueue +//-1:error argv +//-2:not enough space +//-3:enquque error +//-4:notify send failed + int rmb_notify_enqueue (const unsigned int uiCurTime, StMqInfo * pMqInfo, + const char *data, unsigned int uiDataLen); + +//dequeue + int rmb_notify_dequeue (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen); + +//try dequeue + int rmb_notify_try_dequeue (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen); + +//**************select or epoll************************* +//select fifo fd +//return >0 the mq index which has msg +// =0 all mq has no msg +// <0 all mq has no msg +//int rmb_notify_select(StRmbMqFifoNotify* pMqNotify, unsigned int uiSec, unsigned int uiUsec); + +//epoll mq + int rmb_notify_epoll (StRmbSub * pStRmbSub, int iTimeout); + +//filter rmb msg + int rmb_epoll_msg_filter (StRmbSub * pStRmbSub, StRmbMsg * pReceiveMsg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_msg.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_msg.h new file mode 100644 index 0000000000..e606ed9fb5 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_msg.h @@ -0,0 +1,163 @@ +// 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. + +#ifndef RMB_MSG_H_ +#define RMB_MSG_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "rmb_define.h" + + int rmb_msg_clear (StRmbMsg * pStMsg); + int rmb_msg_init (StRmbMsg * pRmbMsg, StRmbConfig * pConfig, + enum RMB_API_YPE type); + +//set fields +//you must fill in under fields + int rmb_msg_set_bizSeqNo (StRmbMsg * pRmbMsg, const char *cBizSeqNo); + + int rmb_msg_set_consumerSysVersion (StRmbMsg * pRmbMsg, + const char *cConsumerSysVersion); + + int rmb_msg_set_consumerSeqNo (StRmbMsg * pRmbMsg, + const char *cConsumerSeqNo); + + int rmb_msg_set_orgSysId (StRmbMsg * pRmbMsg, const char *cOrgSysId); + +//dyed msg,optional + int rmb_msg_set_dyedMsg (StRmbMsg * pRmbMsg, const char *sign); + +/* +Function: rmb_msg_set_dest +Description:设置发送目标 +Retrun:见rmb_error.h +*/ + + int rmb_msg_set_dest (StRmbMsg * pRmbMsg, int desType, + const char *cTargetDcn, int iServiceOrEven, + const char *cServiceId, const char *cScenario); + + int rmb_msg_set_dest_v2 (StRmbMsg * pRmbMsg, const char *cTargetDcn, + const char *cServiceId, const char *cScenario); + +//指定法人 + int rmb_msg_set_dest_v2_1 (StRmbMsg * pRmbMsg, const char *cTargetDcn, + const char *cServiceId, const char *cScenario, + const char *cTargetOrgId); + + int rmb_msg_set_live_time (StRmbMsg * pRmbMsg, unsigned long ulLiveTime); + + int rmb_msg_set_app_header (StRmbMsg * pRmbMsg, const char *appHeader, + unsigned int uiLen); + + int rmb_msg_set_content (StRmbMsg * pRmbMsg, const char *content, + unsigned int uiLen); + + const char *rmb_msg_print (StRmbMsg * pRmbMsg); + int rmb_msg_print_v (StRmbMsg * pRmbMsg); + +//获取msg的消息类型 +/** +* get msg type +* 0: undefined type +* 1: request in queue +* 2: reply package in RR +* 3: broadcast +* see: C_RMB_PKG_TYPE +*/ + int rmb_msg_get_msg_type (StRmbMsg * pRmbMsg); +//get cUniqueId + const char *rmb_msg_get_uniqueId_ptr (StRmbMsg * pRmbMsg); +//get cBizSeqNo + const char *rmb_msg_get_biz_seq_no_ptr (StRmbMsg * pRmbMsg); +//get cConsumerSeqNo + const char *rmb_msg_get_consumer_seq_no_ptr (StRmbMsg * pRmbMsg); +//get cConsumerDcn + const char *rmb_msg_get_consumer_dcn_ptr (StRmbMsg * pRmbMsg); +//get cOrgSysId + const char *rmb_msg_get_org_sys_id_ptr (StRmbMsg * pRmbMsg); +//get cOrgId + const char *rmb_msg_get_org_id_ptr (StRmbMsg * pRmbMsg); + +//get dest.cDestName + int rmb_msg_get_dest (StRmbMsg * pRmbMsg, char *dest, unsigned int *uiLen); + const char *rmb_msg_get_dest_ptr (StRmbMsg * pRmbMsg); + +//get cConsumerSysId + int rmb_msg_get_consumerSysId (StRmbMsg * pRmbMsg, char *cConsumerSysId, + unsigned int *uiLen); + const char *rmb_msg_get_consumerSysId_ptr (StRmbMsg * pRmbMsg); + +//cConsumerSvrId + int rmb_msg_get_consumerSvrId (StRmbMsg * pRmbMsg, char *cConsumerSvrId, + unsigned int *uiLen); + const char *rmb_msg_get_consumerSvrId_ptr (StRmbMsg * pRmbMsg); + +//获取appHeader + int rmb_msg_get_app_header (StRmbMsg * pRmbMsg, char *userHeader, + unsigned int *pLen); + +//获取appHeader指针 + const char *rmb_msg_get_app_header_ptr (StRmbMsg * pRmbMsg, + unsigned int *pLen); + +//获取消息内容 + int rmb_msg_get_content (StRmbMsg * pRmbMsg, char *content, + unsigned int *pLen); + +//获取消息内容指针 + const char *rmb_msg_get_content_ptr (StRmbMsg * pRmbMsg, + unsigned int *pLen); + +//将2进制buf反序列化为rmbMsg + int shift_buf_2_msg (StRmbMsg * pStMsg, const char *cBuf, + unsigned int uiLen); + +//将rmbMsg序列化成2进制buf + int shift_msg_2_buf (char *cBuf, unsigned int *pLen, + const StRmbMsg * pStMsg); + +//rmbMsg各必填字段校验 + int rmb_check_msg_valid (StRmbMsg * pStMsg); + +//获取下一个合适的连接 + int rmb_get_fit_size (const unsigned int uiLen, + const unsigned int uiMaxLen); + +//消息初始化 + StRmbMsg *rmb_msg_malloc (); + +//消息释放 + int rmb_msg_free (StRmbMsg * pRmbMsg); + +//wemq json message to rmb msg + int trans_json_2_rmb_msg (StRmbMsg * pStMsg, const char *bodyJson, + const char *command); + +//set extfields something to rmb msg + int set_extfields_2_rmb_msg (StRmbMsg * pStMsg, const char *command, + int iSeq); + +//生成uuid + int rmb_msg_random_uuid (char *puuid, size_t size); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_pub.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_pub.h new file mode 100644 index 0000000000..7dcb435841 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_pub.h @@ -0,0 +1,157 @@ +// 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. + +/** + * rmb_pub.h + * ---rmb的发包管理,包括发送广播、RR模式等 + * + * History: + * 2014-11-06 RR模式、发topic包 + */ +#ifndef RMB_PUB_H_ +#define RMB_PUB_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include "rmb_define.h" +#include "rmb_msg.h" +#include "message_log_api.h" + + typedef struct StRmbPub + { + StContext *pContext; + //StConfig config; + //for rr send msg + char cRrReplyTopic[200]; + int uiContextNum; //是否已经初始化 + + //for control send to wemq or solace + unsigned long ulLastTime; + unsigned int uiWeight; + + pthread_mutex_t pubMutex; //临界区 + StRmbMsg *pSendMsg; + StRmbMsg *pRcvMsg; + char pkgBuf[MAX_GSL_REQ_BUF_SIZE]; + char printGslBuf[1000]; + } StRmbPub; + +/** +Function: rmb_pub_init +Description:initialize +Retrun: + 0 --success + -1 --failed +*/ + int rmb_pub_init (StRmbPub * rmb_pub); + + int rmb_pub_init_python (); + +/** +Function: rmb_pub_send_and_receive +Description:send message and wait for report +Retrun: + 0 --success + -1 --timeout + -2 --error +*/ + int rmb_pub_send_and_receive (StRmbPub * rmb_pub, StRmbMsg * pSendMsg, + StRmbMsg * pRevMsg, unsigned int uiTimeOut); + int rmb_pub_send_and_receive_python (StRmbMsg * pSendMsg, + StRmbMsg * pRevMsg, + unsigned int uiTimeOut); + +/** +Function: rmb_pub_send_msg +Description:send message +Retrun: + 0 --success + -1 --failed + -2 --queue full +*/ + int rmb_pub_send_msg (StRmbPub * rmb_pub, StRmbMsg * pStMsg); + + int rmb_pub_send_msg_python (StRmbMsg * pStMsg); + +/** +Function: rmb_pub_send_rr_msg +Description:send RR asynchronous message +Retrun: + 0 --success + -1 --failed + -2 --queue full +*/ + int rmb_pub_send_rr_msg_async (StRmbPub * rmb_pub, StRmbMsg * pStMsg, + unsigned int uiTimeOut); + int rmb_pub_send_rr_msg_async_python (StRmbMsg * pStMsg, + unsigned int uiTimeOut); + +/** +Function: rmb_pub_reply_msg +Description:send report packet +Retrun: + 0 --success + -1 --failed +*/ + int rmb_pub_reply_msg (StRmbPub * pRmbPub, StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg); + +/** +Function: rmb_pub_close +Description:close pub +Retrun: + 0 --success + -1 --failed +*/ + int rmb_pub_close (StRmbPub * pRmbPub); + int rmb_pub_close_python (); + +/** +Function: rmb_pub_close_v2 +Description:close pub对象,2.0.12后使用 +Retrun: + 0 --success + -1 --failed +*/ + int rmb_pub_close_v2 (StRmbPub * pRmbPub); + + int rmb_pub_encode_thread_msg (unsigned int uiCmd, + StWemqThreadMsg * ptThreadMsg, + StRmbMsg * ptSendMsg, + unsigned long ulTimeToAlive); + +/** + * 给GSL发送染色消息 + */ + int rmb_pub_send_dyed_msg_to_gsl (StRmbPub * pStPub); + +//extern StRmbPub *pRmbGlobalPub; + +/* + * send log to logserver by wemq + * when iLogPoint is RMB_LOG_ON_ERROR, need iErrCode, cErrMsg + * others, not need + */ +//int rmb_send_log_to_logserver(StRmbMsg *pStMsg, int iContextType, int iLogPoint, int iErrCode, char* cErrMsg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_sub.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_sub.h new file mode 100644 index 0000000000..8ab677e3d8 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_sub.h @@ -0,0 +1,335 @@ +// 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. + +#ifndef RMB_SUB_H_ +#define RMB_SUB_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include "rmb_msg.h" +#include "rmb_context.h" +#include "rmb_define.h" +#include "rmb_udp.h" + + typedef struct StRmbSub + { + StContext *pStContext; + unsigned int uiContextNum; + //for rr reply topic + char cRrReply[255]; + unsigned int uiInitFlag; + //for filter unlisten receive msg + //unsigned int uiFlagForFilter; //rr异步与sub做区分 + //unsigned int uiFlagForSubType; + st_rmb_queue_info *pQueueInfo; + int iQueueNum; + //char **cTopic; + //int iTopicNum; + /* + //for rev req + int iReqPort; + + //for rev reply + int iReplyPort; + + //for rev broadcast + int iBroadcastPort; + */ + } StRmbSub; + +/** + * Function: rmb_sub_init + * Description: rmb sub对象初始化 + * Return: + * 见rmb_errno.h文件 + */ + int rmb_sub_init (StRmbSub * stRmbSub); + + int rmb_sub_init_python (); + +/** + * Function: rmb_sub_add_reveive_req + * Description: init, sub add receive queue request packet + * Return: + * 见rmb_errno.h文件 + */ +#define rmb_sub_add_reveive_req_by_udp rmb_sub_add_reveive_req + int rmb_sub_add_reveive_req (StRmbSub * stRmbSub, + unsigned short usRevReqPort); + +/* +* Function: rmb_sub_add_reveive_req_by_mq +* Description:初始化接收请求的操作(使用mq接收) +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_add_reveive_req_by_mq (StRmbSub * stRmbSub, + rmb_callback_func func, void *func_argv); + +/* +* Function: rmb_sub_add_reveive_req_by_mq_v2 +* Description:初始化接收请求的操作(使用mq接收),自定义mq的key +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_add_reveive_req_by_mq_v2 (StRmbSub * stRmbSub, + const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv); + + int rmb_sub_add_reveive_req_by_mq_python (const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv); + +/* +Function: rmb_sub_get_receve_req_mq +Description:获取接收请求的mq对象 +* Return: +* 见rmb_errno.h文件 +*/ + StMqInfo *rmb_sub_get_receve_req_mq (StRmbSub * stRmbSub); + +/* +Function: rmb_sub_add_reveive_rsp +Description:初始化接收回包(使用UDP) +* Return: +* 见rmb_errno.h文件 +*/ +#define rmb_sub_add_reveive_rsp_by_udp rmb_sub_add_reveive_rsp + int rmb_sub_add_reveive_rsp (StRmbSub * stRmbSub, + unsigned short usRevRspPort); + +/* +Function: rmb_sub_add_reveive_rsp_by_mq +Description:初始化接收回包(使用mq) +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_add_reveive_rsp_by_mq (StRmbSub * stRmbSub, + rmb_callback_func func, void *func_argv); + +/* +Function: rmb_sub_add_reveive_rsp_by_mq_v2 +Description:初始化接收回包(使用UDP),自定义mq key +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_add_reveive_rsp_by_mq_v2 (StRmbSub * stRmbSub, + const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv); + + int rmb_sub_add_reveive_rsp_by_mq_python (const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv); + +/* +Function: rmb_sub_get_receve_rsp_mq +Description:获取接收回包的mq对象 +* Return: +* 见rmb_errno.h文件 +*/ + StMqInfo *rmb_sub_get_receve_rsp_mq (StRmbSub * stRmbSub); + +/* +Function: rmb_sub_add_reveive_broadcast +Description:初始化接收广播(使用UDP) +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_add_reveive_broadcast (StRmbSub * stRmbSub, + unsigned short usRevBroadcastPort); + +/* +Function: rmb_sub_add_reveive_broadcast_by_mq +Description:初始化接收广播(使用mq) +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_add_reveive_broadcast_by_mq (StRmbSub * stRmbSub, + rmb_callback_func func, + void *func_argv); + +/* +Function: rmb_sub_add_reveive_broadcast_by_mq_v2 +Description:初始化接收回包(使用mq),自定义mq key +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_add_reveive_broadcast_by_mq_v2 (StRmbSub * stRmbSub, + const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv); + int rmb_sub_add_reveive_broadcast_by_mq_python (const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int + uiShmSize, + rmb_callback_func func, + void *func_argv); + +/* +Function: rmb_sub_get_receve_broadcast_mq +Description:获取接收回包mq对象 +* Return: +* 见rmb_errno.h文件 +*/ + StMqInfo *rmb_sub_get_receve_broadcast_mq (StRmbSub * stRmbSub); + +/* +Function: rmb_sub_get_fd +Description:获取mq对象的fd +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_get_fd (StMqInfo * pMqInfo); + +/* +Function: rmb_sub_receive_from_mq +Description:从mq中获取消息 +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_receive_from_mq (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen); + +/* +Function: rmb_sub_try_receive_from_mq +Description:尝试从mq中获取消息 +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_try_receive_from_mq (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen); + +/* +Function: rmb_sub_add_listen +Description:听queue +* Return: +* 见rmb_errno.h文件 +*/ +//int rmb_sub_add_listen(StRmbSub *pStRmbSub, const char *cOwnDcn, int iServiceOrEven, const char *cServiceId, const char *cScenario); + int rmb_sub_add_listen (StRmbSub * pStRmbSub, + const st_rmb_queue_info * pQueueInfo, + unsigned int uiQueueSize); + + int rmb_sub_add_listen_python (const st_rmb_queue_info * pQueueInfo, + unsigned int uiQueueSize); + +/* +Function: rmb_sub_add_listen_broadcast +Description:听topic +* Return: +* 见rmb_errno.h文件 +*/ +//int rmb_sub_add_listen_broadcast(StRmbSub *pStRmbSub, const char *cOwnDcn, const char *cServiceId, const char *cScenario); + +/* +Function: rmb_sub_do_receive +Description:听queue +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_do_receive (StRmbSub * pStRmbSub, int iTimeout); + + int rmb_sub_do_receive_python (); + +/* +Function: rmb_sub_reply_msg +Description:回复消息 +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_reply_msg (StRmbSub * pStRmbSub, StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg); + + int rmb_sub_reply_msg_python (StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg); + +/* +Function: rmb_sub_ack_msg +Description:ack消息 +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_ack_msg (StRmbSub * pStRmbSub, StRmbMsg * pStReceiveMsg); + +/* +Function: rmb_sub_close +Description:关闭rmb_sub对象 +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_close (StRmbSub * pStRmbSub); + int rmb_sub_close_python (); + +/* +Function: rmb_sub_close_v2 +Description:关闭rmb_sub对象,2.0.12后使用 +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_close_v2 (StRmbSub * pStRmbSub); + +/* +Function: rmb_sub_stop_receive +Description:rmb_sub停止接受queue消息 +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_stop_receive (StRmbSub * pStRmbSub); + int rmb_sub_stop_receive_python (); + +/* +Function: rmb_sub_check_req_mq_is_null +Description:校验是否请求队列是否已经为空,如果为空,则返回0,非空,则返回1 +* Return: +* 空返回0,非空返回1 +*/ + int rmb_sub_check_req_mq_is_null (StRmbSub * pStRmbSub); + + unsigned long rmb_get_topic_thread_id (); + +/** + * 专用于监听wemq的旁路topic + */ +//int rmb_sub_add_listen_topic_bypass(StRmbSub *pStRmbSub, const char *cTopic); + int rmb_sub_add_listen_topic_bypass (StRmbSub * pStRmbSub, + const char **cTopic, + unsigned int uiTopicSize); + + unsigned long rmb_get_topic_thread_id (); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_udp.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_udp.h new file mode 100644 index 0000000000..7dc9e7180c --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_udp.h @@ -0,0 +1,78 @@ +// 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. + +#ifndef _UDP_SOCKET_FOR_RMB_H_ +#define _UDP_SOCKET_FOR_RMB_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include /* required for ip.h */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//////////////////////// +#include "rmb_define.h" +//////////////////////// + + typedef struct sockaddr_in StSockAddr; + + int udp_get_socket (const char *host, const char *serv, + socklen_t * addrlenp); + + int udp_server (const char *pszHost, unsigned short usPort); + + int check_socket (int iSocket, fd_set * stReadFds, int iNFd); + + int check_socket_with_timeout (int iSocket, fd_set * pStReadFds, int iNfd, + int sec, int usec); + + int check_and_process_socket (int iSocket, fd_set * stReadFds, + char *cPkgBuf, const unsigned int uiMaxLen, + unsigned int *pPkgLen); + + int tcp_nodelay (int iSockfd); + + int get_host_name (char *hostName, unsigned int uiHostNameLen); + + int get_local_ip (char *addr, unsigned int uiAddrLen); + + int get_local_ip_v2 (char *addr, unsigned int uiAddrLen); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_vector.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_vector.h new file mode 100644 index 0000000000..31055477ae --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_vector.h @@ -0,0 +1,43 @@ +// 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. + +#ifndef __RMB_VECTOR_H_ +#define __RMB_VECTOR_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include +#include +#include "rmb_define.h" + +#define MAX_SIZE_PER_TIME 1024 + + void Init (Array * this); + void _constructor (Array * this); + void _destructor (Array * this); + void _input (DataType data, Array * this); + int _get_size (Array * this); + DataType _return_index_value (Array * this, int index); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/wemq_fifo.h b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_fifo.h new file mode 100644 index 0000000000..eed6129af9 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_fifo.h @@ -0,0 +1,639 @@ +// 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. + +/* + * API : + * DEFINE_WEMQ_KFIFO : statically allocated FIFO object + * DECLARE_WEMQ_KFIFO : declare a FIFO object + * DECLARE_WEMQ_KFIFO_PTR: declare a pointer whitch point to a FIFO object + * INIT_WEMQFIFO : init a FIFO object + * + * wemq_kfifo_len : return the num of element that in the fifo + * wemq_kfifo_peek_len: return the num of bytes that in use + * + * wemq_kfifo_is_empty: retruns true if the fifo is empty + * wemq_kfifo_is_full : returns true if the fifo is full + * wemq_kfifo_is_avail: returns the numer of unused elements in the fifo + * wemq_kfifo_skip : skip a element in fifo + * + * wemq_kfifo_alloc : dynamically allocates a new fifo buffer + * wemq_kfifo_free : frees the fifo + * + * wemq_kfifo_put : copies the given value into the fifo (by element) + * wemq_kfifo_get : reads a element from the fifo + * wemq_kfifo_peek : reads a element from the fifo without removing it form the fifo + * + * wemq_kfifo_in : copies the given buffer into the fifo and returnns the number of copied elements + * wemq_kfifo_out : get some elements form the fifo and return the numbers of elements + * wemq_kfifo_out_peek: get the data from the fifo and return the numbers of elements copied. These elements is not removed from the fifo + * + */ + +#ifndef _WEMQ_WEMQ_KFIFO_H +#define _WEMQ_WEMQ_KFIFO_H +#ifdef __cplusplus +extern "C" +{ +#endif +//#include +//#include +//#include + +#define __u32 uint32_t +#define __u64 uint64_t +#define __must_check __attribute__((warn_unused_result)) + +#define __must_be_array(arr) 0 +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) + + enum + { + KFIFO_EINVAL = -1, + KFIFO_ENOMEM = -2 + }; + + static inline int fls (int x) + { + int r; + + __asm__ ("bsrl %1,%0\n\t" + "jnz 1f\n\t" "movl $-1,%0\n" "1:":"=r" (r):"rm" (x)); + return r + 1; + } + + static inline int fls64 (__u64 x) + { + __u32 h = x >> 32; + if (h) + return fls (h) + 32; + return fls (x); + } + + static inline unsigned fls_long (unsigned long l) + { + if (sizeof (l) == 4) + return fls (l); + return fls64 (l); + } + + static inline unsigned long roundup_pow_of_two (unsigned long x) + { + return 1UL << fls_long (x - 1); + } + + struct __wemq_kfifo + { + unsigned int in; + unsigned int out; + unsigned int mask; + unsigned int esize; + void *data; + }; + +#define __STRUCT_WEMQ_KFIFO_COMMON(datatype, recsize, ptrtype) \ + union { \ + struct __wemq_kfifo wemq_kfifo; \ + datatype *type; \ + const datatype *const_type; \ + char (*rectype)[recsize]; \ + ptrtype *ptr; \ + ptrtype const *ptr_const; \ + } + +#define __STRUCT_WEMQ_KFIFO(type, size, recsize, ptrtype) \ +{ \ + __STRUCT_WEMQ_KFIFO_COMMON(type, recsize, ptrtype); \ + type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \ +} + +#define STRUCT_WEMQ_KFIFO(type, size) \ + struct __STRUCT_WEMQ_KFIFO(type, size, 0, type) + +#define __STRUCT_WEMQ_KFIFO_PTR(type, recsize, ptrtype) \ +{ \ + __STRUCT_WEMQ_KFIFO_COMMON(type, recsize, ptrtype); \ + type buf[0]; \ +} + +#define STRUCT_WEMQ_KFIFO_PTR(type) \ + struct __STRUCT_WEMQ_KFIFO_PTR(type, 0, type) + +/* + * define compatibility "struct wemq_kfifo" for dynamic allocated fifos + */ + struct st_wemq_kfifo __STRUCT_WEMQ_KFIFO_PTR (unsigned char, 0, void); + +#define STRUCT_WEMQ_KFIFO_REC_1(size) \ + struct __STRUCT_WEMQ_KFIFO(unsigned char, size, 1, void) + +#define STRUCT_WEMQ_KFIFO_REC_2(size) \ + struct __STRUCT_WEMQ_KFIFO(unsigned char, size, 2, void) + +/* + * define wemq_kfifo_rec types + */ + struct wemq_kfifo_rec_ptr_1 __STRUCT_WEMQ_KFIFO_PTR (unsigned char, 1, + void); + struct wemq_kfifo_rec_ptr_2 __STRUCT_WEMQ_KFIFO_PTR (unsigned char, 2, + void); + +/* + * helper macro to distinguish between real in place fifo where the fifo + * array is a part of the structure and the fifo type where the array is + * outside of the fifo structure. + */ +#define __is_wemq_kfifo_ptr(fifo) (sizeof(*fifo) == sizeof(struct __wemq_kfifo)) + +/** + * DECLARE_WEMQ_KFIFO_PTR - macro to declare a fifo pointer object + * @fifo: name of the declared fifo + * @type: type of the fifo elements + */ +#define DECLARE_WEMQ_KFIFO_PTR(fifo, type) STRUCT_WEMQ_KFIFO_PTR(type) fifo + +/** + * DECLARE_WEMQ_KFIFO - macro to declare a fifo object + * @fifo: name of the declared fifo + * @type: type of the fifo elements + * @size: the number of elements in the fifo, this must be a power of 2 + */ +#define DECLARE_WEMQ_KFIFO(fifo, type, size) STRUCT_WEMQ_KFIFO(type, size) fifo + +/** + * INIT_WEMQ_KFIFO - Initialize a fifo declared by DECLARE_WEMQ_KFIFO + * @fifo: name of the declared fifo datatype + */ +#define INIT_WEMQ_KFIFO(fifo) \ +(void)({ \ + typeof(&(fifo)) __tmp = &(fifo); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + __wemq_kfifo->in = 0; \ + __wemq_kfifo->out = 0; \ + __wemq_kfifo->mask = __is_wemq_kfifo_ptr(__tmp) ? 0 : ARRAY_SIZE(__tmp->buf) - 1;\ + __wemq_kfifo->esize = sizeof(*__tmp->buf); \ + __wemq_kfifo->data = __is_wemq_kfifo_ptr(__tmp) ? NULL : __tmp->buf; \ +}) + +/** + * DEFINE_WEMQ_KFIFO - macro to define and initialize a fifo + * @fifo: name of the declared fifo datatype + * @type: type of the fifo elements + * @size: the number of elements in the fifo, this must be a power of 2 + * + * Note: the macro can be used for global and local fifo data type variables. + */ +#define DEFINE_WEMQ_KFIFO(fifo, type, size) \ + DECLARE_WEMQ_KFIFO(fifo, type, size) = \ + (typeof(fifo)) { \ + { \ + { \ + .in = 0, \ + .out = 0, \ + .mask = __is_wemq_kfifo_ptr(&(fifo)) ? \ + 0 : \ + ARRAY_SIZE((fifo).buf) - 1, \ + .esize = sizeof(*(fifo).buf), \ + .data = __is_wemq_kfifo_ptr(&(fifo)) ? \ + NULL : \ + (fifo).buf, \ + } \ + } \ + } + + static inline unsigned int __must_check + __wemq_kfifo_uint_must_check_helper (unsigned int val) + { + return val; + } + + static inline int __must_check __wemq_kfifo_int_must_check_helper (int val) + { + return val; + } + +/** + * wemq_kfifo_initialized - Check if the fifo is initialized + * @fifo: address of the fifo to check + * + * Return %true if fifo is initialized, otherwise %false. + * Assumes the fifo was 0 before. + */ +#define wemq_kfifo_initialized(fifo) ((fifo)->wemq_kfifo.mask) + +/** + * wemq_kfifo_esize - returns the size of the element managed by the fifo + * @fifo: address of the fifo to be used + */ +#define wemq_kfifo_esize(fifo) ((fifo)->wemq_kfifo.esize) + +/** + * wemq_kfifo_recsize - returns the size of the record length field + * @fifo: address of the fifo to be used + */ +#define wemq_kfifo_recsize(fifo) (sizeof(*(fifo)->rectype)) + +/** + * wemq_kfifo_size - returns the size of the fifo in elements + * @fifo: address of the fifo to be used + */ +#define wemq_kfifo_size(fifo) ((fifo)->wemq_kfifo.mask + 1) + +/** + * wemq_kfifo_reset - removes the entire fifo content + * @fifo: address of the fifo to be used + * + * Note: usage of wemq_kfifo_reset() is dangerous. It should be only called when the + * fifo is exclusived locked or when it is secured that no other thread is + * accessing the fifo. + */ +#define wemq_kfifo_reset(fifo) \ +(void)({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + __tmp->wemq_kfifo.in = __tmp->wemq_kfifo.out = 0; \ +}) + +/** + * wemq_kfifo_reset_out - skip fifo content + * @fifo: address of the fifo to be used + * + * Note: The usage of wemq_kfifo_reset_out() is safe until it will be only called + * from the reader thread and there is only one concurrent reader. Otherwise + * it is dangerous and must be handled in the same way as wemq_kfifo_reset(). + */ +#define wemq_kfifo_reset_out(fifo) \ +(void)({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + __tmp->wemq_kfifo.out = __tmp->wemq_kfifo.in; \ +}) + +/** + * wemq_kfifo_len - returns the number of used elements in the fifo + * @fifo: address of the fifo to be used + */ +#define wemq_kfifo_len(fifo) \ +({ \ + typeof((fifo) + 1) __tmpl = (fifo); \ + __tmpl->wemq_kfifo.in - __tmpl->wemq_kfifo.out; \ +}) + +/** + * wemq_kfifo_is_empty - returns true if the fifo is empty + * @fifo: address of the fifo to be used + */ +#define wemq_kfifo_is_empty(fifo) \ +({ \ + typeof((fifo) + 1) __tmpq = (fifo); \ + __tmpq->wemq_kfifo.in == __tmpq->wemq_kfifo.out; \ +}) + +/** + * wemq_kfifo_is_full - returns true if the fifo is full + * @fifo: address of the fifo to be used + */ +#define wemq_kfifo_is_full(fifo) \ +({ \ + typeof((fifo) + 1) __tmpq = (fifo); \ + wemq_kfifo_len(__tmpq) > __tmpq->wemq_kfifo.mask; \ +}) + +/** + * wemq_kfifo_avail - returns the number of unused elements in the fifo + * @fifo: address of the fifo to be used + */ +#define wemq_kfifo_avail(fifo) \ +__wemq_kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmpq = (fifo); \ + const size_t __recsize = sizeof(*__tmpq->rectype); \ + unsigned int __avail = wemq_kfifo_size(__tmpq) - wemq_kfifo_len(__tmpq); \ + (__recsize) ? ((__avail <= __recsize) ? 0 : \ + __wemq_kfifo_max_r(__avail - __recsize, __recsize)) : \ + __avail; \ +}) \ +) + +/** + * wemq_kfifo_skip - skip output data + * @fifo: address of the fifo to be used + */ +#define wemq_kfifo_skip(fifo) \ +(void)({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + if (__recsize) \ + __wemq_kfifo_skip_r(__wemq_kfifo, __recsize); \ + else \ + __wemq_kfifo->out++; \ +}) + +/** + * wemq_kfifo_peek_len - gets the size of the next fifo record + * @fifo: address of the fifo to be used + * + * This function returns the size of the next fifo record in number of bytes. + */ +#define wemq_kfifo_peek_len(fifo) \ +__wemq_kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + (!__recsize) ? wemq_kfifo_len(__tmp) * sizeof(*__tmp->type) : \ + __wemq_kfifo_len_r(__wemq_kfifo, __recsize); \ +}) \ +) + +/** + * wemq_kfifo_alloc - dynamically allocates a new fifo buffer + * @fifo: pointer to the fifo + * @size: the number of elements in the fifo, this must be a power of 2 + * @gfp_mask: get_free_pages mask, passed to kmalloc() + * + * This macro dynamically allocates a new fifo buffer. + * + * The numer of elements will be rounded-up to a power of 2. + * The fifo will be release with wemq_kfifo_free(). + * Return 0 if no error, otherwise an error code. + */ +#define wemq_kfifo_alloc(fifo, size) \ +__wemq_kfifo_int_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + __is_wemq_kfifo_ptr(__tmp) ? \ + __wemq_kfifo_alloc(__wemq_kfifo, size, sizeof(*__tmp->type)) : \ + -KFIFO_EINVAL; \ +}) \ +) + +/** + * wemq_kfifo_free - frees the fifo + * @fifo: the fifo to be freed + */ +#define wemq_kfifo_free(fifo) \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + if (__is_wemq_kfifo_ptr(__tmp)) \ + __wemq_kfifo_free(__wemq_kfifo); \ +}) + +/** + * wemq_kfifo_init - initialize a fifo using a preallocated buffer + * @fifo: the fifo to assign the buffer + * @buffer: the preallocated buffer to be used + * @size: the size of the internal buffer, this have to be a power of 2 + * + * This macro initialize a fifo using a preallocated buffer. + * + * The numer of elements will be rounded-up to a power of 2. + * Return 0 if no error, otherwise an error code. + */ +#define wemq_kfifo_init(fifo, buffer, size) \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + __is_wemq_kfifo_ptr(__tmp) ? \ + __wemq_kfifo_init(__wemq_kfifo, buffer, size, sizeof(*__tmp->type)) : \ + -KFIFO_EINVAL; \ +}) + +/** + * wemq_kfifo_put - put data into the fifo + * @fifo: address of the fifo to be used + * @val: the data to be added + * + * This macro copies the given value into the fifo. + * It returns 0 if the fifo was full. Otherwise it returns the number + * processed elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define wemq_kfifo_put(fifo, val) \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof(*__tmp->const_type) __val = (val); \ + unsigned int __ret; \ + size_t __recsize = sizeof(*__tmp->rectype); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + if (__recsize) \ + __ret = __wemq_kfifo_in_r(__wemq_kfifo, &__val, sizeof(__val), \ + __recsize); \ + else { \ + __ret = !wemq_kfifo_is_full(__tmp); \ + if (__ret) { \ + (__is_wemq_kfifo_ptr(__tmp) ? \ + ((typeof(__tmp->type))__wemq_kfifo->data) : \ + (__tmp->buf) \ + )[__wemq_kfifo->in & __tmp->wemq_kfifo.mask] = \ + *(typeof(__tmp->type))&__val; \ + __wemq_kfifo->in++; \ + } \ + } \ + __ret; \ +}) + +/** + * wemq_kfifo_get - get data from the fifo + * @fifo: address of the fifo to be used + * @val: address where to store the data + * + * This macro reads the data from the fifo. + * It returns 0 if the fifo was empty. Otherwise it returns the number + * processed elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define wemq_kfifo_get(fifo, val) \ +__wemq_kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof(__tmp->ptr) __val = (val); \ + unsigned int __ret; \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + if (__recsize) \ + __ret = __wemq_kfifo_out_r(__wemq_kfifo, __val, sizeof(*__val), \ + __recsize); \ + else { \ + __ret = !wemq_kfifo_is_empty(__tmp); \ + if (__ret) { \ + *(typeof(__tmp->type))__val = \ + (__is_wemq_kfifo_ptr(__tmp) ? \ + ((typeof(__tmp->type))__wemq_kfifo->data) : \ + (__tmp->buf) \ + )[__wemq_kfifo->out & __tmp->wemq_kfifo.mask]; \ + __wemq_kfifo->out++; \ + } \ + } \ + __ret; \ +}) \ +) + +/** + * wemq_kfifo_peek - get data from the fifo without removing + * @fifo: address of the fifo to be used + * @val: address where to store the data + * + * This reads the data from the fifo without removing it from the fifo. + * It returns 0 if the fifo was empty. Otherwise it returns the number + * processed elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define wemq_kfifo_peek(fifo, val) \ +__wemq_kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof(__tmp->ptr) __val = (val); \ + unsigned int __ret; \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + if (__recsize) \ + __ret = __wemq_kfifo_out_peek_r(__wemq_kfifo, __val, sizeof(*__val), \ + __recsize); \ + else { \ + __ret = !wemq_kfifo_is_empty(__tmp); \ + if (__ret) { \ + *(typeof(__tmp->type))__val = \ + (__is_wemq_kfifo_ptr(__tmp) ? \ + ((typeof(__tmp->type))__wemq_kfifo->data) : \ + (__tmp->buf) \ + )[__wemq_kfifo->out & __tmp->wemq_kfifo.mask]; \ + } \ + } \ + __ret; \ +}) \ +) + +/** + * wemq_kfifo_in - put data into the fifo + * @fifo: address of the fifo to be used + * @buf: the data to be added + * @n: number of elements to be added + * + * This macro copies the given buffer into the fifo and returns the + * number of copied elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define wemq_kfifo_in(fifo, buf, n) \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof(__tmp->ptr_const) __buf = (buf); \ + unsigned long __n = (n); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + (__recsize) ?\ + __wemq_kfifo_in_r(__wemq_kfifo, __buf, __n, __recsize) : \ + __wemq_kfifo_in(__wemq_kfifo, __buf, __n); \ +}) + +/** + * wemq_kfifo_out - get data from the fifo + * @fifo: address of the fifo to be used + * @buf: pointer to the storage buffer + * @n: max. number of elements to get + * + * This macro get some data from the fifo and return the numbers of elements + * copied. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define wemq_kfifo_out(fifo, buf, n) \ +__wemq_kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof(__tmp->ptr) __buf = (buf); \ + unsigned long __n = (n); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + (__recsize) ?\ + __wemq_kfifo_out_r(__wemq_kfifo, __buf, __n, __recsize) : \ + __wemq_kfifo_out(__wemq_kfifo, __buf, __n); \ +}) \ +) + +/** + * wemq_kfifo_out_peek - gets some data from the fifo + * @fifo: address of the fifo to be used + * @buf: pointer to the storage buffer + * @n: max. number of elements to get + * + * This macro get the data from the fifo and return the numbers of elements + * copied. The data is not removed from the fifo. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define wemq_kfifo_out_peek(fifo, buf, n) \ +__wemq_kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof(__tmp->ptr) __buf = (buf); \ + unsigned long __n = (n); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + (__recsize) ? \ + __wemq_kfifo_out_peek_r(__wemq_kfifo, __buf, __n, __recsize) : \ + __wemq_kfifo_out_peek(__wemq_kfifo, __buf, __n); \ +}) \ +) + + extern int __wemq_kfifo_alloc (struct __wemq_kfifo *fifo, unsigned int size, + size_t esize); + + extern void __wemq_kfifo_free (struct __wemq_kfifo *fifo); + + extern int __wemq_kfifo_init (struct __wemq_kfifo *fifo, void *buffer, + unsigned int size, size_t esize); + + extern unsigned int __wemq_kfifo_in (struct __wemq_kfifo *fifo, + const void *buf, unsigned int len); + + extern unsigned int __wemq_kfifo_out (struct __wemq_kfifo *fifo, + void *buf, unsigned int len); + + extern unsigned int __wemq_kfifo_out_peek (struct __wemq_kfifo *fifo, + void *buf, unsigned int len); + + extern unsigned int __wemq_kfifo_in_r (struct __wemq_kfifo *fifo, + const void *buf, unsigned int len, + size_t recsize); + + extern unsigned int __wemq_kfifo_out_r (struct __wemq_kfifo *fifo, + void *buf, unsigned int len, + size_t recsize); + + extern unsigned int __wemq_kfifo_len_r (struct __wemq_kfifo *fifo, + size_t recsize); + + extern void __wemq_kfifo_skip_r (struct __wemq_kfifo *fifo, size_t recsize); + + extern unsigned int __wemq_kfifo_out_peek_r (struct __wemq_kfifo *fifo, + void *buf, unsigned int len, + size_t recsize); + + extern unsigned int __wemq_kfifo_max_r (unsigned int len, size_t recsize); +#ifdef __cplusplus +} +#endif +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/wemq_proto.h b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_proto.h new file mode 100644 index 0000000000..1091be72a0 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_proto.h @@ -0,0 +1,562 @@ +// 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. + +//wemq-c-api与access协议 +#ifndef _WEMQ_PROXY_WORKER_PROTO_H_ +#define _WEMQ_PROXY_WORKER_PROTO_H_ + +#include +#include +#include +#include + +//#pragma pack(1) +#ifdef __cplusplus +extern "C" +{ +#endif + +#define SERVICE_ID_LENGTH 9 +#define SCENE_ID_LENGTH 3 +#define MAX_LISTEN_SIZE 100 + +#define BYTES_LENGTH ((2<<8)-1) +#define WORD_LENGTH ((2<<16)-1) +#define DWORD_LENGTH ((2<<32)-1) + +#define MAX_MSG_WEMQ_MSG_SIZE 2200000 + +/** + * wemq建立监听topic时,在2.0.8版本之前的流程为: + * 第一阶段 发送hello world, access会建立CLIENT Hello session, new出producer和consumer,耗时大约4s + * 第二阶段发送订阅命令,access的subscribe会同时start和consumer,后续的第二次subscribe会有大量的topic not exist,命令如下: + * --- subscribe(51, "订阅(不区分同步/异步) topic") --- + * --- unsubscribe(50, "取消注册服务 --- topic") --- + * --- subscribeTopic(53, "订阅服务(不区分同步/异步) -- 针对非类似生产的topic,例如ft-bq-bypass") --- + * --- unsubscribeTopic(52, "取消注册服务 -- 针对非类似生产的topic, 例如ft-bq-bypass") --- + * + * 在2.0.8版本为了解决access使用wemq的sub和start时序问题,修改为如下: + * 第一阶段 发送hello world, access会建立CLIENT Hello session, new出producer和consumer,耗时大约1s + * 第二阶段只subscribe, 如果客户端有多个topic,则循环发出sub命令, access收到,会sub在第一阶段建立的consumer上,耗时大约30ms + * 第三阶段api发送start命令给access, access会Listen,将ready好的带上了subscribe信息的consumer启动起来,正式开始收发消息, 耗时大约是3s + * 命令字如下: + * --- subscribe(61, "订阅(不区分同步/异步) topic") --- + * --- unsubscribe(60, "取消注册服务 --- topic") --- + * --- subscribeTopic(63, "订阅服务(不区分同步/异步) -- 针对非类似生产的topic,例如ft-bq-bypass") --- + * --- unsubscribeTopic(62, "取消注册服务 -- 针对非类似生产的topic, 例如ft-bq-bypass") --- + * start命令字: + * listen request: + * decode|length=295|headerLength=291|bodyLength=0|header={"type":123,"time":1497331206231,"seq":8995349179,"status":0,"idc":"ft","ip":"10.39.84.50"}|body=null. + * listen response: + * encode|length=299|headerLength=291|bodyLength=0|header={"type":123,"time":1497331206231,"seq":8995349179,,"status":0,"idc":"ft","ip":"10.39.84.50"}|body=null. + * + * 在2.0.12版本,采用新的wemq-access协议 http://rpddoc.weoa.com/index.php?s=/389&page_id=3967 + +enum CMD_FOR_WEMQ_PROXY_WORKER +{ + //proxy offer + //client(worker)-->server(proxy) + WEMQ_CMD_HELLO = 0, //客户端上线通知 + WEMQ_CMD_GOODBYE = 88, //客户端离线通知 + WEMQ_CMD_CLIENTGOODBYE = 881, //客户端主动离线通知 + WEMQ_CMD_SERVERGOODBYE = 882, //access端主动离线通知 + WEMQ_CMD_HEARTBEAT = 66, //ECHO心跳包 + WEMQ_CMD_SYNCREQ = 10, //同步请求消息 + WEMQ_CMD_SYNCRSP = 11, //同步响应消息 + WEMQ_CMD_ASYNCRSP = 21, //RR异步响应消息 + WEMQ_CMD_ASYNCREQ = 20, //RR异步请求消息 + WEMQ_CMD_ASYNCEVENT_PUB = 30, //发送事件消息(发送端) + WEMQ_CMD_ASYNCEVENT_SUB = 31, //接收事件(订阅端) + WEMQ_CMD_ASYNCEVENT_LOG_PUB = 34, //发送事件(发送logserver的命令字) + WEMQ_CMD_BROADCAST_PUB = 40, //广播消息发送(发送端) + WEMQ_CMD_BROADCAST_SUB = 41, //广播消息接收(订阅端) + WEMQ_CMD_REDIRECT = 32, //重定向C客户端到新的ACCESS服务器 + WEMQ_CMD_SUB = 51, //订阅服务(不区分同步/异步) + WEMQ_UNSUBSCRIBE = 50, //取消注册服务 + WEMQ_ACKNOWLEDGED = 100, //ack消息 + WEMQ_UNACKNOWLEDGED = 59, //unack消息 + //由于wemq针对旁边的topic是没有dcn、服务ID等的概念,故增加如下SUB指令 + WEMQ_CMD_SUB_TOPIC = 53, //订阅topic + WEMQ_CMD_UNSUB_TOPIC = 52, //取消topic订阅 + //version 2.0.8 add, for access + WEMQ_CMD_SUB_LISTEN = 61, //订阅服务(不区分同步/异步) + WEMQ_UNSUBSCRIBE_LISTEN = 60, //取消注册服务 + //由于wemq针对旁边的topic是没有dcn、服务ID等的概念,故增加如下SUB指令 + WEMQ_CMD_SUB_TOPIC_LISTEN = 63, //订阅topic + WEMQ_CMD_UNSUB_TOPIC_LISTEN = 62, //取消topic订阅 + WEMQ_CMD_SUB_START = 123, //sub add listen之后,发送start命令 +}; +*/ + + //心跳 +#define HEARTBEAT_REQUEST "HEARTBEAT_REQUEST" //client发给server的心跳包 +#define HEARTBEAT_RESPONSE "HEARTBEAT_RESPONSE" //server回复client的心跳包 + //握手 +#define HELLO_REQUEST "HELLO_REQUEST" //client发给server的握手请求 +#define HELLO_RESPONSE "HELLO_RESPONSE" //server回复client的握手请求 + //断连 +#define CLIENT_GOODBYE_REQUEST "CLIENT_GOODBYE_REQUEST" //client主动断连时通知server +#define CLIENT_GOODBYE_RESPONSE "CLIENT_GOODBYE_RESPONSE" //server回复client的主动断连通知 +#define SERVER_GOODBYE_REQUEST "SERVER_GOODBYE_REQUEST" //server主动断连时通知client +#define SERVER_GOODBYE_RESPONSE "SERVER_GOODBYE_RESPONSE" //client回复server的主动断连通知(client不会回复,准备好之后直接断连) + //订阅管理 +#define SUBSCRIBE_REQUEST "SUBSCRIBE_REQUEST" //client发给server的订阅请求 +#define SUBSCRIBE_RESPONSE "SUBSCRIBE_RESPONSE" //server回复client的订阅请求 +#define UNSUBSCRIBE_REQUEST "UNSUBSCRIBE_REQUEST" //client发给server的取消订阅请求 +#define UNSUBSCRIBE_RESPONSE "UNSUBSCRIBE_RESPONSE" //server回复client的取消订阅请求 + //监听 +#define LISTEN_REQUEST "LISTEN_REQUEST" //client发给server的启动topic监听的请求 +#define LISTEN_RESPONSE "LISTEN_RESPONSE" //server回复client的监听请求 + +#define REQUEST_TO_SERVER "REQUEST_TO_SERVER" //client将RR请求发送给server +#define REQUEST_TO_CLIENT "REQUEST_TO_CLIENT" //server将RR请求推送给client +#define REQUEST_TO_CLIENT_ACK "REQUEST_TO_CLIENT_ACK" //client收到RR请求后回ack给server +#define RESPONSE_TO_SERVER "RESPONSE_TO_SERVER" //client将RR回包发送给server +#define RESPONSE_TO_CLIENT "RESPONSE_TO_CLIENT" //server将RR回包推送给client +#define RESPONSE_TO_CLIENT_ACK "RESPONSE_TO_CLIENT_ACK" //client收到RR回包后回ack给server + + //异步事件 +#define ASYNC_MESSAGE_TO_SERVER "ASYNC_MESSAGE_TO_SERVER" //client将异步事件发送给server +#define ASYNC_MESSAGE_TO_SERVER_ACK "ASYNC_MESSAGE_TO_SERVER_ACK" //server收到异步事件后ACK给client +#define ASYNC_MESSAGE_TO_CLIENT "ASYNC_MESSAGE_TO_CLIENT" //server将异步事件推送给client +#define ASYNC_MESSAGE_TO_CLIENT_ACK "ASYNC_MESSAGE_TO_CLIENT_ACK" // client收到异步事件后回ack给server + + //广播 +#define BROADCAST_MESSAGE_TO_SERVER "BROADCAST_MESSAGE_TO_SERVER" //client将广播消息发送给server +#define BROADCAST_MESSAGE_TO_SERVER_ACK "BROADCAST_MESSAGE_TO_SERVER_ACK" //server收到广播消息后ACK给client +#define BROADCAST_MESSAGE_TO_CLIENT "BROADCAST_MESSAGE_TO_CLIENT" //server将广播消息推送给client +#define BROADCAST_MESSAGE_TO_CLIENT_ACK "BROADCAST_MESSAGE_TO_CLIENT_ACK" //client收到异步事件后回ack给server + //日志上报 +#define TRACE_LOG_TO_LOGSERVER "TRACE_LOG_TO_LOGSERVER" //RMB跟踪日志上报,异常场景也要上报 +#define SYS_LOG_TO_LOGSERVER "SYS_LOG_TO_LOGSERVER" //业务日志上报 + //重定向指令 +#define REDIRECT_TO_CLIENT "REDIRECT_TO_CLIENT" //server将重定向指令推动给client + +#define MSG_ACK "MSG_ACK" //api 内部构造ack包命令字 + +//协议严格按照顺序,不要随便改变结构体的次序 +//严格按照encode和decode函数进行序列化和反序列化 + +//for uint64 + typedef union union64HN + { + unsigned int src[2]; + unsigned long long dest; + } union64HN; + +#define WEMQ_PROXY_MEMCPY(buf,bufLen,p,pLen) \ +if (bufLen > pLen) \ +{ \ + memcpy(buf, p, pLen); \ + return 0; \ +}\ +else \ + return -1; + +#define ENCODE_CHAR(buf,tmp)\ + *buf = tmp; \ + buf += sizeof(char); + +#define ENCODE_SHORT(buf,tmp)\ + *((short*)buf) = htons(tmp); \ + buf += sizeof(short); + +#define ENCODE_INT(buf,tmp)\ + *((int*)buf) = htonl(tmp); \ + buf += sizeof(int); + +#define ENCODE_LONG(buf,tmp)\ + *((long*)buf) = htonll_z(tmp); \ + buf += sizeof(long); + +#define DECODE_CHAR(tmp,buf,pBufLen) \ +if (*pBufLen < sizeof(char)) \ + return -2; \ + tmp = *((char*)(buf)); \ + buf += sizeof(char); \ + *pBufLen -= sizeof(char); + +#define DECODE_SHORT(tmp,buf,pBufLen)\ +if (*pBufLen < sizeof(short))\ + return -2; \ + tmp = ntohs(*((short*)buf)); \ + buf += sizeof(short); \ + *pBufLen -= sizeof(short); + +#define DECODE_INT(tmp,buf,pBufLen)\ +if (*pBufLen < sizeof(int))\ + return -2; \ + tmp = ntohl(*((int*)buf)); \ + buf += sizeof(int); \ + *pBufLen -= sizeof(int); + +#define DECODE_LONG(tmp,buf,pBufLen)\ +if (*pBufLen < sizeof(long))\ + return -2; \ + tmp = ntohll_z(*((long*)buf)); \ + buf += sizeof(long); \ + *pBufLen -= sizeof(long); + +#define ENCODE_CSTR_MEMCPY(buf, str, strLen) \ + ENCODE_CHAR(buf, strLen); \ + memcpy(buf, str, strLen); \ + buf += strLen; + +#define ENCODE_WSTR_MEMCPY(buf, str, strLen) \ + ENCODE_SHORT(buf, strLen); \ + memcpy(buf, str, strLen); \ + buf += strLen; + +/* +#define ENCODE_DWSTR_MEMCPY(buf, str, strLen) \ + ENCODE_INT(buf, strLen); \ + memcpy(buf, str, strLen); \ + buf += strLen; +*/ + +#define ENCODE_DWSTR_MEMCPY(buf, str, strLen) \ + memcpy(buf, str, strLen); \ + buf += strLen; + +#define DECODE_CSTR_MEMCPY(str, strLen, buf, pBufLen) \ + DECODE_CHAR(strLen, buf, pBufLen); \ + if (*pBufLen < strLen) return -2; \ + memcpy(str, buf, strLen); \ + buf += strLen; \ + *pBufLen -= strLen; + +#define DECODE_WSTR_MEMCPY(str, strLen, buf, pBufLen) \ + DECODE_SHORT(strLen, buf, pBufLen); \ + if (*pBufLen < strLen) return -2; \ + memcpy(str, buf, strLen);\ + buf += strLen; \ + *pBufLen -= strLen; +/* +#define DECODE_DWSTR_MEMCPY(str, strLen, buf, pBufLen) \ + DECODE_INT(strLen, buf, pBufLen); \ + if (*pBufLen < strLen) return -2; \ + memcpy(str, buf, strLen);\ + buf += strLen; \ + *pBufLen -= strLen; +*/ + +#define DECODE_DWSTR_MEMCPY(str, strLen, buf, pBufLen) \ + if (*pBufLen < strLen) return -2; \ + memcpy(str, buf, strLen);\ + buf += strLen; \ + *pBufLen -= strLen; + +//***************************0x01 心跳************************** +//请求 + typedef struct StHeartBeatReq + { + int pid; //进程号 + unsigned int uiCount; //心跳次数 + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StHeartBeatReq; + + int EncodeStHeartBeatReq (char *buf, int *pBufLen, + const StHeartBeatReq * pReq); + int DecodeHeartBeatReq (StHeartBeatReq * pReq, const char *buf, + const int bufLen); + +//回复 + typedef struct StHeartBeatRsp + { + unsigned int uiResult; //回复状态,0为ok,非0为不ok + int pid; //进程号 + unsigned int uiCount; //心跳次数 + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StHeartBeatRsp; + + int EncodeStHeartBeatRsp (char *buf, int *pBufLen, + const StHeartBeatRsp * pRsp); + int DecodeHeartBeatRsp (StHeartBeatRsp * pRsp, const char *buf, + const int bufLen); + +//***************************0x02 注册,建立连接************************** +//请求 + typedef struct StRegisterReq + { + int iPid; + char cSolaceHostLen; + char strSolaceHost[BYTES_LENGTH]; + char cSolaceVpnLen; + char strSolaceVpn[BYTES_LENGTH]; + char cSolaceUserLen; + char strSolaceUser[BYTES_LENGTH]; + char cSolacePwdLen; + char strSolacePwd[BYTES_LENGTH]; + char cConsumerIpLen; + char strConsumerIp[BYTES_LENGTH]; + char cConsumerSysIdLen; + char strConsumerSysId[BYTES_LENGTH]; + char cConsumerDcnLen; + char strConsumerDcn[BYTES_LENGTH]; + char cConsumerOrgIdLen; + char strConsumerOrgId[BYTES_LENGTH]; + char cConsumerVersionLen; + char strConsumerVersion[BYTES_LENGTH]; + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StRegisterReq; + + int EncodeStRegisterReq (char *buf, int *pBufLen, + const StRegisterReq * pReq); + int DecodeStRegisterReq (StRegisterReq * pReq, const char *buf, + const int bufLen); + + typedef struct StRegisterRsp + { + unsigned int uiResult; + unsigned int uiCcdIndex; + unsigned int uiCcdFlow; + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StRegisterRsp; + + int EncodeStRegisterRsp (char *buf, int *pBufLen, + const StRegisterRsp * pRsp); + int DecodeStRegisterRsp (StRegisterRsp * pRsp, const char *buf, + const int bufLen); + +//***********************************0x06 注册接收连接*********************************** + typedef struct StRegisterReceiveReq + { + unsigned int uiCcdIndex; + unsigned int uiCcdFlow; + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StRegisterReceiveReq; + + int EncodeStRegisterReceiveReq (char *buf, int *pBufLen, + const StRegisterReceiveReq * pReq); + int DecodeStRegisterReceiveReq (StRegisterReceiveReq * pReq, + const char *buf, const int bufLen); + + typedef struct StRegisterReceiveRsp + { + unsigned int uiResult; + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StRegisterReceiveRsp; + + int EncodeStRegisterReceiveRsp (char *buf, int *pBufLen, + const StRegisterReceiveRsp * pRsp); + int DecodeStRegisterReceiveRsp (StRegisterRsp * pRsp, const char *buf, + const int bufLen); + +//请求 + typedef struct StAddListenReq + { + char strServiceId[SERVICE_ID_LENGTH]; + char strSceneId[SCENE_ID_LENGTH]; + } StAddListenReq; + + int EncodeAddListenReq (char *buf, int *pBufLen, + const StAddListenReq * pReq); + int DecodeAddListenReq (StAddListenReq * pReq, const char *buf, + const int bufLen); + + typedef struct StAddListenRsp + { + unsigned int uiResult; //见last_error + char strServiceId[SERVICE_ID_LENGTH]; + char strSceneId[SCENE_ID_LENGTH]; + } StAddListenRsp; + + int EncodeAddListenRsp (char *buf, int *pBufLen, + const StAddListenRsp * pRsp); + int DecodeAddListenRsp (StAddListenRsp * pRsp, const char *buf, + const int bufLen); + +//***************************0x03 增加监听************************** + +//请求 + typedef struct StAddManageReq + { + char cManageTopicLength; + char strManageTopic[BYTES_LENGTH]; + } StAddManageReq; + + int EncodeAddManageReq (char *buf, int *pBufLen, + const StAddManageReq * pReq); + int DecodeAddManageReq (StAddManageReq * pReq, const char *buf, + const int bufLen); + + typedef struct StAddManageRsp + { + unsigned int uiResult; //见last_error + char cManageTopicLength; + char strManageTopic[BYTES_LENGTH]; + } StAddManageRsp; + + int EncodeAddManageRsp (char *buf, int *pBufLen, + const StAddManageRsp * pRsp); + int DecodeAddManageRsp (StAddManageRsp * pRsp, const char *buf, + const int bufLen); + +//***************************0x04 worker发包************************** +//请求 + enum WORKER_SEND_MSG_TYPE + { + SEND_EVENT_MSG_TYPE = 1, + SEND_RR_MSG_TYPE = 2, + SEND_ASYNC_RR_MSG_TYPE = 3, + SEND_REPLY_MSG_TYPE = 4, + }; + + typedef struct StSendMsgReq + { + unsigned int uiMsgType; //见WORKER_SEND_MSG_TYPE定义 + unsigned int uiWemqMsgLen; + unsigned int uiSendMsgSeq; + char strWemqMsg[MAX_MSG_WEMQ_MSG_SIZE]; + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StSendMsgReq; + + int EncodeSendMsgReq (char *buf, int *pBufLen, const StSendMsgReq * pReq); + int DecodeSendMsgReq (StSendMsgReq * pReq, const char *buf, + const int bufLen); + +//回包 + typedef struct StSendMsgRsp + { + unsigned int uiResult; + unsigned int uiMsgType; //见WORKER_SEND_MSG_TYPE定义 + unsigned int uiRecvMsgSeq; //Worker send window size; + char cUuidLen; //消息uuid长度 + char strUuid[BYTES_LENGTH]; //消息uuid + } StSendMsgRsp; + +//return -1.空间不足 + int EncodeSendMsgRsp (char *buf, int *pBufLen, const StSendMsgRsp * pRsp); + int DecodeSendMsgRsp (StSendMsgRsp * pRsp, const char *buf, + const int bufLen); + +//***************************0x05 worker发送消息ack************************** +//请求,为避免其他业务代码错误导致把其他人的msg ack掉。因此这里将sessionId和sessionIndex、flowIndex做核对。 + typedef struct StAckMsgReq + { + unsigned int uiSessionIndex; + unsigned int uiFlowIndex; + unsigned long ulMsgId; + char cUuidLen; //消息uuid长度 + char strUuid[BYTES_LENGTH]; //消息uuid + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StAckMsgReq; + + int EncodeAckMsgReq (char *buf, int *pBufLen, const StAckMsgReq * pReq); + int DecodeAckMsgReq (StAckMsgReq * pReq, const char *buf, const int bufLen); + +//回包 + typedef struct StAckMsgRsp + { + unsigned int uiResult; + unsigned int uiSessionIndex; + unsigned int uiFlowIndex; + unsigned long ulMsgId; + char cUuidLen; //消息uuid长度 + char strUuid[BYTES_LENGTH]; //消息uuid + } StAckMsgRsp; + + int EncodeAckMsgRsp (char *buf, int *pBufLen, const StAckMsgRsp * pRsp); + int DecodeAckMsgRsp (StAckMsgRsp * pRsp, const char *buf, const int bufLen); + +//以下为proxy推送消息 +//***************************0x50 proxy下发消息************************** +//请求 + enum PUSH_MSG_TYPE + { + PUSH_QUEUE_MSG = 1, + PUSH_BROADCAST_MSG = 2, + PUSH_MANAGE_MSG = 3, + PUSH_RR_REPLY_MSG = 4, + }; + + typedef struct StPushMsgReq + { + char cWemqMsgType; + unsigned int uiSeq; + unsigned int uiWemqMsgLen; + char strWemqMsg[MAX_MSG_WEMQ_MSG_SIZE]; + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StPushMsgReq; + + int EncodePushMsgReq (char *buf, int *pBufLen, const StPushMsgReq * pReq); + int DecodePushMsgReq (StPushMsgReq * pReq, const char *buf, + const int bufLen); + +//回包 + typedef struct StPushMsgRsp + { + unsigned int uiResult; + char cUuidLen; //消息uuid长度 + char strUuid[BYTES_LENGTH]; //消息uuid + } StPushMsgRsp; + + int EncodePushMsgRsp (char *buf, int *pBufLen, const StPushMsgRsp * pRsp); + int DecodePushMsgRsp (StPushMsgRsp * pRsp, const char *buf, + const int bufLen); + +//*************************************************wemq worker-proxy包格式***************************** +//msg的组成都是header + msgBuf,其中header的头4个字节为长度, + typedef struct StWemqHeader + { + unsigned int uiPkgLen; + unsigned int uiColorFlag; + unsigned short usCmd; + unsigned int uiSessionId; + unsigned int uiSeq; + unsigned int uiReserved; + } StWemqHeader; + +#define MAX_WEMQ_HEADER_LEN (4096) +#define MAX_WEMQ_BODY_LEN (3 * 1024 * 1024) + typedef struct StWeMQMSG + { + unsigned int uiTotalLen; + unsigned int uiHeaderLen; + char cStrJsonHeader[MAX_WEMQ_HEADER_LEN]; + char cStrJsonBody[MAX_WEMQ_BODY_LEN]; + } StWeMQMSG; + + int GetWemqHeaderLen (); + int EncodeWemqHeader (char *buf, int *pBufLen, + const StWemqHeader * pHeader); + int DecodeWemqHeader (StWemqHeader * pHeader, const char *buf, + const int bufLen); + int DecodeWeMQMsg (StWeMQMSG * pMsg, const char *buf, const int bufLen); + +//��ʽ������������ + int GetAckMsgReqLength (const StAckMsgReq * pReq); + int GetAddListenReqLegth (const StAddListenReq * pReq); + int GetAddManageReqLegth (const StAddManageReq * pReq); + int GetPushMsgReqLegth (const StPushMsgReq * pReq); + int GetRegisterReceiveReqLegth (const StRegisterReceiveReq * pReq); + int GetRegisterReqLegth (const StRegisterReq * pReq); + int GetSendMsgReqLength (const StSendMsgReq * pReq); + int GetStHeartBeatReqLegth (const StHeartBeatReq * pReq); + +#ifdef __cplusplus +} +#endif +//#pragma pack() +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/wemq_tcp.h b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_tcp.h new file mode 100644 index 0000000000..4bf9c5e412 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_tcp.h @@ -0,0 +1,39 @@ +// 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. + +#ifndef _TCP_SOCKET_FOR_WEMQ_H_ +#define _TCP_SOCKET_FOR_WEMQ_H_ +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + int wemq_tcp_connect (const char *ip, uint16_t port, int timeout); + int wemq_tcp_send (int fd, void *msg, uint32_t totalLen, uint32_t headerLen, + int iTimeOut, SSL * ssl); + int wemq_tcp_recv (int fd, void *msg, uint32_t * len, int iTimeout, + SSL * ssl); + + void wemq_getsockename (int fd, char *ip, uint32_t len, int *port); + void wemq_getpeername (int fd, char *ip, uint32_t len, int *port); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/wemq_thread.h b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_thread.h new file mode 100644 index 0000000000..670c070fd3 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_thread.h @@ -0,0 +1,113 @@ +// 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. + +#ifndef _WEMQ_THREAD_ +#define _WEMQ_THREAD_ + +#include +#include "rmb_define.h" +#define MAX_EVENT 10 +#define TCP_PKG_LEN_BTYES 4 + +#ifdef _WEMQ_THREAD_DEBUG_ +#define ASSERT(A) assert((A)) +#else +#define ASSERT(A) ((void)(0)) +#endif +enum +{ + THREAD_STATE_INIT = 0, + THREAD_STATE_CONNECT, + THREAD_STATE_REGI, + THREAD_STATE_OK, + THREAD_STATE_CLOSE, //准备关闭状态 + THREAD_STATE_SERVER_BREAK, //服务端退出状态 + THREAD_STATE_BREAK, + THREAD_STATE_RECONNECT, + THREAD_STATE_DESTROY, + THREAD_STATE_EXIT +}; + +enum +{ + THREAD_MSG_CMD_BEAT = 0x01, + THREAD_MSG_CMD_REGI = 0x02, + THREAD_MSG_CMD_ADD_LISTEN = 0x03, + THREAD_MSG_CMD_SEND_MSG = 0x04, + THREAD_MSG_CMD_SEND_MSG_ACK = 0x05, + THREAD_MSG_CMD_ADD_MANAGE = 0x06, + THREAD_MSG_CMD_SEND_REQUEST = 0x07, + THREAD_MSG_CMD_SEND_REQUEST_ASYNC = 0x08, + THREAD_MSG_CMD_SEND_REPLY = 0x09, + THREAD_MSG_CMD_START = 0x0a, + THREAD_MSG_CMD_SEND_PUSH = 0x50, + THREAD_MSG_CMD_SEND_CLIENT_GOODBYE = 0x0b, + THREAD_MSG_CMD_SEND_LOG = 0x10, + THREAD_MSG_CMD_RECV_MSG_ACK = 0x11 +}; +/* +typedef struct StWemqThreadMsg +{ + unsigned int m_iCmd; + StWemqHeader m_stWemqHeader; + void* m_stReq; +}StWemqThreadMsg; +*/ +/* +typedef struct WemqThreadCtx +{ +// STRUCT_WEMQ_KFIFO(StWemqThreadMsg, 1024)* m_ptFifo; + stContextProxy* m_ptProxyContext; + + int m_iThreadId; + char* m_pRecvBuff; + char* m_pSendBuff; + + //cache msg which from user thread; + StWemqThreadMsg m_stWemqThreadMsg; + int m_iWemqThreadMsgHandled; + + StRegisterReq m_stReqForRegister; + StAddManageReq m_stReqForAddManage; + StAddListenReq m_stReqForAddListen; + + StWemqHeader m_stWemqHeader; + + StTopicList* m_ptTopicList; + + //for epoll + int m_iEpollFd; + struct epoll_event m_stEv; + struct epoll_event* m_ptEvents; + + int m_iSockFd; + int m_iLastState; + int m_iState; + int m_contextType; + +}WemqThreadCtx; +*/ +#define GetWemqThreadMsgLen() (sizeof(StWemqThreadMsg)) + +int32_t wemq_thread_state_init (WemqThreadCtx * pThreadCtx); +int32_t wemq_thread_state_connect (WemqThreadCtx * pThreadCtx); +int32_t wemq_thread_state_regi (WemqThreadCtx * pThreadCtx); +int32_t wemq_thread_state_ok (WemqThreadCtx * pThreadCtx); +int32_t wemq_thread_state_break (WemqThreadCtx * pThreadCtx); +int32_t wemq_thread_state_reconnect (WemqThreadCtx * pThreadCtx); +int32_t wemq_thread_state_destory (WemqThreadCtx * pThreadCtx); +int32_t wemq_thread_run (WemqThreadCtx * pThreadCtx); +int32_t check_dyed_msg (StRmbMsg * rmbMsg); +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/wemq_topic_list.h b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_topic_list.h new file mode 100644 index 0000000000..2d0971e1ad --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_topic_list.h @@ -0,0 +1,53 @@ +// 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. + +#ifndef _WEMQ_TOPIC_LIST_H_ +#define _WEMQ_TOPIC_LIST_H_ +#include +#include +#include +#include + +#define WEMQ_TOPIC_MAX_LEN 100 + +typedef struct StWemqTopicProp +{ + char cServiceId[32]; + char cScenario[32]; + char cTopic[WEMQ_TOPIC_MAX_LEN]; + int flag; //flag=0, serviceid flag=1, topic + struct StWemqTopicProp *next; +} StWemqTopicProp; + +typedef struct StWemqTopicList +{ + StWemqTopicProp *next; + StWemqTopicProp *tail; +} StWemqTopicList; + +typedef int (*WEMQ_DEC_FUNC) (StWemqTopicProp * pArg); + +void wemq_topic_list_init (StWemqTopicList * ptTopicList); +int32_t wemq_topic_list_delete (StWemqTopicList * pt); +int32_t wemq_topic_list_add_node (StWemqTopicList * pt, + StWemqTopicProp * ptpp); +int32_t wemq_topic_list_find_node (StWemqTopicList * pt, + StWemqTopicProp * ptpp, + StWemqTopicProp ** pos); +int32_t wemq_topic_list_del_node (StWemqTopicList * pt, + StWemqTopicProp * ptpp); +int32_t wemq_topic_list_is_empty (StWemqTopicList * pt); +int32_t wemq_topic_list_clear (StWemqTopicList * ptTopicList); +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/common.h b/eventmesh-sdks/eventmesh-sdk-c/src/common.h new file mode 100644 index 0000000000..1c2db39639 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/common.h @@ -0,0 +1,39 @@ +// 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. + +#ifndef COMMON_H_ +#define COMMON_H_ +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "json.h" +#include "rmb_define.h" + +// context proxy新增结构 + typedef struct json_object WEMQJSON; + typedef struct json_object PROPERTY; + + WEMQJSON *rmb_pub_encode_byte_body_for_wemq (unsigned int uiCmd, + StRmbMsg * ptSendMsg); + WEMQJSON *rmb_pub_encode_property_for_wemq (unsigned int uiCmd, + StRmbMsg * ptSendMsg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/message_log_api.c b/eventmesh-sdks/eventmesh-sdk-c/src/message_log_api.c new file mode 100644 index 0000000000..ee58205a7d --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/message_log_api.c @@ -0,0 +1,397 @@ +// 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. + +#include +#include +#include +#include +#include "common.h" +#include "message_log_api.h" +#include "wemq_thread.h" + +#define gettidv1() syscall(__NR_gettid) +#define gettidv2() syscall(SYS_gettid) + +static int get_log_id (char *clogId, int size) +{ + if (0 != rmb_msg_random_uuid (clogId, size)) + { + return -1; + } + + int i = 0; + for (i = 0; i < size; i++) + { + if (*(clogId + i) == '-') + { + *(clogId + i) = '0'; + } + } + + return 0; +} + +/*headerJson={“code”:0,”command”:”SYS_LOG_TO_LOGSERVER”} + bodyJson={“id”:”839232”,”consumerId”:”5982”,”logName”:”test”,”logTimestamp”:0, + ”content”:”test”,”logType”:”sys”,”lang”:”c”,”level”:”debug”,”processId”:5176,”threadId”:0,”consumerSvrId”:”dsi”,”extFields”:{}} +*/ + +int rmb_send_sys_log_for_api (stContextProxy * pContextProxy, + const char *iLogLevel, const char *cConsumerId, + const char *cLogName, const char *cContent, + const char *extFields) +{ + + if (pContextProxy == NULL || NULL == extFields) + { + LOGRMB (RMB_LOG_ERROR, "pContextProxy or extFields is null"); + return -1; + } + + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_LOG; + + WEMQJSON *jsonHeader = json_object_new_object (); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object for jsonHeader failed"); + return -1; + } + + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (SYS_LOG_TO_LOGSERVER)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object for jsonBody failed"); + json_object_put (jsonHeader); + return -1; + } + char cLogId[33] = { 0 }; + + if (0 != get_log_id (cLogId, sizeof (cLogId))) + { + LOGRMB (RMB_LOG_ERROR, "get_log_id failed"); + return -1; + } + + GetRmbNowLongTime (); + json_object_object_add (jsonBody, LOG_MSG_COM_ID, + json_object_new_string (cLogId)); + json_object_object_add (jsonBody, LOG_MSG_COM_CONSUMERID, + json_object_new_string (cConsumerId)); + json_object_object_add (jsonBody, LOG_MSG_COM_LOGNAME, + json_object_new_string (cLogName)); + json_object_object_add (jsonBody, LOG_MSG_COM_TIMESTAMP, + json_object_new_int64 (pRmbStConfig->ulNowTtime)); + json_object_object_add (jsonBody, LOG_MSG_COM_CONTENT, + json_object_new_string (cContent)); + json_object_object_add (jsonBody, LOG_MSG_COM_LOGTYPE, + json_object_new_string ("sys")); + json_object_object_add (jsonBody, LOG_MSG_COM_LANG, + json_object_new_string ("c")); + json_object_object_add (jsonBody, LOG_MSG_COM_PROCESSID, + json_object_new_int ((int) getpid ())); + json_object_object_add (jsonBody, LOG_MSG_COM_THREADID, + json_object_new_int64 ((long int) gettidv1 ())); + json_object_object_add (jsonBody, LOG_MSG_COM_CONSUMERSVRID, + json_object_new_string (pRmbStConfig->cHostIp)); + json_object_object_add (jsonBody, LOG_MSG_COM_LEVEL, + json_object_new_string (iLogLevel)); + + WEMQJSON *jsonExtFields = json_tokener_parse (extFields); + WEMQJSON *tmp = NULL; + if (jsonExtFields == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_tokener_parse extFields failed"); + tmp = json_tokener_parse ("{}"); + json_object_object_add (jsonBody, LOG_MSG_COM_EXTFIELDS, tmp); + } + else + { + json_object_object_add (jsonBody, LOG_MSG_COM_EXTFIELDS, jsonExtFields); + } + const char *header_str = json_object_get_string (jsonHeader); + + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_get_string for header is null"); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -2; + } + stThreadMsg.m_iHeaderLen = strlen (header_str); + + LOGRMB (RMB_LOG_INFO, "Gen thread msg header succ, len=%d, %s", + stThreadMsg.m_iHeaderLen, header_str); + stThreadMsg.m_pHeader = + (char *) malloc (stThreadMsg.m_iHeaderLen * sizeof (char) + 1); + if (stThreadMsg.m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for m_pHeader failed, errno=%d", errno); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + strncpy (stThreadMsg.m_pHeader, header_str, stThreadMsg.m_iHeaderLen); + stThreadMsg.m_pHeader[stThreadMsg.m_iHeaderLen] = '\0'; + + const char *body_str = json_object_get_string (jsonBody); + if (body_str == NULL) + { + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + + stThreadMsg.m_iBodyLen = strlen (body_str); + stThreadMsg.m_pBody = + (char *) malloc (stThreadMsg.m_iBodyLen * sizeof (char) + 1); + if (stThreadMsg.m_pBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for hello body failed"); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + memcpy (stThreadMsg.m_pBody, body_str, stThreadMsg.m_iBodyLen); + stThreadMsg.m_pBody[stThreadMsg.m_iBodyLen] = '\0'; + + json_object_put (jsonBody); + json_object_put (jsonHeader); + + int iRet = wemq_kfifo_put (&pContextProxy->pubFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error!,iRet=%d", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + return -5; + } + else + { + LOGRMB (RMB_LOG_DEBUG, "put sys log msg to fifo"); + return 0; + } +} + +/* +header=Header{cmd=TRACE_LOG_TO_LOGSERVER, code=0, msg='null', seq='null'}, body=RmbTraceLog{level=debug, logTimestamp=1525674893639, +logPoint=LOG_ERROR_POINT, message='null', model='model', retCode='retCode', retMsg='retMsg', lang='c', extFields={key=value}}} +*/ + +int rmb_send_log_for_error (stContextProxy * pContextProxy, int errCode, + char *errMsg, StRmbMsg * ptSendMsg) +{ + if (pRmbStConfig->iApiLogserverSwitch == 0) + { + return 0; + } + + if (pContextProxy == NULL || NULL == ptSendMsg) + { + LOGRMB (RMB_LOG_ERROR, "pContextProxy or ptSendMsg is null"); + return -1; + } + + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_LOG; + + int iRet = -1; + WEMQJSON *jsonHeader = json_object_new_object (); + + // 组装消息 + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (TRACE_LOG_TO_LOGSERVER)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object return null"); + json_object_put (jsonHeader); + return -1; + } + WEMQJSON *jsonMessage = json_object_new_object (); + if (jsonMessage == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object return null"); + json_object_put (jsonHeader); + json_object_put (jsonBody); + return -1; + } + char cTopic[128]; + char serviceOrEvent = (*(ptSendMsg->strServiceId + 3) == '0') ? 's' : 'e'; + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", + ptSendMsg->strTargetDcn, serviceOrEvent, ptSendMsg->strServiceId, + ptSendMsg->strScenarioId, *(ptSendMsg->strServiceId + 3)); + json_object_object_add (jsonMessage, MSG_BODY_TOPIC_STR, + json_object_new_string (cTopic)); + + WEMQJSON *jsonBodyProperty = + rmb_pub_encode_property_for_wemq (THREAD_MSG_CMD_SEND_LOG, ptSendMsg); + if (jsonBodyProperty == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_property_for_wemq return null"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonBody); + return -1; + } + + json_object_object_add (jsonMessage, MSG_BODY_PROPERTY_JSON, + jsonBodyProperty); + + WEMQJSON *jsonByteBody = + rmb_pub_encode_byte_body_for_wemq (THREAD_MSG_CMD_SEND_LOG, ptSendMsg); + if (jsonByteBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_byte_body_for_wemq return null"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonBody); + return -1; + } + const char *byteBodyStr = json_object_get_string (jsonByteBody); + + json_object_object_add (jsonMessage, MSG_BODY_BYTE_BODY_JSON, + json_object_new_string (byteBodyStr)); + + const char *message_str = json_object_get_string (jsonMessage); + if (message_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg body failed\n"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + + return -1; + } + + json_object_object_add (jsonBody, "retCode", json_object_new_int (errCode)); + json_object_object_add (jsonBody, "retMsg", + json_object_new_string (errMsg)); + json_object_object_add (jsonBody, "level", + json_object_new_string ("error")); + json_object_object_add (jsonBody, "logPoint", + json_object_new_string (LOG_ERROR_POINT)); + json_object_object_add (jsonBody, "model", + json_object_new_string ("model")); + json_object_object_add (jsonBody, "lang", json_object_new_string ("c")); + json_object_object_add (jsonBody, "message", + json_object_new_string (message_str)); + + const char *header_str = json_object_get_string (jsonHeader); + + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_get_string for header is null"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + return -2; + } + + const char *body_str = json_object_get_string (jsonBody); + if (body_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg body failed\n"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + return -1; + } + + stThreadMsg.m_iHeaderLen = strlen (header_str); + + stThreadMsg.m_pHeader = + (char *) malloc (stThreadMsg.m_iHeaderLen * sizeof (char) + 1); + if (stThreadMsg.m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for m_pHeader failed, errno=%d", errno); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + return -1; + } + strncpy (stThreadMsg.m_pHeader, header_str, stThreadMsg.m_iHeaderLen); + stThreadMsg.m_pHeader[stThreadMsg.m_iHeaderLen] = '\0'; + + stThreadMsg.m_iBodyLen = strlen (body_str); + stThreadMsg.m_pBody = + (char *) malloc (stThreadMsg.m_iBodyLen * sizeof (char) + 1); + if (stThreadMsg.m_pBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for hello body failed"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + return -1; + } + memcpy (stThreadMsg.m_pBody, body_str, stThreadMsg.m_iBodyLen); + stThreadMsg.m_pBody[stThreadMsg.m_iBodyLen] = '\0'; + LOGRMB (RMB_LOG_INFO, "Gen error log succ, header :%s, body:%s", header_str, + body_str); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + + iRet = wemq_kfifo_put (&pContextProxy->pubFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error!,iRet=%d", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + return -5; + } + else + { + LOGRMB (RMB_LOG_DEBUG, "error log msg put into fofo"); + return 0; + } +} + +/** + * 提供给业务调用,用于业务主动上报logserver + */ +int rmb_log_for_common (StContext * pStContext, const char *iLogLevel, + const char *cLogName, const char *content, + const char *extFields) +{ + if (pRmbStConfig->iApiLogserverSwitch == 0) + { + return 0; + } + stContextProxy *pContextProxy = pStContext->pContextProxy; + int iRet = + rmb_send_sys_log_for_api (pContextProxy, iLogLevel, + pRmbStConfig->cConsumerSysId, cLogName, content, + extFields); + return iRet; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_access_config.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_access_config.c new file mode 100644 index 0000000000..8d39edc1a3 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_access_config.c @@ -0,0 +1,827 @@ +// 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. + +#include +#include +#include "curl/curl.h" +#include "common.h" +#include "rmb_define.h" +#include "rmb_http_client.h" + +#define WEMQ_PROXY_MAX_SIZE (512) +#define WEMQ_PROXY_BUFFER_SIZE (262144) // 256K +//#define WEMQ_PROXY_SERVER_MAX_TIME (3600) // 1H +#define WEMQ_PROXY_SERVER_MAX_TIME (1 * 60 * 1000000) // 1m + +#define atomic_set(x, y) __sync_lock_test_and_set((x), (y)) + +typedef struct StWemqProxy +{ + char host[100]; + char idc[30]; + unsigned int port; + unsigned int weight; + unsigned int index; + + long failed_time; // 0: 没有失败; >0: 失败时间戳 + int flag; //用于初始连接时,该host是否已连接过 +} StWemqProxy; + +static struct StWemqProxy _wemq_proxy_list[WEMQ_PROXY_MAX_SIZE]; +static int _wemq_proxy_list_num = 0; // proxy个数 +static int _wemq_proxy_list_used = -1; // 当前使用proxy +static int _wemq_proxy_weight_tol = 0; // 权重总和 + +static int _wemq_proxy_inited = 0; + +static pthread_mutex_t __wemq_proxy_rmutex; + +int rmb_get_wemq_proxy_list_num () +{ + return _wemq_proxy_list_num; +} + +int rmb_get_wemq_proxy_list_used () +{ + return _wemq_proxy_list_used; +} + +static void ltrim (char *s) +{ + char *p = s; + int len = 0; + + if (s == NULL || *s == '\0') + { + return; + } + while (*p != '\0' && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')) + { + p++; + len++; + } + memmove (s, p, strlen (s) - len + 1); +} + +static void rtrim (char *s) +{ + int i; + + if (s == NULL || *s == '\0') + { + return; + } + i = strlen (s) - 1; + while ((s[i] == ' ' || + s[i] == '\t' || s[i] == '\n' || s[i] == '\r') && i >= 0) + { + s[i] = '\0'; + i--; + } +} + +static void trim (char *s) +{ + ltrim (s); + rtrim (s); +} + +static int _wemq_proxy_cmp (const void *val1, const void *val2) +{ + const StWemqProxy *proxy1 = (const StWemqProxy *) val1; + const StWemqProxy *proxy2 = (const StWemqProxy *) val2; + + if (proxy1->weight > proxy2->weight) + return 1; + if (proxy1->weight < proxy2->weight) + return -1; + return 0; +} + +/* +返回示例 +{ +"wemq-proxy-servers" : "10.255.1.144:10000#3;;127.0.0.1:36000#1;" +} +服务器列表格式 +host:port#weight; +host:port#weight;host:port#weight; +*/ +static int _wemq_proxy_load_item (StWemqProxy * pproxy, const char *pstr, + size_t len) +{ + char weight[64] = ""; + char idc[32] = ""; + char port[64] = ""; + int index1 = -1; // ':'位置 + int index2 = -1; // '#'位置 + int index3 = -1; // '|' 位置 + int begin = 0; + int size = 0; + int i = 0; + + if (pstr == NULL || pproxy == NULL || len == 0) + { + return -1; + } + + for (i = 0; i < (int) len; i++) + { + if (pstr[i] == ':') + { + if (index1 != -1) + { + return -2; + } + index1 = i; + } + else if (pstr[i] == '#') + { + if (index2 != -1) + { + return -2; + } + index2 = i; + } + else if (pstr[i] == '|') + { + if (index3 != -1) + { + return -2; + } + index3 = i; + } + } + + // 确认格式是否正确 + if (index1 == -1 || index2 == -1 || index1 >= index2 || index2 >= index3) + { + return -2; + } + + // IP + if (index1 > 100 || index1 == 0) + { + return -3; + } + memcpy (pproxy->host, pstr, index1); + pproxy->host[index1] = '\0'; + + // port + begin = index1 + 1; + size = index2 - begin; + if (size > 64 || size == 0) + { + return -3; + } + memcpy (port, &pstr[begin], size); + port[size] = '\0'; + + // weight + begin = index2 + 1; + size = index3 - begin; + if (size > 64 || size == 0) + { + return -3; + } + memcpy (weight, &pstr[begin], size); + weight[size] = '\0'; + + // idc + begin = index3 + 1; + size = len - begin; + if (size > 64 || size == 0) + { + return -3; + } + memcpy (pproxy->idc, &pstr[begin], size); + pproxy->idc[size] = '\0'; + + pproxy->port = atoi (port); + pproxy->weight = atoi (weight); + + if (pproxy->port == 0 || pproxy->weight == 0) + { + return -4; + } + + pproxy->flag = 0; + return 0; +} + +static int _wemq_proxy_load_by_http (StWemqProxy * pproxy, size_t size, + const char *url, long timeout) +{ + + int ret = 0; + if (pproxy == NULL || url == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pproxy or url is null"); + return -1; + } + + char *servers = NULL; + struct rmb_http_buffer req; + req.len = 0; + req.data = (char *) malloc (sizeof (char)); + if (req.data == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for req.data failed"); + return -1; + } + + if ((ret = rmb_http_easy_get (url, (void *) &req, timeout)) != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_http_easy_get error,iRet=%d", ret); + ret = -2; + goto _LOAD_ITEM_END; + } + + servers = (char *) malloc (sizeof (char) * (req.len + 1)); + if (servers == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for servers failed"); + free (req.data); + req.data = NULL; + return -1; + } + + LOGRMB (RMB_LOG_INFO, "_wemq_proxy_load_by_http:[resp:len=%u,%s]!", + (unsigned int) req.len, req.data); + if (req.len <= 2) + return -1; + // 解析json字符串 + + WEMQJSON *json = json_tokener_parse (req.data); + WEMQJSON *wemq_proxy_servers = NULL; + if (json == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "_wemq_proxy_load_by_http: json_tokener_parse error!"); + ret = -3; + goto _LOAD_ITEM_END; + } + + char *config_param = "wemqAccessServer"; + if (strstr (url, "wemqAccessServer") == NULL) + config_param = pRmbStConfig->strDepartMent; + if (!json_object_object_get_ex (json, config_param, &wemq_proxy_servers)) + { + LOGRMB (RMB_LOG_ERROR, + "_wemq_proxy_load_by_http: json_object_object_get_ex error!"); + ret = -3; + json_object_put (json); + goto _LOAD_ITEM_END; + } + + const char *pservers = json_object_get_string (wemq_proxy_servers); + if (pservers != NULL) + { + snprintf (servers, WEMQ_PROXY_BUFFER_SIZE, "%s", pservers); + } + else + { + LOGRMB (RMB_LOG_ERROR, + "_wemq_proxy_load_by_http: wemqAccessServer is null"); + } + json_object_put (json); + + LOGRMB (RMB_LOG_INFO, "_wemq_proxy_load_by_http: [servers:%s]!", servers); + + json = json_tokener_parse (servers); + wemq_proxy_servers = NULL; + if (json == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "_wemq_proxy_load_by_http: json_tokener_parse error!"); + ret = -3; + goto _LOAD_ITEM_END; + } + + //如果当前子系统有特定的access,没有就默认 + if (!json_object_object_get_ex + (json, pRmbStConfig->cConsumerSysId, &wemq_proxy_servers)) + { + LOGRMB (RMB_LOG_INFO, + "current subsystem does not have special access list"); + if (!json_object_object_get_ex + (json, "wemqAccessServer", &wemq_proxy_servers)) + { + LOGRMB (RMB_LOG_ERROR, + "_wemq_proxy_load_by_http: json_object_object_get_ex error!"); + ret = -3; + json_object_put (json); + goto _LOAD_ITEM_END; + } + + } + + pservers = json_object_get_string (wemq_proxy_servers); + if (pservers != NULL) + { + snprintf (servers, WEMQ_PROXY_BUFFER_SIZE, "%s", pservers); + } + else + { + LOGRMB (RMB_LOG_ERROR, + "_wemq_proxy_load_by_http: wemqAccessServer is null"); + } + json_object_put (json); + + // 解析每个字段 + trim (servers); + { + char *item = NULL; + char *saveptr = NULL; + char *ptr = servers; + int i = 0; + + while ((item = strtok_r (ptr, ";", &saveptr)) != NULL) + { + if (i >= (int) size) + { + LOGRMB (RMB_LOG_WARN, + " [index: %d] [size: %zu] _wemq_proxy_load_by_http: servers too more!\n", + i, size); + break; + } + if (_wemq_proxy_load_item (&pproxy[i], item, strlen (item)) == 0) + { + i++; + } + else + { + LOGRMB (RMB_LOG_WARN, + "[item: %s] _wemq_proxy_load_by_http: _wemq_proxy_load_item error!\n", + item); + } + ptr = NULL; + } + if (i == 0) + { + LOGRMB (RMB_LOG_ERROR, "_wemq_proxy_load_by_http: servers is 0!\n"); + } + + ret = i; + } + +_LOAD_ITEM_END: + if (req.data != NULL) + { + free (req.data); + req.data = NULL; + } + if (servers != NULL) + { + free (servers); + servers = NULL; + } + return ret; +} + +static int _wemq_proxy_save (StWemqProxy * pproxy, size_t size, + const char *path) +{ + FILE *fp = NULL; + int i = 0; + + if ((fp = fopen (path, "w")) == NULL) + { + LOGRMB (RMB_LOG_ERROR, "[path: %s] _wemq_proxy_save: fopen error!\n", + path); + return -1; + } + for (i = 0; i < (int) size; i++) + { + fprintf (fp, "%s:%u#%u\n", pproxy[i].host, pproxy[i].port, + pproxy[i].weight); + } + fclose (fp); + return 0; +} + +//int wemq_proxy_load_servers(char* url, long timeout, const char* path) +int wemq_proxy_load_servers (const char *url, long timeout) +{ + int ret = 0; + int tol = 0; + int i = 0; + int j = 0; + if (pRmbStConfig->iWemqUseHttpCfg != 1) + { + return 0; + } + + if (_wemq_proxy_inited == 0) + { + _wemq_proxy_inited = 1; + pthread_mutex_init (&__wemq_proxy_rmutex, NULL); + } + + int tmp_wemq_proxy_list_num = 0; + struct StWemqProxy tmp_wemq_proxy_list[WEMQ_PROXY_MAX_SIZE]; + + memset (tmp_wemq_proxy_list, 0, sizeof (StWemqProxy) * WEMQ_PROXY_MAX_SIZE); + + //1. 通过HTTP请求配置中心 + ret = + _wemq_proxy_load_by_http (tmp_wemq_proxy_list, WEMQ_PROXY_MAX_SIZE, url, + timeout); + if (ret <= 0 && (strstr (url, "wemqAccessServer") == NULL)) + { + LOGRMB (RMB_LOG_WARN, "get wemq proxy departMent ip list failed,url=%s", + url); + return -1; + } + if (ret <= 0) + { + LOGRMB (RMB_LOG_ERROR, "get wemq proxy ip list failed,url=%s", url); + return -1; + } + tmp_wemq_proxy_list_num = ret; + + //2. 排序 + qsort (tmp_wemq_proxy_list, tmp_wemq_proxy_list_num, sizeof (StWemqProxy), + _wemq_proxy_cmp); + + //3. 权重相加 + for (i = 0; i < tmp_wemq_proxy_list_num; i++) + { + tol += tmp_wemq_proxy_list[i].weight; + } + _wemq_proxy_weight_tol = tol; + int equal_flag = 0; + + if (tmp_wemq_proxy_list_num == _wemq_proxy_list_num) + { + for (i = 0; i < _wemq_proxy_list_num; i++) + { + if (strcmp (_wemq_proxy_list[i].host, tmp_wemq_proxy_list[i].host) != 0 + || _wemq_proxy_list[i].port != tmp_wemq_proxy_list[i].port + || _wemq_proxy_list[i].weight != tmp_wemq_proxy_list[i].weight) + { + equal_flag = 1; + break; + } + } + //配置中心和本地的配置相同 + if (equal_flag == 0) + return 0; + } + //打印配置中心和本地的配置 + for (i = 0; i < _wemq_proxy_list_num; i++) + { + LOGRMB (RMB_LOG_DEBUG, + "[local address %d: host,%s|port,%u|idc:%s|weight,%u|index,%u|failed_time,%ld|flag,%d", + i, _wemq_proxy_list[i].host, _wemq_proxy_list[i].port, + _wemq_proxy_list[i].idc, _wemq_proxy_list[i].weight, + _wemq_proxy_list[i].index, _wemq_proxy_list[i].failed_time, + _wemq_proxy_list[i].flag); + } + for (j = 0; j < tmp_wemq_proxy_list_num; j++) + { + LOGRMB (RMB_LOG_DEBUG, + "[configcenter address %d: host,%s|port,%u|idc:%s|weight,%u|index,%u|failed_time,%ld|flag,%d", + j, tmp_wemq_proxy_list[j].host, tmp_wemq_proxy_list[j].port, + tmp_wemq_proxy_list[j].idc, tmp_wemq_proxy_list[j].weight, + tmp_wemq_proxy_list[j].index, tmp_wemq_proxy_list[j].failed_time, + tmp_wemq_proxy_list[j].flag); + } + + pthread_mutex_lock (&__wemq_proxy_rmutex); + //比较缓存数据和配置中心获取的数据,保留缓存数据中的flag和failedtime + for (i = 0; i < _wemq_proxy_list_num; i++) + { + if (_wemq_proxy_list[i].failed_time == 0 && _wemq_proxy_list[i].flag == 0) + continue; + for (j = 0; j < tmp_wemq_proxy_list_num; j++) + { + if (strcmp (_wemq_proxy_list[i].host, tmp_wemq_proxy_list[j].host) == 0 + && _wemq_proxy_list[i].port == tmp_wemq_proxy_list[j].port) + { + tmp_wemq_proxy_list[j].failed_time = _wemq_proxy_list[i].failed_time; + tmp_wemq_proxy_list[j].flag = _wemq_proxy_list[i].flag; + } + } + } + //更新缓存数据 + memset (_wemq_proxy_list, 0, sizeof (StWemqProxy) * WEMQ_PROXY_MAX_SIZE); + memcpy (_wemq_proxy_list, tmp_wemq_proxy_list, + sizeof (StWemqProxy) * tmp_wemq_proxy_list_num); + _wemq_proxy_list_num = tmp_wemq_proxy_list_num; + _wemq_proxy_list_used = -1; + pthread_mutex_unlock (&__wemq_proxy_rmutex); + + return 0; +} + +int wemq_proxy_get_server (char *host, size_t size, unsigned int *port) +{ + int now_index = -1; + int tmp = -1; + int wemq_proxy_usable_server_list[_wemq_proxy_list_num]; + long now_time = 0; + struct timeval tv; + + if (pRmbStConfig->iWemqUseHttpCfg != 1) + { + *port = pRmbStConfig->cWemqProxyPort; + snprintf (host, size, "%s", pRmbStConfig->cWemqProxyIp); + return 1; + } + + pthread_mutex_lock (&__wemq_proxy_rmutex); + if (_wemq_proxy_list_num <= 0) + { + pthread_mutex_unlock (&__wemq_proxy_rmutex); + LOGRMB (RMB_LOG_ERROR, "get proxy list number is:%d", + _wemq_proxy_list_num); + *port = 0; + memset (host, 0x00, sizeof (char) * size); + return 2; + } + + //从可以连接的ip中选取 + int wemq_proxy_usable_sever_weight = 0; + int wemq_proxy_usable_count = 0; + wemq_proxy_get_usable_server_list (wemq_proxy_usable_server_list, + &wemq_proxy_usable_sever_weight, + &wemq_proxy_usable_count); + //LOGRMB(RMB_LOG_DEBUG, "final count: %d | final weight: %d", wemq_proxy_usable_count, wemq_proxy_usable_sever_weight); + if (wemq_proxy_usable_count == 0) + { + pthread_mutex_unlock (&__wemq_proxy_rmutex); + LOGRMB (RMB_LOG_ERROR, "local proxy list all in black list"); + *port = 0; + memset (host, 0x00, sizeof (char) * size); + return 2; + } + else if (wemq_proxy_usable_count == 1) + { + now_index = wemq_proxy_usable_server_list[0]; + } + else + { + + //use weight + gettimeofday (&tv, NULL); + now_time = tv.tv_sec * 1000000 + tv.tv_usec; + srand ((unsigned int) now_time); + int random_index = rand () % wemq_proxy_usable_sever_weight; + int i = 0; + int tmp_weight = 0; + int tmp_index = 0; + for (; i < wemq_proxy_usable_count; i++) + { + tmp_index = wemq_proxy_usable_server_list[i]; + tmp_weight += _wemq_proxy_list[tmp_index].weight; + if (random_index < tmp_weight) + { + //LOGRMB(RMB_LOG_DEBUG, "choose host: %s | failed_time:%ld", _wemq_proxy_list[tmp_index].host, _wemq_proxy_list[tmp_index].failed_time); + now_index = tmp_index; + break; + } + } + } + gettimeofday (&tv, NULL); + now_time = tv.tv_sec * 1000000 + tv.tv_usec; + if ((_wemq_proxy_list[now_index].failed_time + + WEMQ_PROXY_SERVER_MAX_TIME) <= now_time) + { + atomic_set (&_wemq_proxy_list[now_index].failed_time, 0); + } + + // } while (tmp != now_index); + + _wemq_proxy_list_used = now_index; + if (_wemq_proxy_list[now_index].flag == 0) + { + _wemq_proxy_list[now_index].flag = 1; + } + + // 如果没有找到,由之前的使用默认IP调整为打印error日志,并等待黑名单解禁 + if (_wemq_proxy_list[now_index].failed_time != 0 && + (_wemq_proxy_list[now_index].failed_time + WEMQ_PROXY_SERVER_MAX_TIME) > + now_time) + { + pthread_mutex_unlock (&__wemq_proxy_rmutex); + LOGRMB (RMB_LOG_ERROR, "local proxy list all in black list"); + //*port = pRmbStConfig->cWemqProxyPort; + //snprintf(host, size, "%s", pRmbStConfig->cWemqProxyIp); + *port = 0; + memset (host, 0x00, sizeof (char) * size); + return 2; + } + + *port = (int) _wemq_proxy_list[now_index].port; + snprintf (host, size, "%s", _wemq_proxy_list[now_index].host); + pthread_mutex_unlock (&__wemq_proxy_rmutex); + + return 0; +} + +void wemq_proxy_goodbye (const char *host, unsigned int port) +{ + if (pRmbStConfig->iWemqUseHttpCfg != 1) + { + return; + } + + struct timeval tv; + gettimeofday (&tv, NULL); +// long now_time = time(NULL); + long now_time = tv.tv_sec * 1000000 + tv.tv_usec; + + LOGRMB (RMB_LOG_INFO, + "[used: host,%s|port,%u] [wemq_proxy_list_used:%d] wemq_proxy_goodbye!\n", + host, port, _wemq_proxy_list_used); + pthread_mutex_lock (&__wemq_proxy_rmutex); + + int i = 0; + for (i = 0; i < _wemq_proxy_list_num; i++) + { + if ((strcmp (host, _wemq_proxy_list[i].host) == 0) + && (port == _wemq_proxy_list[i].port)) + { +// LOGRMB(RMB_LOG_WARN, "[used: host:%s|port:%d] wemq_proxy_goodbye inconformity!", host, port); + atomic_set (&_wemq_proxy_list[i].failed_time, now_time); + } + } + pthread_mutex_unlock (&__wemq_proxy_rmutex); +} + +void wemq_proxy_to_black_list (const char *host, unsigned int port) +{ + if (pRmbStConfig->iWemqUseHttpCfg != 1) + { + return; + } + + struct timeval tv; + gettimeofday (&tv, NULL); + long now_time = tv.tv_sec * 1000000 + tv.tv_usec; + + LOGRMB (RMB_LOG_INFO, "[host:%s|port:%u] add to black list!\n", host, port); + pthread_mutex_lock (&__wemq_proxy_rmutex); + int i = 0; + for (i = 0; i < _wemq_proxy_list_num; i++) + { + if ((strcmp (host, _wemq_proxy_list[i].host) == 0) + && (port == _wemq_proxy_list[i].port)) + { + atomic_set (&_wemq_proxy_list[i].failed_time, now_time); + } + } + pthread_mutex_unlock (&__wemq_proxy_rmutex); +} + +void wemq_proxy_get_usable_server_list (int *wemq_proxy_usable_server_list, + int *wemq_proxy_usable_sever_weight, + int *wemq_proxy_usable_count) +{ + if (pRmbStConfig->iWemqUseHttpCfg != 1) + { + return; + } + int i = 0; + int j = 0; + int loop = 0; + int local_idc_usable_flag = 0; + int wemq_proxy_usable_server_list_backup[_wemq_proxy_list_num]; + memset (wemq_proxy_usable_server_list_backup, 0x00, + sizeof (int) * _wemq_proxy_list_num); + int wemq_proxy_usable_count_backup = 0; + int wemq_proxy_usable_sever_weight_backup = 0; + bool usableLocalIdc = false; + + struct timeval tv; + gettimeofday (&tv, NULL); + long now_time = tv.tv_sec * 1000000 + tv.tv_usec; + + for (; i < _wemq_proxy_list_num; i++) + { + char isBlack = + ((_wemq_proxy_list[i].failed_time + WEMQ_PROXY_SERVER_MAX_TIME) <= + now_time) ? 'n' : 'y'; + //LOGRMB(RMB_LOG_DEBUG, "[host:%s, port:%d, black:%c]", _wemq_proxy_list[i].host, _wemq_proxy_list[i].port, isBlack); + if (strcmp (_wemq_proxy_list[i].idc, pRmbStConfig->cRegion) == 0) + { + + if (_wemq_proxy_list[i].failed_time == 0 + || (_wemq_proxy_list[i].failed_time + WEMQ_PROXY_SERVER_MAX_TIME) <= + now_time) + { + wemq_proxy_usable_server_list[j] = i; + j++; + *wemq_proxy_usable_count += 1; + *wemq_proxy_usable_sever_weight += (int) _wemq_proxy_list[i].weight; + usableLocalIdc = true; + //LOGRMB(RMB_LOG_DEBUG, "[host:%s | port:%u | weight:%d | index: %d] is usable!\n", _wemq_proxy_list[i].host, _wemq_proxy_list[i].port, _wemq_proxy_list[i].weight, i); + //LOGRMB(RMB_LOG_DEBUG, "j: %d | count: %d | weight: %d", j, *wemq_proxy_usable_count, *wemq_proxy_usable_sever_weight); + } + } + else + { + if (_wemq_proxy_list[i].failed_time == 0 + || (_wemq_proxy_list[i].failed_time + WEMQ_PROXY_SERVER_MAX_TIME) <= + now_time) + { + wemq_proxy_usable_server_list_backup[loop] = i; + loop++; + wemq_proxy_usable_count_backup += 1; + wemq_proxy_usable_sever_weight_backup += + (int) _wemq_proxy_list[i].weight; + //LOGRMB(RMB_LOG_DEBUG, "[host:%s | port:%u | weight:%d | index: %d] is usable!\n", _wemq_proxy_list[i].host, _wemq_proxy_list[i].port, _wemq_proxy_list[i].weight, i); + //LOGRMB(RMB_LOG_DEBUG, "j: %d | count: %d | weight: %d", j, *wemq_proxy_usable_count, *wemq_proxy_usable_sever_weight); + } + } + } + /* + for(i = 0; i < *wemq_proxy_usable_count; i++){ + LOGRMB(RMB_LOG_DEBUG, "[local usable index: %d]\n", wemq_proxy_usable_server_list[i]); + } + for(i = 0; i < wemq_proxy_usable_count_backup; i++){ + LOGRMB(RMB_LOG_DEBUG, "[backup usable index: %d]\n", wemq_proxy_usable_server_list_backup[i]); + } */ + + if (!usableLocalIdc) + { + memset (wemq_proxy_usable_server_list, 0, + sizeof (int) * _wemq_proxy_list_num); + memcpy (wemq_proxy_usable_server_list, + wemq_proxy_usable_server_list_backup, + sizeof (int) * wemq_proxy_usable_count_backup); + *wemq_proxy_usable_count = wemq_proxy_usable_count_backup; + *wemq_proxy_usable_sever_weight = wemq_proxy_usable_sever_weight_backup; + } + /* + for(i = 0; i < *wemq_proxy_usable_count; i++){ + LOGRMB(RMB_LOG_DEBUG, "[final usable index: %d]\n", wemq_proxy_usable_server_list[i]); + } + */ +} + +/** + * 判断所有的ip是否均连接过 + */ +int wemq_proxy_ip_is_connected () +{ + if (pRmbStConfig->iWemqUseHttpCfg != 1) + { + return 1; + } + + int iRet = 0; + int i = 0; + pthread_mutex_lock (&__wemq_proxy_rmutex); + for (i = 0; i < _wemq_proxy_list_num; i++) + { + if (_wemq_proxy_list[i].flag == 0) + break; + } + pthread_mutex_unlock (&__wemq_proxy_rmutex); + + if (i >= _wemq_proxy_list_num) + { + iRet = 1; + } + + return iRet; +} + +/** + * 分隔IP列表 + */ +void split_str (char *ips, char ipArray[][50], int *len) +{ + // printf("%s\n", ips); + //char (*ipArray)[50] = (char(*)[50])malloc(sizeof(char) * 15 * 50); + int count = 0; + char *ip = NULL; + ip = strtok (ips, ";"); + if (ip == NULL) + { + *len = 0; + return; + } + strcpy (ipArray[count], ip); + count++; + while (ip = strtok (NULL, ";")) + { + strcpy (ipArray[count], ip); + count++; + } + *len = count; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_cfg.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_cfg.c new file mode 100644 index 0000000000..15b9fdc0ed --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_cfg.c @@ -0,0 +1,594 @@ +// 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. + +#include +#include +#include +#include +#include "rmb_log.h" +#include "rmb_udp.h" +#include "rmb_cfg.h" +#include +#include +#include +#include + +#include "rmb_access_config.h" + +StRmbConfig *pRmbStConfig; + +int rmb_reload_config (); + +static char *rmb_get_val (char *desc, char *src) +{ + char *descp = desc, *srcp = src; + int mtime = 0, space = 0; + + while (mtime != 2 && *srcp != '\0') + { + switch (*srcp) + { + case ' ': + case '\t': + case '\0': + case '\n': + case US: + space = 1; + srcp++; + break; + default: + if (space || srcp == src) + mtime++; + space = 0; + if (mtime == 2) + break; + *descp = *srcp; + descp++; + srcp++; + } + } + *descp = '\0'; + strcpy (src, srcp); + return desc; +} + +static void rmb_InitDefault (va_list ap) +{ + char *sParam, *sVal, *sDefault; + double *pdVal, dDefault; + long *plVal, lDefault; + int iType, *piVal, iDefault; + long lSize; + short *pwVal = NULL; + short wDefault; + + sParam = va_arg (ap, char *); + + while (sParam != NULL) + { + iType = va_arg (ap, int); + + switch (iType) + { + case CFG_LINE: + sVal = va_arg (ap, char *); + sDefault = va_arg (ap, char *); + lSize = va_arg (ap, long); + + strncpy (sVal, sDefault, (int) lSize - 1); + sVal[lSize - 1] = 0; + //snprintf(sVal,lSize,"%s",sDefault); + break; + case CFG_STRING: + sVal = va_arg (ap, char *); + sDefault = va_arg (ap, char *); + lSize = va_arg (ap, long); + + strncpy (sVal, sDefault, (int) lSize - 1); + sVal[lSize - 1] = 0; + //snprintf(sVal,lSize,"%s",sDefault); + break; + case CFG_LONG: + plVal = va_arg (ap, long *); + lDefault = va_arg (ap, long); + + *plVal = lDefault; + break; + case CFG_INT: + piVal = va_arg (ap, int *); + iDefault = va_arg (ap, int); + + *piVal = iDefault; + break; + case CFG_SHORT: + pwVal = va_arg (ap, short *); + wDefault = va_arg (ap, int); + *pwVal = wDefault; + break; + case CFG_DOUBLE: + pdVal = va_arg (ap, double *); + dDefault = va_arg (ap, double); + + *pdVal = dDefault; + break; + } + sParam = va_arg (ap, char *); + } +} + +static void rmb_SetVal (va_list ap, const char *sP, char *sV) +{ + char *sParam = NULL, *sVal = NULL, *sDefault = NULL; + double *pdVal = NULL, dDefault; + long *plVal = NULL, lDefault; + int iType, *piVal = NULL, iDefault; + long lSize = 0; + char sLine[MAX_CONFIG_LINE_LEN + 1], sLine1[MAX_CONFIG_LINE_LEN + 1]; + short *pwVal = NULL; + short wDefault; + + strcpy (sLine, sV); + strcpy (sLine1, sV); + rmb_get_val (sV, sLine1); + sParam = va_arg (ap, char *); + + while (sParam != NULL) + { + iType = va_arg (ap, int); + + switch (iType) + { + case CFG_LINE: + sVal = va_arg (ap, char *); + sDefault = va_arg (ap, char *); + lSize = va_arg (ap, long); + + if (strcmp (sP, sParam) == 0) + { + strncpy (sVal, sLine, (int) lSize - 1); + sVal[lSize - 1] = 0; + //snprintf(sVal,lSize,"%s",sLine); + } + break; + case CFG_STRING: + sVal = va_arg (ap, char *); + sDefault = va_arg (ap, char *); + lSize = va_arg (ap, long); + + break; + case CFG_LONG: + plVal = va_arg (ap, long *); + lDefault = va_arg (ap, long); + + /* + if (strcmp(sP, sParam) == 0) + { + *plVal = atol(sV); + } + */ + break; + case CFG_INT: + piVal = va_arg (ap, int *); + iDefault = va_arg (ap, int); + + /* + if (strcmp(sP, sParam) == 0) + { + *piVal = iDefault; + } + */ + break; + case CFG_SHORT: + pwVal = va_arg (ap, short *); + wDefault = va_arg (ap, int); + break; + case CFG_DOUBLE: + pdVal = va_arg (ap, double *); + dDefault = va_arg (ap, double); + + *pdVal = dDefault; + break; + } + + if (strcmp (sP, sParam) == 0) + { + switch (iType) + { + case CFG_STRING: + strncpy (sVal, sV, (int) lSize - 1); + sVal[lSize - 1] = 0; + break; + case CFG_LONG: + //*plVal = atol(sV); + *plVal = strtoul (sV, NULL, 0); + break; + case CFG_INT: + //*piVal = atoi(sV); + *piVal = strtoul (sV, NULL, 0); + break; + case CFG_SHORT: + *pwVal = strtoul (sV, NULL, 0); + break; + case CFG_DOUBLE: + *pdVal = atof (sV); + break; + } + + return; + } + + sParam = va_arg (ap, char *); + } +} + +static int rmb_GetParamVal (char *sLine, char *sParam, char *sVal) +{ + + rmb_get_val (sParam, sLine); + strcpy (sVal, sLine); + + if (sParam[0] == '#') + return 1; + + return 0; +} + +void RMB_TLib_Cfg_GetConfig (char *sConfigFilePath, ...) +{ + FILE *pstFile; + char sLine[MAX_CONFIG_LINE_LEN + 1], sParam[MAX_CONFIG_LINE_LEN + 1], + sVal[MAX_CONFIG_LINE_LEN + 1]; + va_list ap; + char *pCur = NULL; + + va_start (ap, sConfigFilePath); + rmb_InitDefault (ap); + va_end (ap); + + if ((pstFile = fopen (sConfigFilePath, "r")) == NULL) + { + // printf("Can't open Config file '%s', ignore.", sConfigFilePath); + return; + } + + while (1) + { + pCur = fgets (sLine, sizeof (sLine), pstFile); + if (pCur == NULL) + break; + + if (feof (pstFile)) + { + break; + } + + if (rmb_GetParamVal (sLine, sParam, sVal) == 0) + { + va_start (ap, sConfigFilePath); + rmb_SetVal (ap, sParam, sVal); + va_end (ap); + } + } + + fclose (pstFile); +} + +void rmb_cfg_process_signal (int sigalNo) +{ + switch (sigalNo) + { + case SIGUSR1: + { + LOGRMB (RMB_LOG_INFO, "pid=%u receive user signal 1,reload cfg!", + pRmbStConfig->uiPid); + rmb_reload_config (); + LOGRMB (RMB_LOG_INFO, "pid=%u reload cfg succ!", pRmbStConfig->uiPid); + break; + } + case SIGUSR2: + { + LOGRMB (RMB_LOG_INFO, "pid=%u receive user signal 2,reload cfg!", + pRmbStConfig->uiPid); + rmb_reload_config (); + LOGRMB (RMB_LOG_INFO, "pid=%u reload cfg succ!", pRmbStConfig->uiPid); + break; + } + default: + { + printf ("receive signal=%u", sigalNo); + } + } + return; +} + +int rmb_reload_config () +{ + Rmb_TLib_Cfg_GetConfig (pRmbStConfig->strConfigFile, + "consumerSysId", CFG_STRING, + pRmbStConfig->cConsumerSysId, "", + sizeof (pRmbStConfig->cConsumerSysId), + "consumerSysVersion", CFG_STRING, + pRmbStConfig->cConsumerSysVersion, "", + sizeof (pRmbStConfig->cConsumerSysVersion), + "consumerDcn", CFG_STRING, + pRmbStConfig->cConsumerDcn, "", + sizeof (pRmbStConfig->cConsumerDcn), "logFile", + CFG_STRING, pRmbStConfig->logFileName, "../rmb/log", + sizeof (pRmbStConfig->logFileName), "logLevel", + CFG_INT, &(pRmbStConfig->iLogLevel), 5, + "logFileNums", CFG_INT, + &(pRmbStConfig->iLogFileNums), 100, "logFileSize", + CFG_INT, &(pRmbStConfig->iLogFileSize), 500000000, + "logSwiftType", CFG_INT, + &(pRmbStConfig->iLogShiftType), 1, "debugSwitch", + CFG_INT, &(pRmbStConfig->iDebugSwitch), 0, + "everyProcessNumFromMq", CFG_INT, + &(pRmbStConfig->iEveryTimeProcessNum), 10, + "notifyCheckSpan", CFG_INT, + &(pRmbStConfig->iNotifyCheckSpan), 1, + "notifyMergeSwitch", CFG_INT, + &(pRmbStConfig->iFLagForMergeNotify), 1, "orgId", + CFG_STRING, pRmbStConfig->strOrgId, "99996", + sizeof (pRmbStConfig->strOrgId), "cacheTimeout", + CFG_INT, &(pRmbStConfig->iCacheTimeoutTime), 10, + "cacheSuccTimeout", CFG_INT, + &(pRmbStConfig->iCacheSuccTimeoutTime), 600, + "cacheFailedTimeout", CFG_INT, + &(pRmbStConfig->iCacheFailedTimeoutTime), 30, + "switchForReloadSignal1", CFG_INT, + &(pRmbStConfig->iSwitchForSignal1), 1, + "switchForReloadSignal2", CFG_INT, + &(pRmbStConfig->iSwitchForSignal2), 0, "ackTimer", + CFG_INT, &(pRmbStConfig->ackTimers), 100, + "ackThreshold", CFG_INT, + &(pRmbStConfig->ackThresHold), 30, "queryTimeout", + CFG_INT, &(pRmbStConfig->iQueryTimeout), 1000, + "CommonTimeOut", CFG_INT, + &(pRmbStConfig->iCommonTimeOut), 500, "StatPeriod", + CFG_INT, &(pRmbStConfig->iStatPeriod), 300, + "GetGroupTopicTime", CFG_INT, + &(pRmbStConfig->iGetGroupTopicTime), 5, + "GetSendWhiteListTime", CFG_INT, + &(pRmbStConfig->iGetSendWhiteListTime), 30, NULL); + + //ackTimer的范围为20到1500 + if (pRmbStConfig->ackTimers > 1500) + pRmbStConfig->ackTimers = 1500; + if (pRmbStConfig->ackTimers < 20) + pRmbStConfig->ackTimers = 20; + + //ackThreshold的范围为1 到75 + if (pRmbStConfig->ackThresHold > 75) + pRmbStConfig->ackThresHold = 75; + if (pRmbStConfig->ackThresHold < 1) + pRmbStConfig->ackThresHold = 1; + + if (pRmbStConfig->iQueryTimeout > 5000) + pRmbStConfig->iQueryTimeout = 5000; + if (pRmbStConfig->iQueryTimeout < 500) + pRmbStConfig->iQueryTimeout = 500; + + if (pRmbStConfig->iSwitchForSignal1) + { + signal (SIGUSR1, rmb_cfg_process_signal); + } + + if (pRmbStConfig->iSwitchForSignal2) + { + signal (SIGUSR2, rmb_cfg_process_signal); + } + + return 0; +} + +int rmb_load_config (const char *configPath) +{ + pRmbStConfig = (StRmbConfig *) calloc (1, sizeof (StRmbConfig)); + if (pRmbStConfig == NULL) + { + printf ("rmb_load_config pRmbStConfig calloc error!"); + return -1; + } + + init_error (); + snprintf (pRmbStConfig->strConfigFile, + sizeof (pRmbStConfig->strConfigFile) - 1, "%s", configPath); + Rmb_TLib_Cfg_GetConfig (pRmbStConfig->strConfigFile, "consumerSysId", CFG_STRING, pRmbStConfig->cConsumerSysId, "", sizeof (pRmbStConfig->cConsumerSysId), "consumerSysVersion", CFG_STRING, pRmbStConfig->cConsumerSysVersion, "1.0.0", sizeof (pRmbStConfig->cConsumerSysVersion), "consumerDcn", CFG_STRING, pRmbStConfig->cConsumerDcn, "", sizeof (pRmbStConfig->cConsumerDcn), "logFile", CFG_STRING, pRmbStConfig->logFileName, "../log/rmb.log", sizeof (pRmbStConfig->logFileName), "logLevel", CFG_INT, &(pRmbStConfig->iLogLevel), 5, "logFileNums", CFG_INT, &(pRmbStConfig->iLogFileNums), 100, "logFileSize", CFG_INT, &(pRmbStConfig->iLogFileSize), 500000000, "logSwiftType", CFG_INT, &(pRmbStConfig->iLogShiftType), 1, "debugSwitch", CFG_INT, &(pRmbStConfig->iDebugSwitch), 0, "everyProcessNumFromMq", CFG_INT, &(pRmbStConfig->iEveryTimeProcessNum), 10, "notifyCheckSpan", CFG_INT, &(pRmbStConfig->iNotifyCheckSpan), 1, "notifyMergeSwitch", CFG_INT, &(pRmbStConfig->iFLagForMergeNotify), 1, "reqFifoPath", CFG_STRING, pRmbStConfig->strFifoPathForReq, "./tmp_req.fifo", sizeof (pRmbStConfig->strFifoPathForReq), "reqShmKey", CFG_INT, &(pRmbStConfig->uiShmKeyForReq), 0x20150203, "reqShmSize", CFG_INT, &(pRmbStConfig->uiShmSizeForReq), 200000000, "ayncRspFifoPath", CFG_STRING, pRmbStConfig->strFifoPathForRRrsp, "./tmp_aync_rsp.fifo", sizeof (pRmbStConfig->strFifoPathForReq), "ayncRspShmKey", CFG_INT, &(pRmbStConfig->uiShmKeyForRRrsp), 0x20150204, "ayncRspShmSize", CFG_INT, &(pRmbStConfig->uiShmSizeForRRrsp), 200000000, "broadcastFifoPath", CFG_STRING, pRmbStConfig->strFifoPathForBroadcast, "./tmp_broadcast.fifo", sizeof (pRmbStConfig->strFifoPathForReq), "broadcastShmKey", CFG_INT, &(pRmbStConfig->uiShmKeyForBroadcast), 0x20150205, "broadcastShmSize", CFG_INT, &(pRmbStConfig->uiShmSizeForBroadcast), 200000000, "orgId", CFG_STRING, pRmbStConfig->strOrgId, "99996", sizeof (pRmbStConfig->strOrgId), "cacheTimeout", CFG_INT, &(pRmbStConfig->iCacheTimeoutTime), 10, "cacheSuccTimeout", CFG_INT, &(pRmbStConfig->iCacheSuccTimeoutTime), 600, "cacheFailedTimeout", CFG_INT, &(pRmbStConfig->iCacheFailedTimeoutTime), 30, "createConnectionTimeOut", CFG_INT, &(pRmbStConfig->createConnectionTimeOut), 120, "switchForReloadSignal1", CFG_INT, &(pRmbStConfig->iSwitchForSignal1), 1, "switchForReloadSignal2", CFG_INT, &(pRmbStConfig->iSwitchForSignal2), 0, "ackTimer", CFG_INT, &(pRmbStConfig->ackTimers), 100, "ackThreshold", CFG_INT, &(pRmbStConfig->ackThresHold), 30, "queryTimeout", CFG_INT, &(pRmbStConfig->iQueryTimeout), 1000, "CommonTimeOut", CFG_INT, &(pRmbStConfig->iCommonTimeOut), 500, "StatPeriod", CFG_INT, &(pRmbStConfig->iStatPeriod), 300, "GetGroupTopicTime", CFG_INT, &(pRmbStConfig->iGetGroupTopicTime), 5, "logserverSwitch", CFG_INT, &(pRmbStConfig->iLogserverSwitch), 1, "logserverForApiSwitch", CFG_INT, &(pRmbStConfig->iApiLogserverSwitch), 1, "ReqGslSwitch", CFG_INT, &(pRmbStConfig->iReqGsl), 1, "wemqUseHttpCfg", CFG_INT, &(pRmbStConfig->iWemqUseHttpCfg), 1, "configCenterIp", CFG_STRING, pRmbStConfig->cConfigIp, "", sizeof (pRmbStConfig->cConfigIp), "configCenterPort", CFG_INT, &(pRmbStConfig->iConfigPort), 8091, "configCenterAddrMulti", CFG_STRING, pRmbStConfig->ConfigAddr, "", sizeof (pRmbStConfig->ConfigAddr), "configCenterTimeout", CFG_INT, &(pRmbStConfig->iConfigTimeout), 10000, "mergeQueueSwitch", CFG_INT, &(pRmbStConfig->iMergeQueue), 0, "tlsOnoff", CFG_INT, &(pRmbStConfig->tlsOnoff), 0, "wemq_user", CFG_STRING, pRmbStConfig->cWemqUser, "", sizeof (pRmbStConfig->cWemqUser), "wemq_passwd", CFG_STRING, pRmbStConfig->cWemqPasswd, "", sizeof (pRmbStConfig->cWemqPasswd), "localIdc", CFG_STRING, pRmbStConfig->cRegion, "", sizeof (pRmbStConfig->cRegion), "heartBeatPeriod", CFG_INT, &(pRmbStConfig->heartBeatPeriod), 30, "heartBeatTimeout", CFG_INT, &(pRmbStConfig->heartBeatTimeout), 45, "getAccessIpPeriod", CFG_INT, &(pRmbStConfig->getAccessIpPeriod), 30, "wemqTcpConnectRetryNum", CFG_INT, &(pRmbStConfig->iWemqTcpConnectRetryNum), 1, "wemqTcpConnectDelayTime", CFG_INT, &(pRmbStConfig->iWemqTcpConnectDelayTime), 5, "wemqTcpConnectTimeout", CFG_INT, &(pRmbStConfig->iWemqTcpConnectTimeout), 3000, "wemqTcpSocketTimeout", CFG_INT, &(pRmbStConfig->iWemqTcpSocketTimeout), 5000, "wemqProxyIp", CFG_STRING, pRmbStConfig->cWemqProxyIp, "", sizeof (pRmbStConfig->cWemqProxyIp), "wemqProxyPort", CFG_INT, &(pRmbStConfig->cWemqProxyPort), 50001, "normalTimeout", CFG_INT, &(pRmbStConfig->iNormalTimeout), 120000, "exitTimeOut", CFG_INT, &(pRmbStConfig->ulExitTimeOut), 30000, "getSendWhiteListTime", CFG_INT, &(pRmbStConfig->iGetSendWhiteListTime), 300, "accessAckTimeOut", CFG_INT, &(pRmbStConfig->accessAckTimeOut), 2000, "rrAsyncTimeOut", CFG_INT, &(pRmbStConfig->rrAsyncTimeOut), 3, //默认rr异步3秒超时 + "goodByeTimeOut", CFG_INT, &(pRmbStConfig->goodByeTimeOut), 2000, //goodbye time 2s + //"rrAsyncListNum", CFG_INT, &(pRmbStConfig->accessAckTimeOut),10240, + "mqIsEmpty", CFG_INT, &(pRmbStConfig->mqIsEmpty), + MQ_INIT, "departMent", CFG_STRING, + pRmbStConfig->strDepartMent, "wemqAccessServer", + sizeof (pRmbStConfig->strDepartMent), NULL); + + pRmbStConfig->uiPid = getpid (); + snprintf (pRmbStConfig->cRmbMode, sizeof (pRmbStConfig->cRmbMode), "wemq"); + //initialize for log + InitRmbLogFile (pRmbStConfig->iLogLevel, pRmbStConfig->iLogShiftType, + pRmbStConfig->logFileName, pRmbStConfig->iLogFileSize, + pRmbStConfig->iLogFileNums); + //API CONNECT MODE + //connect to wemq + pRmbStConfig->iConnWemq = 1; + + //solace api 初始化,用于生成uuid + pRmbStConfig->uiIsInitSolaceApi = 0; + + int iRet = 0; + //从配置中心拉取access的ip list,如果配置为指定access的ip,则无须从配置中心拉取 + if ((pRmbStConfig->iWemqUseHttpCfg == 1) + && (pRmbStConfig->iConnWemq == 1 + || pRmbStConfig->iApiLogserverSwitch == 1)) + { + char url[512]; + char addrArr[15][50] = { 0 }; + int lenAddrs = 0; + pRmbStConfig->configIpPosInArr = 0; + char tmpIps[512] = { 0 }; + strcpy (tmpIps, pRmbStConfig->ConfigAddr); + LOGRMB (RMB_LOG_DEBUG, "config center addr str is:%s", tmpIps); + split_str (tmpIps, addrArr, &lenAddrs); + LOGRMB (RMB_LOG_DEBUG, "config center addr list len is %d,lists:", + lenAddrs); + int j = 0; + for (j = 0; j < lenAddrs; ++j) + { + LOGRMB (RMB_LOG_DEBUG, "%s", addrArr[j]); + } + + if (lenAddrs == 0) + { + LOGRMB (RMB_LOG_ERROR, + "config center addr list len is 0,please check if configCenterAddrMulti is empty in conf file"); + return -1; + } + int i = 0; + for (i = 0; i < lenAddrs; ++i) + { + memset (&url, 0x00, sizeof (url)); + snprintf (url, sizeof (url), "%s/%s", + addrArr[(i + pRmbStConfig->configIpPosInArr) % lenAddrs], + WEMQ_ACCESS_SERVER); + LOGRMB (RMB_LOG_DEBUG, "try to get access addr from %s", url); + iRet = wemq_proxy_load_servers (url, pRmbStConfig->iConfigTimeout); + if (iRet != 0) + { + LOGRMB (RMB_LOG_WARN, + "get access ip from %s failed,try next config center ip", + url); + continue; + } + else + { + LOGRMB (RMB_LOG_INFO, "get all access ip list result=%d from url:%s", + iRet, url); + pRmbStConfig->configIpPosInArr = pRmbStConfig->configIpPosInArr + i; + break; + } + } + if (i == lenAddrs) + { + LOGRMB (RMB_LOG_ERROR, " no available cc"); + return -1; + } + } + pRmbStConfig->iFlagForLoop = 0; + + //ackTimer的范围为20到1500 + if (pRmbStConfig->ackTimers > 1500) + pRmbStConfig->ackTimers = 1500; + if (pRmbStConfig->ackTimers < 20) + pRmbStConfig->ackTimers = 20; + + //ackThreshold的范围为1 到75 + if (pRmbStConfig->ackThresHold > 75) + pRmbStConfig->ackThresHold = 75; + if (pRmbStConfig->ackThresHold < 1) + pRmbStConfig->ackThresHold = 1; + + if (pRmbStConfig->iQueryTimeout > 5000) + pRmbStConfig->iQueryTimeout = 5000; + if (pRmbStConfig->iQueryTimeout < 500) + pRmbStConfig->iQueryTimeout = 500; + + pRmbStConfig->pLogBuf = NULL; + pRmbStConfig->pLogBuf = (char *) malloc ((size_t) MAX_LOG_BUF_SIZE); + if (pRmbStConfig->pLogBuf == NULL) + { + printf ("malloc for pRmbStConfig->pLogBuf error!"); + return -1; + } + + iRet = + get_host_name (pRmbStConfig->cHostName, sizeof (pRmbStConfig->cHostName)); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, " get_host_name failed!"); + //exit(1); + } + +// iRet = get_local_ip(pRmbStConfig->cHostIp, sizeof(pRmbStConfig->cHostIp)); + iRet = + get_local_ip_v2 (pRmbStConfig->cHostIp, sizeof (pRmbStConfig->cHostIp)); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "get_local_ip failed!"); + //exit(1); + } + + LOGRMB (RMB_LOG_INFO, "get_host_name hostname=%s,ip=%s", + pRmbStConfig->cHostName, pRmbStConfig->cHostIp); + + //init queue config + pthread_mutex_init (&pRmbStConfig->configMutex, NULL); + pthread_cond_init (&pRmbStConfig->configCond, NULL); + pRmbStConfig->iFlag = 0; + GetRmbNowLongTime (); + pRmbStConfig->ulStartTime = pRmbStConfig->ulNowTtime; + pRmbStConfig->iCacheServiceNums = 0; + + //init mergeq for gsl + pthread_mutex_init (&pRmbStConfig->mergeqForGslMutex, NULL); + pthread_cond_init (&pRmbStConfig->mergeqForGslCond, NULL); + pRmbStConfig->iFlagForMerge = 0; + + //init merge queue mutex + pthread_mutex_init (&pRmbStConfig->mergeQueueMutex, NULL); + + //init for log + pthread_mutex_init (&pRmbStConfig->configLog, NULL); + + //pthread_mutex_init(&pRmbStConfig->sendWhiteListMutex, NULL); + + if (pRmbStConfig->iSwitchForSignal1) + { + signal (SIGUSR1, rmb_cfg_process_signal); + } + + if (pRmbStConfig->iSwitchForSignal2) + { + signal (SIGUSR2, rmb_cfg_process_signal); + } + + pRmbStConfig->flag_merge = 0; + pRmbStConfig->pid_merge = 0; + + return 0; +} + +void rmb_get_config_python (RmbPythonConfig * config) +{ + //pythonConfig init + snprintf (config->strFifoPathForReq, sizeof (config->strFifoPathForReq), + pRmbStConfig->strFifoPathForReq); + config->uiShmKeyForReq = pRmbStConfig->uiShmKeyForReq; + config->uiShmSizeForReq = pRmbStConfig->uiShmSizeForReq; + snprintf (config->strFifoPathForRRrsp, sizeof (config->strFifoPathForRRrsp), + pRmbStConfig->strFifoPathForRRrsp); + config->uiShmKeyForRRrsp = pRmbStConfig->uiShmKeyForRRrsp; + config->uiShmSizeForRRrsp = pRmbStConfig->uiShmSizeForRRrsp; + + snprintf (config->strFifoPathForBroadcast, + sizeof (config->strFifoPathForBroadcast), + pRmbStConfig->strFifoPathForBroadcast); + config->uiShmKeyForBroadcast = pRmbStConfig->uiShmKeyForBroadcast; + config->uiShmSizeForBroadcast = pRmbStConfig->uiShmSizeForBroadcast; + return; +} + +const char *rmb_get_host_ip () +{ + return pRmbStConfig->cHostIp; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_context.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_context.c new file mode 100644 index 0000000000..b8ad1c9e1f --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_context.c @@ -0,0 +1,907 @@ +// 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. + +#include "rmb_context.h" +#include "rmb_udp.h" +#include "rmb_log.h" +#include "rmb_common.h" +#include "rmb_msg.h" +#include "rmb_mq.h" +#include "rmb_errno.h" +#include +#include +#include "wemq_thread.h" + +//char cManageTopic[30] = "rmb_c/manage"; +char cManageTopic[30] = "rmb_c_api/manage"; +char cQueueFullTopic[30] = "VPN_AD_MSG_SPOOL_TOPIC"; +char cLogLevelTopic[30] = "OPEN_DEBUG_LOG_TOPIC"; +char cPublishCheck[30] = "ALLOW_PUBLISH_MESSAGE_TOPIC"; +#define TWO_STOP_TIME 300000 + +//add for period log thread +int g_iLogThreadInit = 0; +pthread_t g_stLogThreadId; + +//////////////for wemq +static void _wemq_worker_thread_func (void *arg) +{ + StThreadArgs *pArg = (StThreadArgs *) arg; + WemqThreadCtx stThreadCtx; + stThreadCtx.m_ptProxyContext = pArg->pStContextProxy; + stThreadCtx.m_contextType = pArg->contextType; + stThreadCtx.m_iState = THREAD_STATE_INIT; + + stThreadCtx.sslCtx = NULL; + stThreadCtx.m_iSockFd = -1; + stThreadCtx.ssl = NULL; + stThreadCtx.m_iSockFdNew = -1; + stThreadCtx.sslNew = NULL; + stThreadCtx.m_iSockFdOld = -1; + stThreadCtx.sslOld = NULL; + + if (pArg->contextType == RMB_CONTEXT_TYPE_PUB) + { + stThreadCtx.m_ptTopicList = NULL; + stThreadCtx.m_ptFifo = (void *) &(pArg->pStContextProxy->pubFifo); + } + else + { + stThreadCtx.m_ptTopicList = &(pArg->pStContextProxy->stTopicList); + stThreadCtx.m_ptFifo = (void *) &(pArg->pStContextProxy->subFifo); + } + + wemq_thread_run (&stThreadCtx); + free (pArg); +} + +static int _wemq_context_create_thread (int contextType, + stContextProxy * pContextProxy) +{ + int iRet = -1; + if (contextType == RMB_CONTEXT_TYPE_PUB) + { + //thread has been created + if (pContextProxy->mainThreadId != 0) + { + return 0; + } + + //create pub thread (main thread); + StThreadArgs *pMainArgs = (StThreadArgs *) malloc (sizeof (StThreadArgs)); + if (pMainArgs == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for pMainArgs failed!"); + return -1; + } + pMainArgs->pStContextProxy = pContextProxy; + pMainArgs->contextType = RMB_CONTEXT_TYPE_PUB; + + iRet = + pthread_create (&pContextProxy->mainThreadId, NULL, + (void *) &_wemq_worker_thread_func, pMainArgs); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "create main thread error!iRet=%d", iRet); + rmb_errno = RMB_ERROR_CREATE_THREAD_FAIL; + return rmb_errno; + } + + struct timeval nowTimeVal; + gettimeofday (&nowTimeVal, NULL); + struct timespec timeout; + timeout.tv_sec = + nowTimeVal.tv_sec + pRmbStConfig->createConnectionTimeOut; + timeout.tv_nsec = nowTimeVal.tv_usec * 1000; + + pContextProxy->iFlagForPub = 0; + pthread_mutex_lock (&pContextProxy->pubMutex); + if (pContextProxy->iFlagForPub == 0) + { + pthread_cond_timedwait (&pContextProxy->pubCond, + &pContextProxy->pubMutex, &timeout); + } + pthread_mutex_unlock (&pContextProxy->pubMutex); + if (pContextProxy->iFlagForPub != 1) + { + return -1; + } + } + else if (contextType == RMB_CONTEXT_TYPE_SUB) + { + //thread has been created + if (pContextProxy->coThreadId != 0) + { + return 0; + } + + //create sub thread (co thread) + StThreadArgs *pCoArgs = (StThreadArgs *) malloc (sizeof (StThreadArgs)); + if (pCoArgs == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for pCoArgs failed!"); + return -2; + } + pCoArgs->pStContextProxy = pContextProxy; + pCoArgs->contextType = RMB_CONTEXT_TYPE_SUB; + iRet = + pthread_create (&pContextProxy->coThreadId, NULL, + (void *) &_wemq_worker_thread_func, pCoArgs); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "create co thread error!iRet=%d", iRet); + rmb_errno = RMB_ERROR_CREATE_THREAD_FAIL; + return rmb_errno; + } + + struct timeval nowTimeVal; + gettimeofday (&nowTimeVal, NULL); + struct timespec timeout; + timeout.tv_sec = + nowTimeVal.tv_sec + pRmbStConfig->createConnectionTimeOut; + timeout.tv_nsec = nowTimeVal.tv_usec * 1000; + + pContextProxy->iFlagForSub = 0; + pthread_mutex_lock (&pContextProxy->subMutex); + if (pContextProxy->iFlagForSub == 0) + { + pthread_cond_timedwait (&pContextProxy->subCond, + &pContextProxy->subMutex, &timeout); + } + pthread_mutex_unlock (&pContextProxy->subMutex); + if (pContextProxy->iFlagForSub != 1) + { + return -1; + } + } + else + { + LOGRMB (RMB_LOG_ERROR, "contextType is illegal(%d)!", contextType); + rmb_errno = RMB_ERROR_CREATE_THREAD_FAIL; + return rmb_errno; + } +// sleep(1); //等待线程先执行 + return 0; +} + +static void wemq_context_init_thread_sync_obj (stContextProxy * pContextProxy) +{ + pthread_mutex_init (&pContextProxy->rrMutex, NULL); + pthread_cond_init (&pContextProxy->rrCond, NULL); + pContextProxy->iFlagForRR = 0; + + pthread_mutex_init (&pContextProxy->regMutex, NULL); + pthread_cond_init (&pContextProxy->regCond, NULL); + pContextProxy->iFlagForReg = 0; + + pthread_mutex_init (&pContextProxy->pubMutex, NULL); + pthread_cond_init (&pContextProxy->pubCond, NULL); + pContextProxy->iFlagForPub = 0; + + pthread_mutex_init (&pContextProxy->subMutex, NULL); + pthread_cond_init (&pContextProxy->subCond, NULL); + pContextProxy->iFlagForSub = 0; + + pthread_mutex_init (&pContextProxy->eventMutex, NULL); + pthread_cond_init (&pContextProxy->eventCond, NULL); + pContextProxy->iFlagForEvent = 0; //初始值设置为0,发送时设为-1,发送完ack再设为0。确保所有消息都回来的时候为0.相当于初始状态 + pContextProxy->iFlagForRRAsync = 0; + +} + +int wemq_context_init_add_manage_topic (stContextProxy * pContextProxy, + int type) +{ + int iRet = -1; + StWemqThreadMsg stThreadMsg; + stThreadMsg.m_iCmd = THREAD_MSG_CMD_ADD_MANAGE; + + if (type == 1) + { + iRet = wemq_kfifo_put (&pContextProxy->pubFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "send msg to worker thread by kfifo error\n"); + } + } + else + { + iRet = wemq_kfifo_put (&pContextProxy->subFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "send msg to worker thread by kfifo error\n"); + } + } + + struct timeval nowTimeVal; + struct timespec timeout; + gettimeofday (&nowTimeVal, NULL); + timeout.tv_sec = + nowTimeVal.tv_sec + (nowTimeVal.tv_usec / 1000 + + pRmbStConfig->iNormalTimeout) / 1000; + timeout.tv_nsec = + ((nowTimeVal.tv_usec / 1000 + + pRmbStConfig->iNormalTimeout) % 1000) * 1000 * 1000; + + pContextProxy->iFlagForReg = 0; + pthread_mutex_lock (&pContextProxy->regMutex); + if (pContextProxy->iFlagForReg == 0) + { + pthread_cond_timedwait (&pContextProxy->regCond, &pContextProxy->regMutex, + &timeout); + } + pthread_mutex_unlock (&pContextProxy->regMutex); + + if (pContextProxy->iFlagForReg != 1) + { + LOGRMB (RMB_LOG_ERROR, "add manage topic timeout!\n"); + rmb_errno = RMB_ERROR_WORKER_REGISTER_ERROR; + return rmb_errno; + } + + /* + if (pContextProxy->rspForAddManage.uiResult != 0) + { + LOGWEMQ(WEMQ_LOG_ERROR, "Failed to add magnage!manageTopic=%s\n", pContextProxy->rspForAddManage.strManageTopic); + return -1; + } + */ + return 0; +} + +static int wemq_context_init_proxy_model (StContext * pStContext) +{ + stContextProxy *pContextProxy = NULL; + + //context proxy has been init; + //get only one contextproxy; + if (pRmbStConfig->iProxyContextNums == 1) + { + pStContext->pContextProxy = pRmbStConfig->pProxyContext; + pContextProxy = pRmbStConfig->pProxyContext; + if (pStContext->contextType == RMB_CONTEXT_TYPE_PUB) + { + pContextProxy->pubContext = (void *) pStContext; + } + else + { + pContextProxy->subContext = (void *) pStContext; + } + + return _wemq_context_create_thread (pStContext->contextType, + pContextProxy); + } + + //create proxy context + pContextProxy = (stContextProxy *) malloc (sizeof (stContextProxy)); + if (pContextProxy == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStContext->pContextProxy malloc error!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return rmb_errno; + } + memset (pContextProxy, 0, sizeof (stContextProxy)); + pContextProxy->iFlagForRun = 1; + pContextProxy->ulGoodByeTime = 0; + pContextProxy->ulLastClearRRAysncMsgTime = 0; + + pStContext->pContextProxy = pContextProxy; + + if (pStContext->contextType == RMB_CONTEXT_TYPE_PUB) + { + pContextProxy->pubContext = (void *) pStContext; + } + else + { + pContextProxy->subContext = (void *) pStContext; + } + + INIT_WEMQ_KFIFO (pContextProxy->pubFifo); + INIT_WEMQ_KFIFO (pContextProxy->subFifo); + + wemq_topic_list_init (&pContextProxy->stTopicList); + + wemq_context_init_thread_sync_obj (pContextProxy); + +// pContextProxy->rrHashTable = (myhast_t *)malloc(sizeof(myhash_t)); +// if (pContextProxy->rrHashTable == NULL || +// myhash_init(pContextProxy->rrHashTable, 10000000)) +// { +// LOGRMB(RMB_LOG_ERROR, "pContextProxy->rrHashTable malloc or init error!\n"); +// rmb_errno = RMB_ERROR_MALLOC_FAIL; +// return rmb_errno; +// } + + pContextProxy->pReplyMsg = rmb_msg_malloc (); + + //all buffer initialize + pContextProxy->mPubRRBuf = (char *) malloc (TCP_BUF_SIZE * sizeof (char)); + if (pContextProxy->mPubRRBuf == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pContextProxy->mPubRRBuf malloc error!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return rmb_errno; + } + memset (pContextProxy->mPubRRBuf, 0x00, TCP_BUF_SIZE * sizeof (char)); + + Init (&pContextProxy->pUniqueListForRRAsyncNew); + Init (&pContextProxy->pUniqueListForRRAsyncOld); + + //pContextProxy->pUniqueListForRRAsyncNew = pContextProxy->stUniqueListForRRAsync; + //pContextProxy->pUniqueListForRRAsyncOld = pContextProxy->stUniqueListForRRAsyncOld; + //memset(pContextProxy->pUniqueListForRRAsyncNew,0x00,RMB_MAX_UNIQUE_NUMS * sizeof(StUniqueIdList)); + //memset(pContextProxy->pUniqueListForRRAsyncOld,0x00,RMB_MAX_UNIQUE_NUMS * sizeof(StUniqueIdList)); + + // context proxy init ok; + pRmbStConfig->pProxyContext = pContextProxy; + pRmbStConfig->iProxyContextNums = 1; + + return _wemq_context_create_thread (pStContext->contextType, pContextProxy); +} + +StContext *g_pStContextArry[MAX_RMB_CONTEXT] = { NULL }; + +int Log_Thread_Start (StContext * pStContext) +{ + LOGRMB (RMB_LOG_INFO, "call thread start StContext = 0x%p", pStContext); + + if (pStContext->contextType == RMB_CONTEXT_TYPE_PUB) + { + pRmbStConfig->iFlagForLoop = 1; + } + + pthread_mutex_lock (&pRmbStConfig->configLog); + if (g_iLogThreadInit == 1) + { + if (g_pStContextArry[1] == NULL) + g_pStContextArry[1] = pStContext; + pthread_mutex_unlock (&pRmbStConfig->configLog); + return 0; + } + + g_iLogThreadInit = 1; + pthread_mutex_unlock (&pRmbStConfig->configLog); + + g_pStContextArry[0] = pStContext; + g_pStContextArry[1] = NULL; + + int iRet = + pthread_create (&g_stLogThreadId, NULL, (void *) &_Log_Thread_func, NULL); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "create Log thread error!iRet=%d\n", iRet); + } + return iRet; +} + +int rmb_context_init (StContext * pStContext) +{ + if (pStContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStContext is null!"); + rmb_errno = RMB_ERROR_ARGV_NULL; + return -1; + } + if (pStContext->uiInitFlag == 1) + { + LOGRMB (RMB_LOG_ERROR, "pStContext has already init!"); + return 0; + } + + int iRet = 0; + + pStContext->pReceiveWemqMsg = NULL; + pStContext->pReceiveWemqMsg = rmb_msg_malloc (); + if (pStContext->pReceiveWemqMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for pStContext->pReceiveWemqMsg error!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return rmb_errno; + } + + pStContext->pReceiveWemqMsgForRR = NULL; + pStContext->pReceiveWemqMsgForRR = rmb_msg_malloc (); + if (pStContext->pReceiveWemqMsgForRR == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "malloc for pStContext->pReceiveWemqMsgForRR error!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return rmb_errno; + } + + pStContext->pReceiveWemqMsgForBroadCast = NULL; + pStContext->pReceiveWemqMsgForBroadCast = rmb_msg_malloc (); + if (pStContext->pReceiveWemqMsgForBroadCast == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "malloc for pStContext->pReceiveWemqMsgForBroadCast failed!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return rmb_errno; + } + + pStContext->pWemqPkg = NULL; + pStContext->pWemqPkg = (char *) malloc (MAX_LENTH_IN_A_MSG); + if (pStContext->pWemqPkg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for pStContext->pWemqPkg error!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return rmb_errno; + } + memset (pStContext->pWemqPkg, 0x00, MAX_LENTH_IN_A_MSG); + + pStContext->pWemqPkgForRRAsync = NULL; + pStContext->pWemqPkgForRRAsync = (char *) malloc (MAX_LENTH_IN_A_MSG); + if (pStContext->pWemqPkgForRRAsync == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "malloc for pStContext->pWemqPkgForRRAsync error!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return rmb_errno; + } + memset (pStContext->pWemqPkgForRRAsync, 0x00, MAX_LENTH_IN_A_MSG); + + pStContext->uiInitFlag = 1; +// int iRet = Log_Thread_Start(pStContext); + iRet = wemq_context_init_proxy_model (pStContext); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_context_init_proxy_model failed, iRet=%d", + iRet); + return iRet; + } + + iRet = Log_Thread_Start (pStContext); + + return 0; +} + +int rmb_context_add_rsp_socket (StContext * pStContext, const char *cLocalIp, + unsigned short usRspPort) +{ + if (usRspPort != 0) + { + //init udp + pStContext->iSocketForRsp = udp_get_socket ("0.0.0.0", "0", NULL); + if (pStContext->iSocketForRsp < 0) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of udp socket init failed!port=%u", + (unsigned int) usRspPort); + rmb_errno = RMB_ERROR_INIT_UDP_FAIL; + return -3; + } + tcp_nodelay (pStContext->iSocketForRsp); + bzero (&pStContext->tmpReplyAddr, sizeof (pStContext->tmpReplyAddr)); + pStContext->tmpReplyAddr.sin_addr.s_addr = inet_addr (cLocalIp); + pStContext->tmpReplyAddr.sin_port = htons (usRspPort); + pRmbStConfig->iFlagForRRrsp = (int) MSG_IPC_UDP; + } + else + { + pStContext->iSocketForRsp = 0; + } + return 0; +} + +int rmb_context_add_broadcast_socket (StContext * pStContext, + const char *cLocalIp, + unsigned short usBroadcastPort) +{ + if (usBroadcastPort != 0) + { + //init udp + pStContext->iSocketForBroadcast = udp_get_socket ("0.0.0.0", "0", NULL); + if (pStContext->iSocketForBroadcast < 0) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of udp socket init failed!port=%u", + (unsigned int) usBroadcastPort); + rmb_errno = RMB_ERROR_INIT_UDP_FAIL; + return -3; + } + tcp_nodelay (pStContext->iSocketForBroadcast); + bzero (&pStContext->tmpBroadcastAddr, + sizeof (pStContext->tmpBroadcastAddr)); + pStContext->tmpBroadcastAddr.sin_addr.s_addr = inet_addr (cLocalIp); + pStContext->tmpBroadcastAddr.sin_port = htons (usBroadcastPort); + pRmbStConfig->iFlagForBroadCast = (int) MSG_IPC_UDP; + } + else + { + pStContext->iSocketForBroadcast = 0; + } + return 0; +} + +int rmb_context_add_req_socket (StContext * pStContext, const char *cLocalIp, + unsigned short usReqPort) +{ + if (usReqPort != 0) + { + //init udp + pStContext->iSocketForReq = udp_get_socket ("0.0.0.0", "0", NULL); + if (pStContext->iSocketForReq < 0) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of udp socket init failed!port=%u", + (unsigned int) usReqPort); + rmb_errno = RMB_ERROR_INIT_UDP_FAIL; + return -3; + } + tcp_nodelay (pStContext->iSocketForReq); + bzero (&pStContext->tmpReqAddr, sizeof (pStContext->tmpReqAddr)); + //pStContext->tmpReqAddr.sin_family = AF_INET; + pStContext->tmpReqAddr.sin_addr.s_addr = inet_addr (cLocalIp); + pStContext->tmpReqAddr.sin_port = htons (usReqPort); + + if (pRmbStConfig->iDebugSwitch) + { + LOGRMB (RMB_LOG_DEBUG, "add_req,socket=%u,ip=%s,port=%u", + pStContext->iSocketForReq, cLocalIp, usReqPort); + } + pRmbStConfig->iFlagForReq = (int) MSG_IPC_UDP; + } + else + { + pStContext->iSocketForReq = 0; + } + return 0; +} + +int rmb_context_add_req_mq_fifo (StContext * pStContext, + const char *strFiFoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, void *func_argv) +{ + int iRet = 0; + if (strlen (strFiFoPath) == 0) + { + LOGRMB (RMB_LOG_ERROR, "context_add_req_mq error!strFiFoPath size=0!"); + rmb_errno = RMB_ERROR_FIFO_PARA_ERROR; + return -1; + } + if (uiShmKey == 0 || uiShmSize == 0) + { + LOGRMB (RMB_LOG_ERROR, + "context_add_req_mq error!shmKey=%u,shmSize=%u,fifoPath=%s", + uiShmKey, uiShmSize, strFiFoPath); + rmb_errno = RMB_ERROR_SHM_PARA_ERROR; + return -1; + } + //init mq + StRmbMq *pMq = (StRmbMq *) calloc (1, sizeof (StRmbMq)); + if (pMq == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of calloc mq failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + iRet = rmb_mq_init (pMq, uiShmKey, uiShmSize, true, false); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of rmb_mq_init failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + rmb_errno = RMB_ERROR_INIT_MQ_FAIL; + return -3; + } + + //init fifo + StRmbFifo *pFifo = (StRmbFifo *) calloc (1, sizeof (StRmbFifo)); + if (pFifo == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of calloc fifo failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -4; + } + iRet = rmb_fifo_init (pFifo, strFiFoPath); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of rmb_fifo_init failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pFifo); + free (pMq); + rmb_errno = RMB_ERROR_INIT_FIFO_FAIL; + return -5; + } + + iRet = + rmb_notify_add (&pStContext->fifoMq, pMq, pFifo, req_mq_index, func, + func_argv); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of rmb_notify_add failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + free (pFifo); + return -6; + } + LOGRMB (RMB_LOG_INFO, "context_add_req_mq succ!"); + pRmbStConfig->iFlagForReq = (int) MSG_IPC_MQ; + return 0; +} + +int rmb_context_add_rr_rsp_mq_fifo (StContext * pStContext, + const char *strFiFoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, void *func_argv) +{ + int iRet = 0; + if (strlen (strFiFoPath) == 0) + { + LOGRMB (RMB_LOG_ERROR, + "context_add_rr_rsp_mq_fifo error!strFiFoPath size=0!"); + rmb_errno = RMB_ERROR_FIFO_PARA_ERROR; + return -1; + } + if (uiShmKey == 0 || uiShmSize == 0) + { + LOGRMB (RMB_LOG_ERROR, + "context_add_rr_rsp_mq_fifo error!shmKey=%u,shmSize=%u,fifoPath=%s", + uiShmKey, uiShmSize, strFiFoPath); + rmb_errno = RMB_ERROR_SHM_PARA_ERROR; + return -1; + } + //init mq + StRmbMq *pMq = (StRmbMq *) calloc (1, sizeof (StRmbMq)); + if (pMq == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "context_add_rr_rsp_mq_fifo error!because of calloc mq failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + iRet = rmb_mq_init (pMq, uiShmKey, uiShmSize, true, false); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "context_add_rr_rsp_mq_fifo error!because of rmb_mq_init failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + rmb_errno = RMB_ERROR_INIT_MQ_FAIL; + return -3; + } + + //init fifo + StRmbFifo *pFifo = (StRmbFifo *) calloc (1, sizeof (StRmbFifo)); + if (pFifo == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "context_add_rr_rsp_mq_fifo error!because of calloc fifo failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -4; + } + iRet = rmb_fifo_init (pFifo, strFiFoPath); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "context_add_rr_rsp_mq_fifo error!because of rmb_fifo_init failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pFifo); + free (pMq); + rmb_errno = RMB_ERROR_INIT_FIFO_FAIL; + return -5; + } + + iRet = + rmb_notify_add (&pStContext->fifoMq, pMq, pFifo, rr_rsp_mq_index, func, + func_argv); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "context_add_rr_rsp_mq_fifo!because of rmb_notify_add failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + free (pFifo); + return -6; + } + pRmbStConfig->iFlagForRRrsp = (int) MSG_IPC_MQ; + return 0; +} + +int rmb_context_add_broadcast_mq_fifo (StContext * pStContext, + const char *strFiFoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv) +{ + int iRet = 0; + if (strlen (strFiFoPath) == 0) + { + LOGRMB (RMB_LOG_ERROR, "fifo error!strFiFoPath size=0!"); + rmb_errno = RMB_ERROR_FIFO_PARA_ERROR; + return -1; + } + if (uiShmKey == 0 || uiShmSize == 0) + { + LOGRMB (RMB_LOG_ERROR, "shm error!shmKey=%u,shmSize=%u,fifoPath=%s", + uiShmKey, uiShmSize, strFiFoPath); + rmb_errno = RMB_ERROR_SHM_PARA_ERROR; + return -1; + } + //init mq + StRmbMq *pMq = (StRmbMq *) calloc (1, sizeof (StRmbMq)); + if (pMq == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmbMq error!because of calloc mq failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + iRet = rmb_mq_init (pMq, uiShmKey, uiShmSize, true, false); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "mq_init error!because of rmb_mq_init failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + rmb_errno = RMB_ERROR_INIT_MQ_FAIL; + return -3; + } + + //init fifo + StRmbFifo *pFifo = (StRmbFifo *) calloc (1, sizeof (StRmbFifo)); + if (pFifo == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "fifo null error!because of calloc fifo failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -4; + } + iRet = rmb_fifo_init (pFifo, strFiFoPath); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "fifo init error!because of rmb_fifo_init failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pFifo); + free (pMq); + rmb_errno = RMB_ERROR_INIT_FIFO_FAIL; + return -5; + } + + iRet = + rmb_notify_add (&pStContext->fifoMq, pMq, pFifo, broadcast_mq_index, func, + func_argv); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "notify add error!because of rmb_notify_add failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + free (pFifo); + return -6; + } + LOGRMB (RMB_LOG_INFO, "context_add_broadcast_mq succ!"); + pRmbStConfig->iFlagForBroadCast = (int) MSG_IPC_MQ; + return 0; +} + +//////////////////////////////////////////////////////////////////////// +static int rmb_context_add_queue_pipe (StContext * pStContext, + const unsigned int uiSize, + const enum RmbMqIndex iMsgType, + rmb_callback_func func, + void *func_argv) +{ + RMB_CHECK_POINT_NULL (pStContext, "rmb_context_add_queue_pipe:pStContext"); + + int iRet = 0; + if (uiSize == 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_context_add_queue_pipe error!uiSize=%u", + uiSize); + rmb_errno = RMB_ERROR_SHM_PARA_ERROR; + return -1; + } + //init queue + StRmbQueue *pQue = (StRmbQueue *) calloc (1, sizeof (StRmbQueue)); + if (pQue == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_context_add_queue_pipe error!because calloc for queue failed!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + + iRet = rmb_queue_init (pQue, uiSize); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_context_add_queue_pipe error!because rmb_queue_init failed!"); + free (pQue); + rmb_errno = RMB_ERROR_INIT_MQ_FAIL; + return -3; + } + + StRmbPipe *pPipe = (StRmbPipe *) calloc (1, sizeof (StRmbPipe)); + if (pPipe == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_context_add_queue_pipe error!because calloc for pipe failed!"); + free (pQue); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -4; + } + + iRet = rmb_pipe_init (pPipe); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_context_add_queue_pipe error!becaulse rmb_pipe_init failed!"); + free (pPipe); + free (pQue); + rmb_errno = RMB_ERROR_INIT_FIFO_FAIL; + return -5; + } + + iRet = + rmb_wemq_notify_add (&pStContext->fifoMq, pQue, pPipe, iMsgType, func, + func_argv); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of rmb_notify_add failed!"); + free (pPipe); + free (pQue); + return -6; + } + + LOGRMB (RMB_LOG_INFO, "rmb_context_add_queue_pipe succ!"); + pRmbStConfig->iFlagForReq = (int) MSG_IPC_MQ; + return 0; +} + +//static int rmb_context_add_req_queue_pipe(StContext *pStContext, const unsigned int uiSize, rmb_callback_func func, void *func_msg, void* func_argv) +//{ +// return rmb_context_add_queue_pipe(pStContext, uiSize, wemq_req_mq_index, func, func_msg, func_argv); +//} +// +//static int rmb_context_add_rr_rsp_queue_pipe(StContext *pStContext, const unsigned int uiSize, rmb_callback_func func, void *func_msg, void* func_argv) +//{ +// return rmb_context_add_queue_pipe(pStContext, uiSize, wemq_rr_rsp_mq_index, func, func_msg, func_argv); +//} +// +//static int rmb_context_add_broadcast_queue_pipe(StContext *pStContext, const unsigned int uiSize, rmb_callback_func func, void *func_msg, void* func_argv) +//{ +// return rmb_context_add_queue_pipe(pStContext, uiSize, wemq_broadcast_mq_index, func, func_msg, func_argv); +//} +//////////////////////////////////////////////////////////////////////// + +int rmb_context_enqueue (StContext * pStContext, + const enum RmbMqIndex uiMsgType, const char *data, + unsigned int uiDataLen) +{ + pStContext->uiNowTime = time (NULL); + return rmb_notify_enqueue_by_type (&(pStContext->fifoMq), uiMsgType, + pStContext->uiNowTime, data, uiDataLen); +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_errno.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_errno.c new file mode 100644 index 0000000000..ffab955166 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_errno.c @@ -0,0 +1,155 @@ +// 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. + +#include +#include +#include +#include +#include "rmb_errno.h" + +char *p_err_msg[RMB_MAX_ERR_NUMS] = { 0 }; + +struct rmb_err_msg rmb_err_msg_array[] = { + {RMB_ERROR_ARGV_NULL, "argv is null"}, + {RMB_ERROR_ARGV_LEN_ERROR, "argv len error"}, + {RMB_ERROR_MALLOC_FAIL, "malloc fail"}, + {RMB_ERROR_INIT_CONTEXT_FAIL, "init context fail"}, + {RMB_ERROR_MSG_MISSING_PART, "msg missing necessary part"}, + {RMB_ERROR_RR_INTERFACE_CAN_NOT_SEND_EVENT_MSG, + "rr interface can't send event msg"}, + {RMB_ERROR_EVENT_INTERFACE_CAN_NOT_SEND_RR_MSG, + "event msg can't send rr msg"}, + {RMB_ERROR_NOW_CAN_NOT_SEND_MSG, "now can't send msg"}, + {RMB_ERROR_QUEUE_FULL, "queue is full"}, + {RMB_ERROR_GSL_SERVICE_ID_NULL, "gsl service id null"}, + {RMB_ERROR_GSL_SERVICE_ID_ERROR, "gsl service id error"}, + {RMB_ERROR_GSL_SVR_ERROR, "gsl svr return error"}, + {RMB_ERROR_REQ_GSL_ERROR, "req gsl error"}, + {RMB_ERROR_MSG_UUID_FAIL, "msg generate uuid fail"}, + {RMB_ERROR_MSG_SET_SYSTEMHEADER_FAIL, "msg set systemheadfer fail"}, + {RMB_ERROR_SEND_GET_SESSION_FAIL, "send get session fail"}, + {RMB_ERROR_SEND_EVENT_MSG_FAIL, "send event msg fail"}, + {RMB_ERROR_SEND_RR_MSG_FAIL, "send rr msg fail"}, + {RMB_ERROR_SEND_RR_MSG_TIMEOUT, "send rr msg timeout"}, + {RMB_ERROR_REPLY_TO_NULL, "reply to is null"}, + {RMB_ERROR_REPLY_FAIL, "reply msg fail"}, + {RMB_ERROR_SESSION_CONNECT_FAIL, "session connect fail"}, + {RMB_ERROR_SESSION_RECONNECT_FAIL, "session reconnect fail"}, + {RMB_ERROR_SESSION_DESTORY_FAIL, "session destory fail"}, + {RMB_ERROR_SESSION_NUMS_LIMIT, "session nums limit"}, + {RMB_ERROR_LISTEN_QUEUE_NOT_EXIST, "listen queue not exist"}, + {RMB_ERROR_LISTEN_QUEUE_FAIL, "listen queue fail"}, + {RMB_ERROR_FLOW_DESTORY_FAIL, "flow destory fail"}, + {RMB_ERROR_LISTEN_TOPIC_FAIL, "listen topic fail"}, + {RMB_ERROR_INIT_MQ_FAIL, "init mq fail"}, + {RMB_ERROR_INIT_FIFO_FAIL, "init fifo fail"}, + {RMB_ERROR_INIT_UDP_FAIL, "init udp fail"}, + {RMB_ERROR_INIT_EPOLL_FAIL, "init epoll fail"}, + {RMB_ERROR_MQ_NUMS_LIMIT, "mq nums limit"}, + {RMB_ERROR_ENQUEUE_MQ_FAIL, "enqueue mq fail"}, + {RMB_ERROR_DEQUEUE_MQ_FAIL, "dequeue mq fail"}, + {RMB_ERROR_MSG_2_BUF_FAIL, "shift msg to buf fail"}, + {RMB_ERROR_BUF_2_MSG_FAIL, "shift buf to msg fail"}, + {RMB_ERROR_MSG_SET_CONTENT_TOO_LARGE, "msg set content too large"}, + {RMB_ERROR_MSG_SET_APPHEADER_TOO_LARGE, "msg set appheader too large"}, + {RMB_ERROR_MSG_TTL_0, "message ttl can't be 0"}, + {RMB_ERROR_RCV_MSG_GET_CONTENT_FAIL, "receive msg has no content"}, + {RMB_ERROR_RCV_MSG_GET_BINARY_FAIL, "receive msg has no binary"}, + {RMB_ERROR_RCV_MSG_CONTENT_TOO_LARGE, "receive msg content too large"}, + {RMB_ERROR_RCV_MSG_APPHEADER_TOO_LARGE, + "receive message appheader too large"}, + {RMB_ERROR_MANAGE_MSG_PKG_ERROR, "manage msg format error"}, + {RMB_ERROR_MANAGE_MSG_PKG_CHECK_FAIL, "manage msg check fail"}, + {RMB_ERROR_CONTEXT_CREATE_FAIL, "context create fail"}, + {RMB_ERROR_FIFO_PARA_ERROR, "fifo para error"}, + {RMB_ERROR_SHM_PARA_ERROR, "shm para error"}, + {RMB_ERROR_SEND_FIFO_NOTIFY_ERROR, "send notify fail"}, + {RMB_ERROR_FLOW_NUMS_LIMIT, "flow nums limit"}, + {RMB_ERROR_MSG_GET_SYSTEMHEADER_ERROR, "get system header error"}, + {RMB_ERROR_RMB_MSG_2_SOLACE_MSG_ERROR, "copy rmb msg 2 solace msg error"}, + {RMB_ERROR_SOLACE_MSG_2_RMB_MSG_ERROR, "copy solace msg 2 rmb msg error"}, + {RMB_ERROR_NO_AVAILABLE_SESSION, "no available session"}, + {RMB_ERROR_NO_BROADCAST_SESSION, "no broadcast session"}, + {RMB_ERROR_NO_AVAILABLE_CONTEXT, "no available context"}, + {RMB_ERROR_SET_FLOW_PROPETY, "set flow property fail"}, + {RMB_ERROR_ACK_MSG_FAIL, "ack msg fail"}, + {RMB_ERROR_LOGIC_NOTIFY_INIT, "notify for logic init error"}, + {RMB_ERROR_SESSION_ADD_FAIL, "session add fail"}, + {RMB_ERROR_WORKER_NUMS_LIMIT, "worker nums limit"}, + {RMB_ERROR_BUF_NOT_ENOUGH, "buf not enough"}, + {RMB_ERROR_STOP_FLOW_ERROR, "stop flow receive error"}, + {RMB_ERROR_DEQUEUE_MQ_EMPTY, "dequeue empty"}, + {RMB_ERROR_WORKER_WINDOW_FULL, "worker send window full"}, + {RMB_ERROR_WORKER_PUT_FIFO_ERROR, "worker put msg into fifo error"}, + {RMB_ERROR_START_CALL_FAIL, "send log for start call error"}, + {RMB_ERROR_END_CALL_FAIL, "send log for end call error"}, + {RMB_ERROR_ENTRY_FAIL, "send log for entry error"}, + {RMB_ERROR_EXIT_FAIL, "send log for exit error"}, + {RMB_ERROR_BASE_BEGIN, NULL} +}; + +static pthread_key_t rmb_user_key; +static pthread_once_t rmb_user_key_once = PTHREAD_ONCE_INIT; + +static void rmb_make_key () +{ + (void) pthread_key_create (&rmb_user_key, NULL); +} + +int *rmb_error () +{ + int *ptr; + + (void) pthread_once (&rmb_user_key_once, rmb_make_key); + if ((ptr = pthread_getspecific (rmb_user_key)) == NULL) + { + ptr = malloc (sizeof (int)); + memset (ptr, 0, sizeof (int)); + (void) pthread_setspecific (rmb_user_key, ptr); + } + return ptr; +} + +void init_error () +{ + int i = 0; + for (; rmb_err_msg_array[i].err_msg != NULL && i < RMB_MAX_ERR_NUMS; i++) + { + p_err_msg[rmb_err_msg_array[i].err_no - RMB_ERROR_BASE_BEGIN] = + rmb_err_msg_array[i].err_msg; + } + rmb_errno = 0; +} + +const char *get_rmb_last_error () +{ + if (rmb_errno == 0) + { + return "ok"; + } + if (rmb_errno <= RMB_ERROR_BASE_BEGIN + && rmb_errno >= RMB_ERROR_BASE_BEGIN + RMB_MAX_ERR_NUMS) + { + return "unknown errorno"; + } + return ((p_err_msg[rmb_errno - RMB_ERROR_BASE_BEGIN] == + NULL) ? "unknown errorno" : p_err_msg[rmb_errno - + RMB_ERROR_BASE_BEGIN]); +} + +void rmb_reset_error () +{ + rmb_errno = 0; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_http_client.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_http_client.c new file mode 100644 index 0000000000..acab4b0b4d --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_http_client.c @@ -0,0 +1,211 @@ +// 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. + +#include +#include +#include +#include +#include "curl/curl.h" +#include "rmb_http_client.h" +#include "rmb_define.h" + +static pthread_mutex_t LIBCURL_LOCK = PTHREAD_MUTEX_INITIALIZER; +static int LIBCURL_INIT_FLAG = 0; + +static void atexit_callback (void) +{ + if (0 != LIBCURL_INIT_FLAG) + { +#ifdef RMB_HTTP_DEBUG + printf ("[Exit]curl_global_cleanup\n"); +#endif + curl_global_cleanup (); + LIBCURL_INIT_FLAG = 0; + } +} + +static void libcurl_init (void) +{ + pthread_mutex_lock (&LIBCURL_LOCK); + if (0 == LIBCURL_INIT_FLAG) + { +#ifdef RMB_HTTP_DEBUG + printf ("[INIT]curl_global_init\n"); +#endif + curl_global_init (CURL_GLOBAL_ALL); + atexit (atexit_callback); + LIBCURL_INIT_FLAG = 1; + } + pthread_mutex_unlock (&LIBCURL_LOCK); +} + +static int on_http_debug (CURL * handle, curl_infotype type, char *data, + size_t size, void *userptr) +{ + if (type == CURLINFO_TEXT) + { + //printf("[TEXT]%s\n", data); + } + else if (type == CURLINFO_HEADER_IN) + { + printf ("[HEADER_IN]%s\n", data); + } + else if (type == CURLINFO_HEADER_OUT) + { + printf ("[HEADER_OUT]%s\n", data); + } + else if (type == CURLINFO_DATA_IN) + { + printf ("[DATA_IN]%s\n", data); + } + else if (type == CURLINFO_DATA_OUT) + { + printf ("[DATA_OUT]%s\n", data); + } + return 0; +} + +static size_t on_http_body (char *ptr, size_t size, size_t nmemb, + void *userdata) +{ + size_t len = size * nmemb; + + if (ptr == NULL || userdata == NULL) + { + printf ("%s ptr is null\n", __func__); + return -1; + } + + struct rmb_http_buffer *buf = (struct rmb_http_buffer *) userdata; + + buf->data = + (char *) realloc (buf->data, sizeof (char) * (buf->len + len + 1)); + if (buf->data == NULL) + { + /* out of memory */ + printf ("not enough memory for realloc(buf->data)"); + return 0; + } + + memcpy (&(buf->data[buf->len]), ptr, len); + buf->len += len; + buf->data[buf->len] = '\0'; + + return len; +} + +int rmb_http_easy_get (const char *url, void *buffer, long timeout) +{ + CURLcode res; + CURL *curl = NULL; + struct curl_slist *headers = NULL; + + libcurl_init (); + curl = curl_easy_init (); + if (NULL == curl) + { + LOGRMB (RMB_LOG_ERROR, "curl_easy_init failed"); + return -1; + } + + struct rmb_http_buffer *response = (struct rmb_http_buffer *) buffer; + + headers = curl_slist_append (headers, "Connection: Keep-Alive"); + +#ifdef RMB_HTTP_DEBUG + curl_easy_setopt (curl, CURLOPT_VERBOSE, 1); + curl_easy_setopt (curl, CURLOPT_DEBUGFUNCTION, on_http_debug); +#endif + curl_easy_setopt (curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt (curl, CURLOPT_URL, url); + curl_easy_setopt (curl, CURLOPT_READFUNCTION, NULL); + curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, on_http_body); + curl_easy_setopt (curl, CURLOPT_WRITEDATA, (void *) response); + curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT_MS, timeout); + curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, timeout); + res = curl_easy_perform (curl); + curl_easy_cleanup (curl); + curl_slist_free_all (headers); + + if (res == CURLE_COULDNT_CONNECT) + { + return 1; + } + + if (res != CURLE_OK) + { + LOGRMB (RMB_LOG_ERROR, "curl_easy_perform failed: %s\n", + curl_easy_strerror (res)); + return -2; + } + + return 0; +} + +/* +int rmb_http_easy_post(char* url, char* post_data, size_t len, void* buffer, size_t size, size_t* used, long timeout) +{ + CURLcode res; + CURL* curl = NULL; + struct curl_slist *headers = NULL; + struct http_buffer response; + + libcurl_init(); + curl = curl_easy_init(); + if (NULL == curl) + { + return -1; + } + + response.buf = (char*)buffer; + response.size = size; + response.len = 0; + headers = curl_slist_append(headers, "Connection: Keep-Alive"); + +#ifdef HTTP_DEBUG + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); + curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, on_http_debug); +#endif + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl, CURLOPT_URL, url); + + curl_easy_setopt(curl, CURLOPT_POST, 1); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)len); + + curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, on_http_body); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, timeout); + curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, timeout); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + + if (res == CURLE_COULDNT_CONNECT) { + return 1; + } + if (0 != res) { + return -1; + } + *used = response.len; + if (response.len >= response.size) { + return 2; + } + *(response.buf + response.len) = '\0'; + return 0; +} +*/ diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_log.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_log.c new file mode 100644 index 0000000000..2b04f39a32 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_log.c @@ -0,0 +1,1273 @@ +// 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. + +#include "rmb_log.h" +#include +#include "string.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "rmb_define.h" +#include "string.h" +#include "rmb_access_config.h" +#include + +StRmbLog *pStRmbLog = NULL; + +struct tm currRmb; +struct tm lastRmb; +static char StatLogLevel[6][10] = + { "FATAL", "ERROR", "WARN ", "INFO", "DEBUG", "ALL" }; + +int GetRmbNowLongTime () +{ + struct timeval nowRmbTimeVal; + gettimeofday (&nowRmbTimeVal, NULL); + pRmbStConfig->ulNowTtime = + (unsigned long) nowRmbTimeVal.tv_sec * (unsigned long) 1000UL + + (unsigned long) nowRmbTimeVal.tv_usec / 1000UL; + return 0; +} + +char *RmbGetDateTimeStr (const time_t * mytime) +{ + static char s[50]; + currRmb = *localtime (mytime); + if (currRmb.tm_year > 50) + snprintf (s, sizeof (s), "%04d-%02d-%02d %02d:%02d:%02d", + currRmb.tm_year + 1900, currRmb.tm_mon + 1, currRmb.tm_mday, + currRmb.tm_hour, currRmb.tm_min, currRmb.tm_sec); + else + snprintf (s, sizeof (s), "%04d-%02d-%02d %02d:%02d:%02d", + currRmb.tm_year + 2000, currRmb.tm_mon + 1, currRmb.tm_mday, + currRmb.tm_hour, currRmb.tm_min, currRmb.tm_sec); + return s; +} + +char *RmbGetCurDateTimeStr () +{ + time_t mytime = time (NULL); + return RmbGetDateTimeStr (&mytime); +} + +char *RmbGetShortDateStr (const time_t * mytime) +{ + static char s[50]; + currRmb = *localtime (mytime); + if (currRmb.tm_year > 50) + snprintf (s, sizeof (s), "%04d%02d%02d", currRmb.tm_year + 1900, + currRmb.tm_mon + 1, currRmb.tm_mday); + else + snprintf (s, sizeof (s), "%04d%02d%02d", currRmb.tm_year + 2000, + currRmb.tm_mon + 1, currRmb.tm_mday); + + return s; +} + +char *RmbGetCurShortDateStr () +{ + time_t mytime = time (NULL); + return RmbGetShortDateStr (&mytime); +} + +int RmbIsOtherDay (time_t * newTime, time_t * oldTime) +{ + lastRmb = *localtime (oldTime); + currRmb = *localtime (newTime); + if (currRmb.tm_mday != lastRmb.tm_mday) + { + return 1; + } + return 0; +} + +int GetCurFileNum (FILE * fl) +{ + if (fl != NULL) + { + fscanf (fl, "%d %d %lu", &pStRmbLog->_curFileNo, &pStRmbLog->_curFileNums, + &pStRmbLog->_lastShiftTime); + } + return 0; +} + +int SetCurFileNum (FILE * fl) +{ + if (fl != NULL) + { + ftruncate (fileno (fl), 0); + rewind (fl); + fprintf (fl, "%d %d %lu", pStRmbLog->_curFileNo, pStRmbLog->_curFileNums, + pStRmbLog->_lastShiftTime); + } + return 0; +} + +int GetCurFileNumFromStatFile () +{ + FILE *fp = fopen (pStRmbLog->_logStatFileName, "r"); + if (fp == NULL) + { + return 0; + } + fscanf (fp, "%d %d %lu", &pStRmbLog->_curFileNo, &pStRmbLog->_curFileNums, + &pStRmbLog->_lastShiftTime); + fclose (fp); + return 0; +} + +int SetCurFileNumToStatFile () +{ + struct flock lock; + FILE *fp = fopen (pStRmbLog->_logStatFileName, "w"); + if (fp == NULL) + { + return 0; + } + int fd = fileno (fp); + lock.l_type = F_WRLCK; + lock.l_start = 0; + lock.l_whence = SEEK_SET; + lock.l_len = 0; + lock.l_pid = getpid (); + if (-1 != fcntl (fd, F_SETLKW, &lock)) + { +// printf("pid=%d set FileNo=%d.Num=%d", getpid(), pStRmbLog->_curFileNo, pStRmbLog->_curFileNums); + fprintf (fp, "%d %d", pStRmbLog->_curFileNo, pStRmbLog->_curFileNums); + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + fcntl (fd, F_SETLKW, &lock); + } + fclose (fp); + return 0; +} + +int ReloadCfg (int logLevel, int shiftType, const char *path, int maxFileSize, + int maxFileNum) +{ + int iRet = 0; + pStRmbLog->_para._logLevel = logLevel; + pStRmbLog->_para._shiftType = shiftType; + if (shiftType == 6) + { + pStRmbLog->_para._shiftType = (int) RMB_LOG_TYPE_CYCLE; + } + strncpy (pStRmbLog->_para._path, path, sizeof (pStRmbLog->_para._path) - 1); + snprintf (pStRmbLog->_logStatFileName, + sizeof (pStRmbLog->_logStatFileName) - 1, "%s.stat", path); + pStRmbLog->_para._maxFileSize = maxFileSize; + pStRmbLog->_para._maxFileNum = maxFileNum; + pStRmbLog->_lastShiftTime = time (NULL); + if (strlen (pStRmbLog->_para._path) == 0 + || pStRmbLog->_para._shiftType == RMB_LOG_TYPE_NORMAL) + { + pStRmbLog->_pLogFile = stdout; + pStRmbLog->_curFileNums = 1; + pStRmbLog->_para._shiftType = 0; + pStRmbLog->_lastShiftTime = 0; + return 0; + } + + if (pStRmbLog->_para._shiftType == RMB_LOG_TYPE_CYCLE) + { + iRet = GetCurStateFromRmbLogByCirCle (); + if (iRet != 0) + { + return -1; + } + } + else if (pStRmbLog->_para._shiftType == RMB_LOG_TYPE_DAILY + || pStRmbLog->_para._shiftType == RMB_LOG_TYPE_DAILY_AND_CYCLE) + { + pStRmbLog->_para._shiftType = RMB_LOG_TYPE_DAILY; + iRet = GetCurStateFromRmbLogByDaily_V4 (); + if (iRet != 0) + { + return -1; + } + } + else + { + pStRmbLog->_para._shiftType = RMB_LOG_TYPE_CYCLE; + iRet = GetCurStateFromRmbLogByCirCle (); + if (iRet != 0) + { + return -1; + } + } + return 0; +} + +int InitRmbLogFile (int logLevel, int shiftType, const char *path, + int maxFileSize, int maxFileNum) +{ + int iRet = 0; + memset (&pRmbStConfig->gRmbLog, 0, sizeof (StRmbLog)); + pStRmbLog = &pRmbStConfig->gRmbLog; + pStRmbLog->_para._logLevel = logLevel; + + pStRmbLog->_para._shiftType = shiftType; + if (shiftType == 6) + { + pStRmbLog->_para._shiftType = (int) RMB_LOG_TYPE_CYCLE; + } + strncpy (pStRmbLog->_para._path, path, sizeof (pStRmbLog->_para._path) - 1); + snprintf (pStRmbLog->_logStatFileName, + sizeof (pStRmbLog->_logStatFileName) - 1, "%s.stat", path); + pStRmbLog->_para._maxFileSize = maxFileSize; + pStRmbLog->_para._maxFileNum = maxFileNum; + pStRmbLog->_lastShiftTime = time (NULL); + + //spin_lock_init(&logSpinLock); + pthread_mutex_init (&pStRmbLog->rmbLogMutex, NULL); + //printf("log init!!"); + //if len(path) = 0, use stdout + + if (strlen (pStRmbLog->_para._path) == 0 + || pStRmbLog->_para._shiftType == RMB_LOG_TYPE_NORMAL) + { + pStRmbLog->_pLogFile = stdout; + pStRmbLog->_curFileNums = 1; + pStRmbLog->_para._shiftType = 0; + pStRmbLog->_lastShiftTime = 0; + return 0; + } + + if (pStRmbLog->_para._shiftType == RMB_LOG_TYPE_CYCLE) + { + iRet = GetCurStateFromRmbLogByCirCle (); + if (iRet != 0) + { + return -1; + } + } + else if (pStRmbLog->_para._shiftType == RMB_LOG_TYPE_DAILY + || pStRmbLog->_para._shiftType == RMB_LOG_TYPE_DAILY_AND_CYCLE) + { + pStRmbLog->_para._shiftType = RMB_LOG_TYPE_DAILY; + iRet = GetCurStateFromRmbLogByDaily_V4 (); + if (iRet != 0) + { + return -1; + } + } + else + { + pStRmbLog->_para._shiftType = RMB_LOG_TYPE_CYCLE; + iRet = GetCurStateFromRmbLogByCirCle (); + if (iRet != 0) + { + return -1; + } + } + return 0; +} + +int CloseRmbLog () +{ +// if(pStRmbLog->_pLogFile == NULL) +// { +// return 0; +// } +// fclose(pStRmbLog->_pLogFile); +// pStRmbLog->_pLogFile = NULL; +// return 0; + close (pStRmbLog->_fd); + pStRmbLog->_fd = -1; + return 0; +} + +int OpenRmbLog () +{ +// if (pStRmbLog->_pLogFile != NULL) +// { +// return 0; +// } +// printf("open file=%s", pStRmbLog->_logBaseFileName); +// if ((pStRmbLog->_pLogFile = fopen(pStRmbLog->_logBaseFileName, "a+")) == NULL) +// { +// pStRmbLog->_pLogFile = stdout; +// printf("openLog failed!fileName=%s, now select stdout!", pStRmbLog->_logBaseFileName); +// return -1; +// } +// printf("open file=%s succ", pStRmbLog->_logBaseFileName); + pStRmbLog->_fd = + open (pStRmbLog->_logBaseFileName, O_RDWR | O_CREAT | O_APPEND, 0666); + if (pStRmbLog->_fd == -1) + { + printf ("openLog failed!fileName=%s, now select stdout!", + pStRmbLog->_logBaseFileName); + pStRmbLog->_fd = 1; + return 0; + } + return 0; +} + +int OpenStateLog () +{ + pStRmbLog->_pStatFile = fopen (pStRmbLog->_logStatFileName, "a+"); + if (pStRmbLog->_pStatFile == NULL) + { + return 0; + } + return fileno (pStRmbLog->_pStatFile); +} + +int CloseStateLog () +{ + if (pStRmbLog->_pStatFile != NULL) + { + fclose (pStRmbLog->_pStatFile); + } + pStRmbLog->_pStatFile = NULL; + return 0; +} + +int FindNextDeleteLog (StDayInfo * dayInfo) +{ + //update next delete file name and time + int i = 0; + //找当天的 + for (i = 1; i < pStRmbLog->_para._maxFileNum; i++) + { + pStRmbLog->_toDeleteFileNo = + (pStRmbLog->_toDeleteFileNo + 1) % pStRmbLog->_para._maxFileNum; + if (pStRmbLog->_toDeleteFileNo == 0) + { + pStRmbLog->_toDeleteFileNo = 1; + } + + snprintf (pStRmbLog->_toDeleteFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1, "%s_%s.%d", + pStRmbLog->_para._path, + RmbGetShortDateStr ((time_t *) & pStRmbLog->_toDeleteTime), + pStRmbLog->_toDeleteFileNo); +// printf("check fileName=%s is exist or not!", pStRmbLog->_toDeleteFileName); + struct stat sb; + if (stat (pStRmbLog->_toDeleteFileName, &sb) != 0) + { +// printf("i=%u,logFile=%s not exist!", i, pStRmbLog->_toDeleteFileName); + break; + } +// printf("Next deleteNo=%u,deleteFileName=%s", pStRmbLog->_toDeleteFileNo, pStRmbLog->_toDeleteFileName); + return 0; + } + + int count = (time (NULL) - pStRmbLog->_toDeleteTime) / 60 * 60 * 24 + 1; + for (i = 1; i < count; i++) + { + pStRmbLog->_toDeleteTime = pStRmbLog->_toDeleteTime + 60 * 60 * 24; + GetDayInfo (dayInfo, &pStRmbLog->_toDeleteTime); + if (dayInfo->_curFileNum != 0) + { + pStRmbLog->_toDeleteFileNo = dayInfo->_deleteFileNo; + snprintf (pStRmbLog->_toDeleteFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1, "%s_%s.%d", + pStRmbLog->_para._path, + RmbGetShortDateStr ((time_t *) & pStRmbLog->_toDeleteTime), + pStRmbLog->_toDeleteFileNo); + break; + } + } + + return 0; +} + +int ShiftRmbLog (FILE * file) +{ + if (strlen (pStRmbLog->_para._path) == 0 + || pStRmbLog->_para._shiftType == RMB_LOG_TYPE_NORMAL) + { + return 0; + } + + if (pStRmbLog->_para._shiftType == RMB_LOG_TYPE_CYCLE) + { + + if (stat (pStRmbLog->_logBaseFileName, &pStRmbLog->gRmbSb) < 0) + { + pStRmbLog->_curFileSize = 0; + } + else + { + pStRmbLog->_curFileSize = (int) pStRmbLog->gRmbSb.st_size; + } + + if (pStRmbLog->_curFileSize < pStRmbLog->_para._maxFileSize) + { + return 0; + } + + OpenRmbLog (); + //file lock + pStRmbLog->logFileLock.l_type = F_WRLCK; + pStRmbLog->logFileLock.l_start = 0; + pStRmbLog->logFileLock.l_whence = SEEK_SET; + pStRmbLog->logFileLock.l_len = 0; + pStRmbLog->logFileLock.l_pid = getpid (); + if (-1 != fcntl (pStRmbLog->_fd, F_SETLKW, &pStRmbLog->logFileLock)) + { + int fd = OpenStateLog (); + pStRmbLog->logStateLock.l_type = F_WRLCK; + pStRmbLog->logStateLock.l_start = 0; + pStRmbLog->logStateLock.l_whence = SEEK_SET; + pStRmbLog->logStateLock.l_len = 0; + pStRmbLog->logStateLock.l_pid = getpid (); + if (-1 != fcntl (fd, F_SETLKW, &pStRmbLog->logStateLock)) + { + //GetCurFileNum(pStRmbLog->_pStatFile); + GetCurFileNum (pStRmbLog->_pStatFile); +// printf("pid=%d,getCurNo=%d,CurNums=%d", getpid(), pStRmbLog->_curFileNo, pStRmbLog->_curFileNums); + snprintf (pStRmbLog->_logFileName, + sizeof (pStRmbLog->_logFileName) - 1, "%s.%d", + pStRmbLog->_logBaseFileName, pStRmbLog->_curFileNo); + + if (stat (pStRmbLog->_logBaseFileName, &pStRmbLog->gRmbSb) != -1 + && (int) pStRmbLog->gRmbSb.st_size >= + pStRmbLog->_para._maxFileSize) + { + pStRmbLog->_curFileNums += 1; + if (pStRmbLog->_curFileNums > pStRmbLog->_para._maxFileNum) + { + if (access (pStRmbLog->_logFileName, F_OK) == 0) + { +// printf("pid=%d remove file=%s,curNo=%d, curNum=%d", getpid(), pStRmbLog->_logFileName, pStRmbLog->_curFileNo, pStRmbLog->_curFileNums); + remove (pStRmbLog->_logFileName); + } + pStRmbLog->_curFileNums -= 1; + } + + if (access (pStRmbLog->_logBaseFileName, F_OK) == 0) + { +// printf("pid=%d rename %s-->%s, curNo=%d,curNum=%d", getpid(), pStRmbLog->_logBaseFileName, pStRmbLog->_logFileName, pStRmbLog->_curFileNo, pStRmbLog->_curFileNums); + rename (pStRmbLog->_logBaseFileName, pStRmbLog->_logFileName); + } + else + { +// printf("pid=%d baseFileName=%s not exist", getpid(), pStRmbLog->_logBaseFileName); + } + pStRmbLog->_curFileNo = + (pStRmbLog->_curFileNo + 1) % pStRmbLog->_para._maxFileNum; +// if (pStRmbLog->_curFileNo == 0) +// { +// pStRmbLog->_curFileNo = 1; +// } + SetCurFileNum (pStRmbLog->_pStatFile); + //snprintf(pStRmbLog->_logFileName, sizeof(pStRmbLog->_logFileName) - 1, "%s.%d", pStRmbLog->_logBaseFileName, pStRmbLog->_curFileNo); + } + +// printf("pid=%d setFileNum.curNo=%d curNum=%d", getpid(), pStRmbLog->_curFileNo, pStRmbLog->_curFileNums); + pStRmbLog->logStateLock.l_type = F_UNLCK; + pStRmbLog->logStateLock.l_whence = SEEK_SET; + pStRmbLog->logStateLock.l_start = 0; + pStRmbLog->logStateLock.l_len = 0; + fcntl (fd, F_SETLKW, &pStRmbLog->logStateLock); + } + CloseStateLog (); + +// printf("shift over!pid=%d, curNo=%d,curNum=%d, logFileName=%s", getpid(), pStRmbLog->_curFileNo, pStRmbLog->_curFileNums, pStRmbLog->_logFileName); + //strncpy(pStRmbLog->_toDeleteFileName, pStRmbLog->_logFileName, sizeof(pStRmbLog->_toDeleteFileName) - 1); + + pStRmbLog->logFileLock.l_type = F_UNLCK; + pStRmbLog->logFileLock.l_whence = SEEK_SET; + pStRmbLog->logFileLock.l_start = 0; + pStRmbLog->logFileLock.l_len = 0; + fcntl (pStRmbLog->_fd, F_SETLKW, &pStRmbLog->logFileLock); + } + CloseRmbLog (); + return 0; + } + else if (pStRmbLog->_para._shiftType == RMB_LOG_TYPE_DAILY) + { + time_t curTime = time (NULL); + //日期变更发送滚动 + if (RmbIsOtherDay (&curTime, &pStRmbLog->_lastShiftTime)) + { + OpenRmbLog (); + //file lock + pStRmbLog->logFileLock.l_type = F_WRLCK; + pStRmbLog->logFileLock.l_start = 0; + pStRmbLog->logFileLock.l_whence = SEEK_SET; + pStRmbLog->logFileLock.l_len = 0; + pStRmbLog->logFileLock.l_pid = getpid (); + if (-1 != fcntl (pStRmbLog->_fd, F_SETLKW, &pStRmbLog->logFileLock)) + { + int fd = OpenStateLog (); + pStRmbLog->logStateLock.l_type = F_WRLCK; + pStRmbLog->logStateLock.l_start = 0; + pStRmbLog->logStateLock.l_whence = SEEK_SET; + pStRmbLog->logStateLock.l_len = 0; + pStRmbLog->logStateLock.l_pid = getpid (); + if (-1 != fcntl (fd, F_SETLKW, &pStRmbLog->logStateLock)) + { + GetCurFileNum (pStRmbLog->_pStatFile); + snprintf (pStRmbLog->_logFileName, + sizeof (pStRmbLog->_logFileName) - 1, "%s.%d", + pStRmbLog->_logBaseFileName, pStRmbLog->_curFileNo); + + if (RmbIsOtherDay (&curTime, &pStRmbLog->_lastShiftTime)) + { + pStRmbLog->_curFileNums += 1; + if (pStRmbLog->_curFileNums > pStRmbLog->_para._maxFileNum) + { + if (access (pStRmbLog->_logFileName, F_OK) == 0) + { + remove (pStRmbLog->_logFileName); + } + pStRmbLog->_curFileNums -= 1; + } + if (access (pStRmbLog->_logBaseFileName, F_OK) == 0) + { + rename (pStRmbLog->_logBaseFileName, pStRmbLog->_logFileName); + } + + snprintf (pStRmbLog->_logBaseFileName, + sizeof (pStRmbLog->_logBaseFileName), "%s_%s.log", + pStRmbLog->_para._path, RmbGetShortDateStr (&curTime)); + snprintf (pStRmbLog->_logFileName, + sizeof (pStRmbLog->_logFileName), "%s.0", + pStRmbLog->_logBaseFileName); + pStRmbLog->_curFileNo = 0; + pStRmbLog->_curFileNums = 0; + pStRmbLog->_lastShiftTime = curTime; + SetCurFileNum (pStRmbLog->_pStatFile); + } + else + { + snprintf (pStRmbLog->_logBaseFileName, + sizeof (pStRmbLog->_logBaseFileName), "%s_%s.log", + pStRmbLog->_para._path, RmbGetShortDateStr (&curTime)); + } + pStRmbLog->logStateLock.l_type = F_UNLCK; + pStRmbLog->logStateLock.l_whence = SEEK_SET; + pStRmbLog->logStateLock.l_start = 0; + pStRmbLog->logStateLock.l_len = 0; + fcntl (fd, F_SETLKW, &pStRmbLog->logStateLock); + } + CloseStateLog (); + + pStRmbLog->logFileLock.l_type = F_UNLCK; + pStRmbLog->logFileLock.l_whence = SEEK_SET; + pStRmbLog->logFileLock.l_start = 0; + pStRmbLog->logFileLock.l_len = 0; + fcntl (pStRmbLog->_fd, F_SETLKW, &pStRmbLog->logFileLock); + } + CloseRmbLog (); + return 0; + } + + if (stat (pStRmbLog->_logBaseFileName, &pStRmbLog->gRmbSb) < 0) + { + pStRmbLog->_curFileSize = 0; + } + else + { + pStRmbLog->_curFileSize = (int) pStRmbLog->gRmbSb.st_size; + } + + if (pStRmbLog->_curFileSize < pStRmbLog->_para._maxFileSize) + { + return 0; + } + + OpenRmbLog (); + //file lock + pStRmbLog->logFileLock.l_type = F_WRLCK; + pStRmbLog->logFileLock.l_start = 0; + pStRmbLog->logFileLock.l_whence = SEEK_SET; + pStRmbLog->logFileLock.l_len = 0; + pStRmbLog->logFileLock.l_pid = getpid (); + if (-1 != fcntl (pStRmbLog->_fd, F_SETLKW, &pStRmbLog->logFileLock)) + { + int fd = OpenStateLog (); + pStRmbLog->logStateLock.l_type = F_WRLCK; + pStRmbLog->logStateLock.l_start = 0; + pStRmbLog->logStateLock.l_whence = SEEK_SET; + pStRmbLog->logStateLock.l_len = 0; + pStRmbLog->logStateLock.l_pid = getpid (); + if (-1 != fcntl (fd, F_SETLKW, &pStRmbLog->logStateLock)) + { + GetCurFileNum (pStRmbLog->_pStatFile); + snprintf (pStRmbLog->_logFileName, sizeof (pStRmbLog->_logFileName), + "%s.%d", pStRmbLog->_logBaseFileName, + pStRmbLog->_curFileNo); + + if (stat (pStRmbLog->_logBaseFileName, &pStRmbLog->gRmbSb) != -1 + && (int) pStRmbLog->gRmbSb.st_size >= + pStRmbLog->_para._maxFileSize) + { + pStRmbLog->_curFileNums += 1; + if (pStRmbLog->_curFileNums > pStRmbLog->_para._maxFileNum) + { + if (access (pStRmbLog->_logFileName, F_OK) == 0) + { + remove (pStRmbLog->_logFileName); + } + pStRmbLog->_curFileNums -= 1; + } + //CloseZrdLog(); + if (access (pStRmbLog->_logBaseFileName, F_OK) == 0) + { + rename (pStRmbLog->_logBaseFileName, pStRmbLog->_logFileName); + } + + pStRmbLog->_curFileNo = + (pStRmbLog->_curFileNo + 1) % pStRmbLog->_para._maxFileNum; +// if (pStRmbLog->_curFileNo == 0) +// { +// pStRmbLog->_curFileNo = 1; +// } + SetCurFileNum (pStRmbLog->_pStatFile); + + } + + pStRmbLog->logStateLock.l_type = F_UNLCK; + pStRmbLog->logStateLock.l_whence = SEEK_SET; + pStRmbLog->logStateLock.l_start = 0; + pStRmbLog->logStateLock.l_len = 0; + fcntl (fd, F_SETLKW, &pStRmbLog->logStateLock); + } + CloseStateLog (); + + pStRmbLog->logFileLock.l_type = F_UNLCK; + pStRmbLog->logFileLock.l_whence = SEEK_SET; + pStRmbLog->logFileLock.l_start = 0; + pStRmbLog->logFileLock.l_len = 0; + fcntl (pStRmbLog->_fd, F_SETLKW, &pStRmbLog->logFileLock); + } + CloseRmbLog (); + return 0; + } + else if (pStRmbLog->_para._shiftType == RMB_LOG_TYPE_DAILY_AND_CYCLE) + { + time_t curTime = time (NULL); + //日期变更发送滚动 + if (RmbIsOtherDay (&curTime, &pStRmbLog->_lastShiftTime)) + { + pStRmbLog->_curFileNums += 1; + //假如个数限制,则删除老的 + if (pStRmbLog->_curFileNums > pStRmbLog->_para._maxFileNum) + { + remove (pStRmbLog->_toDeleteFileName); + pStRmbLog->_curFileNums -= 1; + StDayInfo dayInfo; + FindNextDeleteLog (&dayInfo); + } + //GetCurStateFromRmbLogByDaily_V3(); //保证没有出错 + //rename + //CloseRmbLog(); + rename (pStRmbLog->_logBaseFileName, pStRmbLog->_logFileName); + snprintf (pStRmbLog->_logBaseFileName, + sizeof (pStRmbLog->_logBaseFileName), "%s_%s.log", + pStRmbLog->_para._path, RmbGetShortDateStr (&curTime)); + snprintf (pStRmbLog->_logFileName, sizeof (pStRmbLog->_logFileName), + "%s_1.log", pStRmbLog->_logBaseFileName); + pStRmbLog->_curFileNo = 1; + //OpenRmbLog(); + return 0; + } + + if (stat (pStRmbLog->_logBaseFileName, &pStRmbLog->gRmbSb) < 0) + { + pStRmbLog->_curFileSize = 0; + } + else + { + pStRmbLog->_curFileSize = (int) pStRmbLog->gRmbSb.st_size; + } + + if (pStRmbLog->_curFileSize < pStRmbLog->_para._maxFileSize) + { + return 0; + } + //文件大小促发滚动 + pStRmbLog->_curFileNums += 1; + if (pStRmbLog->_curFileNums > pStRmbLog->_para._maxFileNum) + { + remove (pStRmbLog->_toDeleteFileName); + pStRmbLog->_curFileNums -= 1; + StDayInfo dayInfo; + FindNextDeleteLog (&dayInfo); + } + //rename + //CloseRmbLog(); + rename (pStRmbLog->_logBaseFileName, pStRmbLog->_logFileName); + pStRmbLog->_curFileNo += 1; + snprintf (pStRmbLog->_logFileName, sizeof (pStRmbLog->_logFileName), + "%s_%d.log", pStRmbLog->_logBaseFileName, + pStRmbLog->_curFileNo); + //OpenRmbLog(); + return 0; + } + return 0; +} + +int LogRmb (int logLevel, const char *format, ...) +{ +// printf("logLevel=%u,sysLevel=%u,file=%p,baseFile=%s", +// logLevel, pStRmbLog->_para._logLevel, pStRmbLog->_pLogFile, pStRmbLog->_logBaseFileName); +// va_list ap1; +// va_start(ap1, format); +// printf(format, ap1); +// va_end(ap1); +// return 0; +// return ShiftRmbLog(pStRmbLog->_pLogFile); + + if (logLevel > pStRmbLog->_para._logLevel) + { + return 0; + } + + //pthread_spin_lock(&logSpinLock); + pthread_mutex_lock (&pStRmbLog->rmbLogMutex); + ShiftRmbLog (pStRmbLog->_pLogFile); + va_list ap; + if ((pStRmbLog->_pLogFile = + fopen (pStRmbLog->_logBaseFileName, "a+")) == NULL) + { + pStRmbLog->_pLogFile = stdout; + //printf("openLog failed!fileName=%s, now select stdout!", pStRmbLog->_logBaseFileName); + } + va_start (ap, format); + gettimeofday (&pStRmbLog->stLogTv, NULL); + fprintf (pStRmbLog->_pLogFile, "[%s][%s %03d][%d][%lu]", + StatLogLevel[logLevel], + RmbGetDateTimeStr ((const time_t *) &(pStRmbLog->stLogTv.tv_sec)), + (int) ((pStRmbLog->stLogTv.tv_usec) / 1000), pRmbStConfig->uiPid, + pthread_self ()); + vfprintf (pStRmbLog->_pLogFile, format, ap); + va_end (ap); + fprintf (pStRmbLog->_pLogFile, "\n"); + if (pStRmbLog->_pLogFile != stdout) + { + fclose (pStRmbLog->_pLogFile); + } + + //pthread_spin_unlock(&logSpinLock); + pthread_mutex_unlock (&pStRmbLog->rmbLogMutex); + return 0; +} + +//统计现在有几个日志,当前日志马上要被rename成什么,是不是需要促发删除 +int GetCurStateFromRmbLogByCirCle () +{ + pStRmbLog->_curFileNums = 1; + //unsigned int minModifyTime = 0; + //int i = 0; + snprintf (pStRmbLog->_logBaseFileName, sizeof (pStRmbLog->_logBaseFileName), + "%s.log", pStRmbLog->_para._path); + //strncpy(pStRmbLog->_logFileName, pStRmbLog->_logBaseFileName, sizeof(pStRmbLog->_logFileName) - 1); + pStRmbLog->_curFileNo = 0; + /* + for (i = 1; i < pStRmbLog->_para._maxFileNum ; i++) + { + snprintf(pStRmbLog->_logFileName, sizeof(pStRmbLog->_logFileName) - 1, "%s.%d", pStRmbLog->_logBaseFileName, i); + printf("log file:%s", pStRmbLog->_logFileName); + + struct stat sb; + if (stat (pStRmbLog->_logFileName, &sb) != 0) + { + //�ļ�������, ʹ�øñ�� + pStRmbLog->_curFileNo = i; + printf("logFile=%s not exist!", pStRmbLog->_logFileName); + break; + } + pStRmbLog->_curFileNums++; + + printf("fileName=%s,modifyTime=%lu", pStRmbLog->_logFileName, sb.st_mtime); + //ѭ����־, ��Ҫ������޸�ʱ��������� + if (minModifyTime == 0 || sb.st_mtime < minModifyTime) + { + pStRmbLog->_toDeleteFileNo = i; + minModifyTime = sb.st_mtime; + } + // if (sb.st_mtime > maxModifyTime) + // { + // pStRmbLog->_curFileNo = i; + // maxModifyTime = sb.st_mtime; + // } + } + */ + pStRmbLog->_curFileNums = 0; + GetCurFileNumFromStatFile (); +// if (pStRmbLog->_curFileNo == 0) +// { +// pStRmbLog->_curFileNo = pStRmbLog->_toDeleteFileNo; +// } + //SetCurFileNumToStatFile(); + snprintf (pStRmbLog->_logFileName, sizeof (pStRmbLog->_logFileName) - 1, + "%s.%d", pStRmbLog->_logBaseFileName, pStRmbLog->_curFileNo); + snprintf (pStRmbLog->_toDeleteFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1, "%s.%d", + pStRmbLog->_logBaseFileName, pStRmbLog->_toDeleteFileNo); + //printf("Circle Log: curFileNo=%u", pStRmbLog->_curFileNo); + return 0; +} + +//统计现在有几个日志,当前日志马上要被rename成什么,是不是需要促发删除(按编号大小) +int GetCurStateFromRmbLogByDaily () +{ + pStRmbLog->_curFileNums = 1; + int i = 0; + snprintf (pStRmbLog->_logBaseFileName, sizeof (pStRmbLog->_logBaseFileName), + "%s_%s.log", pStRmbLog->_para._path, RmbGetCurShortDateStr ()); + //strncpy(pStRmbLog->_logFileName, pStRmbLog->_logBaseFileName, sizeof(pStRmbLog->_logFileName) - 1); + //int todayFileNo = 0; + unsigned int curTime = time (NULL); + //当天 + for (i = 1; i < pStRmbLog->_para._maxFileNum - 1; i++) + { + snprintf (pStRmbLog->_logFileName, sizeof (pStRmbLog->_logFileName) - 1, + "%s.%d", pStRmbLog->_logBaseFileName, i); +// printf("GetCurStateFromRmbLogByDaily log file:%s", pStRmbLog->_logFileName); + + struct stat sb; + if (stat (pStRmbLog->_logFileName, &sb) != 0) + { + //file not exist, use it + pStRmbLog->_curFileNo = i; + //pStRmbLog->_curFileNums = i; +// printf("GetCurStateFromRmbLogByDaily logFile=%s not exist!", pStRmbLog->_logFileName); + break; + } + pStRmbLog->_toDeleteTime = curTime; + pStRmbLog->_curFileNums++; + } + + //unsigned int minModifyTime = 0; + char baseFileName[300] = { 0 }; + int j = 0; + int finishFlag = 0; + int deleteNo = 0; + //往前找 + for (i = 1; !finishFlag && i < pStRmbLog->_para._maxFileNum; i++) + { + pStRmbLog->_toDeleteFileNo = deleteNo; + pStRmbLog->_toDeleteTime = curTime - 60 * 60 * 24 * i; + snprintf (baseFileName, sizeof (baseFileName), "%s_%s.log", + pStRmbLog->_para._path, + RmbGetShortDateStr ((time_t *) & pStRmbLog->_toDeleteTime)); +// printf("%d_baseName=%s", i , baseFileName); + int iNotNullFlag = 0; + for (j = 1; j < pStRmbLog->_para._maxFileNum; j++) + { + snprintf (pStRmbLog->_toDeleteFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1, "%s.%d", + baseFileName, i); +// printf("check fileName=%s is exist or not!", pStRmbLog->_toDeleteFileName); + struct stat sb; + if (stat (pStRmbLog->_toDeleteFileName, &sb) != 0) + { + if (iNotNullFlag == 1) + { +// printf("GetCurStateFromRmbLogByDaily logFile=%s not exist!", pStRmbLog->_toDeleteFileName); + break; + } + if (j == pStRmbLog->_para._maxFileNum - 1) + { + if (iNotNullFlag == 0) + { + finishFlag = 1; +// printf("GetCurStateFromRmbLogByDaily logFile=%s has't exist", pStRmbLog->_toDeleteFileName); + break; + } + } + + continue; + } + if (deleteNo == 0) + { + deleteNo = j; + } + iNotNullFlag = 1; + pStRmbLog->_curFileNums++; + } + } + snprintf (pStRmbLog->_toDeleteFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1, "%s.1", baseFileName); +// printf("Status:curFileNums=%u,mayBeDeleteFileName=%s", pStRmbLog->_curFileNums, pStRmbLog->_toDeleteFileName); + return 0; +} + +int GetDayInfo (StDayInfo * dayInfo, time_t * curTime) +{ + int i = 0; + time_t minModifyTime = 0; + dayInfo->_deleteFileNo = 1; + dayInfo->_curFileNo = 0; + dayInfo->_curFileNum = 0; + + snprintf (dayInfo->_baseFileName, sizeof (dayInfo->_baseFileName), + "%s_%s.log", pStRmbLog->_para._path, + RmbGetShortDateStr (curTime)); + + //当天 + for (i = 1; i < pStRmbLog->_para._maxFileNum; i++) + { + snprintf (dayInfo->_logFileName, sizeof (dayInfo->_logFileName) - 1, + "%s.%d", dayInfo->_baseFileName, i); +// printf("GetDayInfo log file:%s", dayInfo->_logFileName); + + struct stat sb; + if (stat (dayInfo->_logFileName, &sb) != 0) + { + //file not exist, use it + if (dayInfo->_curFileNo == 0) + { + dayInfo->_curFileNo = i; + } +// printf("GetDayInfo logFile=%s not exist!", dayInfo->_logFileName); + continue; + //break; //之所以不用break, 因为存在消除该日期下其他日志的可能 + } + dayInfo->_curFileNum++; + //循环日志,需要按最后修改时间排序 + if (minModifyTime == 0 || sb.st_mtime < minModifyTime) + { + dayInfo->_deleteFileNo = i; + minModifyTime = sb.st_mtime; + } + } + return 0; +} + +int GetDayInfoWithBreak (StDayInfo * dayInfo, time_t * curTime) +{ + int i = 0; + time_t minModifyTime = 0; + dayInfo->_deleteFileNo = 1; + dayInfo->_curFileNo = 0; + dayInfo->_curFileNum = 0; + snprintf (dayInfo->_baseFileName, sizeof (dayInfo->_baseFileName), + "%s_%s.log", pStRmbLog->_para._path, + RmbGetShortDateStr (curTime)); + + //当天 + for (i = 1; i < pStRmbLog->_para._maxFileNum; i++) + { + snprintf (dayInfo->_logFileName, sizeof (dayInfo->_logFileName) - 1, + "%s.%d", dayInfo->_baseFileName, i); +// printf("GetDayInfoWithBreak log file:%s", dayInfo->_logFileName); + + struct stat sb; + if (stat (dayInfo->_logFileName, &sb) != 0) + { + //file not exist, use it + if (dayInfo->_curFileNo == 0) + { + dayInfo->_curFileNo = i; + } +// printf("GetDayInfoWithBreak logFile=%s not exist!", dayInfo->_logFileName); + break; + } + dayInfo->_curFileNum++; + //循环日志,需要按最后修改时间排序 + if (minModifyTime == 0 || sb.st_mtime < minModifyTime) + { + dayInfo->_deleteFileNo = i; + minModifyTime = sb.st_mtime; + } + } + return 0; +} + +//统计现在有几个日志,当前日志马上要被rename成什么,是不是需要促发删除(同一个日期,按修改日期滚动) +int GetCurStateFromRmbLogByDaily_V3 () +{ + pStRmbLog->_curFileNums = 1; + int i = 0; + //当前天 + time_t curTime = time (NULL); + StDayInfo dayInfo; + GetDayInfo (&dayInfo, &curTime); + if (dayInfo._curFileNo == 0) + { + pStRmbLog->_curFileNo = dayInfo._deleteFileNo; + } + else + { + pStRmbLog->_curFileNo = dayInfo._curFileNo; + } + pStRmbLog->_curFileNums += dayInfo._curFileNum; + pStRmbLog->_toDeleteFileNo = dayInfo._deleteFileNo; + pStRmbLog->_toDeleteTime = curTime; + snprintf (pStRmbLog->_logBaseFileName, sizeof (pStRmbLog->_logBaseFileName), + "%s_%s.log", pStRmbLog->_para._path, + RmbGetShortDateStr (&curTime)); + snprintf (pStRmbLog->_logFileName, sizeof (pStRmbLog->_logFileName) - 1, + "%s.%d", pStRmbLog->_logBaseFileName, pStRmbLog->_curFileNo); + + //往前数 + for (i = 1; i < pStRmbLog->_para._maxFileNum; i++) + { + curTime = curTime - 60 * 60 * 24; + GetDayInfo (&dayInfo, &curTime); + if (dayInfo._curFileNum != 0) + { + pStRmbLog->_curFileNums += dayInfo._curFileNum; + pStRmbLog->_toDeleteFileNo = dayInfo._deleteFileNo; + pStRmbLog->_toDeleteTime = curTime; + } + else + { + break; + } + + } + + snprintf (pStRmbLog->_toDeleteFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1, "%s_%s.%d", + pStRmbLog->_para._path, + RmbGetShortDateStr (&pStRmbLog->_toDeleteTime), + pStRmbLog->_toDeleteFileNo); +// printf("GetCurStateFromRmbLogByDaily_V3 Status:curFileNums=%u,mayBeDeleteFileName=%s", pStRmbLog->_curFileNums, pStRmbLog->_toDeleteFileName); + return 0; +} + +//统计现在有几个日志,当前日志马上要被rename成什么,是不是需要促发删除(同一个日期,按修改日期滚动) +int GetCurStateFromRmbLogByDaily_V2 () +{ + pStRmbLog->_curFileNums = 1; + int i = 0; + snprintf (pStRmbLog->_logBaseFileName, sizeof (pStRmbLog->_logBaseFileName), + "%s_%s.log", pStRmbLog->_para._path, RmbGetCurShortDateStr ()); + //strncpy(pStRmbLog->_logFileName, pStRmbLog->_logBaseFileName, sizeof(pStRmbLog->_logFileName) - 1); + //int todayFileNo = 0; + unsigned int curTime = time (NULL); + //unsigned int maxModifyTime = 0; + unsigned int minModifyTime = 0; + + pStRmbLog->_toDeleteFileNo = 1; + //当天 + for (i = 1; i < pStRmbLog->_para._maxFileNum; i++) + { + snprintf (pStRmbLog->_logFileName, sizeof (pStRmbLog->_logFileName) - 1, + "%s.%d", pStRmbLog->_logBaseFileName, i); +// printf("GetCurStateFromRmbLogByDaily log file:%s", pStRmbLog->_logFileName); + + struct stat sb; + if (stat (pStRmbLog->_logFileName, &sb) != 0) + { + //file not exist, use it + pStRmbLog->_curFileNo = i; + +// printf("GetCurStateFromRmbLogByDaily logFile=%s not exist!", pStRmbLog->_logFileName); + break; + } + pStRmbLog->_toDeleteTime = curTime; + pStRmbLog->_curFileNums++; + + //循环日志,需要按最后修改时间排序 + if (minModifyTime == 0 || sb.st_mtime < minModifyTime) + { + pStRmbLog->_toDeleteFileNo = i; + minModifyTime = sb.st_mtime; + } + } + + char baseFileName[300] = { 0 }; + int j = 0; + int finishFlag = 0; + int deleteNo = 0; + //往前 + for (i = 1; !finishFlag && i < pStRmbLog->_para._maxFileNum; i++) + { + pStRmbLog->_toDeleteTime = curTime - 60 * 60 * 24 * i; + time_t uiDeleteTime = pStRmbLog->_toDeleteTime; + snprintf (baseFileName, sizeof (baseFileName), "%s_%s.log", + pStRmbLog->_para._path, RmbGetShortDateStr (&uiDeleteTime)); +// printf("%d_baseName=%s", i , baseFileName); + int iNotNullFlag = 0; + deleteNo = 0; + //针对每一天查找 + for (j = 1; j < pStRmbLog->_para._maxFileNum; j++) + { + snprintf (pStRmbLog->_toDeleteFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1, "%s.%d", + baseFileName, j); +// printf("check fileName=%s is exist or not!", pStRmbLog->_toDeleteFileName); + struct stat sb; + if (stat (pStRmbLog->_toDeleteFileName, &sb) != 0) + { + if (iNotNullFlag == 1) + { +// printf("GetCurStateFromRmbLogByDaily logFile=%s not exist!", pStRmbLog->_toDeleteFileName); + break; + } + if (j == pStRmbLog->_para._maxFileNum - 1) + { + if (iNotNullFlag == 0) + { + finishFlag = 1; + pStRmbLog->_toDeleteTime = + pStRmbLog->_toDeleteTime + 60 * 60 * 24; +// printf("GetCurStateFromRmbLogByDaily logFile=%s has't exist", pStRmbLog->_toDeleteFileName); + break; + } + } + + continue; + } + if (deleteNo == 0) + { + deleteNo = j; + pStRmbLog->_toDeleteFileNo = deleteNo; //记录当前最应该删除的 + } + iNotNullFlag = 1; //表示前面不是空的,没有类似000111的情况 + pStRmbLog->_curFileNums++; + } + + } + time_t uiDeleteTime = pStRmbLog->_toDeleteTime; + snprintf (baseFileName, sizeof (baseFileName), "%s_%s.log", + pStRmbLog->_para._path, RmbGetShortDateStr (&uiDeleteTime)); + snprintf (pStRmbLog->_toDeleteFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1, "%s.%d", baseFileName, + pStRmbLog->_toDeleteFileNo); +// printf("Status:curFileNums=%u,mayBeDeleteFileName=%s", pStRmbLog->_curFileNums, pStRmbLog->_toDeleteFileName); + return 0; +} + +//只在当天滚 +int GetCurStateFromRmbLogByDaily_V4 () +{ + pStRmbLog->_curFileNums = 0; + //当前天 + /* + time_t curTime = time(NULL); + StDayInfo dayInfo; + GetDayInfoWithBreak(&dayInfo, &curTime); + if (dayInfo._curFileNo == 0) + { + pStRmbLog->_curFileNo = dayInfo._deleteFileNo; + } + else + { + pStRmbLog->_curFileNo = dayInfo._curFileNo; + } + pStRmbLog->_curFileNums = dayInfo._curFileNum; + pStRmbLog->_toDeleteFileNo = dayInfo._curFileNo; + pStRmbLog->_toDeleteTime = curTime; + */ + pStRmbLog->_curFileNo = 0; + time_t curTime = time (NULL); + pStRmbLog->_lastShiftTime = curTime; + GetCurFileNumFromStatFile (); + pStRmbLog->_toDeleteFileNo = pStRmbLog->_curFileNo; + + snprintf (pStRmbLog->_logBaseFileName, sizeof (pStRmbLog->_logBaseFileName), + "%s_%s.log", pStRmbLog->_para._path, + RmbGetShortDateStr (&curTime)); + snprintf (pStRmbLog->_logFileName, sizeof (pStRmbLog->_logFileName) - 1, + "%s.%d", pStRmbLog->_logBaseFileName, pStRmbLog->_curFileNo); + strncpy (pStRmbLog->_toDeleteFileName, pStRmbLog->_logFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1); + return 0; +} + +void _Log_Thread_func (void *args) +{ + struct timeval nowTimeVal; + gettimeofday (&nowTimeVal, NULL); + unsigned long ulNowTime = + (unsigned long) nowTimeVal.tv_sec * (unsigned long) 1000UL + + (unsigned long) nowTimeVal.tv_usec / 1000UL; + unsigned long lastPrintTime = 0; + + struct timeval tv_now; + unsigned long ulLastGetConfigTime = 0; + unsigned long ulLastGetAccessTime = 0; + + // char url[512]; + // snprintf(url, sizeof(url), "http://%s:%d/%s/%s/%s/%s", pRmbStConfig->cConfigIp, pRmbStConfig->iConfigPort, RMB_REQ_SINGLE, RMB_WHITE_LIST_SND, pRmbStConfig->cConsumerSysId, pRmbStConfig->cRegion); + + while (1) + { + int i = 0; + if ((pRmbStConfig->iWemqUseHttpCfg == 1)) + { + gettimeofday (&tv_now, NULL); + if (tv_now.tv_sec > + (ulLastGetAccessTime + pRmbStConfig->getAccessIpPeriod)) + { + ulLastGetAccessTime = tv_now.tv_sec; + //int iRet = wemq_proxy_load_servers(cAccessIpUrl, pRmbStConfig->iConfigTimeout, pRmbStConfig->cWemqSavePath); + char cAccessIpUrl[512]; + char addrArr[15][50] = { 0 }; + int lenAddrs = 0; + char tmpAddrs[512] = { 0 }; + strcpy (tmpAddrs, pRmbStConfig->ConfigAddr); + LOGRMB (RMB_LOG_DEBUG, + "config center ip str is:%s,try get access ip from the %d config center in list,lists:", + tmpAddrs, pRmbStConfig->configIpPosInArr + 1); + split_str (tmpAddrs, addrArr, &lenAddrs); + int j = 0; + for (j = 0; j < lenAddrs; ++j) + { + LOGRMB (RMB_LOG_DEBUG, "%s", addrArr[j]); + } + if (lenAddrs == 0) + { + LOGRMB (RMB_LOG_ERROR, + "config center addr list len is 0,please check if configCenterAddrMulti is empty in conf file"); + return -1; + } + + int iRet = 0; + int i = 0; + for (i = 0; i < lenAddrs; ++i) + { + memset (&cAccessIpUrl, 0x00, sizeof (cAccessIpUrl)); + snprintf (cAccessIpUrl, sizeof (cAccessIpUrl), "%s/%s", + addrArr[(i + pRmbStConfig->configIpPosInArr) % lenAddrs], + WEMQ_ACCESS_SERVER); + LOGRMB (RMB_LOG_DEBUG, "try to get access addr from %s", + cAccessIpUrl); + iRet = + wemq_proxy_load_servers (cAccessIpUrl, + pRmbStConfig->iConfigTimeout); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_WARN, + "get access ip from %s failed,try next config center ip", + cAccessIpUrl); + continue; + } + else + { + LOGRMB (RMB_LOG_INFO, + "get all access ip list result=%d from url:%s", iRet, + cAccessIpUrl); + pRmbStConfig->configIpPosInArr = + pRmbStConfig->configIpPosInArr + i; + break; + } + } + + // free addrArr + } + } + + sleep (1); + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_mq.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_mq.c new file mode 100644 index 0000000000..c6e6dfd302 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_mq.c @@ -0,0 +1,1357 @@ +// 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. + +#include "rmb_mq.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rmb_cfg.h" +#include "rmb_log.h" +#include "rmb_define.h" +#include +#include "rmb_pub.h" + +#define NO_CLEAR_FLAG 0 +#define CLEAR_FLAG 1 + +int rmb_notify_get_fator (const int iCount) +{ + if (iCount < 5000) + { + return iCount / 1000 + 1; + } + else if (iCount < 10000) + { + return 5; + } + else if (iCount < 20000) + { + return 8; + } + else if (iCount < 30000) + { + return 12; + } + else if (iCount < 50000) + { + return 20; + } + else if (iCount < 100000) + { + return 30; + } + return 40; +} + +//get shared mem +int rmb_mq_get_shm (StRmbMq * pMq, const unsigned int shmKey, + const unsigned int shmSize, const int flags, + const int bReadOnly) +{ + long lRet; + if ((pMq->ulShmId = shmget (shmKey, shmSize, flags)) == -1) + { + return -1; + } + if (1 == bReadOnly) + { + if ((lRet = (long) shmat (pMq->ulShmId, NULL, SHM_RDONLY)) == -1) + { + return -2; + } + } + else + { + if ((lRet = (long) shmat (pMq->ulShmId, NULL, 0)) == -1) + { + return -3; + } + } + pMq->pMqData = (char *) lRet; + return 0; +} + +//mq init +int rmb_mq_init (StRmbMq * pMq, const unsigned int shmKey, + const unsigned int shmSize, const int bCreate, + const int bReadOnly) +{ + if (shmSize <= C_RMB_MQ_HEAD_SIZE) + { + LOGRMB (RMB_LOG_ERROR, "rmb_mq_init shmSize if too small=%d", + (int) shmSize); + return -1; + } + pMq->uiShmkey = shmKey; + pMq->uiShmSize = shmSize; + + int nFlag = 0666; + //pMq->mqStat.ulShmId = + int iRet = rmb_mq_get_shm (pMq, shmKey, shmSize, nFlag, bReadOnly); + if (iRet != 0) + { + if (bCreate) + { + nFlag = nFlag | IPC_CREAT; + iRet = rmb_mq_get_shm (pMq, shmKey, shmSize, nFlag, bReadOnly); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_mq_init get shm failed! has create,iRet=%d", iRet); + return -2; + } + if (!bReadOnly) + { + //memset(pMq->pMqData, 0, pMq->uiShmSize); + memset (pMq->pMqData, 0, C_RMB_MQ_HEAD_SIZE); // set head and tail + } + } + else + { + LOGRMB (RMB_LOG_ERROR, "rmb_mq_init get shm failed! no create,iRet=%d", + iRet); + return -3; + } + } + + //init shm + pMq->pHead = (unsigned int *) pMq->pMqData; + pMq->pTail = (unsigned int *) (pMq->pMqData + sizeof (unsigned int)); + *(pMq->pHead) = 0; + *(pMq->pTail) = 0; + pMq->pBlock = (char *) (pMq->pTail + 1); + pMq->uiBlockSize = pMq->uiShmSize - C_RMB_MQ_HEAD_SIZE; + return 0; +} + +//mq_enqueue +//return -2: not enough space +int rmb_mq_enqueue (StRmbMq * pMq, const char *data, unsigned int uiDataLen, + unsigned int uiFLow) +{ + if (pMq == NULL || data == NULL) + { + LOGRMB (RMB_LOG_ERROR, "enqueue failed!pMq==NULL or data==NULL"); + rmb_errno = RMB_ERROR_ARGV_NULL; + return -1; + } + + unsigned int uiHead = *pMq->pHead; + unsigned int uiTail = *pMq->pTail; + unsigned int uiFreeLen = + uiHead > uiTail ? uiHead - uiTail : uiHead + pMq->uiBlockSize - uiTail; + unsigned int uiTailLen = pMq->uiBlockSize - uiTail; + char *pBlock = pMq->pBlock; + + char sHead[C_RMB_MQ_PKG_HEAD_SIZE] = { 0 }; + unsigned int uiTotalLen = uiDataLen + C_RMB_MQ_PKG_HEAD_SIZE; + + //1.if no enough space + if (uiFreeLen <= uiTotalLen) + { + return -2; + } + + memcpy (sHead, &uiTotalLen, sizeof (unsigned int)); + memcpy (sHead + sizeof (unsigned int), &uiFLow, sizeof (unsigned int)); + + //2.if tail space > 8+len + //copy 8 byte, copy data + if (uiTailLen >= uiTotalLen) + { + memcpy (pBlock + uiTail, sHead, C_RMB_MQ_PKG_HEAD_SIZE); + memcpy (pBlock + uiTail + C_RMB_MQ_PKG_HEAD_SIZE, data, uiDataLen); + //update tail + *pMq->pTail += (uiDataLen + C_RMB_MQ_PKG_HEAD_SIZE); + + } + //3.if tail space > 8 && < 8+len + else if (uiTailLen >= C_RMB_MQ_PKG_HEAD_SIZE + && uiTailLen < C_RMB_MQ_PKG_HEAD_SIZE + uiDataLen) + { + // copy 8 byte + memcpy (pBlock + uiTail, sHead, C_RMB_MQ_PKG_HEAD_SIZE); + + // copy firstlen + unsigned int uiFirstLen = uiTailLen - C_RMB_MQ_PKG_HEAD_SIZE; + memcpy (pBlock + uiTail + C_RMB_MQ_PKG_HEAD_SIZE, data, uiFirstLen); + + // copy secondlen + unsigned int uiSecondLen = uiDataLen - uiFirstLen; + memcpy (pBlock, data + uiFirstLen, uiSecondLen); + + //update tail + unsigned int tail = + *pMq->pTail + uiDataLen + C_RMB_MQ_PKG_HEAD_SIZE - pMq->uiBlockSize; + *pMq->pTail = tail; + } + //4.if tail space < 8 + else + { + //copy tail byte + memcpy (pBlock + uiTail, sHead, uiTailLen); + + //copy 8-tail byte + unsigned int uiSecondLen = C_RMB_MQ_PKG_HEAD_SIZE - uiTailLen; + memcpy (pBlock, sHead + uiTailLen, uiSecondLen); + + //copy data + memcpy (pBlock + uiSecondLen, data, uiDataLen); + + //update tail + *pMq->pTail = uiSecondLen + uiDataLen; + } + return 0; +} + +//mq_dequeue +int rmb_mq_dequeue (StRmbMq * pMq, char *buf, unsigned int uiBufSize, + unsigned int *pDataLen, unsigned int *pFlowId) +{ + RMB_CHECK_POINT_NULL (pMq, "pMq"); + RMB_CHECK_POINT_NULL (pMq, "buf"); + RMB_CHECK_POINT_NULL (pMq, "pDataLen"); + + unsigned int uiHead = *pMq->pHead; + unsigned int uiTail = *pMq->pTail; + const char *pBlock = pMq->pBlock; + + if (uiHead == uiTail) + { + *pDataLen = 0; + return 0; + } + unsigned int uiUsedLen = + uiTail > uiHead ? uiTail - uiHead : uiTail + pMq->uiBlockSize - uiHead; + char sHead[C_RMB_MQ_PKG_HEAD_SIZE]; + + //1.get head + if (uiHead + C_RMB_MQ_PKG_HEAD_SIZE > pMq->uiBlockSize) + { + unsigned int uiFirstSize = pMq->uiBlockSize - uiHead; + unsigned int uiSecondSize = C_RMB_MQ_PKG_HEAD_SIZE - uiFirstSize; + memcpy (sHead, pBlock + uiHead, uiFirstSize); + memcpy (sHead + uiFirstSize, pBlock, uiSecondSize); + uiHead = uiSecondSize; + } + else + { + memcpy (sHead, pBlock + uiHead, C_RMB_MQ_PKG_HEAD_SIZE); + uiHead += C_RMB_MQ_PKG_HEAD_SIZE; + } + + //2.get meta data len + unsigned int uiTotalLen = *((unsigned int *) sHead); + if (pFlowId) + { + *pFlowId = *((unsigned *) (sHead + sizeof (unsigned int))); + } + + if (uiTotalLen > uiUsedLen) + { + LOGRMB (RMB_LOG_ERROR, "dequeue error!uiTotallen=%u > usedLen=%u", + uiTotalLen, uiUsedLen); + return -1; + } + + *pDataLen = uiTotalLen - C_RMB_MQ_PKG_HEAD_SIZE; + if (*pDataLen > uiBufSize) + { + LOGRMB (RMB_LOG_ERROR, + "dequeue error!buffer size=%u is not enough,at least=%u!", + uiBufSize, *pDataLen); + return -1; + } + + //3.memcpy the meata data + if (uiHead + *pDataLen > pMq->uiBlockSize) + { + unsigned int uiFirstSize = pMq->uiBlockSize - uiHead; + unsigned int uiSecondSize = *pDataLen - uiFirstSize; + memcpy (buf, pBlock + uiHead, uiFirstSize); + memcpy (buf + uiFirstSize, pBlock, uiSecondSize); + //update the head + *pMq->pHead = uiSecondSize; + } + else + { + memcpy (buf, pBlock + uiHead, *pDataLen); + //update the head + *pMq->pHead = uiHead + *pDataLen; + } + + return 0; +} + +//mq_try_deuque +int rmb_mq_try_dequeue (StRmbMq * pMq, char *buf, unsigned int uiBufSize, + unsigned int *pDataLen, unsigned int *pFlowId) +{ + return rmb_mq_dequeue (pMq, buf, uiBufSize, pDataLen, pFlowId); +} + +//mq_get_stat +int rmb_mq_get_stat (StRmbMq * pMq) +{ + unsigned int uiHead = *pMq->pHead; + unsigned int uiTail = *pMq->pTail; + unsigned int uiFreeLen = + uiHead > uiTail ? uiHead - uiTail : uiHead + pMq->uiBlockSize - uiTail; + unsigned int uiUsedLen = + uiTail > uiHead ? uiTail - uiHead : uiTail + pMq->uiBlockSize - uiHead; + LOGRMB (RMB_LOG_ERROR, "Mq Stat:[head=%u,tail=%u,freeLen=%u,usedLen=%u]", + uiHead, uiTail, uiFreeLen, uiUsedLen); + return 0; +} + +//*****************************for rmb queue(private memory)************************************ +//queue init +int rmb_queue_init (StRmbQueue * pQue, const unsigned int size) +{ + if (size <= C_RMB_MQ_HEAD_SIZE) + { + LOGRMB (RMB_LOG_ERROR, "rmb_queue_init size is too small=%u", size); + return -1; + } + + pQue->pData = (char *) malloc (sizeof (char) * size); + if (pQue->pData == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_queue_init malloc for pQue->pData failed"); + return -2; + } + + pQue->uiSize = size; + + pQue->pHead = (unsigned int *) pQue->pData; + pQue->pTail = (unsigned int *) (pQue->pData + sizeof (unsigned int)); + *(pQue->pHead) = 0; + *(pQue->pTail) = 0; + pQue->pBlock = (char *) (pQue->pTail + 1); + pQue->uiBlockSize = pQue->uiSize - C_RMB_MQ_HEAD_SIZE; + + return 0; +} + +int rmb_queue_enqueue (StRmbQueue * pQue, const char *data, + unsigned int uiDataLen, unsigned int uiFLow) +{ + RMB_CHECK_POINT_NULL (pQue, "StRmbQueue:pQue"); + RMB_CHECK_POINT_NULL (data, "StRmbQueue:data"); + + unsigned int uiHead = *pQue->pHead; + unsigned int uiTail = *pQue->pTail; + unsigned int uiFreeLen = + (uiHead > + uiTail) ? (uiHead - uiTail) : (uiHead + pQue->uiBlockSize - uiTail); + unsigned int uiTailLen = pQue->uiBlockSize - uiTail; + char *pBlock = pQue->pBlock; + + char sHead[C_RMB_MQ_PKG_HEAD_SIZE] = { 0 }; + unsigned int uiTotalLen = uiDataLen + C_RMB_MQ_PKG_HEAD_SIZE; + + //1.if no enough space + if (uiFreeLen <= uiTotalLen) + { + return -2; + } + + memcpy (sHead, &uiTotalLen, sizeof (unsigned int)); + memcpy (sHead + sizeof (unsigned int), &uiFLow, sizeof (unsigned int)); + + //2.if tail space > 8+len + //copy 8 byte, copy data + if (uiTailLen >= uiTotalLen) + { + memcpy (pBlock + uiTail, sHead, C_RMB_MQ_PKG_HEAD_SIZE); + memcpy (pBlock + uiTail + C_RMB_MQ_PKG_HEAD_SIZE, data, uiDataLen); + //update tail + *pQue->pTail += (uiDataLen + C_RMB_MQ_PKG_HEAD_SIZE); + } + //3.if tail space > 8 && < 8+len + else if (uiTailLen >= C_RMB_MQ_PKG_HEAD_SIZE + && uiTailLen < C_RMB_MQ_PKG_HEAD_SIZE + uiDataLen) + { + // copy 8 byte + memcpy (pBlock + uiTail, sHead, C_RMB_MQ_PKG_HEAD_SIZE); + + // copy firstlen + unsigned int uiFirstLen = uiTailLen - C_RMB_MQ_PKG_HEAD_SIZE; + memcpy (pBlock + uiTail + C_RMB_MQ_PKG_HEAD_SIZE, data, uiFirstLen); + + // copy secondlen + unsigned int uiSecondLen = uiDataLen - uiFirstLen; + memcpy (pBlock, data + uiFirstLen, uiSecondLen); + + //update tail + unsigned int tail = + *pQue->pTail + uiDataLen + C_RMB_MQ_PKG_HEAD_SIZE - pQue->uiBlockSize; + *pQue->pTail = tail; + } + //4.if tail space < 8 + else + { + //copy tail byte + memcpy (pBlock + uiTail, sHead, uiTailLen); + + //copy 8-tail byte + unsigned int uiSecondLen = C_RMB_MQ_PKG_HEAD_SIZE - uiTailLen; + memcpy (pBlock, sHead + uiTailLen, uiSecondLen); + + //copy data + memcpy (pBlock + uiSecondLen, data, uiDataLen); + + //update tail + *pQue->pTail = uiSecondLen + uiDataLen; + } + + return 0; +} + +int rmb_queue_dequeue (StRmbQueue * pQue, char *buf, unsigned int uiBufSize, + unsigned int *pDataLen, unsigned int *pFlowId) +{ + RMB_CHECK_POINT_NULL (pQue, "rmb_queue_dequeue:pQue"); + RMB_CHECK_POINT_NULL (buf, "rmb_queue_dequeue:buf"); + RMB_CHECK_POINT_NULL (pDataLen, "rmb_queue_dequeue:pDataLen"); + + unsigned int uiHead = *pQue->pHead; + unsigned int uiTail = *pQue->pTail; + const char *pBlock = pQue->pBlock; + + if (uiHead == uiTail) + { + *pDataLen = 0; + return 0; + } + unsigned int uiUsedLen = + uiTail > uiHead ? uiTail - uiHead : uiTail + pQue->uiBlockSize - uiHead; + char sHead[C_RMB_MQ_PKG_HEAD_SIZE]; + + //1.get head + if (uiHead + C_RMB_MQ_PKG_HEAD_SIZE > pQue->uiBlockSize) + { + unsigned int uiFirstSize = pQue->uiBlockSize - uiHead; + unsigned int uiSecondSize = C_RMB_MQ_PKG_HEAD_SIZE - uiFirstSize; + memcpy (sHead, pBlock + uiHead, uiFirstSize); + memcpy (sHead + uiFirstSize, pBlock, uiSecondSize); + uiHead = uiSecondSize; + } + else + { + memcpy (sHead, pBlock + uiHead, C_RMB_MQ_PKG_HEAD_SIZE); + uiHead += C_RMB_MQ_PKG_HEAD_SIZE; + } + + //2.get meta data len + unsigned int uiTotalLen = *((unsigned int *) sHead); + if (pFlowId) + { + *pFlowId = *((unsigned *) (sHead + sizeof (unsigned int))); + } + + if (uiTotalLen > uiUsedLen) + { + LOGRMB (RMB_LOG_ERROR, "dequeue error!uiTotallen=%u > usedLen=%u", + uiTotalLen, uiUsedLen); + return -1; + } + + *pDataLen = uiTotalLen - C_RMB_MQ_PKG_HEAD_SIZE; + if (*pDataLen > uiBufSize) + { + LOGRMB (RMB_LOG_ERROR, + "dequeue error!buffer size=%u is not enough,at least=%u!", + uiBufSize, *pDataLen); + return -1; + } + + //3.memcpy the meata data + if (uiHead + *pDataLen > pQue->uiBlockSize) + { + unsigned int uiFirstSize = pQue->uiBlockSize - uiHead; + unsigned int uiSecondSize = *pDataLen - uiFirstSize; + memcpy (buf, pBlock + uiHead, uiFirstSize); + memcpy (buf + uiFirstSize, pBlock, uiSecondSize); + //update the head + *pQue->pHead = uiSecondSize; + } + else + { + memcpy (buf, pBlock + uiHead, *pDataLen); + //update the head + *pQue->pHead = uiHead + *pDataLen; + } + + return 0; +} + +int rmb_queue_try_dequeue (StRmbQueue * pQue, char *buf, + unsigned int uiBufSize, unsigned int *pDataLen, + unsigned int *pFlowId) +{ + return rmb_queue_dequeue (pQue, buf, uiBufSize, pDataLen, pFlowId); +} + +int rmb_queue_get_stat (StRmbQueue * pQue) +{ + unsigned int uiHead = *pQue->pHead; + unsigned int uiTail = *pQue->pTail; + unsigned int uiFreeLen = + uiHead > uiTail ? uiHead - uiTail : uiHead + pQue->uiBlockSize - uiTail; + unsigned int uiUsedLen = + uiTail > uiHead ? uiTail - uiHead : uiTail + pQue->uiBlockSize - uiHead; + LOGRMB (RMB_LOG_ERROR, "queue Stat:[head=%u,tail=%u,freeLen=%u,usedLen=%u]", + uiHead, uiTail, uiFreeLen, uiUsedLen); + return 0; +} + +//*****************************for fifo**************************************** +//fifo init +//return -1 exist error +int rmb_fifo_init (StRmbFifo * pFifo, const char *strPath) +{ + errno = 0; + int mode = 0666 | O_NONBLOCK | O_NDELAY; + if ((mkfifo (strPath, mode)) < 0) + { + if (errno != EEXIST) + { + LOGRMB (RMB_LOG_ERROR, "fifo strPath=%s has exist", strPath); + return -1; + } + } + + if (pFifo->iFd != -1 && pFifo->iFd != 0) + { + close (pFifo->iFd); + pFifo->iFd = -1; + } + + if ((pFifo->iFd = open (strPath, O_RDWR)) < 0) + { + return -2; + } + if (pFifo->iFd > 1024) + { + close (pFifo->iFd); + return -3; + } + + int val = fcntl (pFifo->iFd, F_GETFL, 0); + + if (val == -1) + { + return -4; + } + + if (val & O_NONBLOCK) + { + return 0; + } + + int iRet = fcntl (pFifo->iFd, F_SETFL, val | O_NONBLOCK | O_NDELAY); + if (iRet < 0) + { + return -5; + } + return 0; +} + +//notify +int rmb_fifo_send (StRmbFifo * pFifo) +{ + int iRet = write (pFifo->iFd, "\0", 1); + //LOGRMB(RMB_LOG_DEBUG, "rmb_fifo_send succ!iRet=%d, fd=%d", iRet, pFifo->iFd); + if (iRet != 0) + { + //return -1; + } + return 0; +} + +//clear notify +int rmb_fifo_clear_flag (StRmbFifo * pFifo) +{ + static char buffer[1]; + read (pFifo->iFd, buffer, 1); + //LOGRMB(RMB_LOG_DEBUG, "rmb_fifo_clear_flag succ!fd=%d", pFifo->iFd); + return 0; +} + +//*****************************for pipe**************************************** +//pipe init +//return -1 exist error +int rmb_pipe_init (StRmbPipe * pPipe) +{ + RMB_CHECK_POINT_NULL (pPipe, "rmb_pipe_init:pPipe"); + + if (pipe (pPipe->fd) < 0) + { + LOGRMB (RMB_LOG_ERROR, "pipe failed\n"); + return -1; + } + + int val = fcntl (pPipe->fd[0], F_GETFL, 0); + if (val == -1) + { + LOGRMB (RMB_LOG_ERROR, "fcntl get fd[0] failed\n"); + return -2; + } + + int iRet = fcntl (pPipe->fd[0], F_SETFL, val | O_NONBLOCK | O_NDELAY); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "fcntl set fd[0] failed\n"); + return -3; + } + + val = fcntl (pPipe->fd[1], F_GETFL, 0); + if (val == -1) + { + LOGRMB (RMB_LOG_ERROR, "fcntl get fd[1] failed\n"); + return -2; + } + + iRet = fcntl (pPipe->fd[1], F_SETFL, val | O_NONBLOCK | O_NDELAY); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "fcntl set fd[1] failed\n"); + return -3; + } + + pPipe->r_fd = pPipe->fd[0]; + pPipe->w_fd = pPipe->fd[1]; + + return 0; +} + +//notify +int rmb_pipe_send (StRmbPipe * pPipe) +{ + RMB_CHECK_POINT_NULL (pPipe, "rmb_pipe_send:pPipe"); + + write (pPipe->w_fd, "\0", 1); + + return 0; +} + +//clear notify +int rmb_pipe_clear_flag (StRmbPipe * pPipe) +{ + RMB_CHECK_POINT_NULL (pPipe, "rmb_pipe_send:pPipe"); + + static char buffer[1]; + read (pPipe->r_fd, buffer, 1); + + return 0; +} + +//******************************for rmb mq notify******************************* +int rmb_notify_init (StRmbMqFifoNotify * pMqNotify) +{ + memset ((char *) pMqNotify, 0, sizeof (StRmbMqFifoNotify)); + if (pMqNotify->pBuf == NULL) + { + pMqNotify->pBuf = (char *) calloc (MAX_MQ_PKG_SIZE, sizeof (char)); + if (pMqNotify->pBuf == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_init error!calloc buf failed!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return rmb_errno; + } + } + + //epoll init + pMqNotify->iEpollFd = epoll_create (MAX_MQ_NUMS); + if (pMqNotify->iEpollFd < 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_init error!epoll_create failed!"); + rmb_errno = RMB_ERROR_INIT_EPOLL_FAIL; + return rmb_errno; + } + return 0; +} + +//notify add +int rmb_notify_add (StRmbMqFifoNotify * pMqNotify, StRmbMq * mq, + StRmbFifo * fifo, const enum RmbMqIndex iMsgType, + rmb_callback_func func, void *func_argv) +{ + if (pMqNotify->iMqNum >= MAX_MQ_NUMS) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_add error!mqCurNum=%d,maxNum=%d", + pMqNotify->iMqNum, MAX_MQ_NUMS); + rmb_errno = RMB_ERROR_MQ_NUMS_LIMIT; + return -1; + } + + if (pMqNotify->mqIndex[(int) iMsgType] != NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_add error!type:%d has add!!!", + (int) iMsgType); + return -1; + } + + pMqNotify->vecMqInfo[pMqNotify->iMqNum].mq = mq; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].fifo = fifo; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].que = NULL; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].pipe = NULL; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].func = func; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].args = func_argv; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].iMsgType = iMsgType; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].iIndex = pMqNotify->iMqNum; + //add init mutex + pthread_mutex_init (&(pMqNotify->vecMqInfo[pMqNotify->iMqNum].queMutex), + NULL); + pMqNotify->mqIndex[(int) iMsgType] = + &(pMqNotify->vecMqInfo[pMqNotify->iMqNum]); + + pMqNotify->vecMqInfo[pMqNotify->iMqNum].iMergeNotifyFLag = 1; + if (func == NULL) + { + pMqNotify->vecMqInfo[pMqNotify->iMqNum].iMergeNotifyFLag = 0; + } + + //for select + FD_SET (fifo->iFd, &pMqNotify->readFd); + if (fifo->iFd >= pMqNotify->iMaxFd) + { + pMqNotify->iMaxFd = fifo->iFd + 1; + } + + //for epoll + struct epoll_event ev; + ev.events = EPOLLIN | EPOLLERR; + ev.data.fd = fifo->iFd; + ev.data.u32 = pMqNotify->iMqNum; + epoll_ctl (pMqNotify->iEpollFd, EPOLL_CTL_ADD, fifo->iFd, &ev); + pMqNotify->vecMqInfo[pMqNotify->iMqNum].active = 0; + + pMqNotify->iMqNum += 1; + return 0; +} + +int rmb_wemq_notify_add (StRmbMqFifoNotify * pMqNotify, StRmbQueue * que, + StRmbPipe * pipe, const enum RmbMqIndex iMsgType, + rmb_callback_func func, void *func_argv) +{ + if (pMqNotify->iMqNum >= MAX_MQ_NUMS) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_add error!mqCurNum=%d,maxNum=%d", + pMqNotify->iMqNum, MAX_MQ_NUMS); + rmb_errno = RMB_ERROR_MQ_NUMS_LIMIT; + return -1; + } + pMqNotify->vecMqInfo[pMqNotify->iMqNum].mq = NULL; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].fifo = NULL; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].que = que; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].pipe = pipe; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].func = func; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].args = func_argv; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].iMsgType = iMsgType; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].iIndex = pMqNotify->iMqNum; + pMqNotify->mqIndex[(int) iMsgType] = + &(pMqNotify->vecMqInfo[pMqNotify->iMqNum]); + + pMqNotify->vecMqInfo[pMqNotify->iMqNum].iMergeNotifyFLag = 1; + if (func == NULL) + { + pMqNotify->vecMqInfo[pMqNotify->iMqNum].iMergeNotifyFLag = 0; + } + + //for select + FD_SET (pipe->r_fd, &pMqNotify->readFd); + if (pipe->r_fd >= pMqNotify->iMaxFd) + { + pMqNotify->iMaxFd = pipe->r_fd + 1; + } + + //for epoll + struct epoll_event ev; + ev.events = EPOLLIN | EPOLLERR; + ev.data.fd = pipe->r_fd; + ev.data.u32 = pMqNotify->iMqNum; + epoll_ctl (pMqNotify->iEpollFd, EPOLL_CTL_ADD, pipe->r_fd, &ev); + pMqNotify->vecMqInfo[pMqNotify->iMqNum].active = 0; + + pMqNotify->iMqNum += 1; + return 0; +} + +int rmb_notify_enqueue_by_type_for_wemq (StRmbMqFifoNotify * pMqNotify, + const enum RmbMqIndex uiMsgType, + const unsigned int uiCurTime, + const char *data, + unsigned int uiDataLen) +{ + StMqInfo *pMqInfo = pMqNotify->mqIndex[(int) uiMsgType]; + if (pMqInfo == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_enqueue_for_wemq error!pMqInfo is NULL"); + return -1; + } + + return rmb_notify_enqueue_for_wemq (uiCurTime, pMqInfo, data, uiDataLen); +} + +int rmb_notify_enqueue_for_wemq (const unsigned int uiCurTime, + StMqInfo * pMqInfo, const char *data, + unsigned int uiDataLen) +{ + if (pMqInfo == NULL || pMqInfo->que == NULL || pMqInfo->pipe == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_enqueue_for_wemq error!pMqInfo==NULL || pMqInfo->que==NULL || pMqInfo->pipe==NULL"); + return -1; + } + + int iRet = + rmb_queue_enqueue (pMqInfo->que, data, uiDataLen, pMqInfo->iMsgType); + if (iRet == -2) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_enqueue_for_wemq failed!queue full!"); + rmb_errno = RMB_ERROR_ENQUEUE_MQ_FAIL; + return -2; + } + else if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_enqueue_for_wemq failed!iRet=%d", + iRet); + return -3; + } + if (pMqInfo->iMergeNotifyFLag == 1) + { + if (uiCurTime >= + pMqInfo->uiLastCheckTime + pRmbStConfig->iNotifyCheckSpan) + { + pMqInfo->uiLastCheckTime = uiCurTime; + pMqInfo->iNotifyFactor = rmb_notify_get_fator (pMqInfo->iCount); + pMqInfo->iCount = 0; + } + else + { + pMqInfo->iCount++; + } + if (pMqInfo->iCount % pMqInfo->iNotifyFactor == 0) + { + iRet = rmb_pipe_send (pMqInfo->pipe); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_enqueue failed!rmb_pipe_send return iRet=%d", + iRet); + rmb_errno = RMB_ERROR_SEND_FIFO_NOTIFY_ERROR; + return -4; + } + } + } + else + { + iRet = rmb_pipe_send (pMqInfo->pipe); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_enqueue failed!rmb_pipe_send return iRet=%d", iRet); + rmb_errno = RMB_ERROR_SEND_FIFO_NOTIFY_ERROR; + return -5; + } + } + + return 0; +} + +//enqueue +int rmb_notify_enqueue_by_type (StRmbMqFifoNotify * pMqNotify, + const enum RmbMqIndex uiMsgType, + const unsigned int uiCurTime, + const char *data, unsigned int uiDataLen) +{ + StMqInfo *pMqInfo = pMqNotify->mqIndex[(int) uiMsgType]; + if (pMqInfo == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_enqueue error!pMqInfo == NULL"); + return -1; + } + return rmb_notify_enqueue (uiCurTime, pMqInfo, data, uiDataLen); +} + +//enqueue +//-1:error argv +//-2:not enough space +//-3:enquque error +//-4:notify send failed +int rmb_notify_enqueue (const unsigned int uiCurTime, StMqInfo * pMqInfo, + const char *data, unsigned int uiDataLen) +{ +// if (pMqInfo->iMsgType >= wemq_req_mq_index) { +// return rmb_notify_enqueue_for_wemq(uiCurTime, pMqInfo, data, uiDataLen); +// } + + pthread_mutex_lock (&pMqInfo->queMutex); + + //StMqInfo *pMqInfo = &(pMqNotify->vecMqInfo[(int)iOffset]); + if (pMqInfo->mq == NULL || pMqInfo->fifo == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_enqueue error!pMqInfo->mq == NULL || pMqInfo->fifo == NULL"); + rmb_errno = RMB_ERROR_ARGV_NULL; + pthread_mutex_unlock (&pMqInfo->queMutex); + return -1; + } + + int iRet = rmb_mq_enqueue (pMqInfo->mq, data, uiDataLen, pMqInfo->iMsgType); + if (iRet == -2) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_enqueue error!queue full!"); + rmb_errno = RMB_ERROR_ENQUEUE_MQ_FAIL; + pthread_mutex_unlock (&pMqInfo->queMutex); + return -2; + } + else if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_enqueue error!rmb_mq_enqueue iRet=%d", + iRet); + rmb_errno = RMB_ERROR_ENQUEUE_MQ_FAIL; + pthread_mutex_unlock (&pMqInfo->queMutex); + return -3; + } + if (pMqInfo->iMergeNotifyFLag == 1) + { + if (uiCurTime >= + pMqInfo->uiLastCheckTime + pRmbStConfig->iNotifyCheckSpan) + { + pMqInfo->uiLastCheckTime = uiCurTime; + pMqInfo->iNotifyFactor = rmb_notify_get_fator (pMqInfo->iCount); + pMqInfo->iCount = 0; + } + else + { + pMqInfo->iCount++; + } + if (pMqInfo->iCount % pMqInfo->iNotifyFactor == 0) + { + iRet = rmb_fifo_send (pMqInfo->fifo); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_enqueue error!rmb_fifo_send iRet=%d", iRet); + rmb_errno = RMB_ERROR_SEND_FIFO_NOTIFY_ERROR; + pthread_mutex_unlock (&pMqInfo->queMutex); + return -4; + } + } + } + else + { + iRet = rmb_fifo_send (pMqInfo->fifo); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_enqueue error!rmb_fifo_send iRet=%d", + iRet); + rmb_errno = RMB_ERROR_SEND_FIFO_NOTIFY_ERROR; + pthread_mutex_unlock (&pMqInfo->queMutex); + return -5; + } + } + pthread_mutex_unlock (&pMqInfo->queMutex); + return 0; +} + +int rmb_notify_dequeue_for_wemq (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen) +{ + if (pMqInfo->que == NULL || pMqInfo->pipe == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_dequeue_for_wemq error!pMqInfo->que == NULL || pMqInfo->pipe == NULL"); + return -1; + } + + int iRet = rmb_queue_dequeue (pMqInfo->que, buf, uiBufSize, pDataLen, NULL); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_queue_dequeue error!iRet=%d", iRet); + rmb_errno = RMB_ERROR_DEQUEUE_MQ_FAIL; + return -2; + } + + if (pMqInfo->iMergeNotifyFLag == 0) + { + iRet = rmb_pipe_clear_flag (pMqInfo->pipe); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_dequeue_for_wemq error!iRet=%d", + iRet); + rmb_errno = RMB_ERROR_DEQUEUE_MQ_FAIL; + return -2; + } + } + + return 0; +} + +//dequeue +int rmb_notify_dequeue (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, unsigned int *pDataLen) +{ +// if (pMqInfo->iMsgType >= wemq_req_mq_index) { +// return rmb_notify_dequeue_for_wemq(pMqInfo, buf, uiBufSize, pDataLen); +// } + + pthread_mutex_lock (&pMqInfo->queMutex); + //StMqInfo *pMqInfo = &(pMqNotify->vecMqInfo[(int)iOffset]); + if (pMqInfo->mq == NULL || pMqInfo->fifo == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_dequeue error!pMqInfo->mq == NULL || pMqInfo->fifo == NULL"); + rmb_errno = RMB_ERROR_ARGV_NULL; + pthread_mutex_unlock (&pMqInfo->queMutex); + return -1; + } + + int iRet = rmb_mq_dequeue (pMqInfo->mq, buf, uiBufSize, pDataLen, NULL); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_dequeue error!rmb_mq_dequeue iRet=%d", + iRet); + rmb_errno = RMB_ERROR_DEQUEUE_MQ_FAIL; + pthread_mutex_unlock (&pMqInfo->queMutex); + return -2; + } + if (pMqInfo->iMergeNotifyFLag == 0) + { + iRet = rmb_fifo_clear_flag (pMqInfo->fifo); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_dequeue error!rmb_fifo_clear_flag iRet=%d", iRet); + //return -3; + //return 0; + } + } + pthread_mutex_unlock (&pMqInfo->queMutex); + return 0; +} + +int rmb_notify_try_dequeue_for_wemq (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen) +{ + if (pMqInfo == NULL || pMqInfo->que == NULL || pMqInfo->pipe == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_try_dequeue_for_wemq failed!pMqInfo==NULL or pMqInfo->que==NULL || pMqInfo->pipe==NULL"); + return -1; + } + + int iRet = + rmb_queue_try_dequeue (pMqInfo->que, buf, uiBufSize, pDataLen, NULL); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_queue_try_dequeue failed!iRet=%d", iRet); + rmb_errno = RMB_ERROR_DEQUEUE_MQ_FAIL; + return -2; + } + + if (*pDataLen == 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_try_dequeue_for_wemq failed!queue is empty"); + rmb_errno = RMB_ERROR_DEQUEUE_MQ_EMPTY; + return -3; + } + + return 0; +} + +//try dequeue +int rmb_notify_try_dequeue (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen) +{ +// if (pMqInfo->iMsgType >= wemq_req_mq_index) { +// return rmb_notify_try_dequeue_for_wemq(pMqInfo, buf, uiBufSize, pDataLen); +// } + //StMqInfo *pMqInfo = &(pMqNotify->vecMqInfo[(int)iOffset]); + if (pMqInfo->mq == NULL || pMqInfo->fifo == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_dequeue error!pMqInfo->mq == NULL || pMqInfo->fifo == NULL"); + rmb_errno = RMB_ERROR_ARGV_NULL; + return -1; + } + + pthread_mutex_lock (&pMqInfo->queMutex); + int iRet = rmb_mq_try_dequeue (pMqInfo->mq, buf, uiBufSize, pDataLen, NULL); + pthread_mutex_unlock (&pMqInfo->queMutex); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_dequeue error!rmb_mq_dequeue iRet=%d", + iRet); + rmb_errno = RMB_ERROR_DEQUEUE_MQ_FAIL; + return -2; + } + if (*pDataLen == 0) + { + rmb_errno = RMB_ERROR_DEQUEUE_MQ_EMPTY; + return -3; + } +// iRet = rmb_fifo_clear_flag(pMqInfo->fifo); +// if (iRet != 0) +// { +// printf("rmb_notify_dequeue error!rmb_fifo_clear_flag iRet=%d", iRet); +// return -3; +// } + return 0; +} + +//**************select or epoll************************* +//select fifo fd +//return >0 the mq index which has msg +// =0 all mq has no msg +// <0 all mq has no msg +static int rmb_notify_select (StRmbMqFifoNotify * pMqNotify, + unsigned int uiSec, unsigned int uiUsec) +{ + int i = 0; + int j = 0; + errno = 0; + StMqInfo *pMqInfo; + FD_ZERO (&(pMqNotify->tmpReadFd)); + pMqNotify->tmpReadFd = pMqNotify->readFd; + pMqNotify->tv.tv_sec = uiSec; + pMqNotify->tv.tv_usec = uiUsec; + int iRet = + select (pMqNotify->iMaxFd, &(pMqNotify->tmpReadFd), NULL, NULL, + &(pMqNotify->tv)); + if (iRet > 0) + { + for (i = 0; i < pMqNotify->iMqNum; i++) + { + if (FD_ISSET + (pMqNotify->vecMqInfo[i].fifo->iFd, &(pMqNotify->tmpReadFd))) + { + pMqInfo = &(pMqNotify->vecMqInfo[i]); + rmb_fifo_clear_flag (pMqInfo->fifo); + + for (j = 0; j < pRmbStConfig->iEveryTimeProcessNum; i++) + { + iRet = + rmb_notify_dequeue (&(pMqNotify->vecMqInfo[i]), pMqNotify->pBuf, + MAX_MQ_PKG_SIZE, &(pMqNotify->uiBufLen)); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_dequeue error!iRet=%d", iRet); + break;; + } + if (pMqNotify->uiBufLen == 0) + { + break; + } + + pMqNotify->pBuf[pMqNotify->uiBufLen] = '\0'; + //shift_buf_2_msg((StRmbMsg *)pMqInfo->pReceiveMsg, pMqNotify->pBuf, pMqNotify->uiBufLen); + pMqInfo->func (pMqNotify->pBuf, pMqNotify->uiBufLen, pMqInfo->args); + } + } + } + } + else + { + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "select error!iRet=%d", iRet); + } + for (i = 0; i < pMqNotify->iMqNum; i++) + { + for (j = 0; j < pRmbStConfig->iEveryTimeProcessNum; i++) + { + iRet = + rmb_notify_dequeue (&(pMqNotify->vecMqInfo[i]), pMqNotify->pBuf, + MAX_MQ_PKG_SIZE, &(pMqNotify->uiBufLen)); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_dequeue error!iRet=%d", iRet); + break;; + } + if (pMqNotify->uiBufLen == 0) + { + break; + } + + pMqNotify->pBuf[pMqNotify->uiBufLen] = '\0'; + //shift_buf_2_msg((StRmbMsg *)pMqInfo->pReceiveMsg, pMqNotify->pBuf, pMqNotify->uiBufLen); + pMqInfo = &pMqNotify->vecMqInfo[i]; + pMqInfo->func (pMqNotify->pBuf, pMqNotify->uiBufLen, pMqInfo->args); + + LOGRMB (RMB_LOG_ERROR, "try_dequee succ,j=%d!", j); + //rmb_mq_get_stat(pMqNotify->vecMqInfo[i].mq); + } + } + } + return 0; +} + +//***********************for epoll************************* +//epoll +int rmb_notify_epoll (StRmbSub * pStRmbSub, int iTimeout) +{ + StRmbMqFifoNotify *pMqNotify = &pStRmbSub->pStContext->fifoMq; + static struct epoll_event epv[MAX_MQ_NUMS]; + int iEventNum = + epoll_wait (pMqNotify->iEpollFd, epv, MAX_MQ_NUMS, iTimeout); + int iRet = 0; + StMqInfo *pMqInfo; + int i = 0; + int j = 0; + StRmbMsg *pReceiveMsg = rmb_msg_malloc (); + for (; i < iEventNum; ++i) + { + LOGRMB (RMB_LOG_DEBUG, "rmb_notify_epoll succ!num=%d,i=%d,eventNum=%d", + epv[i].data.u32, i, iEventNum); + pMqInfo = &(pMqNotify->vecMqInfo[epv[i].data.u32]); + + rmb_fifo_clear_flag (pMqInfo->fifo); + + for (j = 0; j < pRmbStConfig->iEveryTimeProcessNum; j++) + { + iRet = + rmb_notify_dequeue (pMqInfo, pMqNotify->pBuf, MAX_MQ_PKG_SIZE, + &(pMqNotify->uiBufLen)); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_dequeue error!iRet=%d", iRet); + break; + } + if (pMqNotify->uiBufLen == 0) + { + break; + } + + pMqNotify->pBuf[pMqNotify->uiBufLen] = '\0'; + //rmb_send_log_for_func(pMqNotify->pBuf, pMqNotify->uiBufLen, RMB_CONTEXT_TYPE_SUB, pMqInfo->iMsgType); + shift_buf_2_msg (pReceiveMsg, pMqNotify->pBuf, pMqNotify->uiBufLen); + //do not filter + if (rmb_epoll_msg_filter (pStRmbSub, pReceiveMsg) == 0) + { + pRmbStConfig->mqIsEmpty = MQ_IS_NOT_EMPTY; + pMqInfo->func (pMqNotify->pBuf, pMqNotify->uiBufLen, pMqInfo->args); + wemq_sub_ack_msg (pStRmbSub, pReceiveMsg); + if (rmb_sub_check_mq_is_null (pStRmbSub) == 0) + { + pRmbStConfig->mqIsEmpty = MQ_IS_EMPTY; + } + pMqInfo->active = 1; + } + + } + } + + //for sure write fd is ok! + for (i = 0; i < pMqNotify->iMqNum; ++i) + { + pMqInfo = &pMqNotify->vecMqInfo[i]; + if (pMqInfo->active == 0) + { + for (j = 0; j < pRmbStConfig->iEveryTimeProcessNum; j++) + { + iRet = + rmb_notify_dequeue (pMqInfo, pMqNotify->pBuf, MAX_MQ_PKG_SIZE, + &(pMqNotify->uiBufLen)); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_dequeue error!iRet=%d", iRet); + break; + } + if (pMqNotify->uiBufLen == 0) + { + break; + } + + pMqNotify->pBuf[pMqNotify->uiBufLen] = '\0'; + //rmb_send_log_for_func(pMqNotify->pBuf, pMqNotify->uiBufLen, RMB_CONTEXT_TYPE_SUB, pMqInfo->iMsgType); + shift_buf_2_msg (pReceiveMsg, pMqNotify->pBuf, pMqNotify->uiBufLen); + if (rmb_epoll_msg_filter (pStRmbSub, pReceiveMsg) == 0) + { + pRmbStConfig->mqIsEmpty = MQ_IS_NOT_EMPTY; + pMqInfo->func (pMqNotify->pBuf, pMqNotify->uiBufLen, pMqInfo->args); + wemq_sub_ack_msg (pStRmbSub, pReceiveMsg); + if (rmb_sub_check_mq_is_null (pStRmbSub) == 0) + { + pRmbStConfig->mqIsEmpty = MQ_IS_EMPTY; + } + } + } + } + else + { + pMqInfo->active = 0; + } + } + rmb_msg_free (pReceiveMsg); + + return 0; +} + +int rmb_epoll_msg_filter (StRmbSub * pStRmbSub, StRmbMsg * pReceiveMsg) +{ + RMB_CHECK_POINT_NULL (pStRmbSub, "pStRmbSub"); + RMB_CHECK_POINT_NULL (pReceiveMsg, "pReceiveMsg"); + //rr异步的包,直接返回 + if (pReceiveMsg->cPkgType == RR_TOPIC_PKG) + { + return 0; + } + + //监听模式下调用do_receive,过滤 + int iFlag = 1; + int i; + st_rmb_queue_info *p = pStRmbSub->pQueueInfo; + for (i = 0; i < pStRmbSub->iQueueNum; i++) + { + if (strcmp (pReceiveMsg->strServiceId, p->cServiceId) == 0) + { + iFlag = 0; + break; + } + p += 1; + } + + if (iFlag != 0) + { + LOGRMB (RMB_LOG_WARN, "pReceiveMsg bizseqno=%s not at listen topic!", + pReceiveMsg->sysHeader.cBizSeqNo); + return -2; + } + return 0; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_msg.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_msg.c new file mode 100644 index 0000000000..47c0c61c6f --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_msg.c @@ -0,0 +1,1686 @@ +// 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. + +#include "uuid/uuid.h" +#include "common.h" +#include "rmb_msg.h" +#include "string.h" +#include "time.h" +#include "rmb_errno.h" + +static const int i1KB = 1 << 10; +static const int i2KB = 1 << 11; +static const int i4KB = 1 << 12; +static const int i8KB = 1 << 13; +static const int i16KB = 1 << 14; +static const int i32KB = 1 << 15; +static const int i64KB = 1 << 16; +static const int i128KB = 1 << 17; +static const int i256KB = 1 << 18; +static const int i512KB = 1 << 19; +static const int i1024KB = 1 << 20; +static const int i2048KB = 1 << 21; + +//private func +const static char *strLogicType[] = + { "null", "req_in", "rsp_in", "event_in", "req_out", "rsp_out", "event_out", +"null" }; + +int rmb_msg_clear (StRmbMsg * pStMsg) +{ + RMB_CHECK_POINT_NULL (pStMsg, "pStMsg"); + + //pStMsg->cPkgType = 0; + //pStMsg->cLogicType = 0; + memset (&(pStMsg->sysHeader), 0, sizeof (StSystemHeader)); + pStMsg->replyTo.cDestName[0] = '\0'; + pStMsg->dest.cDestName[0] = '\0'; + pStMsg->iCorrLen = 0; + pStMsg->iContentLen = 0; + pStMsg->iAppHeaderLen = 0; + pStMsg->ulMsgId = 0; + pStMsg->ulMsgLiveTime = 0; + //add in 2016-09-26 + pStMsg->flag = 0; + pStMsg->isDyedMsg[0] = "\0"; + return 0; +} + +int rmb_msg_init (StRmbMsg * pRmbMsg, StRmbConfig * pConfig, + enum RMB_API_YPE type) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + + pRmbMsg->replyTo.cDestName[0] = '\0'; + char cUniqueId[100] = { 0 }; + char cUniqueIdEx[50] = { 0 }; + rmb_msg_random_uuid (cUniqueIdEx, sizeof (cUniqueIdEx)); + snprintf (cUniqueId, sizeof (cUniqueId), "c/%s", cUniqueIdEx); +// pRmbMsg->cApiType = C_TYPE; + pRmbMsg->cApiType = type; + pRmbMsg->cLogicType = 0; + pRmbMsg->sysHeader.iReceiveMode = 1; + RMB_MEMCPY (pRmbMsg->sysHeader.cConsumerSysId, pConfig->cConsumerSysId); + if (pRmbMsg->sysHeader.iSetSysVersionFlag != 1) + { //没有被用户设置过 + RMB_MEMCPY (pRmbMsg->sysHeader.cConsumerSysVersion, + pConfig->cConsumerSysVersion); + } + RMB_MEMCPY (pRmbMsg->sysHeader.cConsumerSvrId, pConfig->cHostIp); + RMB_MEMCPY (pRmbMsg->sysHeader.cOrgSvrId, pConfig->cHostIp); + RMB_MEMCPY (pRmbMsg->sysHeader.cUniqueId, cUniqueId); + RMB_MEMCPY (pRmbMsg->sysHeader.cConsumerDcn, pConfig->cConsumerDcn); + RMB_MEMCPY (pRmbMsg->sysHeader.cOrgId, pConfig->strOrgId); + RMB_MEMCPY (pRmbMsg->sysHeader.cRmbVersion, RMBVERSION); + + char cAppHeaderClassName[50] = "cn.webank.rmb.message.AppHeader"; + RMB_MEMCPY (pRmbMsg->sysHeader.cAppHeaderClass, cAppHeaderClassName); + + //RMB_MEMSET(pRmbMsg->strScenarioId); + //RMB_MEMSET(pRmbMsg->strServiceId); + //RMB_MEMSET(pRmbMsg->strTargetDcn); + //pRmbMsg->iEventOrService = 0; + + GetRmbNowLongTime (); + pRmbMsg->sysHeader.ulTranTimeStamp = pRmbStConfig->ulNowTtime; + pRmbMsg->sysHeader.ulMessageDate = pRmbStConfig->ulNowTtime; + + //for wemq + + return 0; +} + +//you must fill in under fields +int rmb_msg_set_bizSeqNo (StRmbMsg * pRmbMsg, const char *cBizSeqNo) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_CHECK_POINT_NULL (cBizSeqNo, "cBizSeqNo"); + RMB_LEN_CHECK (cBizSeqNo, 32); + + RMB_MEMCPY (pRmbMsg->sysHeader.cBizSeqNo, cBizSeqNo); + return 0; +} + +int rmb_msg_set_consumerSysVersion (StRmbMsg * pRmbMsg, + const char *cConsumerSysVersion) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_CHECK_POINT_NULL (cConsumerSysVersion, "cConsumerSysVersion"); + //RMB_LEN_CHECK(cBizSeqNo,32); + + RMB_MEMCPY (pRmbMsg->sysHeader.cConsumerSysVersion, cConsumerSysVersion); + pRmbMsg->sysHeader.iSetSysVersionFlag = 1; + return 0; +} + +int rmb_msg_set_dyedMsg (StRmbMsg * pRmbMsg, const char *sign) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_MEMCPY (pRmbMsg->isDyedMsg, sign); + return 0; +} + +int rmb_msg_set_consumerSeqNo (StRmbMsg * pRmbMsg, const char *cConsumerSeqNo) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_CHECK_POINT_NULL (cConsumerSeqNo, "cConsumerSeqNo"); + RMB_LEN_CHECK (cConsumerSeqNo, 32); + + RMB_MEMCPY (pRmbMsg->sysHeader.cConsumerSeqNo, cConsumerSeqNo); + return 0; +} + +int rmb_msg_set_orgSysId (StRmbMsg * pRmbMsg, const char *cOrgSysId) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_CHECK_POINT_NULL (cOrgSysId, "cOrgSysId"); + RMB_LEN_CHECK (cOrgSysId, 4) + RMB_MEMCPY (pRmbMsg->sysHeader.cOrgSysId, cOrgSysId); + return 0; +} + +//*********************** + +int rmb_msg_set_dest (StRmbMsg * pRmbMsg, int desType, const char *cTargetDcn, + int iServiceOrEven, const char *cServiceId, + const char *cScenario) +{ + return rmb_msg_set_dest_v2 (pRmbMsg, cTargetDcn, cServiceId, cScenario); + +} + +int rmb_msg_set_dest_v2 (StRmbMsg * pRmbMsg, const char *cTargetDcn, + const char *cServiceId, const char *cScenario) +{ + return rmb_msg_set_dest_v2_1 (pRmbMsg, cTargetDcn, cServiceId, cScenario, + (char *) NULL); +} + +int rmb_msg_set_dest_v2_1 (StRmbMsg * pRmbMsg, const char *cTargetDcn, + const char *cServiceId, const char *cScenario, + const char *cTargetOrgId) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + //RMB_CHECK_POINT_NULL(cTargetDcn, "cTargetDcn"); + RMB_CHECK_POINT_NULL (cServiceId, "cServiceId"); + RMB_CHECK_POINT_NULL (cScenario, "cScenario"); + + if (cTargetDcn == NULL || strlen (cTargetDcn) == 0) + { + pRmbMsg->strTargetDcn[0] = 0; + } + else + { + if (strlen (cTargetDcn) != DEFAULT_DCN_LENGTH) + { + LOGRMB (RMB_LOG_ERROR, "destination dcn must be 3 length!input=%lu", + strlen (cTargetDcn)); + rmb_errno = RMB_ERROR_ARGV_LEN_ERROR; + return -2; + } + strncpy (pRmbMsg->strTargetDcn, cTargetDcn, + sizeof (pRmbMsg->strTargetDcn) - 1); + } + + if (strlen (cServiceId) != DEFAULT_SERVICE_ID_LENGTH) + { + LOGRMB (RMB_LOG_ERROR, + "destination service_id must be 8 length!input=%lu", + strlen (cServiceId)); + rmb_errno = RMB_ERROR_ARGV_LEN_ERROR; + return -2; + } + if (strlen (cScenario) != DEFAULT_SCENE_ID_LENGTH) + { + LOGRMB (RMB_LOG_ERROR, "destination scene_id must be 2 length!input=%lu", + strlen (cScenario)); + rmb_errno = RMB_ERROR_ARGV_LEN_ERROR; + return -2; + } + + pRmbMsg->iEventOrService = + (*(cServiceId + 3) == '0') ? RMB_SERVICE_CALL : RMB_EVENT_CALL; + + strncpy (pRmbMsg->strServiceId, cServiceId, + sizeof (pRmbMsg->strServiceId) - 1); + strncpy (pRmbMsg->strScenarioId, cScenario, + sizeof (pRmbMsg->strScenarioId) - 1); + if (cTargetOrgId == NULL) + { + pRmbMsg->iFLagForOrgId = RMB_COMMIT_BY_API; + } + else + { + pRmbMsg->iFLagForOrgId = RMB_COMMIT_BY_OWN; + strncpy (pRmbMsg->strTargetOrgId, cTargetOrgId, + sizeof (pRmbMsg->strTargetOrgId) - 1); + } + //modify 2016-09-26 + //pRmbMsg->flag = pRmbMsg->flag & (1 << RMBMSG_DEST_HAS_SET); + pRmbMsg->flag = pRmbMsg->flag | (1 << RMBMSG_DEST_HAS_SET); + + return 0; +} + +//////////////////1.7.3 add ////////////////////////////////////////////////////// + +//get dest +int rmb_msg_get_dest (StRmbMsg * pRmbMsg, char *dest, unsigned int *uiLen) +{ + if (pRmbMsg == NULL || dest == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbMsg or dest is null"); + return -1; + } + + if (*uiLen < strlen (pRmbMsg->dest.cDestName)) + { + LOGRMB (RMB_LOG_ERROR, "dest is too small, len=%u, but msg_dest_len=%u\n", + *uiLen, strlen (pRmbMsg->dest.cDestName)); + return -2; + } + + memcpy (dest, pRmbMsg->dest.cDestName, strlen (pRmbMsg->dest.cDestName)); + *uiLen = strlen (pRmbMsg->dest.cDestName); + + return 0; +} + +const char *rmb_msg_get_dest_ptr (StRmbMsg * pRmbMsg) +{ + if (pRmbMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbMsg is null"); + return NULL; + } + + return pRmbMsg->dest.cDestName; +} + +//get cConsumerSysId +int rmb_msg_get_consumerSysId (StRmbMsg * pRmbMsg, char *cConsumerSysId, + unsigned int *uiLen) +{ + if (pRmbMsg == NULL || cConsumerSysId == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbMsg or cConsumerSysId is null"); + return -1; + } + + unsigned int uiConsumerLen = + (unsigned int) strlen (pRmbMsg->sysHeader.cConsumerSysId); + + if (*uiLen < uiConsumerLen) + { + LOGRMB (RMB_LOG_ERROR, + "rmb msg consumerSysId len=%u, but arg len=%u(too small)", + uiConsumerLen, *uiLen); + return -2; + } + + memcpy (cConsumerSysId, pRmbMsg->sysHeader.cConsumerSysId, uiConsumerLen); + *uiLen = uiConsumerLen; + + return 0; +} + +const char *rmb_msg_get_consumerSysId_ptr (StRmbMsg * pRmbMsg) +{ + if (pRmbMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbMsg is null"); + return NULL; + } + + return pRmbMsg->sysHeader.cConsumerSysId; +} + +//get cConsumerSvrId +int rmb_msg_get_consumerSvrId (StRmbMsg * pRmbMsg, char *cConsumerSvrId, + unsigned int *uiLen) +{ + if (pRmbMsg == NULL || cConsumerSvrId == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbMsg or cConsumerSvrId is null"); + return -1; + } + + unsigned int uiConsumerLen = + (unsigned int) strlen (pRmbMsg->sysHeader.cConsumerSvrId); + + if (*uiLen < uiConsumerLen) + { + LOGRMB (RMB_LOG_ERROR, + "rmb msg consumerSvrId len=%u, but arg len=%u(too small)", + uiConsumerLen, *uiLen); + return -2; + } + + memcpy (cConsumerSvrId, pRmbMsg->sysHeader.cConsumerSvrId, uiConsumerLen); + *uiLen = uiConsumerLen; + + return 0; +} + +const char *rmb_msg_get_consumerSvrId_ptr (StRmbMsg * pRmbMsg) +{ + if (pRmbMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbMsg is null"); + return NULL; + } + + return pRmbMsg->sysHeader.cConsumerSvrId; +} + +////////////////////////////////////////////////////////////////////////////// + +int rmb_check_msg_valid (StRmbMsg * pStMsg) +{ + //modify in 2016-09-26 + //if (pStMsg->flag | (1 << RMBMSG_DEST_HAS_SET == 0)) + if ((pStMsg->flag & (1 << RMBMSG_DEST_HAS_SET)) == 0) + { + LOGRMB (RMB_LOG_ERROR, "pStMsg=%s must be init first!", + rmb_msg_print (pStMsg)); + rmb_errno = RMB_ERROR_MSG_MISSING_PART; + return -1; + } + return 0; +} + +int rmb_msg_set_live_time (StRmbMsg * pRmbMsg, unsigned long ulLiveTime) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + if (ulLiveTime == 0) + { + LOGRMB (RMB_LOG_ERROR, "ttl time must gt 0"); + rmb_errno = RMB_ERROR_MSG_TTL_0; + return -2; + } + + pRmbMsg->ulMsgLiveTime = ulLiveTime; + return 0; +} + +int rmb_get_fit_size (const unsigned int uiLen, const unsigned int uiMaxLen) +{ +// if (uiLen >= uiMaxLen) + if (uiLen > uiMaxLen) + { + return -1; + } + unsigned int uiCount = 0; + unsigned int uiTmpLen = uiLen; + while ((uiTmpLen = uiTmpLen >> 1) != 0) + { + uiCount++; + } + uiCount++; + uiCount = (uiCount >= 10) ? uiCount : 10; + return (1 << uiCount) + 1; +} + +int rmb_msg_set_app_header (StRmbMsg * pRmbMsg, const char *appHeader, + unsigned int uiLen) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_CHECK_POINT_NULL (appHeader, "appHeader"); + +// if (uiLen >= MAX_APPHEADER_LENGTH) +// { +// LOGRMB(RMB_LOG_ERROR, "uiLen=%u too large!max_limit=%u", uiLen, MAX_APPHEADER_LENGTH); +// rmb_errno = RMB_ERROR_MSG_SET_APPHEADER_TOO_LARGE; +// return -2; +// } + if (pRmbMsg->cAppHeader == NULL || pRmbMsg->iMallocAppHeaderLength == 0) + { + pRmbMsg->cAppHeader = (char *) malloc (i1KB); + pRmbMsg->iMallocAppHeaderLength = i1KB; + } + if (uiLen >= pRmbMsg->iMallocAppHeaderLength) + { + int iFitSize = rmb_get_fit_size (uiLen, MAX_APPHEADER_LENGTH); + if (iFitSize < 0) + { + LOGRMB (RMB_LOG_ERROR, "uiLen=%u too large!max_limit=%u\n", uiLen, + MAX_APPHEADER_LENGTH); + rmb_errno = RMB_ERROR_BUF_NOT_ENOUGH; + return -2; + } + free (pRmbMsg->cAppHeader); + pRmbMsg->cAppHeader = NULL; + pRmbMsg->cAppHeader = (char *) malloc (iFitSize); + pRmbMsg->iMallocAppHeaderLength = iFitSize; + } + + memcpy (pRmbMsg->cAppHeader, appHeader, uiLen); + pRmbMsg->cAppHeader[uiLen] = '\0'; + pRmbMsg->iAppHeaderLen = (int) uiLen; + return 0; +} + +int rmb_msg_set_content (StRmbMsg * pRmbMsg, const char *content, + unsigned int uiLen) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_CHECK_POINT_NULL (content, "content"); + +// if (uiLen >= sizeof(pRmbMsg->cContent)) +// { +// LOGRMB(RMB_LOG_ERROR, "uiLen=%u too large!max_limit=%lu",uiLen, sizeof(pRmbMsg->cContent)); +// rmb_errno = RMB_ERROR_MSG_SET_CONTENT_TOO_LARGE; +// return -2; +// } + + if (pRmbMsg->cContent == NULL || pRmbMsg->iMallocContentLength == 0) + { + pRmbMsg->cContent = (char *) malloc (i1KB); + pRmbMsg->iMallocContentLength = i1KB; + } + if (uiLen >= pRmbMsg->iMallocContentLength) + { + int iFitSize = rmb_get_fit_size (uiLen, MAX_MSG_CONTENT_SIZE); + if (iFitSize < 0) + { + LOGRMB (RMB_LOG_ERROR, "uiLen=%u too large!max_limit=%u\n", uiLen, + MAX_MSG_CONTENT_SIZE); + rmb_errno = RMB_ERROR_BUF_NOT_ENOUGH; + return rmb_errno; + } + free (pRmbMsg->cContent); + pRmbMsg->cContent = NULL; + pRmbMsg->cContent = (char *) malloc (iFitSize); + pRmbMsg->iMallocContentLength = iFitSize; + } + + memcpy (pRmbMsg->cContent, content, uiLen); + pRmbMsg->cContent[uiLen] = '\0'; + pRmbMsg->iContentLen = (int) uiLen; + pRmbMsg->sysHeader.iContentLength = pRmbMsg->iContentLen; + return 0; +} + +/** + * get msg type + * 0: undefined type + * 1: request in queue + * 2: reply package in RR + * 3: broadcast + * see: C_RMB_PKG_TYPE + */ +int rmb_msg_get_msg_type (StRmbMsg * pRmbMsg) +{ + return (int) pRmbMsg->cPkgType; +} + +const char *rmb_msg_get_uniqueId_ptr (StRmbMsg * pRmbMsg) +{ + return pRmbMsg->sysHeader.cUniqueId; +} + +const char *rmb_msg_get_biz_seq_no_ptr (StRmbMsg * pRmbMsg) +{ + return pRmbMsg->sysHeader.cBizSeqNo; +} + +const char *rmb_msg_get_consumer_seq_no_ptr (StRmbMsg * pRmbMsg) +{ + return pRmbMsg->sysHeader.cConsumerSeqNo; +} + +const char *rmb_msg_get_consumer_dcn_ptr (StRmbMsg * pRmbMsg) +{ + return pRmbMsg->sysHeader.cConsumerDcn; +} + +const char *rmb_msg_get_org_sys_id_ptr (StRmbMsg * pRmbMsg) +{ + return pRmbMsg->sysHeader.cOrgSysId; +} + +const char *rmb_msg_get_org_id_ptr (StRmbMsg * pRmbMsg) +{ + return pRmbMsg->sysHeader.cOrgId; +} + +const char *rmb_msg_get_app_header_ptr (StRmbMsg * pRmbMsg, + unsigned int *pLen) +{ + if (pRmbMsg == NULL || pLen == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbMsg or pLen == NULL"); + } + + *pLen = pRmbMsg->iAppHeaderLen; + return pRmbMsg->cAppHeader; +} + +int rmb_msg_get_app_header (StRmbMsg * pRmbMsg, char *userHeader, + unsigned int *pLen) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_CHECK_POINT_NULL (userHeader, "userHeader"); + + if (pRmbMsg->iAppHeaderLen > *pLen) + { + LOGRMB (RMB_LOG_ERROR, " buffer len too small.uiLen=%u,buffSize=%u", + *pLen, pRmbMsg->iAppHeaderLen); + rmb_errno = RMB_ERROR_BUF_NOT_ENOUGH; + return rmb_errno; + } + memcpy (userHeader, pRmbMsg->cAppHeader, pRmbMsg->iAppHeaderLen); + *pLen = pRmbMsg->iAppHeaderLen; + return 0; +} + +const char *rmb_msg_get_content_ptr (StRmbMsg * pRmbMsg, unsigned int *pLen) +{ + if (pRmbMsg == NULL || pLen == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbMsg or pLen == NULL"); + } + + *pLen = pRmbMsg->iContentLen; + return pRmbMsg->cContent; +} + +int rmb_msg_get_content (StRmbMsg * pRmbMsg, char *content, + unsigned int *pLen) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_CHECK_POINT_NULL (content, "content"); + + if (pRmbMsg->iContentLen > *pLen) + { + LOGRMB (RMB_LOG_ERROR, + " content buffer len too small.uiLen=%u,buffSize=%u", *pLen, + pRmbMsg->iContentLen); + rmb_errno = RMB_ERROR_BUF_NOT_ENOUGH; + return rmb_errno; + } + memcpy (content, pRmbMsg->cContent, pRmbMsg->iContentLen); + *pLen = pRmbMsg->iContentLen; + return 0; +} + +int shift_buf_2_msg (StRmbMsg * pStMsg, const char *cBuf, unsigned int uiLen) +{ + //StRmbMsg msg; + const char *p = cBuf; + + unsigned int uiBufLen = + 3 * sizeof (char) + sizeof (pStMsg->sysHeader) + + 2 * sizeof (pStMsg->dest) + 2 * sizeof (unsigned long) + + 3 * sizeof (int) + sizeof (StFlow *) + sizeof (pStMsg->strTargetDcn) + + sizeof (pStMsg->strServiceId) + sizeof (pStMsg->strScenarioId) + + sizeof (int) + sizeof (int); + if (uiBufLen > uiLen) + { + rmb_errno = RMB_ERROR_BUF_2_MSG_FAIL; + return -1; + } + + //copy msg src + memcpy (&pStMsg->iMsgMode, p, sizeof (int)); + p += sizeof (int); + + //copy cPkgType + pStMsg->cPkgType = *p; + p += sizeof (char); + + //copy cLogicType + pStMsg->cLogicType = *p; + p += sizeof (char); + + //copy cApiType + pStMsg->cApiType = *p; + p += sizeof (char); + + //copy sysHeader + memcpy (&pStMsg->sysHeader, p, sizeof (pStMsg->sysHeader)); + p += sizeof (pStMsg->sysHeader); + + //copy dest + memcpy (&pStMsg->dest, p, sizeof (pStMsg->dest)); + p += sizeof (pStMsg->dest); + + //copy replyTo + memcpy (&pStMsg->replyTo, p, sizeof (pStMsg->replyTo)); + p += sizeof (pStMsg->replyTo); + + //copy msgid + memcpy (&pStMsg->ulMsgId, p, sizeof (unsigned long)); + p += sizeof (unsigned long); + + //copy msgLiveTime + memcpy (&pStMsg->ulMsgLiveTime, p, sizeof (unsigned long)); + p += sizeof (unsigned long); + + //copy AppHeader -- len + memcpy (&pStMsg->iAppHeaderLen, p, sizeof (int)); + p += sizeof (int); + + uiBufLen += pStMsg->iAppHeaderLen; + if (pStMsg->iAppHeaderLen >= pStMsg->iMallocAppHeaderLength) + { + int iFitSize = + rmb_get_fit_size (pStMsg->iAppHeaderLen, MAX_APPHEADER_LENGTH); + if (iFitSize < 0) + { + LOGRMB (RMB_LOG_ERROR, "appheader len=%u too large!max_limit=%u\n", + pStMsg->iAppHeaderLen, MAX_APPHEADER_LENGTH); + rmb_errno = RMB_ERROR_BUF_2_MSG_FAIL; + return rmb_errno; + } + free (pStMsg->cAppHeader); + pStMsg->cAppHeader = NULL; + pStMsg->cAppHeader = (char *) malloc (iFitSize); + pStMsg->iMallocAppHeaderLength = iFitSize; + } + if (uiBufLen > uiLen) + { + rmb_errno = RMB_ERROR_BUF_2_MSG_FAIL; + return -2; + } + + //copy AppHeader -- data + memcpy (pStMsg->cAppHeader, p, pStMsg->iAppHeaderLen); + pStMsg->cAppHeader[pStMsg->iAppHeaderLen] = 0; + p += pStMsg->iAppHeaderLen; + + //copy content + memcpy (&pStMsg->iContentLen, p, sizeof (int)); + p += sizeof (int); + + uiBufLen += pStMsg->iContentLen; + if (pStMsg->iContentLen >= pStMsg->iMallocContentLength) + { + int iFitSize = + rmb_get_fit_size (pStMsg->iContentLen, MAX_MSG_CONTENT_SIZE); + if (iFitSize < 0) + { + LOGRMB (RMB_LOG_ERROR, "content len=%u too large!max_limit=%u\n", uiLen, + MAX_MSG_CONTENT_SIZE); + rmb_errno = RMB_ERROR_BUF_2_MSG_FAIL; + return -3; + } + free (pStMsg->cContent); + pStMsg->cContent = NULL; + pStMsg->cContent = (char *) malloc (iFitSize); + pStMsg->iMallocContentLength = iFitSize; + } + + if (uiBufLen > uiLen) + { + rmb_errno = RMB_ERROR_BUF_2_MSG_FAIL; + return -3; + } + + //copy content + memcpy (pStMsg->cContent, p, pStMsg->iContentLen); + pStMsg->cContent[pStMsg->iContentLen] = 0; + p += pStMsg->iContentLen; + + //copy corrid + memcpy (&pStMsg->iCorrLen, p, sizeof (int)); + p += sizeof (int); + + uiBufLen += pStMsg->iCorrLen; + if (uiBufLen > uiLen) + { + rmb_errno = RMB_ERROR_BUF_2_MSG_FAIL; + return -4; + } + + memcpy (pStMsg->cCorrId, p, pStMsg->iCorrLen); + p += pStMsg->iCorrLen; + + memcpy (&pStMsg->iEventOrService, p, sizeof (int)); + p += sizeof (int); + + memcpy (pStMsg->strTargetDcn, p, sizeof (pStMsg->strTargetDcn)); + p += sizeof (pStMsg->strTargetDcn); + + memcpy (pStMsg->strServiceId, p, sizeof (pStMsg->strServiceId)); + p += sizeof (pStMsg->strServiceId); + + memcpy (pStMsg->strScenarioId, p, sizeof (pStMsg->strScenarioId)); + p += sizeof (pStMsg->strScenarioId); + + //memcpy(pStMsg, &msg, sizeof(StRmbMsg)); + + return 0; +} + +int shift_msg_2_buf (char *cBuf, unsigned int *pLen, const StRmbMsg * pStMsg) +{ + unsigned int uiMsgLen = 0; + uiMsgLen = + 3 * sizeof (char) + sizeof (StSystemHeader) + 2 * sizeof (StDestination) + + 2 * sizeof (unsigned long); + uiMsgLen += + 3 * sizeof (int) + sizeof (StFlow *) + sizeof (pStMsg->strTargetDcn) + + sizeof (pStMsg->strServiceId) + sizeof (pStMsg->strScenarioId) + + sizeof (int); + uiMsgLen += pStMsg->iAppHeaderLen + pStMsg->iContentLen + pStMsg->iCorrLen; + uiMsgLen += sizeof (int); + + char *p = cBuf; + + if (*pLen < uiMsgLen) + { + rmb_errno = RMB_ERROR_MSG_2_BUF_FAIL; + return rmb_errno; + } + + *pLen = uiMsgLen; + + //set msg src + memcpy (p, &pStMsg->iMsgMode, sizeof (int)); + p += sizeof (int); + + //copy cPkgType + *p = pStMsg->cPkgType; + p += sizeof (char); + + //copy cLogicType + *p = pStMsg->cLogicType; + p += sizeof (char); + + //copy cApiType + *p = pStMsg->cApiType; + p += sizeof (char); + + //copy sysheader + memcpy (p, &pStMsg->sysHeader, sizeof (pStMsg->sysHeader)); + p += sizeof (pStMsg->sysHeader); + + //copy dest + memcpy (p, &pStMsg->dest, sizeof (pStMsg->dest)); + p += sizeof (pStMsg->dest); + + //copy replyTo + memcpy (p, &pStMsg->replyTo, sizeof (pStMsg->replyTo)); + p += sizeof (pStMsg->replyTo); + + //copy msgid + memcpy (p, &pStMsg->ulMsgId, sizeof (unsigned long)); + p += sizeof (unsigned long); + + //copy msgLiveTime + memcpy (p, &pStMsg->ulMsgLiveTime, sizeof (unsigned long)); + p += sizeof (unsigned long); + + //copy Appheader + memcpy (p, &pStMsg->iAppHeaderLen, sizeof (int)); + p += sizeof (int); + + memcpy (p, pStMsg->cAppHeader, pStMsg->iAppHeaderLen); + p += pStMsg->iAppHeaderLen; + + //copy content + memcpy (p, &pStMsg->iContentLen, sizeof (int)); + p += sizeof (int); + + memcpy (p, pStMsg->cContent, pStMsg->iContentLen); + p += pStMsg->iContentLen; + + //copy corrid + memcpy (p, &pStMsg->iCorrLen, sizeof (int)); + p += sizeof (int); + + memcpy (p, pStMsg->cCorrId, pStMsg->iCorrLen); + p += pStMsg->iCorrLen; + + memcpy (p, &pStMsg->iEventOrService, sizeof (int)); + p += sizeof (int); + + memcpy (p, pStMsg->strTargetDcn, sizeof (pStMsg->strTargetDcn)); + p += sizeof (pStMsg->strTargetDcn); + + memcpy (p, pStMsg->strServiceId, sizeof (pStMsg->strServiceId)); + p += sizeof (pStMsg->strServiceId); + + memcpy (p, pStMsg->strScenarioId, sizeof (pStMsg->strScenarioId)); + p += sizeof (pStMsg->strScenarioId); + + return 0; +} + +int set_extfields_2_rmb_msg (StRmbMsg * pStMsg, const char *command, int iSeq) +{ + char born_time[32]; + char store_time[32]; + char leave_time[32]; + char arrive_time[32]; + + memset (born_time, 0x00, sizeof (born_time)); + memset (store_time, 0x00, sizeof (store_time)); + memset (leave_time, 0x00, sizeof (leave_time)); + memset (arrive_time, 0x00, sizeof (arrive_time)); + + WEMQJSON *jsonDecoder = NULL; + WEMQJSON *jsonExtField = NULL; + WEMQJSON *property = json_tokener_parse (pStMsg->sysHeader.cProperty); + if (NULL != property) + { + if (json_object_object_get_ex + (property, MSG_BODY_PROPERTY_BORN_TIME_STR, &jsonDecoder)) + { + const char *tmpTime = json_object_get_string (jsonDecoder); + snprintf (born_time, sizeof (born_time), "%s", tmpTime); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In property, %s is null!", + MSG_BODY_PROPERTY_BORN_TIME_STR); + } + + if (json_object_object_get_ex + (property, MSG_BODY_PROPERTY_STORE_TIME_STR, &jsonDecoder)) + { + const char *tmpTime = json_object_get_string (jsonDecoder); + snprintf (store_time, sizeof (store_time), "%s", tmpTime); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In property, %s is null!", + MSG_BODY_PROPERTY_STORE_TIME_STR); + } + + if (json_object_object_get_ex + (property, MSG_BODY_PROPERTY_LEAVE_TIME_STR, &jsonDecoder)) + { + const char *tmpTime = json_object_get_string (jsonDecoder); + snprintf (leave_time, sizeof (leave_time), "%s", tmpTime); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In property, %s is null!", + MSG_BODY_PROPERTY_LEAVE_TIME_STR); + } + + if (json_object_object_get_ex + (property, MSG_BODY_PROPERTY_ARRIVE_TIME_STR, &jsonDecoder)) + { + const char *tmpTime = json_object_get_string (jsonDecoder); + snprintf (arrive_time, sizeof (arrive_time), "%s", tmpTime); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In property, %s is null!", + MSG_BODY_PROPERTY_ARRIVE_TIME_STR); + } + } + jsonExtField = json_tokener_parse (pStMsg->sysHeader.cExtFields); + if (jsonExtField == NULL) + { + jsonExtField = json_object_new_object (); + } + + if (strcmp (command, REQUEST_TO_CLIENT) == 0 + || strcmp (command, ASYNC_MESSAGE_TO_CLIENT) == 0 + || strcmp (command, BROADCAST_MESSAGE_TO_CLIENT) == 0) + { + json_object_object_add (jsonExtField, REQ_BORN_TIMESTAMP, + json_object_new_string (born_time)); + json_object_object_add (jsonExtField, REQ_STORE_TIMESTAMP, + json_object_new_string (store_time)); + json_object_object_add (jsonExtField, REQ_LEAVE_TIMESTAMP, + json_object_new_string (leave_time)); + json_object_object_add (jsonExtField, REQ_ARRIVE_TIMESTAMP, + json_object_new_string (arrive_time)); + json_object_object_add (jsonExtField, MSG_BODY_SYSTEM_ACK_SEQ, + json_object_new_int (iSeq)); + } + else if (strcmp (command, RESPONSE_TO_CLIENT) == 0) + { + json_object_object_add (jsonExtField, RSP_BORN_TIMESTAMP, + json_object_new_string (born_time)); + json_object_object_add (jsonExtField, RSP_STORE_TIMESTAMP, + json_object_new_string (store_time)); + json_object_object_add (jsonExtField, RSP_LEAVE_TIMESTAMP, + json_object_new_string (leave_time)); + json_object_object_add (jsonExtField, RSP_ARRIVE_TIMESTAMP, + json_object_new_string (arrive_time)); + } + + const char *extFields = json_object_get_string (jsonExtField); + if (extFields != NULL) + { + int len = (int) strlen (extFields); + if (len >= RMB_SYSTEMHEADER_EXTFIELDS_MAX_LEN) + { + LOGRMB (RMB_LOG_ERROR, "systemHeader len=%d too large!max_limit=%d: %s", + len, RMB_SYSTEMHEADER_EXTFIELDS_MAX_LEN, extFields); + } + else + { + snprintf (pStMsg->sysHeader.cExtFields, + sizeof (pStMsg->sysHeader.cExtFields), "%s", extFields); + } + } + json_object_put (property); + json_object_put (jsonExtField); + return 0; +} + +static WEMQJSON *generate_destination_from_topic (StRmbMsg * pStMsg, + char *pTopic) +{ + + char cDestName[200]; + char strTargetDcn[10]; + char strServiceId[10]; + char strScenarioId[5]; + + //判断分隔符数量是否正确 + int i = 0; + char *ptopic = pTopic; + char *pTemp = NULL; + do + { + pTemp = strchr (ptopic, '-'); + if (pTemp == NULL) + { + break; + } + i++; + ptopic = pTemp + 1; + } + while (ptopic != NULL); + + if (i != 4) + { + if (strstr (pTopic, "reply-topic") == NULL) + { + LOGRMB (RMB_LOG_WARN, "topic:%s formatting is not conformed!", pTopic); + return NULL; + } + } + + WEMQJSON *jsonDest = json_object_new_object (); + if (jsonDest == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object failed"); + return NULL; + } + + memset (cDestName, 0x00, sizeof (cDestName)); + snprintf (cDestName, sizeof (pStMsg->dest.cDestName), "%s", pTopic); + + for (i = 0; i < strlen (cDestName) && cDestName[i] != '\0'; i++) + { + if (cDestName[i] == '-') + { + cDestName[i] = '/'; + } + } + json_object_object_add (jsonDest, MSG_BODY_DEST_NAME_STR, + json_object_new_string (cDestName)); + + pTemp = strrchr (cDestName, '/'); + *pTemp = '\0'; + //copy ScenarioId + pTemp = strrchr (cDestName, '/'); + if (pTemp == NULL) + { + return NULL; + } + snprintf (strScenarioId, sizeof (strScenarioId), "%s", pTemp + 1); + *pTemp = '\0'; + + //copy ServiceId + pTemp = strrchr (cDestName, '/'); + if (pTemp == NULL) + { + return NULL; + } + snprintf (strServiceId, sizeof (strServiceId), "%s", pTemp + 1); + *pTemp = '\0'; + + pTemp = strrchr (cDestName, '/'); + if (pTemp == NULL) + { + return NULL; + } + *pTemp = '\0'; + //copy TargetDcn + snprintf (strTargetDcn, sizeof (strTargetDcn), "%s", cDestName); + + json_object_object_add (jsonDest, MSG_BODY_DEST_TYPE_STR, + json_object_new_string ("se")); + json_object_object_add (jsonDest, MSG_BODY_DEST_SORE_STR, + json_object_new_string (strServiceId)); + json_object_object_add (jsonDest, MSG_BODY_DEST_SCENARIO_STR, + json_object_new_string (strScenarioId)); + json_object_object_add (jsonDest, MSG_BODY_DEST_DCN_STR, + json_object_new_string (strTargetDcn)); + json_object_object_add (jsonDest, MSG_BODY_DEST_ORGID_STR, + json_object_new_string (pStMsg->sysHeader.cOrgId)); + + return jsonDest; +} + +int trans_json_2_rmb_msg (StRmbMsg * pStMsg, const char *bodyJson, + const char *command) +{ + if (pStMsg == NULL || bodyJson == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStMsg or bodyJson is null"); + return -1; + } + + rmb_msg_clear (pStMsg); + + pStMsg->cApiType = C_TYPE_WEMQ; + + WEMQJSON *systemHeader = NULL; + WEMQJSON *dest = NULL; + WEMQJSON *jsonDecoder = NULL; + WEMQJSON *property = NULL; + WEMQJSON *jsonByteBody = NULL; + + WEMQJSON *jsonBody = json_tokener_parse (bodyJson); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_tokener_parse failed!,buf is:%s", bodyJson); + return -1; + } + if (!json_object_object_get_ex + (jsonBody, MSG_BODY_BYTE_BODY_JSON, &jsonByteBody)) + { + LOGRMB (RMB_LOG_ERROR, "body json no byte body!"); + return -2; + } //byte body json + + if (!json_object_object_get_ex + (jsonBody, MSG_BODY_PROPERTY_JSON, &property)) + { + LOGRMB (RMB_LOG_ERROR, "body json no properties!"); + return -2; + } //property json + jsonByteBody = json_tokener_parse (json_object_get_string (jsonByteBody)); + if (!json_object_object_get_ex + (jsonByteBody, MSG_BODY_BYTE_BODY_SYSTEM_HEADER_CONTENT_JSON, + &systemHeader)) + { + LOGRMB (RMB_LOG_ERROR, "byte body json no system header content!"); + return -2; + } //system header json + systemHeader = json_tokener_parse (json_object_get_string (systemHeader)); + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_BIZ_STR, &jsonDecoder)) + { + const char *bizNo = json_object_get_string (jsonDecoder); + if (bizNo != NULL) + { + snprintf (pStMsg->sysHeader.cBizSeqNo, + sizeof (pStMsg->sysHeader.cBizSeqNo), "%s", bizNo); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_BIZ_STR); + } + } //system header bizno + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_SEQNO_STR, &jsonDecoder)) + { + const char *seqNo = json_object_get_string (jsonDecoder); + if (seqNo != NULL) + { + snprintf (pStMsg->sysHeader.cConsumerSeqNo, + sizeof (pStMsg->sysHeader.cConsumerSeqNo), "%s", seqNo); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_SEQNO_STR); + } + } //system header seqNo + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_SVRID_STR, &jsonDecoder)) + { + const char *svrId = json_object_get_string (jsonDecoder); + if (svrId != NULL) + { + snprintf (pStMsg->sysHeader.cConsumerSvrId, + sizeof (pStMsg->sysHeader.cConsumerSvrId), "%s", svrId); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_SVRID_STR); + } + } //system header svrId + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_ORGSYS_STR, &jsonDecoder)) + { + const char *orgId = json_object_get_string (jsonDecoder); + if (orgId != NULL) + { + snprintf (pStMsg->sysHeader.cOrgSysId, + sizeof (pStMsg->sysHeader.cOrgSysId), "%s", orgId); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_ORGSYS_STR); + } + } //system header orgId + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_CSMID_STR, &jsonDecoder)) + { + const char *csmId = json_object_get_string (jsonDecoder); + if (csmId != NULL) + { + snprintf (pStMsg->sysHeader.cConsumerSysId, + sizeof (pStMsg->sysHeader.cConsumerSysId), "%s", csmId); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_CSMID_STR); + } + } //system header csmId + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_TIME_LINT, &jsonDecoder)) + { + pStMsg->sysHeader.ulTranTimeStamp = json_object_get_int64 (jsonDecoder); + } //system header transTime + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_CSMDCN_STR, &jsonDecoder)) + { + const char *csmDcn = json_object_get_string (jsonDecoder); + if (csmDcn != NULL) + { + snprintf (pStMsg->sysHeader.cConsumerDcn, + sizeof (pStMsg->sysHeader.cConsumerDcn), "%s", csmDcn); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_CSMDCN_STR); + } + } //system header csmDcn + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_ORGSVR_STR, &jsonDecoder)) + { + const char *orgSysId = json_object_get_string (jsonDecoder); + if (orgSysId != NULL) + { + snprintf (pStMsg->sysHeader.cOrgSvrId, + sizeof (pStMsg->sysHeader.cOrgSvrId), "%s", orgSysId); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_ORGSVR_STR); + } + } //system header orgSysId + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_ORGID_STR, &jsonDecoder)) + { + const char *cOrgId = json_object_get_string (jsonDecoder); + if (cOrgId != NULL) + { + snprintf (pStMsg->sysHeader.cOrgId, sizeof (pStMsg->sysHeader.cOrgId), + "%s", cOrgId); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_ORGID_STR); + } + } //system header cOrgId + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_UNIID_STR, &jsonDecoder)) + { + const char *cUniqueId = json_object_get_string (jsonDecoder); + if (cUniqueId != NULL) + { + snprintf (pStMsg->sysHeader.cUniqueId, + sizeof (pStMsg->sysHeader.cUniqueId), "%s", cUniqueId); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_UNIID_STR); + } + } //system header cUniqueId + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_CONLEN_INT, &jsonDecoder)) + { + pStMsg->sysHeader.iContentLength = json_object_get_int (jsonDecoder); + } //system header iContentLength + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_SENDTIME_LINT, &jsonDecoder)) + { + pStMsg->sysHeader.ulSendTime = json_object_get_int64 (jsonDecoder); + } //system header ulSendTime + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_RECVTIME_LINT, &jsonDecoder)) + { + pStMsg->sysHeader.ulReceiveTime = json_object_get_int64 (jsonDecoder); + } + if (pStMsg->sysHeader.ulReceiveTime == 0) + { + GetRmbNowLongTime (); + pStMsg->sysHeader.ulReceiveTime = pRmbStConfig->ulNowTtime; + } + //system header ulReceiveTime + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_REPLYTIME_LINT, &jsonDecoder)) + { + pStMsg->sysHeader.ulReplyTime = json_object_get_int64 (jsonDecoder); + } //system header ulReplyTime + + if (json_object_object_get_ex + (jsonByteBody, MSG_BODY_BYTE_BODY_APPHEADER_NAME_STR, &jsonDecoder)) + { + const char *pAppheaderClass = json_object_get_string (jsonDecoder); + if (pAppheaderClass != NULL) + { + snprintf (pStMsg->sysHeader.cAppHeaderClass, + sizeof (pStMsg->sysHeader.cAppHeaderClass), "%s", + pAppheaderClass); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_BYTE_BODY_APPHEADER_NAME_STR); + } + } // system header cAppHeaderClass + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_VER_STR, &jsonDecoder)) + { + const char *pConsumerSysVersion = json_object_get_string (jsonDecoder); + if (pConsumerSysVersion != NULL) + { + snprintf (pStMsg->sysHeader.cConsumerSysVersion, + sizeof (pStMsg->sysHeader.cConsumerSysVersion), "%s", + pConsumerSysVersion); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_VER_STR); + } + } + //system consumerSysVersion + + const char *cProperty = json_object_get_string (property); + if (cProperty != NULL) + { + int len = (int) strlen (property); + if (len >= RMB_SYSTEMHEADER_PROPERTY_MAX_LEN) + { + LOGRMB (RMB_LOG_ERROR, "property len=%d too large!max_limit=%d: %s", + len, RMB_SYSTEMHEADER_PROPERTY_MAX_LEN, cProperty); + } + else + { + snprintf (pStMsg->sysHeader.cProperty, + sizeof (pStMsg->sysHeader.cProperty), "%s", cProperty); + } + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_PROPERTY_JSON); + } + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_EXTFIELDS_STR, &jsonDecoder)) + { + const char *extFields = json_object_get_string (jsonDecoder); + if (extFields != NULL) + { + int len = (int) strlen (extFields); + if (len >= RMB_SYSTEMHEADER_EXTFIELDS_MAX_LEN) + { + LOGRMB (RMB_LOG_ERROR, + "systemHeader len=%d too large!max_limit=%d: %s", len, + RMB_SYSTEMHEADER_EXTFIELDS_MAX_LEN, extFields); + } + else + { + snprintf (pStMsg->sysHeader.cExtFields, + sizeof (pStMsg->sysHeader.cExtFields), "%s", extFields); + } + if (strstr (extFields, "\"IS_DYED_MSG\": \"true\"") != NULL) + { + LOGRMB (RMB_LOG_DEBUG, "trans msg, extfield is %s", extFields); + strcpy (pStMsg->isDyedMsg, "true"); + } + else + { + strcpy (pStMsg->isDyedMsg, "false"); + } + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_EXTFIELDS_STR); + } + + } //system header extFields + + if (json_object_object_get_ex + (jsonByteBody, MSG_BODY_BYTE_BODY_APPHEADER_CONTENT_JSON, &jsonDecoder)) + { + const char *appHeader = json_object_get_string (jsonDecoder); + if (appHeader != NULL) + { + //get appHeader len + unsigned int uiAppHeaderLen = json_object_get_string_len (jsonDecoder); + if (uiAppHeaderLen >= pStMsg->iMallocAppHeaderLength) + { + int iFitSize = + rmb_get_fit_size (uiAppHeaderLen, MAX_APPHEADER_LENGTH); + if (iFitSize < 0) + { + LOGRMB (RMB_LOG_ERROR, "appHeader len=%d too large!max_limit=%u", + uiAppHeaderLen, MAX_APPHEADER_LENGTH); + return -1; + } + free (pStMsg->cAppHeader); + pStMsg->cAppHeader = NULL; + pStMsg->cAppHeader = (char *) malloc (iFitSize); + pStMsg->iMallocAppHeaderLength = iFitSize; + } + pStMsg->iAppHeaderLen = uiAppHeaderLen; + memcpy (pStMsg->cAppHeader, json_object_get_string (jsonDecoder), + uiAppHeaderLen); + pStMsg->cAppHeader[pStMsg->iAppHeaderLen] = '\0'; + } + else + { + LOGRMB (RMB_LOG_ERROR, "In body, %s is null!", MSG_BODY_APP_JSON); + } + } //appHeader + + if (json_object_object_get_ex + (property, MSG_BODY_PROPERTY_TTL_INT, &jsonDecoder)) + { + pStMsg->ulMsgLiveTime = json_object_get_int64 (jsonDecoder); + } //header ulMsgLiveTime + + //if (json_object_object_get_ex(jsonBody, MSG_BODY_TOPIC_STR, &jsonDecoder)) + //{ + // const char *topic = json_object_get_string(jsonDecoder); + + // dest = generate_destination_from_topic(pStMsg,topic); + if (json_object_object_get_ex (jsonByteBody, MSG_BODY_DEST_JSON, &dest)) + { + dest = json_tokener_parse (json_object_get_string (dest)); + } + else + { + if (json_object_object_get_ex + (jsonBody, MSG_BODY_TOPIC_STR, &jsonDecoder)) + { + const char *topic = json_object_get_string (jsonDecoder); + dest = generate_destination_from_topic (pStMsg, topic); + } + + } + if (NULL != dest) + { + if (json_object_object_get_ex + (dest, MSG_BODY_DEST_NAME_STR, &jsonDecoder)) + { + //get name + const char *destTmp = json_object_get_string (jsonDecoder); + if (destTmp != NULL) + { + snprintf (pStMsg->dest.cDestName, sizeof (pStMsg->dest.cDestName), + "%s", destTmp); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In destination, %s is null", + MSG_BODY_DEST_NAME_STR); + } + } //get name + + if (json_object_object_get_ex + (dest, MSG_BODY_DEST_SORE_STR, &jsonDecoder)) + { + const char *pServiceId = json_object_get_string (jsonDecoder); + if (pServiceId != NULL) + { + snprintf (pStMsg->strServiceId, sizeof (pStMsg->strServiceId), "%s", + pServiceId); + pStMsg->iEventOrService = + (*(pServiceId + 3) == '0') ? RMB_SERVICE_CALL : RMB_EVENT_CALL; + } + else + { + LOGRMB (RMB_LOG_ERROR, "In destination, %s is null", + MSG_BODY_DEST_SORE_STR); + } + } //get serviceOrEventId + + if (json_object_object_get_ex + (dest, MSG_BODY_DEST_SCENARIO_STR, &jsonDecoder)) + { + const char *pScenarioId = json_object_get_string (jsonDecoder); + if (pScenarioId != NULL) + { + snprintf (pStMsg->strScenarioId, sizeof (pStMsg->strScenarioId), "%s", + pScenarioId); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In destination, %s is null!", + MSG_BODY_DEST_SCENARIO_STR); + } + } //get scenario + + if (json_object_object_get_ex (dest, MSG_BODY_DEST_DCN_STR, &jsonDecoder)) + { + const char *pDcn = json_object_get_string (jsonDecoder); + if (pDcn != NULL) + { + snprintf (pStMsg->strTargetDcn, sizeof (pStMsg->strTargetDcn), "%s", + pDcn); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In destination, %s is null!", + MSG_BODY_DEST_DCN_STR); + } + } //get dcn + + if (json_object_object_get_ex + (dest, MSG_BODY_DEST_ORGID_STR, &jsonDecoder)) + { + const char *pOrganization = json_object_get_string (jsonDecoder); + if (pOrganization != NULL) + { + snprintf (pStMsg->strTargetOrgId, sizeof (pStMsg->strTargetOrgId), + "%s", pOrganization); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In destination, %s is null", + MSG_BODY_DEST_ORGID_STR); + } + } //get organization + //header dest + } + //topic + + if (json_object_object_get_ex + (property, MSG_BODY_PROPERTY_REPLYTO_STR, &jsonDecoder)) + { + const char *replyTo = json_object_get_string (jsonDecoder); + if (replyTo != NULL) + { + snprintf (pStMsg->replyTo.cDestName, sizeof (pStMsg->replyTo.cDestName), + "%s", replyTo); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In bodyjson, %s is null", MSG_BODY_REPLYTO_STR); + } + } //header replyTo + + if (json_object_object_get_ex + (jsonByteBody, MSG_BODY_BYTE_BODY_CONTENT_STR, &jsonDecoder)) + { + const char *cContent = json_object_get_string (jsonDecoder); + if (cContent != NULL) + { +// pStMsg->iContentLen = strlen(cContent); + pStMsg->iContentLen = json_object_get_string_len (jsonDecoder); + LOGRMB (RMB_LOG_DEBUG, "get content len:%d", pStMsg->iContentLen); + if (pStMsg->iContentLen >= pStMsg->iMallocContentLength) + { + int iFitSize = + rmb_get_fit_size (pStMsg->iContentLen, MAX_MSG_CONTENT_SIZE); + if (iFitSize < 0) + { + LOGRMB (RMB_LOG_ERROR, "content len=%d too large!max_limit=%u", + pStMsg->iContentLen, MAX_MSG_CONTENT_SIZE); + return -1; + } + free (pStMsg->cContent); + pStMsg->cContent = NULL; + pStMsg->cContent = (char *) malloc (iFitSize); + pStMsg->iMallocContentLength = iFitSize; + } + //strncpy(pStMsg->cContent, cContent, pStMsg->iContentLen); + memcpy (pStMsg->cContent, cContent, pStMsg->iContentLen); + pStMsg->cContent[pStMsg->iContentLen] = '\0'; + LOGRMB (RMB_LOG_DEBUG, "get content:%d - %s", pStMsg->iContentLen, + pStMsg->cContent); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In bodyjson, %s is null", MSG_BODY_CONTENT_STR); + } + } //header cContent + + json_object_put (dest); + json_object_put (systemHeader); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + + return 0; +} + +int rmb_msg_print_v (StRmbMsg * pRmbMsg) +{ + LOGRMB (RMB_LOG_DEBUG, + "[type=%s,send=%lu,rev=%lu,dest=%s,bizSeqNo=%s,cSeqNo=%s,replyTo=%s,len=%d,content=%s]", + (int) pRmbMsg->cLogicType <= + 6 ? strLogicType[(int) (pRmbMsg->cLogicType)] : "null", + pRmbMsg->sysHeader.ulSendTime, pRmbMsg->sysHeader.ulReceiveTime, + pRmbMsg->dest.cDestName, pRmbMsg->sysHeader.cBizSeqNo, + pRmbMsg->sysHeader.cConsumerSeqNo, pRmbMsg->replyTo.cDestName, + pRmbMsg->iContentLen, pRmbMsg->cContent); + return 0; +} + +const char *rmb_msg_print (StRmbMsg * pRmbMsg) +{ + if (pRmbMsg->cLogicType == REQ_PKG_IN + || pRmbMsg->cLogicType == EVENT_PKG_IN) + { + snprintf (pRmbMsg->strLogBuf, sizeof (pRmbMsg->strLogBuf) - 1, + "[type=%s,send=%lu,rev=%lu,dest=%s,bizSeqNo=%s,cSeqNo=%s,replyTo=%s,len=%d,content=%s]", + (int) pRmbMsg->cLogicType <= + 6 ? strLogicType[(int) (pRmbMsg->cLogicType)] : "null", + pRmbMsg->sysHeader.ulSendTime, pRmbMsg->sysHeader.ulReceiveTime, + pRmbMsg->dest.cDestName, pRmbMsg->sysHeader.cBizSeqNo, + pRmbMsg->sysHeader.cConsumerSeqNo, pRmbMsg->replyTo.cDestName, + pRmbMsg->iContentLen, pRmbMsg->cContent); + } + else if (pRmbMsg->cLogicType == RSP_PKG_IN + || pRmbMsg->cLogicType == RSP_PKG_OUT) + { + snprintf (pRmbMsg->strLogBuf, sizeof (pRmbMsg->strLogBuf) - 1, + "[type=%s,send=%lu,rev=%lu,reply=%lu,dest=%s,bizSeqNo=%s,cSeqNo=%s,replyTo=%s,len=%d,content=%s]", + (int) pRmbMsg->cLogicType <= + 6 ? strLogicType[(int) (pRmbMsg->cLogicType)] : "null", + pRmbMsg->sysHeader.ulSendTime, pRmbMsg->sysHeader.ulReceiveTime, + pRmbMsg->sysHeader.ulReplyTime, pRmbMsg->dest.cDestName, + pRmbMsg->sysHeader.cBizSeqNo, pRmbMsg->sysHeader.cConsumerSeqNo, + pRmbMsg->replyTo.cDestName, pRmbMsg->iContentLen, + pRmbMsg->cContent); + } + else + { + snprintf (pRmbMsg->strLogBuf, sizeof (pRmbMsg->strLogBuf) - 1, + "[type=%s,send=%lu,dest=%s,bizSeqNo=%s,cSeqNo=%s,replyTo=%s,len=%d,content=%s]", + (int) pRmbMsg->cLogicType <= + 6 ? strLogicType[(int) (pRmbMsg->cLogicType)] : "null", + pRmbMsg->sysHeader.ulSendTime, pRmbMsg->dest.cDestName, + pRmbMsg->sysHeader.cBizSeqNo, pRmbMsg->sysHeader.cConsumerSeqNo, + pRmbMsg->replyTo.cDestName, pRmbMsg->iContentLen, + pRmbMsg->cContent); + } + + pRmbMsg->strLogBuf[sizeof (pRmbMsg->strLogBuf) - 1] = 0; + return pRmbMsg->strLogBuf; +} + +//消息初始化 +StRmbMsg *rmb_msg_malloc () +{ + StRmbMsg *rmbMsg = (StRmbMsg *) malloc (sizeof (StRmbMsg)); + if (rmbMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for rmbMsg error!\n"); + return NULL; + } + memset (rmbMsg, 0, sizeof (StRmbMsg)); + + rmbMsg->cContent = (char *) malloc (i1KB); + if (rmbMsg->cContent == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for rmbMsg->cContent error!\n"); + free (rmbMsg); + rmbMsg = NULL; + return NULL; + } + memset (rmbMsg->cContent, 0x00, sizeof (char) * i1KB); + rmbMsg->iMallocContentLength = i1KB; + + rmbMsg->cAppHeader = (char *) malloc (i1KB); + if (rmbMsg->cAppHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for rmbMsg->cAppHeader error!\n"); + free (rmbMsg->cContent); + rmbMsg->cContent = NULL; + free (rmbMsg); + rmbMsg = NULL; + return NULL; + } + memset (rmbMsg->cAppHeader, 0x00, sizeof (char) * i1KB); + rmbMsg->iMallocAppHeaderLength = i1KB; + + return rmbMsg; +} + +//消息释放 +int rmb_msg_free (StRmbMsg * pRmbMsg) +{ + if (pRmbMsg == NULL) + { + return 0; + } + if (pRmbMsg->cContent != NULL && pRmbMsg->iMallocContentLength != 0) + { + free (pRmbMsg->cContent); + pRmbMsg->cContent = NULL; + } + if (pRmbMsg->cAppHeader != NULL && pRmbMsg->iMallocAppHeaderLength != 0) + { + free (pRmbMsg->cAppHeader); + pRmbMsg->cAppHeader = NULL; + } + + free (pRmbMsg); + return 0; +} + +int rmb_msg_random_uuid (char *puuid, size_t size) +{ + char cUniqueIdEx[50] = { 0 }; + uuid_t uuidout; + uuid_generate_random (uuidout); + uuid_unparse (uuidout, cUniqueIdEx); + snprintf (puuid, size, "%s", cUniqueIdEx); + return 0; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_pub.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_pub.c new file mode 100644 index 0000000000..784ce498cc --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_pub.c @@ -0,0 +1,2453 @@ +// 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. + +#include +#include +#include +#include +#include "common.h" +#include "rmb_pub.h" +#include "rmb_context.h" +#include "rmb_udp.h" +#include "rmb_common.h" +#include "rmb_errno.h" +#include "wemq_thread.h" + +static int g_iSendReq = 0; +static unsigned long g_iSendReqForEvent = 100000000; +static StRmbPub *pRmbGlobalPub; + +unsigned int g_uiSendMsgSeq = 0; +unsigned int g_uiRecvMsgSeq = 0; +unsigned int DEFAULT_WINDOW_SIZE = 100; + +typedef struct gsl_err +{ + char result; + const char *err_msg; +} gsl_err; + +gsl_err gsl_error[] = { + {0x01, NULL}, + {0x11, "query ckv null"}, + {0x21, "chvvalue.orgid_list_size() = 0"}, + {0x31, "orgid for query rules is null"}, + {0x41, "no available rules for service"}, + {0x51, "ckvvalue.org.dcn_list_size() = 0"}, + {0x61, "target dcn is null according to query rules for event"}, + {0x71, NULL}, + {0x81, NULL}, + {0x91, NULL}, + {0xA1, NULL}, + {0xB1, NULL}, + {0xC1, NULL}, + {0xD1, NULL}, + {0xE1, NULL}, + {0xF1, NULL}, + {0x02, NULL}, + {0x12, + "CommonOrgid points to SingleOrgid, service cannot be deployed in more than one ADM or C-DCN"}, + {0x22, + "CommonOrgid points to SingleOrgid, service cannot be found in either ADM or C-DCN"}, + {0x32, + "public service id is deployed in multiple regions causing conflicts"}, + {0x42, + "service is poly-active in one area(R-DCN/C-DCN/ADM/Common), but dcn matching IDC of clientDcn not found"}, + {0x52, + "event subscriptors belong to one area(CS/DMZ/ECN), but dcn matching IDC of clientDcn not found"}, + {0x62, NULL}, + {0x72, NULL}, + {0x82, NULL}, + {0x92, NULL}, + {0xA2, NULL}, + {0xB2, NULL}, + {0xC2, NULL}, + {0xD2, NULL}, + {0xE2, NULL}, + {0xF2, NULL}, + {0x03, NULL}, + {0x13, "DecodeBuf error or ParseFromString error"}, + {0x23, "query ckv error"}, + {0x33, NULL}, + {0x43, NULL}, + {0x53, NULL}, + {0x63, NULL}, + {0x73, NULL}, + {0x83, NULL}, + {0x93, NULL}, + {0xA3, NULL}, + {0xB3, NULL}, + {0xC3, NULL}, + {0xD3, NULL}, + {0xE3, NULL}, + {0xF3, NULL} +}; + +//#define TCP_BUF_SIZE 5<<01 +static int rmb_pub_encode_header_for_wemq (unsigned int uiCmd, + StWemqThreadMsg * ptThreadMsg, + StRmbMsg * ptSendMsg) +{ + if (ptThreadMsg == NULL || ptSendMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "ptThreadMsg is null or ptSendMsg is null"); + return -1; + } + + switch (uiCmd) + { + case THREAD_MSG_CMD_SEND_MSG: + { + ptThreadMsg->m_iCmd = THREAD_MSG_CMD_SEND_MSG; + + WEMQJSON *jsonHeader = json_object_new_object (); + + // ptSendMsg->strServiceId[3] == '3' 多播使用ASYNC_MESSAGE_TO_SERVER + if (ptSendMsg->strServiceId[3] == '4') + { + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string + (BROADCAST_MESSAGE_TO_SERVER)); + } + else + { + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string + (ASYNC_MESSAGE_TO_SERVER)); + } + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (++g_iSendReqForEvent)); + LOGRMB (RMB_LOG_DEBUG, "put seq:%ld in pkg", g_iSendReqForEvent); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "get thread msg header failed"); + json_object_put (jsonHeader); + return -1; + } + ptThreadMsg->m_iHeaderLen = strlen (header_str); + + LOGRMB (RMB_LOG_DEBUG, "Get thread msg header succ, len=%d,%s\n", + ptThreadMsg->m_iHeaderLen, header_str); + ptThreadMsg->m_pHeader = + (char *) malloc ((ptThreadMsg->m_iHeaderLen + 1) * sizeof (char)); + if (ptThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for ptThreadMsg->m_pHeader failed"); + json_object_put (jsonHeader); + return -2; + } + memcpy (ptThreadMsg->m_pHeader, header_str, ptThreadMsg->m_iHeaderLen); + ptThreadMsg->m_pHeader[ptThreadMsg->m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + return 0; + } + case THREAD_MSG_CMD_SEND_REQUEST: + { + ptThreadMsg->m_iCmd = THREAD_MSG_CMD_SEND_REQUEST; + + WEMQJSON *jsonHeader = json_object_new_object (); + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (REQUEST_TO_SERVER)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (g_iSendReq++)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg header failed"); + json_object_put (jsonHeader); + return -1; + } + ptThreadMsg->m_iHeaderLen = strlen (header_str); + + LOGRMB (RMB_LOG_DEBUG, "Get thread msg header succ, len=%d,%s\n", + ptThreadMsg->m_iHeaderLen, header_str); + ptThreadMsg->m_pHeader = + (char *) malloc ((ptThreadMsg->m_iHeaderLen + 1) * sizeof (char)); + if (ptThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for ptThreadMsg->m_pHeader failed\n"); + json_object_put (jsonHeader); + return -2; + } + memcpy (ptThreadMsg->m_pHeader, header_str, ptThreadMsg->m_iHeaderLen); + ptThreadMsg->m_pHeader[ptThreadMsg->m_iHeaderLen] = '\0'; + json_object_put (jsonHeader); + return 0; + } + case THREAD_MSG_CMD_SEND_REQUEST_ASYNC: + { + ptThreadMsg->m_iCmd = THREAD_MSG_CMD_SEND_REQUEST_ASYNC; + + WEMQJSON *jsonHeader = json_object_new_object (); + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (REQUEST_TO_SERVER)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (g_iSendReq++)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg header failed"); + json_object_put (jsonHeader); + return -1; + } + ptThreadMsg->m_iHeaderLen = strlen (header_str); + + LOGRMB (RMB_LOG_DEBUG, "Get thread msg header succ, len=%d,%s\n", + ptThreadMsg->m_iHeaderLen, header_str); + ptThreadMsg->m_pHeader = + (char *) malloc ((ptThreadMsg->m_iHeaderLen + 1) * sizeof (char)); + if (ptThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for ptThreadMsg->m_pHeader failed\n"); + json_object_put (jsonHeader); + return -2; + } + memcpy (ptThreadMsg->m_pHeader, header_str, ptThreadMsg->m_iHeaderLen); + ptThreadMsg->m_pHeader[ptThreadMsg->m_iHeaderLen] = '\0'; + json_object_put (jsonHeader); + return 0; + } + case THREAD_MSG_CMD_SEND_REPLY: + { + ptThreadMsg->m_iCmd = THREAD_MSG_CMD_SEND_REPLY; + + WEMQJSON *jsonHeader = json_object_new_object (); + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (RESPONSE_TO_SERVER)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (g_iSendReq++)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg header failed"); + json_object_put (jsonHeader); + return -1; + } + ptThreadMsg->m_iHeaderLen = strlen (header_str); + + //LOGRMB(RMB_LOG_DEBUG, "Get thread msg header succ, len=%d,%s\n", ptThreadMsg->m_iHeaderLen, header_str); + ptThreadMsg->m_pHeader = + (char *) malloc ((ptThreadMsg->m_iHeaderLen + 1) * sizeof (char)); + if (ptThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for ptThreadMsg->m_pHeader failed\n"); + json_object_put (jsonHeader); + return -2; + } + memcpy (ptThreadMsg->m_pHeader, header_str, ptThreadMsg->m_iHeaderLen); + ptThreadMsg->m_pHeader[ptThreadMsg->m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + return 0; + } + case THREAD_MSG_CMD_SEND_MSG_ACK: + { + ptThreadMsg->m_iCmd = THREAD_MSG_CMD_SEND_MSG_ACK; + + WEMQJSON *jsonHeader = json_object_new_object (); + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (MSG_ACK)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (g_iSendReq++)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg header failed"); + json_object_put (jsonHeader); + return -1; + } + ptThreadMsg->m_iHeaderLen = strlen (header_str); + + //LOGRMB(RMB_LOG_DEBUG, "Get thread msg header succ, len=%d,%s\n", ptThreadMsg->m_iHeaderLen, header_str); + ptThreadMsg->m_pHeader = + (char *) malloc ((ptThreadMsg->m_iHeaderLen + 1) * sizeof (char)); + if (ptThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for ptThreadMsg->m_pHeader failed\n"); + json_object_put (jsonHeader); + return -2; + } + memcpy (ptThreadMsg->m_pHeader, header_str, ptThreadMsg->m_iHeaderLen); + ptThreadMsg->m_pHeader[ptThreadMsg->m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + return 0; + } + default: + LOGRMB (RMB_LOG_ERROR, "unknown cmd:%u", uiCmd); + return -1; + } + + return 0; +} + +static WEMQJSON *rmb_pub_encode_system_header_for_wemq (unsigned int uiCmd, + StRmbMsg * ptSendMsg) +{ + if (ptSendMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "ptSendMsg is null"); + return NULL; + } + + WEMQJSON *jsonSystem = json_object_new_object (); + + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_BIZ_STR, + json_object_new_string (ptSendMsg->sysHeader. + cBizSeqNo)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_SEQNO_STR, + json_object_new_string (ptSendMsg->sysHeader. + cConsumerSeqNo)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_SVRID_STR, + json_object_new_string (ptSendMsg->sysHeader. + cConsumerSvrId)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_ORGSYS_STR, + json_object_new_string (ptSendMsg->sysHeader. + cOrgSysId)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_CSMID_STR, + json_object_new_string (ptSendMsg->sysHeader. + cConsumerSysId)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_TIME_LINT, + json_object_new_int64 (ptSendMsg->sysHeader. + ulTranTimeStamp)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_CSMDCN_STR, + json_object_new_string (ptSendMsg->sysHeader. + cConsumerDcn)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_ORGSVR_STR, + json_object_new_string (ptSendMsg->sysHeader. + cOrgSvrId)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_ORGID_STR, + json_object_new_string (ptSendMsg->sysHeader. + cOrgId)); + //发送消息时,version为consumerSysVersion,且必须为1.0.0 + //json_object_object_add(jsonSystem, MSG_BODY_SYSTEM_VER_STR, json_object_new_string("weq_c_1_0_0")); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_VER_STR, + json_object_new_string (ptSendMsg->sysHeader. + cConsumerSysVersion)); + //add rmb api version + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_API_VERSION, + json_object_new_string (RMBVERSION)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_UNIID_STR, + json_object_new_string (ptSendMsg->sysHeader. + cUniqueId)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_CONLEN_INT, + json_object_new_int (ptSendMsg->sysHeader. + iContentLength)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_MSGTYPE_INT, + json_object_new_int (1)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_RECVTYPE_INT, + json_object_new_int (1)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_SENDTIME_LINT, + json_object_new_int64 (ptSendMsg->sysHeader. + ulSendTime)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_RECVTIME_LINT, + json_object_new_int64 (ptSendMsg->sysHeader. + ulReceiveTime)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_REPLYTIME_LINT, + json_object_new_int64 (ptSendMsg->sysHeader. + ulReplyTime)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_REPLYRECEIVETIME_LINT, + json_object_new_int64 (ptSendMsg->sysHeader. + ulReplyReceiveTime)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_APITYPE_INT, + json_object_new_int (ptSendMsg->cApiType)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_LOGICTYPE_INT, + json_object_new_int ((int32_t) ptSendMsg-> + cLogicType)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_SOCOID_STR, + json_object_new_string ("#C")); + + if (uiCmd == THREAD_MSG_CMD_SEND_REPLY || uiCmd == THREAD_MSG_CMD_RECV_MSG_ACK || uiCmd == THREAD_MSG_CMD_SEND_MSG_ACK) //一般发回包时候、单播回ack,需要rsp_ip + { + WEMQJSON *extFields = + json_tokener_parse (ptSendMsg->sysHeader.cExtFields); + if (extFields == NULL) + { + extFields = json_object_new_object (); + } + json_object_object_add (extFields, MSG_BODY_SYSTEM_RSP_IP, + json_object_new_string (pRmbStConfig->cHostIp)); + json_object_object_add (extFields, MSG_BODY_SYSTEM_RSP_SYS, + json_object_new_string (pRmbStConfig-> + cConsumerSysId)); + json_object_object_add (extFields, MSG_BODY_SYSTEM_RSP_DCN, + json_object_new_string (pRmbStConfig-> + cConsumerDcn)); + json_object_object_add (extFields, MSG_BODY_SYSTEM_RSP_IDC, + json_object_new_string (pRmbStConfig->cRegion)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_EXTFIELDS_STR, + extFields); + const char *systemStr = json_object_get_string (jsonSystem); + WEMQJSON *jsonSystemHeader = json_tokener_parse (systemStr); + json_object_put (jsonSystem); + return jsonSystemHeader; + } + else //发包时候 + { + WEMQJSON *extFields = + json_tokener_parse (ptSendMsg->sysHeader.cExtFields); + if (extFields == NULL) + { + extFields = json_object_new_object (); + } + json_object_object_add (extFields, MSG_BODY_SYSTEM_REQ_IP, + json_object_new_string (pRmbStConfig->cHostIp)); + json_object_object_add (extFields, MSG_BODY_SYSTEM_REQ_SYS, + json_object_new_string (pRmbStConfig-> + cConsumerSysId)); + json_object_object_add (extFields, MSG_BODY_SYSTEM_REQ_DCN, + json_object_new_string (pRmbStConfig-> + cConsumerDcn)); + json_object_object_add (extFields, MSG_BODY_SYSTEM_REQ_IDC, + json_object_new_string (pRmbStConfig->cRegion)); + if (strcmp (ptSendMsg->isDyedMsg, "true") == 0) + { + json_object_object_add (extFields, IS_DYED_MSG, + json_object_new_string ("true")); + } + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_EXTFIELDS_STR, + extFields); + const char *systemStr = json_object_get_string (jsonSystem); + WEMQJSON *jsonSystemHeader = json_tokener_parse (systemStr); + json_object_put (jsonSystem); + return jsonSystemHeader; + } +} + +/** + * set destination proto, like: + * "destination" : { + * "name" : "A00/s/10000000/01/0", + * "type" : "se", + * "serviceOrEventId" : "10000000", + * "scenario" : "01", + * "dcnNo" : "A00", -- not support 000 + * "organizationId" : "99996", + * "organizationIdInputFlag" : 0, + * } + * 其中,type固定为"se",wemq java历史遗留问题 + */ +static WEMQJSON *rmb_pub_encode_body_dest_for_wemq (StRmbMsg * ptSendMsg) +{ + if (ptSendMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "ptSendMsg is null"); + return NULL; + } + + WEMQJSON *jsonDest = json_object_new_object (); + if (jsonDest == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object failed"); + return NULL; + } + + json_object_object_add (jsonDest, MSG_BODY_DEST_NAME_STR, + json_object_new_string (ptSendMsg->dest.cDestName)); + json_object_object_add (jsonDest, MSG_BODY_DEST_TYPE_STR, + json_object_new_string ("se")); + json_object_object_add (jsonDest, MSG_BODY_DEST_SORE_STR, + json_object_new_string (ptSendMsg->strServiceId)); + json_object_object_add (jsonDest, MSG_BODY_DEST_SCENARIO_STR, + json_object_new_string (ptSendMsg->strScenarioId)); + json_object_object_add (jsonDest, MSG_BODY_DEST_DCN_STR, + json_object_new_string (ptSendMsg->strTargetDcn)); + json_object_object_add (jsonDest, MSG_BODY_DEST_ANY_DCN_STR, + json_object_new_boolean (0)); + + json_object_object_add (jsonDest, MSG_BODY_DEST_ORGID_STR, + json_object_new_string (ptSendMsg->strTargetOrgId)); + json_object_object_add (jsonDest, MSG_BODY_DEST_ORGFLAG_INT, + json_object_new_int (ptSendMsg->iFLagForOrgId)); + + return jsonDest; +} + +WEMQJSON *rmb_pub_encode_property_for_wemq (unsigned int uiCmd, + StRmbMsg * ptSendMsg) +{ + if (ptSendMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "ptSendMsg is null"); + return NULL; + } + + WEMQJSON *jsonProperty = NULL; + + if (uiCmd == THREAD_MSG_CMD_SEND_REPLY + || uiCmd == THREAD_MSG_CMD_RECV_MSG_ACK + || uiCmd == THREAD_MSG_CMD_SEND_MSG_ACK) + { + jsonProperty = json_tokener_parse (ptSendMsg->sysHeader.cProperty); + if (jsonProperty == NULL) + { + jsonProperty = json_object_new_object (); + } + } + else + { + jsonProperty = json_object_new_object (); + json_object_object_add (jsonProperty, MSG_BODY_PROPERTY_REPLYTO_STR, + json_object_new_string (ptSendMsg->replyTo. + cDestName)); + json_object_object_add (jsonProperty, + MSG_BODY_PROPERTY_RR_REQUEST_UNIQ_ID_STR, + json_object_new_string (ptSendMsg->sysHeader. + cUniqueId)); + json_object_object_add (jsonProperty, MSG_BODY_PROPERTY_KEYS_STR, + json_object_new_string (ptSendMsg->sysHeader. + cConsumerSeqNo)); + json_object_object_add (jsonProperty, MSG_BODY_PROPERTY_MSG_TYPE_STR, + json_object_new_string ("persistent")); + json_object_object_add (jsonProperty, MSG_BODY_PROPERTY_TTL_INT, + json_object_new_int64 (ptSendMsg->ulMsgLiveTime)); + json_object_object_add (jsonProperty, MSG_BODY_PROPERTY_SEQ_STR, + json_object_new_string (ptSendMsg->sysHeader. + cBizSeqNo)); + } + return jsonProperty; +} + +WEMQJSON *rmb_pub_encode_byte_body_for_wemq (unsigned int uiCmd, + StRmbMsg * ptSendMsg) +{ + if (ptSendMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "ptSendMsg is null"); + return NULL; + } + + WEMQJSON *jsonByteBody = json_object_new_object (); + json_object_object_add (jsonByteBody, + MSG_BODY_BYTE_BODY_APPHEADER_CONTENT_JSON, + json_object_new_string (ptSendMsg->cAppHeader)); + json_object_object_add (jsonByteBody, MSG_BODY_BYTE_BODY_APPHEADER_NAME_STR, + json_object_new_string (ptSendMsg->sysHeader. + cAppHeaderClass)); + json_object_object_add (jsonByteBody, MSG_BODY_BYTE_BODY_CONTENT_STR, + json_object_new_string_len (ptSendMsg->cContent, + ptSendMsg-> + iContentLen)); + json_object_object_add (jsonByteBody, MSG_BODY_BYTE_BODY_CREATETIME_LINT, + json_object_new_int64 (pRmbStConfig->ulNowTtime)); + json_object_object_add (jsonByteBody, MSG_BODY_COID_STR, + json_object_new_string ("#c")); + json_object_object_add (jsonByteBody, MSG_BODY_DELIVERYTIME_INT, + json_object_new_int (1)); + json_object_object_add (jsonByteBody, MSG_BODY_TTL_LINT, + json_object_new_int64 (ptSendMsg->ulMsgLiveTime)); + if (uiCmd == THREAD_MSG_CMD_SEND_REQUEST + || uiCmd == THREAD_MSG_CMD_SEND_REQUEST_ASYNC + || uiCmd == THREAD_MSG_CMD_SEND_REPLY) + { + json_object_object_add (jsonByteBody, MSG_BODY_SYN_BOOL, + json_object_new_boolean (1)); + } + else + { + json_object_object_add (jsonByteBody, MSG_BODY_SYN_BOOL, + json_object_new_boolean (0)); + } + + WEMQJSON *jsonSystemHeaderContent = + rmb_pub_encode_system_header_for_wemq (uiCmd, ptSendMsg); + if (jsonSystemHeaderContent == NULL) + { + LOGRMB (RMB_LOG_ERROR, "wemq_pub_encode_system_header return null"); + return NULL; + } + const char *systemHeaderContentStr = + json_object_get_string (jsonSystemHeaderContent); + json_object_object_add (jsonByteBody, + MSG_BODY_BYTE_BODY_SYSTEM_HEADER_CONTENT_JSON, + json_object_new_string (systemHeaderContentStr)); + + WEMQJSON *jsonBodyDest = rmb_pub_encode_body_dest_for_wemq (ptSendMsg); + if (jsonBodyDest == NULL) + { + LOGRMB (RMB_LOG_ERROR, "wemq_pub_encode_body_dest return null"); + return NULL; + } + const char *jsonBodyDestStr = json_object_get_string (jsonBodyDest); + json_object_object_add (jsonByteBody, MSG_BODY_DEST_JSON, + json_object_new_string (jsonBodyDestStr)); + + const char *byteBodyStr = json_object_get_string (jsonByteBody); + if (byteBodyStr == NULL) + { + json_object_put (jsonByteBody); + return NULL; + } + + int sysLen = strlen (byteBodyStr); + //LOGRMB(RMB_LOG_DEBUG, "Gen thread msg json byte body succ, len %d, %s\n", sysLen, byteBodyStr); + json_object_put (jsonSystemHeaderContent); + json_object_put (jsonBodyDest); + return jsonByteBody; +} + +//根据最新协议解析 +int rmb_pub_encode_body_for_wemq (unsigned int uiCmd, + StWemqThreadMsg * ptThreadMsg, + StRmbMsg * ptSendMsg, + unsigned long ulTimeToAlive) +{ + if (ptThreadMsg == NULL || ptSendMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "ptThreadMsg or ptSendMsg is null"); + return -1; + } + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object return null"); + return -1; + } + char cTopic[128]; + char serviceOrEvent = (*(ptSendMsg->strServiceId + 3) == '0') ? 's' : 'e'; + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", + ptSendMsg->strTargetDcn, serviceOrEvent, ptSendMsg->strServiceId, + ptSendMsg->strScenarioId, *(ptSendMsg->strServiceId + 3)); + json_object_object_add (jsonBody, MSG_BODY_TOPIC_STR, + json_object_new_string (cTopic)); + + if (THREAD_MSG_CMD_SEND_REQUEST_ASYNC == uiCmd) + { + snprintf (ptSendMsg->sysHeader.cExtFields, sizeof ("{\"rrType\": 1 }"), + "%s", "{\"rrType\": 1 }"); + } + WEMQJSON *jsonBodyProperty = + rmb_pub_encode_property_for_wemq (uiCmd, ptSendMsg); + if (jsonBodyProperty == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_property_for_wemq return null"); + json_object_put (jsonBody); + return -1; + } + + json_object_object_add (jsonBody, MSG_BODY_PROPERTY_JSON, jsonBodyProperty); + + WEMQJSON *jsonByteBody = + rmb_pub_encode_byte_body_for_wemq (uiCmd, ptSendMsg); + if (jsonByteBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_byte_body_for_wemq return null"); + json_object_put (jsonBody); + return -1; + } + const char *byteBodyStr = json_object_get_string (jsonByteBody); + + json_object_object_add (jsonBody, MSG_BODY_BYTE_BODY_JSON, + json_object_new_string (byteBodyStr)); + //json_object_object_add(jsonBody, MSG_BODY_BYTE_BODY_JSON, jsonByteBody); + + const char *bodyStr = json_object_get_string (jsonBody); + if (bodyStr == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg body failed\n"); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + return -1; + } + ptThreadMsg->m_iBodyLen = strlen (bodyStr); + + //LOGRMB(RMB_LOG_DEBUG, "Get thread msg body succ, len=%d,%s", ptThreadMsg->m_iBodyLen, bodyStr); + ptThreadMsg->m_pBody = + (char *) malloc ((ptThreadMsg->m_iBodyLen + 1) * sizeof (char)); + if (ptThreadMsg->m_pBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for ptThreadMsg->m_pBody failed"); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + return -1; + } +// strncpy(ptThreadMsg->m_pBody, bodyStr, ptThreadMsg->m_iBodyLen); + memcpy (ptThreadMsg->m_pBody, bodyStr, ptThreadMsg->m_iBodyLen); + ptThreadMsg->m_pBody[ptThreadMsg->m_iBodyLen] = '\0'; + json_object_put (jsonBody); + json_object_put (jsonByteBody); + + return 0; +} + +int rmb_pub_encode_thread_msg (unsigned int uiCmd, + StWemqThreadMsg * ptThreadMsg, + StRmbMsg * ptSendMsg, + unsigned long ulTimeToAlive) +{ + int iRet = -1; + + if (ptSendMsg == NULL || ptThreadMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "ptThreadMsg or ptSendMsg is null"); + return -1; + } + + iRet = rmb_pub_encode_header_for_wemq (uiCmd, ptThreadMsg, ptSendMsg); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_header_for_wemq failed"); + return iRet; + } + + iRet = + rmb_pub_encode_body_for_wemq (uiCmd, ptThreadMsg, ptSendMsg, + ulTimeToAlive); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_body_for_wemq failed"); + return iRet; + } + LOGRMB (RMB_LOG_INFO, + "Get thread msg header succ, headerLen=%d,%s Get thread msg body succ, bodyLen=%d,%s\n", + ptThreadMsg->m_iHeaderLen, ptThreadMsg->m_pHeader, + ptThreadMsg->m_iBodyLen, ptThreadMsg->m_pBody); + + return 0; + +} + +char *rmb_printf_service_status (StRmbPub * pStPub, + StServiceStatus * pTmpService) +{ + //if ((int)pTmpService->cResult == 1) + if ((pTmpService->cResult & 0x0F) == 0x01) + { + snprintf (pStPub->printGslBuf, sizeof (pStPub->printGslBuf) - 1, + "service[%s,%s,%s,%d] null,gettime=%lu,InvalidTime=%lu pls check!", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + pTmpService->ulGetTimes, pTmpService->ulInvalidTime); + } + //else if ((int)pTmpService->cResult == 2) + else if ((pTmpService->cResult & 0x0F) == 0x02) + { + snprintf (pStPub->printGslBuf, sizeof (pStPub->printGslBuf) - 1, + "service[%s,%s,%s,%d] route error,gettime=%lu,InvalidTime=%lu pls check!", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + pTmpService->ulGetTimes, pTmpService->ulInvalidTime); + } + //else if ((int)pTmpService->cResult == 3) + else if ((pTmpService->cResult & 0x0F) == 0x03) + { + snprintf (pStPub->printGslBuf, sizeof (pStPub->printGslBuf) - 1, + "service[%s,%s,%s,%d] gsl_svr error,gettime=%lu,InvalidTime=%lu pls retry!", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + pTmpService->ulGetTimes, pTmpService->ulInvalidTime); + } + else if ((int) pTmpService->cResult == 0) + { + if ((int) pTmpService->cRouteFlag == 2) + { + snprintf (pStPub->printGslBuf, sizeof (pStPub->printGslBuf) - 1, + "service[%s,%s,%s,%d] routeFlag=%d,dcn=%s,time=%lu,InvalidTime=%lu", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + (int) pTmpService->cRouteFlag, pTmpService->strTargetDcn, + pTmpService->ulGetTimes, pTmpService->ulInvalidTime); + } + else + { + snprintf (pStPub->printGslBuf, sizeof (pStPub->printGslBuf) - 1, + "service[%s,%s,%s,%d] routeFlag=%d,time=%lu,InvalidTime=%lu", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + (int) pTmpService->cRouteFlag, pTmpService->ulGetTimes, + pTmpService->ulInvalidTime); + } + + } + pStPub->printGslBuf[sizeof (pStPub->printGslBuf) - 1] = 0; + return pStPub->printGslBuf; +} + +/** + * 将字符串中的'/'替换为'-' + */ +static void rmb_change_slash_to_hyphen (char *str, int iLen) +{ + int i = 0; + for (i = 0; i < iLen && str[i] != '\0'; i++) + { + if (str[i] == '/') + { + str[i] = '-'; + } + } +} + +/** + * 用于判断消息发往wemq + */ +static int rmb_pub_send_mode (StRmbPub * pPub, StRmbMsg * pMsg) +{ + if (pPub == NULL || pMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pPub or pMsg is null"); + return -1; + } + + pMsg->iMsgMode = RMB_MSG_WEMQ; + + return 0; +} + +/** + * private func, request gsl for route and dcn + * 参见 + * api cache需求: + * 1. api使用同步的方式更新本地gsl cache,不做全量缓存 + * 2. api请求gsl服务的超时时间默认为1000ms + * 3. cache数据初始的超时时间为600s + * 4. cache数据更新逻辑如下: + * 1) cache中没有本次查询的数据, 则: + * result字段为0,则查询结果存入缓存,失效时间为600s + * result字段低4位为1,则查询结果存入缓存,失效时间为600s,向调用方返错 + * result字段低4位为2,则查询结果不存入缓存,向调用方返错 + * result字段低4位为3或者查询超时,查询结果不存入缓存,向调用方返错 + * 2) api发送消息时发现cache中数据已失效,则去gsl拉取数据: + * result字段为0,更新本地cache,同时将失效时间延后600s,使用最新查询到的数据发送rmb消息 + * result字段低4位为1,则查询结果存入缓存,失效时间为600s,向调用方返错 + * result字段低4位为2,则删除本地缓存数据,向调用方返错 + * result字段低4位为3或者查询超时,如果cache原数据的result字段为0,更新本地数据的失效时间,延后30s + */ +static int rmb_pub_send_gsl (StRmbPub * pStPub, StServiceStatus * pTmpService, + const char *cBizSeqNo, + const char *cConsumerSeqNo) +{ + //get dcn + //char pkgBuf[MAX_GSL_REQ_BUF_SIZE]; + char *p = pStPub->pkgBuf; + int iPkgLen = 0; + //*p = GSL_SUBCMD_QUERY_SERVICE; + *p = GSL_SUBCMD_NEW_QUERY_SERVICE; + p += 1; + iPkgLen += 1; + + int tmp = strlen (pTmpService->strTargetOrgId); + *p = tmp; + p += 1; + iPkgLen += 1; + memcpy (p, pTmpService->strTargetOrgId, tmp); + p += tmp; + iPkgLen += tmp; + + tmp = strlen (pRmbStConfig->cConsumerDcn); + *p = tmp; + p += 1; + iPkgLen += 1; + memcpy (p, pRmbStConfig->cConsumerDcn, tmp); + p += tmp; + iPkgLen += tmp; + + tmp = strlen (pTmpService->strServiceId); + *p = tmp; + p += 1; + iPkgLen += 1; + memcpy (p, pTmpService->strServiceId, tmp); + p += tmp; + iPkgLen += tmp; + + tmp = strlen (pTmpService->strScenarioId); + *p = tmp; + p += 1; + iPkgLen += 1; + memcpy (p, pTmpService->strScenarioId, tmp); + p += tmp; + iPkgLen += tmp; + + *p = pTmpService->cFlagForOrgId; + iPkgLen += 1; + + rmb_msg_set_bizSeqNo (pStPub->pSendMsg, cBizSeqNo); + rmb_msg_set_consumerSeqNo (pStPub->pSendMsg, cConsumerSeqNo); + rmb_msg_set_orgSysId (pStPub->pSendMsg, pRmbStConfig->cConsumerSysId); + rmb_msg_set_dest_v2_1 (pStPub->pSendMsg, GSL_DEFAULT_DCN, + GSL_DEFAULT_SERVICE_ID, GSL_DEFAULT_SCENE_ID, + GSL_DEFAULT_COMMON_ORGID); + + rmb_msg_set_content (pStPub->pSendMsg, pStPub->pkgBuf, iPkgLen); + char appHeader[5] = "{}"; + rmb_msg_set_app_header (pStPub->pSendMsg, appHeader, strlen (appHeader)); + + int iRet = + rmb_pub_send_and_receive (pStPub, pStPub->pSendMsg, pStPub->pRcvMsg, + pRmbStConfig->iQueryTimeout); + if (iRet == 0) + { + char receiveBuf[MAX_GSL_RSP_BUF_SIZE]; + unsigned int receiveLen = sizeof (receiveBuf); + rmb_msg_get_content (pStPub->pRcvMsg, receiveBuf, &receiveLen); + if (receiveLen == 0) + { + LOGRMB (RMB_LOG_ERROR, "GSL reply len=0, req=%s\n", + rmb_msg_print (pStPub->pSendMsg)); + rmb_errno = RMB_ERROR_GSL_SVR_ERROR; + return 3; + } + // result(char) + routeFlag(char) + targetDcn(cStr) + char result = *(receiveBuf + 1); + pTmpService->cResult = result; + + if (result == 0) + { + pTmpService->cRouteFlag = *(receiveBuf + 2); + if (pTmpService->cRouteFlag == 0 || pTmpService->cRouteFlag == 1) + { + LOGRMB (RMB_LOG_INFO, "GSL:[%s-%s-%s-%d] routeFlag=%d\n", + pTmpService->strServiceId, + pTmpService->strScenarioId, + pTmpService->strTargetOrgId, + (int) pTmpService->cFlagForOrgId, + (int) pTmpService->cRouteFlag); + return 0; + } + unsigned int uiDcnLen = *(receiveBuf + 3); + memcpy (pTmpService->strTargetDcn, receiveBuf + 4, uiDcnLen); + pTmpService->strTargetDcn[uiDcnLen] = 0; + + LOGRMB (RMB_LOG_INFO, + "GSL:[%s-%s-%s-%d],get succ!routeFlag=2,targetDcn=%s \n", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + pTmpService->strTargetDcn); + return 0; + } + //兼容老的gsl的错误返回码 + else if (result == 1) + { + LOGRMB (RMB_LOG_INFO, + "GSL:[%s-%s-%s-%d] service=NULL,result=1, uniqueID=%s\n", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + pStPub->pRcvMsg->sysHeader.cUniqueId); + //pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; + rmb_errno = RMB_ERROR_GSL_SERVICE_ID_NULL; + return 1; + } + else if (result == 2) + { + + LOGRMB (RMB_LOG_INFO, + "GSL:[%s-%s-%s-%d] service error,result=2, uniqueID=%s\n", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + pStPub->pRcvMsg->sysHeader.cUniqueId); + //pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; + rmb_errno = RMB_ERROR_GSL_SERVICE_ID_ERROR; + return 2; + } + else if (result == 3) + { + LOGRMB (RMB_LOG_INFO, + "GSL:[%s-%s-%s-%d] gsl svr error,result=3, uniqueID=%s\n", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + pStPub->pRcvMsg->sysHeader.cUniqueId); + //pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; + rmb_errno = RMB_ERROR_GSL_SVR_ERROR; + //return 3; + return 4; + } + ////////////////////////////// + else if ((result & 0x0F) == 0x01) + { + int index = (result & 0xF0) >> 4; + LOGRMB (RMB_LOG_INFO, "GSL:[%s-%s-%s-%d] uId=%s, result=0x%02x, %s\n", + pTmpService->strServiceId, + pTmpService->strScenarioId, + pTmpService->strTargetOrgId, + (int) pTmpService->cFlagForOrgId, + pStPub->pRcvMsg->sysHeader.cUniqueId, + gsl_error[index].result, gsl_error[index].err_msg); + rmb_errno = RMB_ERROR_GSL_SERVICE_ID_NULL; + return 1; + } + else if ((result & 0x0F) == 0x02) + { + int index = ((result & 0xF0) >> 4) + 16; + LOGRMB (RMB_LOG_INFO, "GSL:[%s-%s-%s-%d] uId=%s, result=0x%02x, %s\n", + pTmpService->strServiceId, + pTmpService->strScenarioId, + pTmpService->strTargetOrgId, + (int) pTmpService->cFlagForOrgId, + pStPub->pRcvMsg->sysHeader.cUniqueId, + gsl_error[index].result, gsl_error[index].err_msg); + rmb_errno = RMB_ERROR_GSL_SERVICE_ID_ERROR; + return 2; + } + else if ((result & 0x0F) == 0x03) + { + int index = ((result & 0xF0) >> 4) + 32; + LOGRMB (RMB_LOG_INFO, "GSL:[%s-%s-%s-%d] uId=%s, result=0x%02x, %s\n", + pTmpService->strServiceId, + pTmpService->strScenarioId, + pTmpService->strTargetOrgId, + (int) pTmpService->cFlagForOrgId, + pStPub->pRcvMsg->sysHeader.cUniqueId, + gsl_error[index].result, gsl_error[index].err_msg); + rmb_errno = RMB_ERROR_GSL_SVR_ERROR; + return 4; + } + } + else + { + if (rmb_errno == RMB_ERROR_SEND_RR_MSG_TIMEOUT) + { + LOGRMB (RMB_LOG_ERROR, + "GSL:[%s-%s-%s-%d],send and receive from GSL timeout.\n", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId); + pTmpService->cResult = 3; + return 4; + } + + LOGRMB (RMB_LOG_ERROR, + "GSL:[%s-%s-%s-%d],send and recevie from GSL error,iRet=%d!\n", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + iRet); + //pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; + pTmpService->cResult = 3; + rmb_errno = RMB_ERROR_REQ_GSL_ERROR; + return 3; + } + return 0; +} + +/** + * 给gsl发染色消息 + */ + +int rmb_pub_send_dyed_msg_to_gsl (StRmbPub * pStPub) +{ + char cBizSeqNo[50] = ""; + char cConsumerSeqNo[50] = ""; + rmb_msg_random_uuid (cBizSeqNo, 32); + rmb_msg_random_uuid (cConsumerSeqNo, 32); + + rmb_msg_set_bizSeqNo (pStPub->pSendMsg, cBizSeqNo); + rmb_msg_set_consumerSeqNo (pStPub->pSendMsg, cConsumerSeqNo); + rmb_msg_set_orgSysId (pStPub->pSendMsg, pRmbStConfig->cConsumerSysId); + rmb_msg_set_dest_v2_1 (pStPub->pSendMsg, GSL_DEFAULT_DCN, + GSL_DEFAULT_SERVICE_ID, GSL_DEFAULT_SCENE_ID, + GSL_DEFAULT_COMMON_ORGID); + + rmb_msg_set_content (pStPub->pSendMsg, "", 0); + char appHeader[5] = "{}"; + rmb_msg_set_app_header (pStPub->pSendMsg, appHeader, strlen (appHeader)); + rmb_msg_set_dyedMsg (pStPub->pSendMsg, "true"); + + int iRet = + rmb_pub_send_and_receive (pStPub, pStPub->pSendMsg, pStPub->pRcvMsg, + pRmbStConfig->iQueryTimeout); + if (iRet == 1) + { + LOGRMB (RMB_LOG_DEBUG, "send dyed msg to GSL success,ret code is %d", + iRet); + } + rmb_msg_clear (pStPub->pSendMsg); + return iRet; +} + +//0:succ +//1:GSL服务id为空 +//2:GSL服务id路由错误 +//3:GSL服务器错误 +//-1:服务错误 + +int rmb_pub_send_gsl_and_insert_cache (StRmbPub * pStPub, StRmbMsg * pStMsg, + StServiceStatus * pTmpService, + StServiceStatus * hasCachedService) +{ + //pthread_mutex_lock(&pStPub->pubMutex); + if (hasCachedService != NULL) + { + //if (hasCachedService->ulGetTimes + pRmbStConfig->iCacheTimeoutTime * 1000 >= pRmbStConfig->ulNowTtime) + if (hasCachedService->ulInvalidTime >= pRmbStConfig->ulNowTtime) + { + //if (hasCachedService->cResult == 1) + if ((hasCachedService->cResult & 0x0F) == 0x01) + { + LOGRMB (RMB_LOG_ERROR, "Cache:[%s-%s-%s-%d] service=NULL", + pTmpService->strServiceId, + pTmpService->strScenarioId, + pTmpService->strTargetOrgId, + (int) pTmpService->cFlagForOrgId); + rmb_errno = RMB_ERROR_GSL_SERVICE_ID_NULL; + return 1; + } +// else if (hasCachedService->cResult == 2) +// { +// LOGRMB(RMB_LOG_ERROR, "Cache:[%s-%s-%s-%d] service error", +// pTmpService->strServiceId, +// pTmpService->strScenarioId, +// pTmpService->strTargetOrgId, +// (int)pTmpService->cFlagForOrgId +// ); +// rmb_errno = RMB_ERROR_GSL_SERVICE_ID_ERROR; +// return 2; +// } + else if (hasCachedService->cResult == 0) + { + if (hasCachedService->cRouteFlag == 0 + || hasCachedService->cRouteFlag == 1) + { + return 0; + } + else + { + //LOGRMB(RMB_LOG_DEBUG, "nowTime=%lu,Cache:[%s]", pRmbStConfig->ulNowTtime, rmb_printf_service_status(pStPub, tmpService)); + if (strcmp (pStMsg->strTargetDcn, hasCachedService->strTargetDcn) != + 0) + { + LOGRMB (RMB_LOG_INFO, "GSL DCN=%s is diffrent with input DCN=%s", + hasCachedService->strTargetDcn, pStMsg->strTargetDcn); + strncpy (pStMsg->strTargetDcn, hasCachedService->strTargetDcn, + sizeof (pStMsg->strTargetDcn) - 1); + //LOGRMB(RMB_LOG_INFO, "GSL DCN=%s is diffrent with input DCN=%s", hasCachedService->strTargetDcn, pStMsg->strTargetDcn); + } + return 0; + } + } + } + } + else + { + hasCachedService = + bsearch (pTmpService, pRmbStConfig->serviceStatusList, + pRmbStConfig->iCacheServiceNums, sizeof (StServiceStatus), + cmpServiceStatusStr); + if (hasCachedService != NULL) + { + //if (hasCachedService->ulGetTimes + pRmbStConfig->iCacheTimeoutTime * 1000 >= pRmbStConfig->ulNowTtime) + if (hasCachedService->ulInvalidTime >= pRmbStConfig->ulNowTtime) + { + //if (hasCachedService->cResult == 1) + if ((hasCachedService->cResult & 0x0F) == 0x01) + { + LOGRMB (RMB_LOG_ERROR, "Cache:[%s-%s-%s-%d] service=NULL", + pTmpService->strServiceId, + pTmpService->strScenarioId, + pTmpService->strTargetOrgId, + (int) pTmpService->cFlagForOrgId); + rmb_errno = RMB_ERROR_GSL_SERVICE_ID_NULL; + return 1; + } +// else if (hasCachedService->cResult == 2) +// { +// LOGRMB(RMB_LOG_ERROR, "Cache:[%s-%s-%s-%d] service error", +// pTmpService->strServiceId, +// pTmpService->strScenarioId, +// pTmpService->strTargetOrgId, +// (int)pTmpService->cFlagForOrgId +// ); +// rmb_errno = RMB_ERROR_GSL_SERVICE_ID_ERROR; +// return 2; +// } + else if (hasCachedService->cResult == 0) + { + if (hasCachedService->cRouteFlag == 0 + || hasCachedService->cRouteFlag == 1) + { + return 0; + } + else + { + //LOGRMB(RMB_LOG_DEBUG, "nowTime=%lu,Cache:[%s]", pRmbStConfig->ulNowTtime, rmb_printf_service_status(pStPub, tmpService)); + if (strcmp (pStMsg->strTargetDcn, hasCachedService->strTargetDcn) + != 0) + { + LOGRMB (RMB_LOG_INFO, + "GSL DCN=%s is diffrent with input DCN=%s", + hasCachedService->strTargetDcn, pStMsg->strTargetDcn); + strncpy (pStMsg->strTargetDcn, hasCachedService->strTargetDcn, + sizeof (pStMsg->strTargetDcn) - 1); + } + return 0; + } + } + } + } + } + int iRet = + rmb_pub_send_gsl (pStPub, pTmpService, pStMsg->sysHeader.cBizSeqNo, + pStMsg->sysHeader.cConsumerSeqNo); + if (iRet == 2 || iRet == 3) + { + pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; + if (hasCachedService != NULL) + { + hasCachedService->cResult = pTmpService->cResult; + hasCachedService->cRouteFlag = pTmpService->cRouteFlag; + } + return iRet; + } +// if (iRet == 3) +// { +// pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; +// pTmpService->ulInvalidTime = pRmbStConfig->ulNowTtime + pRmbStConfig->iCacheFailedTimeoutTime * 1000; +// //pthread_mutex_unlock(&pStPub->pubMutex); +// return 3; +// } + + if (iRet == 4) + { + pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; + pTmpService->ulInvalidTime = + pRmbStConfig->ulNowTtime + pRmbStConfig->iCacheFailedTimeoutTime * 1000; + if (hasCachedService != NULL) + { + if ((hasCachedService->cResult == 0) + || ((hasCachedService->cResult & 0x0F) == 0x01)) + { + hasCachedService->ulInvalidTime = + pRmbStConfig->ulNowTtime + + pRmbStConfig->iCacheFailedTimeoutTime * 1000; + } + } + return 4; + } + + //cache过期,且在本地存在 + if (hasCachedService != NULL) + { + pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; + + hasCachedService->cResult = pTmpService->cResult; + hasCachedService->cRouteFlag = pTmpService->cRouteFlag; + hasCachedService->ulGetTimes = pRmbStConfig->ulNowTtime; + if (hasCachedService->cResult == 0) + { + memcpy (hasCachedService->strTargetDcn, pTmpService->strTargetDcn, + sizeof (hasCachedService->strTargetDcn)); + } + if (iRet == 0 || iRet == 1) + { + hasCachedService->ulInvalidTime = + pRmbStConfig->ulNowTtime + pRmbStConfig->iCacheSuccTimeoutTime * 1000; + } + else + { + hasCachedService->ulInvalidTime = + pRmbStConfig->ulNowTtime + + pRmbStConfig->iCacheFailedTimeoutTime * 1000; + } + } + else + { //本地无cach + //本地无cache,且返回结果为2或3,则不缓存 + if (iRet == 2 || iRet == 3 || iRet == 4) + return iRet; + + pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; + if (iRet == 0 || iRet == 1) + { + pTmpService->ulInvalidTime = + pRmbStConfig->ulNowTtime + pRmbStConfig->iCacheSuccTimeoutTime * 1000; + } + else + { + pTmpService->ulInvalidTime = + pRmbStConfig->ulNowTtime + + pRmbStConfig->iCacheFailedTimeoutTime * 1000; + } + //select + StServiceStatus *pTmp = NULL; + if (pRmbStConfig->iCacheServiceNums >= MAX_SERVICE_STATUS_CACHE_NUMS) + { + //find the oldest cache + int i = 0; + //unsigned long ulMinTimestamp = 1 << (sizeof(unsigned long)-1); + unsigned long ulMinTimestamp = + pRmbStConfig->serviceStatusList[0].ulGetTimes; + for (; i < MAX_SERVICE_STATUS_CACHE_NUMS; i++) + { + if (ulMinTimestamp > pRmbStConfig->serviceStatusList[i].ulGetTimes) + { + ulMinTimestamp = pRmbStConfig->serviceStatusList[i].ulGetTimes; + pTmp = &pRmbStConfig->serviceStatusList[i]; + } + } + pRmbStConfig->iCacheServiceNums -= 1; + } + else + { + pTmp = + &pRmbStConfig->serviceStatusList[pRmbStConfig->iCacheServiceNums]; + } + memcpy (pTmp, pTmpService, sizeof (StServiceStatus)); + pRmbStConfig->iCacheServiceNums += 1; + //sort + qsort (pRmbStConfig->serviceStatusList, pRmbStConfig->iCacheServiceNums, + sizeof (StServiceStatus), cmpServiceStatusStr); + } + int i = 0; + for (; i < pRmbStConfig->iCacheServiceNums; i++) + { + LOGRMB (RMB_LOG_INFO, "cache%dth:[%s]", i, + rmb_printf_service_status (pStPub, + &pRmbStConfig->serviceStatusList[i])); + } + //pthread_mutex_unlock(&pStPub->pubMutex); + //return pTmpService->cResult; + return iRet; +} + +/** + * before 0.9.15 version + * req: subcmd(char) + targetOrgId(cStr) + selfDcn(cStr) + serverId(cStr) + scenseId(cStr) + flag(char)(0: user 1: api) + * rsp: subcmd(char) + result(char) + routeFlag(char) + targetDcn(cStr) + * + * 0.9.15: + * req: subcmd -- 0x11 + * rsp: result -- 0x11 0x21 ... + * result 0x1x -- cache 600s + * result 0x2x -- clean cache + * return: + * 0:success + * 1:null + * 2:serverId error + * 3:GSL server error + */ +int rmb_pub_get_target_dcn (StRmbPub * pStPub, StRmbMsg * pStMsg) +{ + //search cache + //int iFLagForReqGsl = 1; + StServiceStatus tmpStatus; + tmpStatus.ulInvalidTime = 0; + StServiceStatus *pTmpService = &tmpStatus; + + pTmpService->cFlagForOrgId = pStMsg->iFLagForOrgId; + if (pStMsg->iFLagForOrgId == RMB_COMMIT_BY_OWN) + { + strncpy (pTmpService->strTargetOrgId, pStMsg->strTargetOrgId, + sizeof (pTmpService->strTargetOrgId) - 1); + } + else + { + strncpy (pTmpService->strTargetOrgId, pRmbStConfig->strOrgId, + sizeof (pTmpService->strTargetOrgId) - 1); + } + strncpy (pTmpService->strServiceId, pStMsg->strServiceId, + sizeof (pTmpService->strServiceId) - 1); + strncpy (pTmpService->strScenarioId, pStMsg->strScenarioId, + sizeof (pTmpService->strScenarioId) - 1); + + StServiceStatus *tmpService = + bsearch (pTmpService, pRmbStConfig->serviceStatusList, + pRmbStConfig->iCacheServiceNums, sizeof (StServiceStatus), + cmpServiceStatusStr); + if (tmpService != NULL) + { + //if (tmpService->ulGetTimes + pRmbStConfig->iCacheTimeoutTime * 1000 >= pRmbStConfig->ulNowTtime) + if (tmpService->ulInvalidTime >= pRmbStConfig->ulNowTtime) + { + //if (tmpService->cResult == 1) +// if (tmpService->cResult == 0x11 || tmpService->cResult == 0x21 || tmpService->cResult == 0x31 || +// tmpService->cResult == 0x41 || tmpService->cResult == 0x51 || tmpService->cResult == 0x61) + if ((tmpService->cResult & 0x0F) == 0x01) + { + LOGRMB (RMB_LOG_ERROR, "Cache:[%s-%s-%s-%d] service=NULL", + pTmpService->strServiceId, + pTmpService->strScenarioId, + pTmpService->strTargetOrgId, + (int) pTmpService->cFlagForOrgId); + rmb_errno = RMB_ERROR_GSL_SERVICE_ID_NULL; + return 1; + } +// else if (tmpService->cResult == 2) +// { +// LOGRMB(RMB_LOG_ERROR, "Cache:[%s-%s-%s-%d] service error", +// pTmpService->strServiceId, +// pTmpService->strScenarioId, +// pTmpService->strTargetOrgId, +// (int)pTmpService->cFlagForOrgId +// ); +// rmb_errno = RMB_ERROR_GSL_SERVICE_ID_ERROR; +// return 2; +// } + else if (tmpService->cResult == 0) + { + if (tmpService->cRouteFlag == 0 || tmpService->cRouteFlag == 1) + { + return 0; + } + else + { + //LOGRMB(RMB_LOG_DEBUG, "nowTime=%lu,Cache:[%s]", pRmbStConfig->ulNowTtime, rmb_printf_service_status(pStPub, tmpService)); + if (strcmp (pStMsg->strTargetDcn, tmpService->strTargetDcn) != 0) + { + LOGRMB (RMB_LOG_INFO, "GSL DCN=%s is diffrent with input DCN=%s", + tmpService->strTargetDcn, pStMsg->strTargetDcn); + strncpy (pStMsg->strTargetDcn, tmpService->strTargetDcn, + sizeof (pStMsg->strTargetDcn) - 1); + //LOGRMB(RMB_LOG_INFO, "GSL DCN=%s is diffrent with input DCN=%s", tmpService->strTargetDcn, pStMsg->strTargetDcn); + } + return 0; + } + } + } + else + { + LOGRMB (RMB_LOG_INFO, "cache time out!nowTime=%lu, Cache:[%s] ", + pRmbStConfig->ulNowTtime, rmb_printf_service_status (pStPub, + tmpService)); + } + } + pthread_mutex_lock (&pStPub->pubMutex); + int iRet = + rmb_pub_send_gsl_and_insert_cache (pStPub, pStMsg, pTmpService, + tmpService); + pthread_mutex_unlock (&pStPub->pubMutex); + if (iRet != 0) + { +// if (iRet == 3 && tmpService != NULL) + if (iRet == 4 && tmpService != NULL && tmpService->cResult == 0) + { + //copy dcn to msg + if (tmpService->cRouteFlag == 2) + { + if (strcmp (pStMsg->strTargetDcn, tmpService->strTargetDcn) != 0) + { + LOGRMB (RMB_LOG_INFO, "GSL DCN=%s is diffrent with input DCN=%s", + tmpService->strTargetDcn, pStMsg->strTargetDcn); + strncpy (pStMsg->strTargetDcn, tmpService->strTargetDcn, + sizeof (pStMsg->strTargetDcn) - 1); + //LOGRMB(RMB_LOG_INFO, "GSL DCN=%s is diffrent with input DCN=%s", tmpService->strTargetDcn, pStMsg->strTargetDcn); + } + } + LOGRMB (RMB_LOG_ERROR, "ReqGsl error,but use cache! gsl=[%s],cache=%s", + rmb_printf_service_status (pStPub, pTmpService), + rmb_printf_service_status (pStPub, tmpService)); + return 0; + } + LOGRMB (RMB_LOG_ERROR, "ReqGsl gsl=[%s]", + rmb_printf_service_status (pStPub, pTmpService)); + return iRet; + } + else + { + //copy dcn to msg + // + if (pTmpService->cResult == 0 && pTmpService->cRouteFlag == 2) + { + if (strcmp (pStMsg->strTargetDcn, pTmpService->strTargetDcn) != 0) + { + LOGRMB (RMB_LOG_INFO, "GSL DCN=%s is diffrent with input DCN=%s", + pTmpService->strTargetDcn, pStMsg->strTargetDcn); + strncpy (pStMsg->strTargetDcn, pTmpService->strTargetDcn, + sizeof (pStMsg->strTargetDcn) - 1); + //LOGRMB(RMB_LOG_INFO, "GSL DCN=%s is diffrent with input DCN=%s", pTmpService->strTargetDcn, pStMsg->strTargetDcn); + } + } + LOGRMB (RMB_LOG_INFO, "ReqGsl succ! gsl=[%s]", + rmb_printf_service_status (pStPub, pTmpService)); + } + return 0; +} + +int rmb_pub_set_destination_Interval (StRmbPub * pStPub, StRmbMsg * pStMsg) +{ + //req gsl control + if (pRmbStConfig->iReqGsl == 1) + { + if (!strcmp (pStMsg->strServiceId, GSL_DEFAULT_SERVICE_ID)) + { + strncpy (pStMsg->strTargetDcn, GSL_DEFAULT_DCN, + sizeof (pStMsg->strTargetDcn) - 1); + } + else + { + int iRet = rmb_pub_get_target_dcn (pStPub, pStMsg); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_get_target_dcn error!iRet=%d", iRet); + return iRet; + } + } + } + + if (pStMsg->iEventOrService == RMB_EVENT_CALL) + { + snprintf (pStMsg->dest.cDestName, sizeof (pStMsg->dest.cDestName), + "%s/e/%s/%s/%c", pStMsg->strTargetDcn, pStMsg->strServiceId, + pStMsg->strScenarioId, *(pStMsg->strServiceId + 3)); + } + else + { + snprintf (pStMsg->dest.cDestName, sizeof (pStMsg->dest.cDestName), + "%s/s/%s/%s/%c", pStMsg->strTargetDcn, pStMsg->strServiceId, + pStMsg->strScenarioId, *(pStMsg->strServiceId + 3)); + } + pStMsg->dest.iDestType = RMB_DEST_TOPIC; + + //set pub message to wemq + rmb_pub_send_mode (pStPub, pStMsg); + + return 0; +} + +/** + * Function: rmb_pub_init + * Description: rmb pub initialize + * Return: + * 0: success + * -1: failed + */ +int rmb_pub_init (StRmbPub * pRmbPub) +{ + if (pRmbPub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbPub arg is null\n"); + rmb_errno = RMB_ERROR_ARGV_NULL; + return -1; + } + + if (pRmbPub->uiContextNum == 1) + { + LOGRMB (RMB_LOG_ERROR, "pRmbPub has already init!"); + return 0; + } + pRmbPub->pContext = (StContext *) malloc (sizeof (StContext)); + if (pRmbPub->pContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbPub->pContext malloc error!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + pRmbStConfig->uiPid = (unsigned int) getpid (); + memset (pRmbPub->pContext, 0, sizeof (StContext)); + pRmbPub->pContext->contextType = RMB_CONTEXT_TYPE_PUB; + + int iRet = rmb_context_init (pRmbPub->pContext); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_init failed!iRet=%d,error=%s", iRet, + get_rmb_last_error ()); + rmb_errno = RMB_ERROR_INIT_CONTEXT_FAIL; + return -3; + } + pRmbPub->uiContextNum = 1; + pRmbPub->pContext->pFather = (void *) pRmbPub; + + pRmbPub->ulLastTime = 0; + //rmb_pub_rand(pRmbPub); + + pRmbPub->pSendMsg = rmb_msg_malloc (); + if (pRmbPub->pSendMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_init malloc failed!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + + //pRmbPub->pRcvMsg = (StRmbMsg*)malloc(sizeof(StRmbMsg)); + pRmbPub->pRcvMsg = rmb_msg_malloc (); + if (pRmbPub->pRcvMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_init malloc failed!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + pthread_mutex_init (&pRmbPub->pubMutex, NULL); + rmb_pub_send_dyed_msg_to_gsl (pRmbPub); + + return 0; +} + +/** + * Function: rmb_pub_init_python + * Description: rmb pub initialize + * Return: + * 0: success + * -1: failed + */ +int rmb_pub_init_python () +{ + pRmbGlobalPub = (StRmbPub *) calloc (1, sizeof (StRmbPub)); + if (pRmbGlobalPub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbGlobalPub arg is null\n"); + rmb_errno = RMB_ERROR_ARGV_NULL; + return -1; + } + + rmb_pub_init (pRmbGlobalPub); + + return 0; +} + +int rmb_pub_send_msg_to_wemq (StRmbPub * pRmbPub, StRmbMsg * pMsg) +{ + if (pRmbPub == NULL || pMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbPub or pMsg is null"); + return -1; + } + + //check dest is set + if (rmb_check_msg_valid (pMsg) != 0) + { + rmb_errno = RMB_ERROR_MSG_MISSING_PART; + return -2; + } + + if (pMsg->iEventOrService == (int) RMB_SERVICE_CALL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb pub event interface can't send rr msg,serviceId=%s!\n", + pMsg->strServiceId); + rmb_errno = RMB_ERROR_EVENT_INTERFACE_CAN_NOT_SEND_RR_MSG; + return -3; + } + + int iRet = 0; + + iRet = rmb_msg_init (pMsg, pRmbStConfig, C_TYPE_WEMQ); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_msg_init failed!iRet=%d\n", iRet); + return -5; + } + + if (pMsg->ulMsgLiveTime == 0 + || pMsg->ulMsgLiveTime > DEFAULT_MSG_MAX_LIVE_TIME) + { + pMsg->ulMsgLiveTime = DEFAULT_MSG_MAX_LIVE_TIME; + } + + pMsg->cLogicType = EVENT_PKG_IN_WEMQ; + GetRmbNowLongTime (); + pMsg->sysHeader.ulSendTime = pRmbStConfig->ulNowTtime; + + StContext *pStContext = pRmbPub->pContext; + pStContext->uiPkgLen = MAX_LENTH_IN_A_MSG; + + if (pMsg->ulMsgLiveTime == 0 + || pMsg->ulMsgLiveTime > DEFAULT_MSG_MAX_LIVE_TIME) + { + pMsg->ulMsgLiveTime = DEFAULT_MSG_MAX_LIVE_TIME; + } + + stContextProxy *pContextProxy = pStContext->pContextProxy; + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_MSG; + iRet = + rmb_pub_encode_thread_msg (stThreadMsg.m_iCmd, &stThreadMsg, pMsg, + pMsg->ulMsgLiveTime); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_pub_encode_thread_msg error!"); + rmb_send_log_for_error (pStContext->pContextProxy, RMB_ERROR_ENCODE_FAIL, + "wemq_pub_encode_thread_msg error", pMsg); + return iRet; + } + + pthread_mutex_lock (&pContextProxy->eventMutex); + iRet = wemq_kfifo_put (&pContextProxy->pubFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error!,iRet=%d", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + rmb_send_log_for_error (pStContext->pContextProxy, + RMB_ERROR_WORKER_PUT_FIFO_ERROR, + "wemq_kfifo_put error", pMsg); + return -5; + } + + struct timeval tv; + gettimeofday (&tv, NULL); + struct timespec ts_timeout; + ts_timeout.tv_sec = + tv.tv_sec + (tv.tv_usec / 1000 + pRmbStConfig->accessAckTimeOut) / 1000; + ts_timeout.tv_nsec = + ((tv.tv_usec / 1000 + + pRmbStConfig->accessAckTimeOut) % 1000) * 1000 * 1000; + + pContextProxy->iFlagForEvent = -1; + if (pContextProxy->iFlagForEvent == -1) + { + //reset seq + pContextProxy->iSeqForEvent = g_iSendReqForEvent; + LOGRMB (RMB_LOG_DEBUG, "reset seq:%ld, pContextProxy->iSeqForEvent:%ld", + g_iSendReqForEvent, pContextProxy->iSeqForEvent); + + pthread_cond_timedwait (&pContextProxy->eventCond, + &pContextProxy->eventMutex, &ts_timeout); + + } + pthread_mutex_unlock (&pContextProxy->eventMutex); + + switch (pContextProxy->iFlagForEvent) + { + case RMB_CODE_TIME_OUT: + LOGRMB (RMB_LOG_ERROR, "time out!req=%s", rmb_msg_print (pMsg)); + rmb_errno = RMB_ERROR_SEND_EVENT_MSG_FAIL; + rmb_send_log_for_error (pStContext->pContextProxy, + RMB_ERROR_SEND_EVENT_MSG_FAIL, + "wemq send event msg ack timeout", pMsg); + return -6; + case RMB_CODE_SUSS: + LOGRMB (RMB_LOG_DEBUG, "send msg succ!req=%s\n", rmb_msg_print (pMsg)); + return 0; + case RMB_CODE_OTHER_FAIL: + LOGRMB (RMB_LOG_ERROR, "send msg failed!req=%s", rmb_msg_print (pMsg)); + return -6; + case RMB_CODE_AUT_FAIL: + LOGRMB (RMB_LOG_ERROR, "Authentication failed!req=%s", + rmb_msg_print (pMsg)); + return -5; + } + +} + +static int rmb_pub_send_and_receive_to_wemq (StRmbPub * pRmbPub, + StRmbMsg * pSendMsg, + StRmbMsg * pRevMsg, + unsigned int uiTimeOut) +{ + RMB_CHECK_POINT_NULL (pRmbPub, "pRmbPub"); + RMB_CHECK_POINT_NULL (pSendMsg, "pSendMsg"); + RMB_CHECK_POINT_NULL (pRevMsg, "pRevMsg"); + + if (pSendMsg->iEventOrService == (int) RMB_EVENT_CALL) + { + LOGRMB (RMB_LOG_ERROR, "rr interface can't send event msg!"); + rmb_errno = RMB_ERROR_RR_INTERFACE_CAN_NOT_SEND_EVENT_MSG; + return -1; + } + + int iRet = 0; + + iRet = rmb_msg_init (pSendMsg, pRmbStConfig, C_TYPE_WEMQ); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_msg_init failed!iRet=%d", iRet); + return -3; + } + + if (pSendMsg->ulMsgLiveTime == 0 + || pSendMsg->ulMsgLiveTime > DEFAULT_MSG_MAX_LIVE_TIME) + { + pSendMsg->ulMsgLiveTime = uiTimeOut; + } + + pSendMsg->cLogicType = REQ_PKG_IN_WEMQ; + GetRmbNowLongTime (); + pSendMsg->sysHeader.ulSendTime = pRmbStConfig->ulNowTtime; + + StContext *pStContext = pRmbPub->pContext; + pStContext->uiPkgLen = MAX_LENTH_IN_A_MSG; + stContextProxy *pContextProxy = pStContext->pContextProxy; + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_REQUEST; + iRet = + rmb_pub_encode_thread_msg (stThreadMsg.m_iCmd, &stThreadMsg, pSendMsg, + uiTimeOut); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_pub_encode_thread_msg error!"); + rmb_send_log_for_error (pStContext->pContextProxy, RMB_ERROR_ENCODE_FAIL, + "wemq_pub_encode_thread_msg error", pSendMsg); + return -4; + } + + pthread_mutex_lock (&pContextProxy->rrMutex); + iRet = wemq_kfifo_put (&pContextProxy->pubFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error!iRet=%d", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + rmb_send_log_for_error (pStContext->pContextProxy, + RMB_ERROR_WORKER_PUT_FIFO_ERROR, + "wemq_kfifo_put error", pSendMsg); + return -5; + } + + struct timeval tv; + gettimeofday (&tv, NULL); + struct timespec ts_timeout; + ts_timeout.tv_sec = tv.tv_sec + (tv.tv_usec / 1000 + uiTimeOut) / 1000; + ts_timeout.tv_nsec = ((tv.tv_usec / 1000 + uiTimeOut) % 1000) * 1000 * 1000; + + int i = 0; + unsigned int uiUniqueLen = strlen (pSendMsg->sysHeader.cUniqueId); + pContextProxy->iFlagForRR = -1; + + if (pContextProxy->iFlagForRR == -1) + { + //add uniqueId + strncpy (pContextProxy->stUnique.unique_id, pSendMsg->sysHeader.cUniqueId, + uiUniqueLen); + pContextProxy->stUnique.unique_id[uiUniqueLen] = '\0'; + pContextProxy->stUnique.flag = 1; + + } + + pthread_cond_timedwait (&pContextProxy->rrCond, &pContextProxy->rrMutex, + &ts_timeout); + + if (pContextProxy->iFlagForRR == RMB_CODE_TIME_OUT) + { + pContextProxy->stUnique.flag = 0; + + } + pthread_mutex_unlock (&pContextProxy->rrMutex); + + switch (pContextProxy->iFlagForRR) + { + case RMB_CODE_TIME_OUT: + LOGRMB (RMB_LOG_ERROR, "time out!req=%s", rmb_msg_print (pSendMsg)); + rmb_errno = RMB_ERROR_SEND_RR_MSG_TIMEOUT; + rmb_send_log_for_error (pStContext->pContextProxy, + RMB_ERROR_SEND_RR_MSG_TIMEOUT, + "wemq send rr msg timeout", pSendMsg); + return -6; + case RMB_CODE_SUSS: + trans_json_2_rmb_msg (pRevMsg, pContextProxy->mPubRRBuf, + RESPONSE_TO_CLIENT); + LOGRMB (RMB_LOG_DEBUG, "receive reply succ,buf:%s", + pContextProxy->mPubRRBuf); + pRevMsg->cPkgType = RR_TOPIC_PKG; + return 0; + case RMB_CODE_OTHER_FAIL: + LOGRMB (RMB_LOG_ERROR, "receive reply failed!req=%s", + rmb_msg_print (pSendMsg)); + rmb_errno = RMB_ERROR_SEND_RR_MSG_TIMEOUT; + return -4; + case RMB_CODE_AUT_FAIL: + LOGRMB (RMB_LOG_ERROR, "receive reply Authentication failed!req=%s", + rmb_msg_print (pSendMsg)); + rmb_errno = RMB_ERROR_SEND_RR_MSG_TIMEOUT; + return -5; + case RMB_CODE_DYED_MSG: + LOGRMB (RMB_LOG_INFO, "receive dyed msg:%s", pContextProxy->mPubRRBuf); + return 1; + } + +} + +int rmb_pub_send_rr_msg_async_to_wemq (StRmbPub * pRmbPub, + StRmbMsg * pSendMsg, + unsigned int uiTimeOut) +{ + RMB_CHECK_POINT_NULL (pRmbPub, "pRmbPub"); + RMB_CHECK_POINT_NULL (pSendMsg, "pSendMsg"); + + if (pSendMsg->iEventOrService == (int) RMB_EVENT_CALL) + { + LOGRMB (RMB_LOG_ERROR, "async rr interface can't send event msg!"); + rmb_errno = RMB_ERROR_RR_INTERFACE_CAN_NOT_SEND_EVENT_MSG; + return -1; + } + + //pub connect status error + //if (pRmbPub->pContext->pContextProxy->iFlagForPublish == 0) { + // LOGRMB(RMB_LOG_ERROR, "rmb pub not connect to access!!!"); + // return -4; + //} + + int iRet = 0; +// iRet = rmb_pub_set_destination_Interval(pRmbPub, pSendMsg); +// if (iRet != 0) { +// LOGRMB(RMB_LOG_ERROR, "rmb set destination error!serviceId=%s,sceneId=%s,iRet=%d", pSendMsg->strServiceId, pSendMsg->strScenarioId, iRet); +// return -2; +// } + LOGRMB (RMB_LOG_DEBUG, "pubMsg dest=%d,%s,replyTo=%s", + pSendMsg->dest.iDestType, pSendMsg->dest.cDestName, + pSendMsg->replyTo.cDestName); + + iRet = rmb_msg_init (pSendMsg, pRmbStConfig, C_TYPE_WEMQ); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_msg_init failed!iRet=%d", iRet); + return -3; + } + + if (uiTimeOut > RR_ASYNC_MSG_MAX_LIVE_TIME) + { + LOGRMB (RMB_LOG_ERROR, "RR sync ttl too large, max value is:%ld", + RR_ASYNC_MSG_MAX_LIVE_TIME); + return -4; + } + + if (pSendMsg->ulMsgLiveTime == 0 + || pSendMsg->ulMsgLiveTime > DEFAULT_MSG_MAX_LIVE_TIME) + { + pSendMsg->ulMsgLiveTime = uiTimeOut; + } + + GetRmbNowLongTime (); + pSendMsg->sysHeader.ulSendTime = pRmbStConfig->ulNowTtime; + pSendMsg->replyTo.iDestType = RMB_DEST_TOPIC; + + StContext *pStContext = pRmbPub->pContext; + pStContext->uiPkgLen = MAX_LENTH_IN_A_MSG; + stContextProxy *pContextProxy = pStContext->pContextProxy; + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_REQUEST_ASYNC; + iRet = + rmb_pub_encode_thread_msg (stThreadMsg.m_iCmd, &stThreadMsg, pSendMsg, 0); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_pub_encode_thread_msg error!"); + rmb_send_log_for_error (pStContext->pContextProxy, RMB_ERROR_ENCODE_FAIL, + "wemq_pub_encode_thread_msg error", pSendMsg); + return iRet; + } + unsigned int uiUniqueLen = strlen (pSendMsg->sysHeader.cUniqueId); + int i = 0; + struct timeval tv_now; + gettimeofday (&tv_now, NULL); + unsigned long ulNowTime = tv_now.tv_sec * 1000 + tv_now.tv_usec / 1000; + int iFlagForList = 0; + for (i = 0; + i < + pContextProxy->pUniqueListForRRAsyncNew. + get_array_size (&pContextProxy->pUniqueListForRRAsyncNew); i++) + { + + if (pContextProxy->pUniqueListForRRAsyncNew.Data[i].flag == 0) + { + pthread_mutex_lock (&pContextProxy->rrMutex); + snprintf (pContextProxy->pUniqueListForRRAsyncNew.Data[i].unique_id, + sizeof (pContextProxy->pUniqueListForRRAsyncNew.Data[i]. + unique_id), "%s", pSendMsg->sysHeader.cUniqueId); + snprintf (pContextProxy->pUniqueListForRRAsyncNew.Data[i].biz_seq, + sizeof (pContextProxy->pUniqueListForRRAsyncNew.Data[i]. + biz_seq), "%s", pSendMsg->sysHeader.cBizSeqNo); + pContextProxy->pUniqueListForRRAsyncNew.Data[i].flag = 1; + pContextProxy->pUniqueListForRRAsyncNew.Data[i].timeStamp = ulNowTime; + pContextProxy->pUniqueListForRRAsyncNew.Data[i].timeout = uiTimeOut; + iFlagForList = 1; + pthread_mutex_unlock (&pContextProxy->rrMutex); + break; + } + } + //已有空间已装满 + if (iFlagForList == 0) + { + LOGRMB (RMB_LOG_INFO, "local list for rr async push back"); + StUniqueIdList uniqueIdList; + strncpy (uniqueIdList.unique_id, pSendMsg->sysHeader.cUniqueId, + uiUniqueLen); + uniqueIdList.unique_id[uiUniqueLen] = '\0'; + uniqueIdList.flag = 1; + uniqueIdList.timeStamp = ulNowTime; + uniqueIdList.timeout = uiTimeOut; + pthread_mutex_lock (&pContextProxy->rrMutex); + pContextProxy->pUniqueListForRRAsyncNew.Input (uniqueIdList, + &pContextProxy-> + pUniqueListForRRAsyncNew); + pthread_mutex_unlock (&pContextProxy->rrMutex); + } + iRet = wemq_kfifo_put (&pContextProxy->pubFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error!iRet=%d", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + rmb_send_log_for_error (pStContext->pContextProxy, + RMB_ERROR_WORKER_PUT_FIFO_ERROR, + "wemq_kfifo_put error", pSendMsg); + return -4; + } + + pContextProxy->iFlagForRRAsync = 1; + return 0; +} + +/** +Function: wemq_pub_reply_msg +Description:send report packet +Retrun: + 0 --success + -1 --failed +*/ +int rmb_pub_reply_msg_for_wemq (StRmbPub * pRmbPub, StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg) +{ + if (pRmbPub == NULL || pStReceiveMsg == NULL || pStReplyMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbPub or pStReceiveMsg or pStReplyMsg is null"); + return -1; + } + + if (strlen (pStReceiveMsg->replyTo.cDestName) == 0) + { + LOGRMB (RMB_LOG_ERROR, "receiveMsg has no replyTo,can't reply!\n"); + return -2; + } + + //pub connect status error + //if (pRmbPub->pContext->pContextProxy->iFlagForPublish == 0) { + // LOGRMB(RMB_LOG_ERROR, "rmb pub not connect to access!!!"); + // return -4; + //} + + memcpy (&pStReplyMsg->sysHeader, &pStReceiveMsg->sysHeader, + sizeof (pStReceiveMsg->sysHeader)); + memcpy (&pStReplyMsg->dest, &pStReceiveMsg->replyTo, + sizeof (pStReceiveMsg->replyTo)); + + //serviceId + memcpy (pStReplyMsg->strServiceId, pStReceiveMsg->strServiceId, + sizeof (pStReceiveMsg->strServiceId)); + //scenarioId + memcpy (pStReplyMsg->strScenarioId, pStReceiveMsg->strScenarioId, + sizeof (pStReceiveMsg->strScenarioId)); + //dcn + memcpy (pStReplyMsg->strTargetDcn, pStReceiveMsg->strTargetDcn, + sizeof (pStReceiveMsg->strTargetDcn)); + //organization + memcpy (pStReplyMsg->strTargetOrgId, pStReceiveMsg->strTargetOrgId, + sizeof (pStReceiveMsg->strTargetOrgId)); + //ttl + pStReplyMsg->ulMsgLiveTime = pStReceiveMsg->ulMsgLiveTime; + + strncpy (pStReplyMsg->cCorrId, pStReceiveMsg->cCorrId, + sizeof (pStReceiveMsg->cCorrId)); + pStReplyMsg->iCorrLen = pStReceiveMsg->iCorrLen; + pStReplyMsg->cApiType = C_TYPE_WEMQ; + pStReplyMsg->cLogicType = RSP_PKG_OUT_WEMQ; + + GetRmbNowLongTime (); + pStReplyMsg->sysHeader.ulReplyTime = pRmbStConfig->ulNowTtime; +/* + while (CURRENT_WINDOW_SIZE >= DEFAULT_WINDOW_SIZE) { + LOGRMB(RMB_LOG_ERROR, "Send Window Full, recvSeq=%u,sendSeq=%u", g_uiRecvMsgSeq, g_uiSendMsgSeq); + usleep(1000); + } +*/ + StContext *pStContext = pRmbPub->pContext; + pStContext->uiPkgLen = MAX_LENTH_IN_A_MSG; + stContextProxy *pContextProxy = pStContext->pContextProxy; + + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_REPLY; + int iRet = 0; + iRet = + rmb_pub_encode_thread_msg (stThreadMsg.m_iCmd, &stThreadMsg, pStReplyMsg, + 0); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_thread_msg error!"); + rmb_send_log_for_error (pStContext->pContextProxy, RMB_ERROR_ENCODE_FAIL, + "wemq_reply_encode_thread_msg error", + pStReplyMsg); + return iRet; + } + + iRet = wemq_kfifo_put (&pContextProxy->pubFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error!iRet=%d", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + rmb_send_log_for_error (pStContext->pContextProxy, + RMB_ERROR_WORKER_PUT_FIFO_ERROR, + "reply message wemq_kfifo_put error", + pStReplyMsg); + return rmb_errno; + } + + return 0; +} + +/** + * Function: rmb_pub_send_msg + * Description: send event msg + * Return: + * 0: success + * -1: failed + * -2: queue full + */ +int rmb_pub_send_msg (StRmbPub * pRmbPub, StRmbMsg * pStMsg) +{ + + RMB_CHECK_POINT_NULL (pRmbPub, "pRmbPub"); + RMB_CHECK_POINT_NULL (pStMsg, "pStMsg"); + + if (rmb_check_msg_valid (pStMsg) != 0) + { + rmb_errno = RMB_ERROR_MSG_MISSING_PART; + return rmb_errno; + } + + if (pStMsg->iEventOrService == (int) RMB_SERVICE_CALL) + { + LOGRMB (RMB_LOG_ERROR, "event interface can't send rr msg,serviceId=%s!", + pStMsg->strServiceId); + rmb_errno = RMB_ERROR_EVENT_INTERFACE_CAN_NOT_SEND_RR_MSG; + return rmb_errno; + } + + int iRet = rmb_pub_set_destination_Interval (pRmbPub, pStMsg); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb set destination error!serviceId=%s,sceneId=%s,iRet=%d,error=%s", + pStMsg->strServiceId, pStMsg->strScenarioId, iRet, + get_rmb_last_error ()); + return rmb_errno; + } + + return rmb_pub_send_msg_to_wemq (pRmbPub, pStMsg); + +} + +/** + * Function: rmb_pub_send_msg_python + * Description: send event msg_python + * Return: + * 0: success + * -1: failed + * -2: queue full + */ +int rmb_pub_send_msg_python (StRmbMsg * pStMsg) +{ + StRmbPub *pRmbPub = pRmbGlobalPub; + + return rmb_pub_send_msg (pRmbPub, pStMsg); + +} + +/** +Function: rmb_pub_send_rr_msg +Description:send RR asynchronous message +Retrun: + 0 --success + -1 --failed + -2 --queue full +*/ +int rmb_pub_send_rr_msg_async (StRmbPub * pRmbPub, StRmbMsg * pStMsg, + unsigned int uiTimeOut) +{ + RMB_CHECK_POINT_NULL (pRmbPub, "pRmbPub"); + RMB_CHECK_POINT_NULL (pStMsg, "pStMsg"); + + if (pStMsg->iEventOrService == (int) RMB_EVENT_CALL) + { + LOGRMB (RMB_LOG_ERROR, "aync RR interface can't send event msg!"); + rmb_errno = RMB_ERROR_RR_INTERFACE_CAN_NOT_SEND_EVENT_MSG; + return rmb_errno; + } + + //set destination + int iRet = rmb_pub_set_destination_Interval (pRmbPub, pStMsg); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb set destination error!serviceId=%s,sceneId=%s,iRet=%d", + pStMsg->strServiceId, pStMsg->strScenarioId, iRet); + return rmb_errno; + } + + return rmb_pub_send_rr_msg_async_to_wemq (pRmbPub, pStMsg, uiTimeOut); + +} + +/** +Function: rmb_pub_send_rr_msg_async_python +Description:send RR asynchronous message +Retrun: + 0 --success + -1 --failed + -2 --queue full +*/ +int rmb_pub_send_rr_msg_async_python (StRmbMsg * pStMsg, + unsigned int uiTimeOut) +{ + StRmbPub *pRmbPub = pRmbGlobalPub; + + return rmb_pub_send_rr_msg_async (pRmbPub, pStMsg, uiTimeOut); +} + +/** +Function: rmb_pub_send_and_receive +Description:send message and wait for report +Retrun: + 0 --success + -1 --timeout + -2 --error +*/ +int rmb_pub_send_and_receive (StRmbPub * pRmbPub, StRmbMsg * pSendMsg, + StRmbMsg * pRevMsg, unsigned int uiTimeOut) +{ + RMB_CHECK_POINT_NULL (pRmbPub, "pRmbPub"); + RMB_CHECK_POINT_NULL (pSendMsg, "pSendMsg"); + RMB_CHECK_POINT_NULL (pRevMsg, "pRevMsg"); + + if (pSendMsg->iEventOrService == (int) RMB_EVENT_CALL) + { + LOGRMB (RMB_LOG_ERROR, "RR interface can't send event msg!"); + rmb_errno = RMB_ERROR_RR_INTERFACE_CAN_NOT_SEND_EVENT_MSG; + return rmb_errno; + } + + //set destination + int iRet = rmb_pub_set_destination_Interval (pRmbPub, pSendMsg); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb set destination error!serviceId=%s,sceneId=%s,iRet=%d", + pSendMsg->strServiceId, pSendMsg->strScenarioId, iRet); + return rmb_errno; + } + + return rmb_pub_send_and_receive_to_wemq (pRmbPub, pSendMsg, pRevMsg, + uiTimeOut); + +} + +int rmb_pub_send_and_receive_python (StRmbMsg * pSendMsg, StRmbMsg * pRevMsg, + unsigned int uiTimeOut) +{ + StRmbPub *pRmbPub = pRmbGlobalPub; + + return rmb_pub_send_and_receive (pRmbPub, pSendMsg, pRevMsg, uiTimeOut); +} + +/** +Function: rmb_pub_reply_msg +Description:send report packet +Retrun: + 0 --success + -1 --failed +*/ +int rmb_pub_reply_msg (StRmbPub * pRmbPub, StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg) +{ + RMB_CHECK_POINT_NULL (pRmbPub, "pRmbPub"); + RMB_CHECK_POINT_NULL (pStReceiveMsg, "pStReceiveMsg"); + RMB_CHECK_POINT_NULL (pStReplyMsg, "pStReplyMsg"); + if (strlen (pStReceiveMsg->replyTo.cDestName) == 0) + { + //LOGRMB(RMB_LOG_INFO, "rmb receivemsg reply destname empty"); + LOGRMB (RMB_LOG_WARN, "pStReceiveMsg->replyTo.cDestName=%s", + pStReceiveMsg->replyTo.cDestName); + return 0; + } + return rmb_pub_reply_msg_for_wemq (pRmbPub, pStReceiveMsg, pStReplyMsg); + +} + +/** +Function: rmb_pub_close +Description:close pub +Retrun: + 0 --success + -1 --failed +*/ +int rmb_pub_close (StRmbPub * pRmbPub) +{ + if (pRmbPub == NULL || pRmbPub->pContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbPub or pRmbPub->pContext is null"); + return 0; + } + + //wemq + if (pRmbStConfig->iConnWemq == 1 || pRmbStConfig->iApiLogserverSwitch == 1) + { + if (pRmbPub->pContext->pContextProxy != NULL) + { + stContextProxy *pContextProxy = pRmbPub->pContext->pContextProxy; + + //pContextProxy->iFlagForRun = 0; + if (rmb_pub_send_client_goodbye_to_wemq (pRmbPub) != 0) + { + LOGRMB (RMB_LOG_DEBUG, "rmb_pub_send_client_goodbye_to_wemq failed"); + } + pContextProxy->iFlagForRun = 0; + GetRmbNowLongTime (); + pContextProxy->ulGoodByeTime = pRmbStConfig->ulNowTtime; + LOGRMB (RMB_LOG_DEBUG, "pthread_join mainThreadId"); + if (pContextProxy->mainThreadId != 0) + { + pthread_join (pContextProxy->mainThreadId, NULL); + } + + LOGRMB (RMB_LOG_DEBUG, "pthread_join coThreadId"); + if (pContextProxy->coThreadId != 0) + { + pthread_join (pContextProxy->coThreadId, NULL); + } + } + } + return 0; +} + +int rmb_pub_close_python () +{ + StRmbPub *pRmbPub = pRmbGlobalPub; + + int ret = rmb_pub_close_v2 (pRmbPub); + free (pRmbPub); + return ret; +} + +/** +Function: rmb_pub_close_v2 +Description:close pub +Retrun: + 0 --success + -1 --failed +*/ +int rmb_pub_close_v2 (StRmbPub * pRmbPub) +{ + if (pRmbPub == NULL || pRmbPub->pContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbPub or pRmbPub->pContext is null"); + return 0; + } + + //wemq + if (pRmbStConfig->iConnWemq == 1 || pRmbStConfig->iApiLogserverSwitch == 1) + { + if (pRmbPub->pContext->pContextProxy != NULL) + { + stContextProxy *pContextProxy = pRmbPub->pContext->pContextProxy; + + pContextProxy->iFlagForRun = 0; + GetRmbNowLongTime (); + pContextProxy->ulGoodByeTime = pRmbStConfig->ulNowTtime; + LOGRMB (RMB_LOG_DEBUG, "pthread_join mainThreadId"); + if (pContextProxy->mainThreadId != 0) + { + pthread_join (pContextProxy->mainThreadId, NULL); + } + + LOGRMB (RMB_LOG_DEBUG, "pthread_join coThreadId"); + if (pContextProxy->coThreadId != 0) + { + pthread_join (pContextProxy->coThreadId, NULL); + } + } + } + + return 0; +} + +int rmb_pub_send_client_goodbye_to_wemq (StRmbPub * pRmbPub) +{ + RMB_CHECK_POINT_NULL (pRmbPub, "pRmbPub"); + + stContextProxy *pContextProxy = pRmbPub->pContext->pContextProxy; + + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_CLIENT_GOODBYE; + + WEMQJSON *jsonHeader = json_object_new_object (); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object failed"); + return -2; + } + //add type + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (CLIENT_GOODBYE_REQUEST)); + //add seq + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + //add status + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "header is null"); + json_object_put (jsonHeader); + return -2; + } + + stThreadMsg.m_iHeaderLen = strlen (header_str); + LOGRMB (RMB_LOG_DEBUG, "Get thread msg header succ, len=%u, %s", + stThreadMsg.m_iHeaderLen, header_str) stThreadMsg.m_pHeader = + (char *) malloc ((stThreadMsg.m_iHeaderLen + 1) * sizeof (char)); + if (stThreadMsg.m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for stThreadMsg.m_pHeader failed"); + json_object_put (jsonHeader); + return -2; + } + memcpy (stThreadMsg.m_pHeader, header_str, stThreadMsg.m_iHeaderLen); + stThreadMsg.m_pHeader[stThreadMsg.m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + + stThreadMsg.m_iBodyLen = 0; + stThreadMsg.m_pBody = NULL; + + int iRet = wemq_kfifo_put (&pContextProxy->pubFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error,iRet=%d!\n", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + return rmb_errno; + } + + struct timeval nowTimeVal; + gettimeofday (&nowTimeVal, NULL); + struct timespec timeout; + timeout.tv_sec = + nowTimeVal.tv_sec + (nowTimeVal.tv_usec / 1000 + + pRmbStConfig->goodByeTimeOut) / 1000; + timeout.tv_nsec = + ((nowTimeVal.tv_usec / 1000 + + pRmbStConfig->goodByeTimeOut) % 1000) * 1000 * 1000; + + pContextProxy->iFlagForGoodBye = 0; + pthread_mutex_lock (&pContextProxy->goodByeMutex); + if (pContextProxy->iFlagForGoodBye == 0) + { + pthread_cond_timedwait (&pContextProxy->goodByeCond, + &pContextProxy->goodByeMutex, &timeout); + } + pthread_mutex_unlock (&pContextProxy->goodByeMutex); + + if (pContextProxy->iFlagForGoodBye != 1) + { + LOGRMB (RMB_LOG_ERROR, "send pub client goodBye timeout!"); + rmb_errno = RMB_ERROR_CLIENT_GOODBYE_TIMEOUT; + return rmb_errno; + } + + LOGRMB (RMB_LOG_DEBUG, "send and recv sub client goodbye succ"); + + return 0; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_sub.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_sub.c new file mode 100644 index 0000000000..7ca7ea4b73 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_sub.c @@ -0,0 +1,1379 @@ +// 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. + +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "rmb_common.h" +#include "rmb_errno.h" +#include "rmb_sub.h" +#include "rmb_udp.h" +#include "rmb_pub.h" +#include "rmb_list.h" +#include "rmb_context.h" +#include "wemq_thread.h" + +#define SRV_GOV_DATA_LVQ "SRV_GOV_DATA_LVQ" +#define SRV_BROADCAST_LVQ "BROADCAST_DATA_LVQ" + +#define atomic_set(x, y) __sync_lock_test_and_set((x), (y)) + +static StRmbPub *pRmbGlobalSub; + +//****************************************private************************************************ + +//根据类型获取mq +StMqInfo *rmb_sub_get_mq_by_type (StRmbSub * stRmbSub, int iType); + +void rmb_get_topic_group (void *args); + +int rmb_sub_add_rr_topic_v2 (StRmbSub * pStRmbSub); +int rmb_sub_add_listen_to_wemq (StRmbSub * pRmbSub, + const st_rmb_queue_info * pQueueInfo, + unsigned int uiQueueSize, const char *cDcn, + const char *cSysId); +int wemq_sub_reply_msg (StRmbSub * pStRmbSub, StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg); +int wemq_sub_ack_msg (StRmbSub * pStRmbSub, StRmbMsg * pStReceiveMsg); + +//int wemq_sub_add_listen_topic_bypass(StRmbSub *pStRmbSub, const char *cTopic); +int wemq_sub_add_listen_topic_bypass (StRmbSub * pStRmbSub, + const char **cTopic, + unsigned int uiTopicSize); + +int wemq_sub_add_start_to_access (StRmbSub * pStRmbSub); + +//************************************************************************************************* + +static unsigned long ulGetTopicGroupPthreadId = 0; + +static StRmbTopicInfo rmbTopicInfo[1024]; +static volatile int rmbTopicIndex = -1; + +unsigned long rmb_get_topic_thread_id () +{ + return ulGetTopicGroupPthreadId; +} + +/** + * Function: rmb_sub_init + * Description: rmb sub initialize + * Return: + * 0: success + * other: failed + */ +int rmb_sub_init (StRmbSub * pStRmbSub) +{ + if (pStRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub is null"); + return -1; + } + + if (pStRmbSub->uiContextNum == 1) + { + LOGRMB (RMB_LOG_ERROR, + " sub had inited. uiContextNum is :%u, max context is : %u", + pStRmbSub->uiContextNum, 1); + return 0; + } + + pStRmbSub->pStContext = (StContext *) malloc (sizeof (StContext)); + if (pStRmbSub->pStContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub->pContext malloc error!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -1; + } + pRmbStConfig->uiPid = (unsigned int) getpid (); + memset (pStRmbSub->pStContext, 0, sizeof (StContext)); + + pStRmbSub->pQueueInfo = + (st_rmb_queue_info *) malloc (sizeof (st_rmb_queue_info) * + MAX_LISTEN_TOPIC_NUM); + if (pStRmbSub->pQueueInfo == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub->pQueueInfo malloc error!"); + return -1; + } + memset (pStRmbSub->pQueueInfo, 0x00, + (sizeof (st_rmb_queue_info) * MAX_LISTEN_TOPIC_NUM)); + pStRmbSub->iQueueNum = 0; + + //pStRmbSub->uiFlagForFilter = RMB_FILTER_FLAG_FOR_RR_ASYNC; + + pStRmbSub->pStContext->contextType = RMB_CONTEXT_TYPE_SUB; + + //init context + int iRet = rmb_context_init (pStRmbSub->pStContext); + if (iRet < 0) + { + rmb_errno = RMB_ERROR_INIT_CONTEXT_FAIL; + return -2; + } + + //init notify, from init_context to here, 1.8.0 + iRet = rmb_notify_init (&(pStRmbSub->pStContext->fifoMq)); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_init error!iRet=%u", iRet); + return -3; + } + + pStRmbSub->pStContext->pFather = (void *) pStRmbSub; + + pStRmbSub->uiContextNum = 1; + + return 0; +} + +/** + * Function: rmb_sub_init_python + * Description: rmb sub initialize + * Return: + * 0: success + * -1: failed + */ +int rmb_sub_init_python () +{ + + pRmbGlobalSub = (StRmbSub *) calloc (1, sizeof (StRmbSub)); + if (pRmbGlobalSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbGlobalSub arg is null\n"); + rmb_errno = RMB_ERROR_ARGV_NULL; + return -1; + } + rmb_sub_init (pRmbGlobalSub); +} + +/** + * Function: rmb_sub_add_reveive_rsp + * Description: init, sub add receive RR async report packages + * Return: + * 0: success + * other: failed + */ +int rmb_sub_add_reveive_rsp (StRmbSub * pStRmbSub, unsigned short usRspPort) +{ + int iRet = 0; + + iRet = + rmb_context_add_rsp_socket (pStRmbSub->pStContext, pRmbStConfig->cHostIp, + usRspPort); + if (iRet != 0) + { + rmb_errno = RMB_ERROR_INIT_UDP_FAIL; + return rmb_errno; + } + return 0; +} + +int rmb_sub_add_reveive_rsp_by_mq (StRmbSub * pStRmbSub, + rmb_callback_func func, void *func_argv) +{ + + int iRet = 0; + iRet = + rmb_context_add_rr_rsp_mq_fifo (pStRmbSub->pStContext, + pRmbStConfig->strFifoPathForRRrsp, + pRmbStConfig->uiShmKeyForRRrsp, + pRmbStConfig->uiShmSizeForRRrsp, func, + func_argv); + if (iRet != 0) + { + return rmb_errno; + } + return 0; +} + +int rmb_sub_add_reveive_rsp_by_mq_v2 (StRmbSub * pStRmbSub, + const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, void *func_argv) +{ + int iRet = 0; + + iRet = + rmb_context_add_rr_rsp_mq_fifo (pStRmbSub->pStContext, strFifoPath, + uiShmKey, uiShmSize, func, func_argv); + if (iRet != 0) + { + return rmb_errno; + } + return 0; +} + +int rmb_sub_add_reveive_rsp_by_mq_python (const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv) +{ + int iRet = 0; + StRmbSub *pStRmbSub = pRmbGlobalSub; + + iRet = + rmb_context_add_rr_rsp_mq_fifo (pStRmbSub->pStContext, strFifoPath, + uiShmKey, uiShmSize, func, func_argv); + if (iRet != 0) + { + return rmb_errno; + } + return 0; +} + +/** + * Function: rmb_sub_add_reveive_req + * Description: init, sub add receive queue request package + * Return: + * 0: success + * other: failed + */ +int rmb_sub_add_reveive_req (StRmbSub * pStRmbSub, unsigned short usReqPort) +{ + + int iRet = + rmb_context_add_req_socket (pStRmbSub->pStContext, pRmbStConfig->cHostIp, + usReqPort); + if (iRet != 0) + { + rmb_errno = RMB_ERROR_INIT_UDP_FAIL; + return rmb_errno; + } + return 0; +} + +int rmb_sub_add_reveive_req_by_mq (StRmbSub * pStRmbSub, + rmb_callback_func func, void *func_argv) +{ + + int iRet = 0; + + iRet = + rmb_context_add_req_mq_fifo (pStRmbSub->pStContext, + pRmbStConfig->strFifoPathForReq, + pRmbStConfig->uiShmKeyForReq, + pRmbStConfig->uiShmSizeForReq, func, + func_argv); + if (iRet != 0) + { + return -1; + } + + return 0; +} + +int rmb_sub_add_reveive_req_by_mq_v2 (StRmbSub * pStRmbSub, + const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, void *func_argv) +{ + + int iRet = 0; + + iRet = + rmb_context_add_req_mq_fifo (pStRmbSub->pStContext, strFifoPath, uiShmKey, + uiShmSize, func, func_argv); + if (iRet != 0) + { + return -1; + } + + return 0; +} + +int rmb_sub_add_reveive_req_by_mq_python (const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv) +{ + + int iRet = 0; + StRmbSub *pStRmbSub = pRmbGlobalSub; + iRet = + rmb_context_add_req_mq_fifo (pStRmbSub->pStContext, strFifoPath, uiShmKey, + uiShmSize, func, func_argv); + if (iRet != 0) + { + return -1; + } + + return 0; +} + +int rmb_sub_add_reveive_broadcast (StRmbSub * pStRmbSub, + unsigned short usRevBroadcastPort) +{ + + int iRet = + rmb_context_add_broadcast_socket (pStRmbSub->pStContext, + pRmbStConfig->cHostIp, + usRevBroadcastPort); + if (iRet != 0) + { + rmb_errno = RMB_ERROR_INIT_UDP_FAIL; + return rmb_errno; + } + return 0; +} + +/** + * Function: rmb_sub_add_reveive_broadcast_by_mq + * Description: init, sub add receive broadcast package + * Return: + * 0: success + * other: failed + */ +int rmb_sub_add_reveive_broadcast_by_mq (StRmbSub * pStRmbSub, + rmb_callback_func func, + void *func_argv) +{ + + int iRet = 0; + + iRet = + rmb_context_add_broadcast_mq_fifo (pStRmbSub->pStContext, + pRmbStConfig->strFifoPathForBroadcast, + pRmbStConfig->uiShmKeyForBroadcast, + pRmbStConfig->uiShmSizeForBroadcast, + func, func_argv); + if (iRet != 0) + { + return -1; + } + + return 0; +} + +int rmb_sub_add_reveive_broadcast_by_mq_v2 (StRmbSub * pStRmbSub, + const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv) +{ + + int iRet = 0; + + iRet = + rmb_context_add_broadcast_mq_fifo (pStRmbSub->pStContext, strFifoPath, + uiShmKey, uiShmSize, func, func_argv); + if (iRet != 0) + { + return -1; + } + + return 0; +} + +int rmb_sub_add_reveive_broadcast_by_mq_python (const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv) +{ + + int iRet = 0; + StRmbSub *pStRmbSub = pRmbGlobalSub; + iRet = + rmb_context_add_broadcast_mq_fifo (pStRmbSub->pStContext, strFifoPath, + uiShmKey, uiShmSize, func, func_argv); + if (iRet != 0) + { + return -1; + } + + return 0; +} + +int rmb_sub_add_listen (StRmbSub * pStRmbSub, + const st_rmb_queue_info * pQueueInfo, + unsigned int uiQueueSize) +{ + if (pStRmbSub == NULL || pQueueInfo == NULL || uiQueueSize == 0) + { + LOGRMB (RMB_LOG_ERROR, + "pStRmbSub or pQueueInfo is null or uiQueueSize=%u", uiQueueSize); + return -1; + } + st_rmb_queue_info *p = pQueueInfo; + + pStRmbSub->pQueueInfo = pQueueInfo; + pStRmbSub->iQueueNum = uiQueueSize; + //pStRmbSub->uiFlagForFilter = RMB_FILTER_FLAG_FOR_SUB; + + int i = 0; + int iRet = 0; + iRet = + rmb_sub_add_listen_to_wemq (pStRmbSub, pQueueInfo, uiQueueSize, + pRmbStConfig->cConsumerDcn, + pRmbStConfig->cConsumerSysId); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "sub add listen to wemq failed, dcn=%s", + pRmbStConfig->cConsumerDcn); + return iRet; + } + + return wemq_sub_add_start_to_access (pStRmbSub); +} + +int rmb_sub_add_listen_python (const st_rmb_queue_info * pQueueInfo, + unsigned int uiQueueSize) +{ + StRmbSub *pStRmbSub = pRmbGlobalSub; + + return rmb_sub_add_listen (pStRmbSub, pQueueInfo, uiQueueSize); +} + +/** + * Function: rmb_sub_do_receive + * Description: add epoll + * Return: + * 0: success + * other: failed + */ +int rmb_sub_do_receive (StRmbSub * pStRmbSub, int iTimeout) +{ + int iRet = rmb_notify_epoll (pStRmbSub, iTimeout); + + return iRet; + +} + +int rmb_sub_do_receive_python () +{ + StRmbSub *pStRmbSub = pRmbGlobalSub; + int iRet = rmb_notify_epoll (pStRmbSub, 1); + + return iRet; + +} + +/** + * Function: rmb_sub_reply_msg + * Description: report message + * Return: + * 0: success + * -1: failed + */ +int rmb_sub_reply_msg (StRmbSub * pStRmbSub, StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg) +{ + RMB_CHECK_POINT_NULL (pStRmbSub, "pStRmbSub"); + RMB_CHECK_POINT_NULL (pStReceiveMsg, "pStReceiveMsg"); + RMB_CHECK_POINT_NULL (pStReplyMsg, "pStReplyMsg"); + + if (strlen (pStReceiveMsg->replyTo.cDestName) == 0) + { + LOGRMB (RMB_LOG_WARN, "pStReceiveMsg->replyTo.cDestName=%s", + pStReceiveMsg->replyTo.cDestName); + return 0; + } + + return wemq_sub_reply_msg (pStRmbSub, pStReceiveMsg, pStReplyMsg); + +} + +int rmb_sub_reply_msg_python (StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg) +{ + StRmbSub *pStRmbSub = pRmbGlobalSub; + + return rmb_sub_reply_msg (pStRmbSub, pStReceiveMsg, pStReplyMsg); +} + +/** + * Function: rmb_sub_ack_msg + * Description: ack received message + * Return: + * 0: success + * -1: failed + */ +int rmb_sub_ack_msg (StRmbSub * pStRmbSub, StRmbMsg * pStReceiveMsg) +{ + RMB_CHECK_POINT_NULL (pStRmbSub, "pStRmbSub"); + RMB_CHECK_POINT_NULL (pStReceiveMsg, "pStReceiveMsg"); + + return 0; +} + +/** + * Function: rmb_sub_close + * Description:close sub + */ +int rmb_sub_close (StRmbSub * pStRmbSub) +{ + if (pStRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub is null"); + return 0; + } + + //wemq + if (pRmbStConfig->iConnWemq == 1 || pRmbStConfig->iApiLogserverSwitch == 1) + { + if (pStRmbSub->pStContext != NULL + && pStRmbSub->pStContext->pContextProxy != NULL) + { + stContextProxy *pContextProxy = pStRmbSub->pStContext->pContextProxy; + + if (rmb_sub_send_client_goodbye_to_wemq (pStRmbSub) != 0) + { + LOGRMB (RMB_LOG_ERROR, "send sub client goodbye to wemq fail"); + } + pContextProxy->iFlagForRun = 0; + GetRmbNowLongTime (); + pContextProxy->ulGoodByeTime = pRmbStConfig->ulNowTtime; + LOGRMB (RMB_LOG_DEBUG, "pthread_join mainThreadId"); + if (pContextProxy->mainThreadId != 0) + { + pthread_join (pContextProxy->mainThreadId, NULL); + } + + LOGRMB (RMB_LOG_DEBUG, "pthread_join coThreadId"); + if (pContextProxy->coThreadId != 0) + { + pthread_join (pContextProxy->coThreadId, NULL); + } + + rmb_msg_free (pStRmbSub->pStContext->pReceiveWemqMsg); + rmb_msg_free (pStRmbSub->pStContext->pReceiveWemqMsgForRR); + rmb_msg_free (pStRmbSub->pStContext->pReceiveWemqMsgForBroadCast); + free (pStRmbSub->pStContext->pWemqPkg); + free (pStRmbSub->pStContext->pWemqPkgForRRAsync); + + } + } + + LOGRMB (RMB_LOG_DEBUG, "call rmb_sub_close for over"); + + return 0; +} + +int rmb_sub_close_python () +{ + StRmbSub *pStRmbSub = pRmbGlobalSub; + while (rmb_sub_check_req_mq_is_null (pStRmbSub) != 0) //本地的共享内存还有未处理完的消息 + { + rmb_sub_do_receive (pStRmbSub, 1); + } + + int ret = rmb_sub_close_v2 (pStRmbSub); + free (pStRmbSub); + return ret; +} + +/** + * Function: rmb_sub_close_v2 + * Description:close sub + */ +int rmb_sub_close_v2 (StRmbSub * pStRmbSub) +{ + if (pStRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub is null"); + return 0; + } + + //wemq + if (pRmbStConfig->iConnWemq == 1 || pRmbStConfig->iApiLogserverSwitch == 1) + { + if (pStRmbSub->pStContext != NULL + && pStRmbSub->pStContext->pContextProxy != NULL) + { + stContextProxy *pContextProxy = pStRmbSub->pStContext->pContextProxy; + + pContextProxy->iFlagForRun = 0; + GetRmbNowLongTime (); + pContextProxy->ulGoodByeTime = pRmbStConfig->ulNowTtime; + LOGRMB (RMB_LOG_DEBUG, "pthread_join mainThreadId"); + if (pContextProxy->mainThreadId != 0) + { + pthread_join (pContextProxy->mainThreadId, NULL); + } + + LOGRMB (RMB_LOG_DEBUG, "pthread_join coThreadId"); + if (pContextProxy->coThreadId != 0) + { + pthread_join (pContextProxy->coThreadId, NULL); + } + + rmb_msg_free (pStRmbSub->pStContext->pReceiveWemqMsg); + rmb_msg_free (pStRmbSub->pStContext->pReceiveWemqMsgForRR); + rmb_msg_free (pStRmbSub->pStContext->pReceiveWemqMsgForBroadCast); + free (pStRmbSub->pStContext->pWemqPkg); + free (pStRmbSub->pStContext->pWemqPkgForRRAsync); + } + } + + LOGRMB (RMB_LOG_DEBUG, "call rmb_sub_close for over"); + + return 0; +} + +int rmb_sub_send_client_goodbye_to_wemq (StRmbSub * pRmbSub) +{ + RMB_CHECK_POINT_NULL (pRmbSub, "pStRmbSub"); + + stContextProxy *pContextProxy = pRmbSub->pStContext->pContextProxy; + + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_CLIENT_GOODBYE; + + WEMQJSON *jsonHeader = json_object_new_object (); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object failed"); + return -2; + } + //add command + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (CLIENT_GOODBYE_REQUEST)); + //add seq + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + //add code + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "header is null"); + json_object_put (jsonHeader); + return -2; + } + + stThreadMsg.m_iHeaderLen = strlen (header_str); + LOGRMB (RMB_LOG_DEBUG, "Get thread msg header succ, len=%u, %s", + stThreadMsg.m_iHeaderLen, header_str) stThreadMsg.m_pHeader = + (char *) malloc ((stThreadMsg.m_iHeaderLen + 1) * sizeof (char)); + if (stThreadMsg.m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for stThreadMsg.m_pHeader failed"); + json_object_put (jsonHeader); + return -2; + } + memcpy (stThreadMsg.m_pHeader, header_str, stThreadMsg.m_iHeaderLen); + stThreadMsg.m_pHeader[stThreadMsg.m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + + stThreadMsg.m_iBodyLen = 0; + stThreadMsg.m_pBody = NULL; + pthread_mutex_lock (&pContextProxy->goodByeMutex); + int iRet = wemq_kfifo_put (&pContextProxy->subFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error,iRet=%d!\n", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + return rmb_errno; + } + + struct timeval nowTimeVal; + gettimeofday (&nowTimeVal, NULL); + struct timespec timeout; + timeout.tv_sec = + nowTimeVal.tv_sec + (nowTimeVal.tv_usec / 1000 + + pRmbStConfig->goodByeTimeOut) / 1000; + timeout.tv_nsec = + ((nowTimeVal.tv_usec / 1000 + + pRmbStConfig->goodByeTimeOut) % 1000) * 1000 * 1000; + + pContextProxy->iFlagForGoodBye = 0; + + if (pContextProxy->iFlagForGoodBye == 0) + { + pthread_cond_timedwait (&pContextProxy->goodByeCond, + &pContextProxy->goodByeMutex, &timeout); + } + pthread_mutex_unlock (&pContextProxy->goodByeMutex); + + if (pContextProxy->iFlagForGoodBye != 1) + { + LOGRMB (RMB_LOG_ERROR, "send sub client goodBye timeout!"); + rmb_errno = RMB_ERROR_CLIENT_GOODBYE_TIMEOUT; + return rmb_errno; + } + + LOGRMB (RMB_LOG_DEBUG, "send and recv sub client goodBye succ"); + + return 0; +} + +/* +Function: rmb_sub_stop_receive +Description:rmb_sub停止接受queue消息 +* Return: +* 见rmb_errno.h文件 +*/ +int rmb_sub_stop_receive (StRmbSub * pStRmbSub) +{ + int iRet = 0; + if (pRmbStConfig->iConnWemq == 1 || pRmbStConfig->iApiLogserverSwitch == 1) + { + if (pStRmbSub->pStContext != NULL + && pStRmbSub->pStContext->pContextProxy != NULL) + { + stContextProxy *pContextProxy = pStRmbSub->pStContext->pContextProxy; + if (rmb_sub_send_client_goodbye_to_wemq (pStRmbSub) == 0) + { + //pContextProxy->iFlagForRun = 0; + return 0; + } + else + { + LOGRMB (RMB_LOG_ERROR, "send client goodbye to wemq fail"); + //pContextProxy->iFlagForRun = 0; + return -1; + } + } + else + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub->pStContext null"); + return -2; + } + } + return 0; +} + +/* +Function: rmb_sub_stop_receive_python +Description:rmb_sub停止接受queue消息 +* Return: +* 见rmb_errno.h文件 +*/ +int rmb_sub_stop_receive_python () +{ + StRmbSub *pStRmbSub = pRmbGlobalSub; + + return rmb_sub_stop_receive (pStRmbSub); +} + +//add 2015-02-10 +StMqInfo *rmb_sub_get_mq_by_type (StRmbSub * stRmbSub, int iType) +{ + return stRmbSub->pStContext->fifoMq.mqIndex[iType]; +} + +StMqInfo *rmb_sub_get_receve_req_mq (StRmbSub * stRmbSub) +{ + if (stRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "stRmb==NULL"); + return NULL; + } + return rmb_sub_get_mq_by_type (stRmbSub, (int) req_mq_index); +} + +StMqInfo *rmb_sub_get_rr_rsp_mq (StRmbSub * stRmbSub) +{ + if (stRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "stRmb==NULL"); + return NULL; + } + return rmb_sub_get_mq_by_type (stRmbSub, (int) rr_rsp_mq_index); +} + +StMqInfo *rmb_sub_get_broadcast_mq (StRmbSub * stRmbSub) +{ + if (stRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "stRmb==NULL"); + return NULL; + } + return rmb_sub_get_mq_by_type (stRmbSub, (int) broadcast_mq_index); +} + +StMqInfo *rmb_sub_get_receve_rsp_mq (StRmbSub * stRmbSub) +{ + if (stRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "stRmb==NULL"); + return NULL; + } + return rmb_sub_get_mq_by_type (stRmbSub, (int) rr_rsp_mq_index); +} + +StMqInfo *rmb_sub_get_receve_broadcast_mq (StRmbSub * stRmbSub) +{ + if (stRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "stRmb==NULL"); + return NULL; + } + return rmb_sub_get_mq_by_type (stRmbSub, (int) broadcast_mq_index); +} + +int rmb_sub_get_fd (StMqInfo * pMqInfo) +{ + RMB_CHECK_POINT_NULL (pMqInfo, "pMqInfo"); + + return pMqInfo->fifo->iFd; +} + +int rmb_sub_receive_from_mq (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen) +{ + RMB_CHECK_POINT_NULL (pMqInfo, "pMqInfo"); + + return rmb_notify_dequeue (pMqInfo, buf, uiBufSize, pDataLen); +} + +int rmb_sub_try_receive_from_mq (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen) +{ + RMB_CHECK_POINT_NULL (pMqInfo, "pMqInfo"); + + return rmb_notify_try_dequeue (pMqInfo, buf, uiBufSize, pDataLen); +} + +/* +Function: rmb_sub_check_mq_is_null +Description:校验所有队列是否已经为空,如果为空,则返回0,非空,则返回1 +* Return: +* 空返回0,非空返回1 +*/ +int rmb_sub_check_mq_is_null (StRmbSub * pStRmbSub) +{ + if (pStRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub==NULL"); + return NULL; + } + int result = rmb_sub_check_req_mq_is_null (pStRmbSub) + && rmb_sub_check_rr_rsp_mq_is_null (pStRmbSub) + && rmb_sub_check_broadcast_mq_is_null (pStRmbSub); + return result; +} + +/* +Function: rmb_sub_check_req_mq_is_null +Description:校验是否请求队列是否已经为空,如果为空,则返回0,非空,则返回1 +* Return: +* 空返回0,非空返回1 +*/ +int rmb_sub_check_req_mq_is_null (StRmbSub * pStRmbSub) +{ + StMqInfo *p = rmb_sub_get_receve_req_mq (pStRmbSub); + if (p == NULL) + { + return 0; + } + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + usleep (1000); + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + return 0; +} + +/* +Function: rmb_sub_check_rr_rsp_mq_is_null +Description:校验rr_rsp队列是否已经为空,如果为空,则返回0,非空,则返回1 +* Return: +* 空返回0,非空返回1 +*/ +int rmb_sub_check_rr_rsp_mq_is_null (StRmbSub * pStRmbSub) +{ + StMqInfo *p = rmb_sub_get_rr_rsp_mq (pStRmbSub); + if (p == NULL) + { + return 0; + } + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + usleep (1000); + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + return 0; +} + +/* +Function: rmb_sub_check_broadcast_mq_is_null +Description:校验broadcast队列是否已经为空,如果为空,则返回0,非空,则返回1 +* Return: +* 空返回0,非空返回1 +*/ +int rmb_sub_check_broadcast_mq_is_null (StRmbSub * pStRmbSub) +{ + StMqInfo *p = rmb_sub_get_broadcast_mq (pStRmbSub); + if (p == NULL) + { + return 0; + } + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + usleep (1000); + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////// +/** + * Description: add bind to wemq + * Return: + * 0: success + * -1: arg error + * -2: error + * json: + * send: + * headerJson={"code":0,"seq":"1333580037","command":"SUBSCRIBE_REQUEST"} + * |bodyJson={"topicList":["PRX-e-10030002-05-3","PRX-e-10020002-02-2","PRX-s-10000002-01-0","PRX-e-10020002-06-2"]} + * 例如: + * success: -- code为0 + * headerJson={"code":0,"seq":"1333580037","command":"SUBSCRIBE_RESPONSE", "message":"ok"}|bodyJson=null + * failed: -- code非0 + headerJson={"code":0,"seq":"1333580037","command":"SUBSCRIBE_RESPONSE", "message":"no topic route"}|bodyJson=null + * + */ +int rmb_sub_add_listen_to_wemq (StRmbSub * pRmbSub, + const st_rmb_queue_info * pQueueInfo, + unsigned int uiQueueSize, const char *cDcn, + const char *cSysId) +{ + RMB_CHECK_POINT_NULL (pRmbSub, "pStRmbSub"); + RMB_CHECK_POINT_NULL (pRmbSub->pStContext, "pStRmbSub->pStContext"); + RMB_CHECK_POINT_NULL (pRmbSub->pStContext->pContextProxy, + "pStRmbSub->pStContext->pContextProxy"); + RMB_CHECK_POINT_NULL (cDcn, "cDcn"); + RMB_CHECK_POINT_NULL (cSysId, "cSysId"); + + stContextProxy *pContextProxy = pRmbSub->pStContext->pContextProxy; + + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_ADD_LISTEN; + WEMQJSON *jsonTopicList = json_object_new_array (); + st_rmb_queue_info *p = pQueueInfo; + int i; + char cBroadcastDcn[10] = "000"; + for (i = 0; i < uiQueueSize; i++) + { + char cTopic[200] = { 0 }; + char serviceOrEvent = (*(p->cServiceId + 3) == '0') ? 's' : 'e'; + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", cDcn, serviceOrEvent, + p->cServiceId, p->cScenarioId, *(p->cServiceId + 3)); + json_object_array_add (jsonTopicList, json_object_new_string (cTopic)); + //自动监听广播topic + if (serviceOrEvent == 'e') + { + memset (cTopic, 0x00, sizeof (cTopic)); + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", cBroadcastDcn, + serviceOrEvent, p->cServiceId, p->cScenarioId, + *(p->cServiceId + 3)); + json_object_array_add (jsonTopicList, json_object_new_string (cTopic)); + } + p += 1; + } + + WEMQJSON *jsonHeader = json_object_new_object (); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object for jsonHeader failed"); + return -1; + } + + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (SUBSCRIBE_REQUEST)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object for jsonBody failed"); + json_object_put (jsonHeader); + json_object_put (jsonTopicList); + return -1; + } + + json_object_object_add (jsonBody, MSG_BODY_TOPIC_LIST_JSON, jsonTopicList); + + const char *header_str = json_object_get_string (jsonHeader); + + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_get_string for header is null"); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -2; + } + stThreadMsg.m_iHeaderLen = strlen (header_str); + + LOGRMB (RMB_LOG_INFO, "Gen thread msg header succ, len=%d, %s", + stThreadMsg.m_iHeaderLen, header_str); + stThreadMsg.m_pHeader = + (char *) malloc (stThreadMsg.m_iHeaderLen * sizeof (char) + 1); + if (stThreadMsg.m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for m_pHeader failed, errno=%d", errno); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + strncpy (stThreadMsg.m_pHeader, header_str, stThreadMsg.m_iHeaderLen); + stThreadMsg.m_pHeader[stThreadMsg.m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + + const char *body_str = json_object_get_string (jsonBody); + if (body_str == NULL) + { + json_object_put (jsonBody); + return -1; + } + + stThreadMsg.m_iBodyLen = strlen (body_str); + stThreadMsg.m_pBody = + (char *) malloc (stThreadMsg.m_iBodyLen * sizeof (char) + 1); + if (stThreadMsg.m_pBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for hello body failed"); + json_object_put (jsonBody); + return -1; + } + memcpy (stThreadMsg.m_pBody, body_str, stThreadMsg.m_iBodyLen); + stThreadMsg.m_pBody[stThreadMsg.m_iBodyLen] = '\0'; + + json_object_put (jsonBody); + pthread_mutex_lock (&pContextProxy->regMutex); + int iRet = wemq_kfifo_put (&pContextProxy->subFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error,iRet=%d!\n", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + return -3; + } + + struct timeval nowTimeVal; + gettimeofday (&nowTimeVal, NULL); + struct timespec timeout; + timeout.tv_sec = + nowTimeVal.tv_sec + (nowTimeVal.tv_usec / 1000 + + pRmbStConfig->iNormalTimeout) / 1000; + timeout.tv_nsec = + ((nowTimeVal.tv_usec / 1000 + + pRmbStConfig->iNormalTimeout) % 1000) * 1000 * 1000; + + pContextProxy->iFlagForReg = 0; + pContextProxy->iResultForReg = -1; + if (pContextProxy->iFlagForReg == 0) + { + pthread_cond_timedwait (&pContextProxy->regCond, &pContextProxy->regMutex, + &timeout); + } + pthread_mutex_unlock (&pContextProxy->regMutex); + + if (pContextProxy->iFlagForReg == 1 && pContextProxy->iResultForReg != 0) + { + LOGRMB (RMB_LOG_ERROR, "add listen failed,iRet=%d,dcn=%s", + pContextProxy->iResultForReg, cDcn); + rmb_errno = RMB_ERROR_WORKER_REGISTER_ERROR; + return rmb_errno; + } + + if (pContextProxy->iFlagForReg != 1) + { + LOGRMB (RMB_LOG_ERROR, "add listen timeout!dcn=%s", cDcn); + rmb_errno = RMB_ERROR_WORKER_REGISTER_ERROR; + return rmb_errno; + } + + LOGRMB (RMB_LOG_DEBUG, "add listen succ!dcn=%s", cDcn); + //cache sub topic; + p = pQueueInfo; + for (i = 0; i < uiQueueSize; i++) + { + StWemqTopicProp stTopicProp; + memset (&stTopicProp, 0, sizeof (stTopicProp)); + stTopicProp.flag = 0; + strncpy (stTopicProp.cServiceId, p->cServiceId, strlen (p->cServiceId)); + stTopicProp.cServiceId[8] = '\0'; + strncpy (stTopicProp.cScenario, p->cScenarioId, strlen (p->cScenarioId)); + stTopicProp.cScenario[2] = '\0'; + wemq_topic_list_add_node (&pContextProxy->stTopicList, &stTopicProp); + p += 1; + } + + return 0; +} + +int wemq_sub_add_start_to_access (StRmbSub * pStRmbSub) +{ + if (pStRmbSub == NULL || pStRmbSub->pStContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub or pStRmbSub->pStContext is null"); + return -1; + } + + stContextProxy *pContextProxy = pStRmbSub->pStContext->pContextProxy; + if (pContextProxy == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub->pStContext->pContextProxy is null"); + return -1; + } + + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_START; + + WEMQJSON *jsonHeader = json_object_new_object (); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object failed"); + return -2; + } + //add command + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (LISTEN_REQUEST)); + //add seq + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + //add code + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "header is null"); + json_object_put (jsonHeader); + return -2; + } + + stThreadMsg.m_iHeaderLen = strlen (header_str); + LOGRMB (RMB_LOG_DEBUG, "Get thread msg header succ, len=%u, %s", + stThreadMsg.m_iHeaderLen, header_str); + stThreadMsg.m_pHeader = + (char *) malloc ((stThreadMsg.m_iHeaderLen + 1) * sizeof (char)); + if (stThreadMsg.m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for stThreadMsg.m_pHeader failed"); + json_object_put (jsonHeader); + return -2; + } + memcpy (stThreadMsg.m_pHeader, header_str, stThreadMsg.m_iHeaderLen); + stThreadMsg.m_pHeader[stThreadMsg.m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + + stThreadMsg.m_iBodyLen = 0; + stThreadMsg.m_pBody = NULL; + + int iRet = 0; + struct timeval nowTimeVal; + struct timespec timeout; + pthread_mutex_lock (&pContextProxy->regMutex); + iRet = wemq_kfifo_put (&pContextProxy->subFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put for listen comman error"); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + return -3; + } + + gettimeofday (&nowTimeVal, NULL); + timeout.tv_sec = + nowTimeVal.tv_sec + (nowTimeVal.tv_usec / 1000 + + pRmbStConfig->iNormalTimeout) / 1000; + timeout.tv_nsec = + ((nowTimeVal.tv_usec / 1000 + + pRmbStConfig->iNormalTimeout) % 1000) * 1000 * 1000; + + pContextProxy->iResultForReg = -1; + pContextProxy->iFlagForReg = 0; + if (pContextProxy->iFlagForReg == 0) + { + pthread_cond_timedwait (&pContextProxy->regCond, &pContextProxy->regMutex, + &timeout); + } + pthread_mutex_unlock (&pContextProxy->regMutex); + + switch (pContextProxy->iResultForReg) + { + case RMB_CODE_TIME_OUT: + LOGRMB (RMB_LOG_ERROR, "send start command timeout"); + return -6; + case RMB_CODE_SUSS: + LOGRMB (RMB_LOG_INFO, "send start command to access succ"); + return 0; + case RMB_CODE_OTHER_FAIL: + LOGRMB (RMB_LOG_ERROR, "send start command failed,iRet=%d", + pContextProxy->iResultForReg); + return -4; + case RMB_CODE_AUT_FAIL: + LOGRMB (RMB_LOG_ERROR, "send start command authentication failed,iRet=%d", + pContextProxy->iResultForReg); + return -5; + default: + return 0; + } + +} + +int wemq_sub_reply_msg (StRmbSub * pStRmbSub, StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg) +{ + if (pStRmbSub == NULL || pStReceiveMsg == NULL || pStReplyMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmb or pStReceiveMsg or pStReplyMsg is null"); + return -1; + } + + memcpy (&pStReplyMsg->sysHeader, &pStReceiveMsg->sysHeader, + sizeof (pStReceiveMsg->sysHeader)); + memcpy (&pStReplyMsg->dest, &pStReceiveMsg->replyTo, + sizeof (pStReceiveMsg->replyTo)); + if (strlen (pStReplyMsg->dest.cDestName) == 0) + { + LOGRMB (RMB_LOG_ERROR, "receiveMsg has no replyTo, can't reply!"); + return -2; + } + LOGRMB (RMB_LOG_DEBUG, "receive msg property: %s", + pStReceiveMsg->sysHeader.cProperty); + memcpy (&pStReplyMsg->sysHeader.cProperty, + &pStReceiveMsg->sysHeader.cProperty, + sizeof (pStReceiveMsg->sysHeader.cProperty)); + + //serviceId + memcpy (pStReplyMsg->strServiceId, pStReceiveMsg->strServiceId, + sizeof (pStReceiveMsg->strServiceId)); + //scenarioId + memcpy (pStReplyMsg->strScenarioId, pStReceiveMsg->strScenarioId, + sizeof (pStReceiveMsg->strScenarioId)); + //dcn + memcpy (pStReplyMsg->strTargetDcn, pStReceiveMsg->strTargetDcn, + sizeof (pStReceiveMsg->strTargetDcn)); + //organization + memcpy (pStReplyMsg->strTargetOrgId, pStReceiveMsg->strTargetOrgId, + sizeof (pStReceiveMsg->strTargetOrgId)); + //ttl + pStReplyMsg->ulMsgLiveTime = pStReceiveMsg->ulMsgLiveTime; + + strncpy (pStReplyMsg->cCorrId, pStReceiveMsg->cCorrId, + sizeof (pStReceiveMsg->cCorrId)); + pStReplyMsg->iCorrLen = pStReceiveMsg->iCorrLen; + pStReplyMsg->cApiType = C_TYPE_WEMQ; + pStReplyMsg->cLogicType = RSP_PKG_OUT_WEMQ; + GetRmbNowLongTime (); + pStReplyMsg->sysHeader.ulReplyTime = pRmbStConfig->ulNowTtime; + + StContext *pStContext = pStRmbSub->pStContext; + pStContext->uiPkgLen = MAX_LENTH_IN_A_MSG; + stContextProxy *pContextProxy = pStContext->pContextProxy; + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_REPLY; + int iRet = + rmb_pub_encode_thread_msg (stThreadMsg.m_iCmd, &stThreadMsg, pStReplyMsg, + 3000); + //LOGRMB(RMB_LOG_DEBUG, "encode succ header %s, body %s\n",stThreadMsg.m_pHeader, stThreadMsg.m_pBody); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_pub_encode_thread_msg error!\n"); + return iRet; + } + + iRet = wemq_kfifo_put (&pContextProxy->subFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error!iRet=%d", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + rmb_send_log_for_error (pStContext->pContextProxy, + RMB_ERROR_WORKER_PUT_FIFO_ERROR, + "sub reply wemq_kfifo_put error", pStReplyMsg); + return rmb_errno; + } + + return 0; +} + +int wemq_sub_ack_msg (StRmbSub * pStRmbSub, StRmbMsg * pStAckMsg) +{ + if (pStRmbSub == NULL || pStAckMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmb or pStReplyMsg is null"); + return -1; + } + + if (pStAckMsg->cPkgType == RR_TOPIC_PKG) + { + return 0; + } + + LOGRMB (RMB_LOG_DEBUG, "receive msg property: %s", + pStAckMsg->sysHeader.cProperty); + + StContext *pStContext = pStRmbSub->pStContext; + pStContext->uiPkgLen = MAX_LENTH_IN_A_MSG; + stContextProxy *pContextProxy = pStContext->pContextProxy; + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_MSG_ACK; + int iRet = + rmb_pub_encode_thread_msg (stThreadMsg.m_iCmd, &stThreadMsg, pStAckMsg, + 3000); + //LOGRMB(RMB_LOG_DEBUG, "encode succ header %s, body %s\n",stThreadMsg.m_pHeader, stThreadMsg.m_pBody); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_pub_encode_thread_msg error!\n"); + return iRet; + } + + iRet = wemq_kfifo_put (&pContextProxy->subFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error!iRet=%d", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + rmb_send_log_for_error (pStContext->pContextProxy, + RMB_ERROR_WORKER_PUT_FIFO_ERROR, + "sub ack wemq_kfifo_put error", pStAckMsg); + return rmb_errno; + } + + return 0; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_udp.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_udp.c new file mode 100644 index 0000000000..76fd187ed1 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_udp.c @@ -0,0 +1,383 @@ +// 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. + +#include "rmb_udp.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int udp_get_socket (const char *host, const char *serv, socklen_t * addrlenp) +{ + int iUDPSocket; + int iRet; + + struct addrinfo hints; + struct addrinfo *res, *ressave; + + memset (&hints, 0, sizeof (struct addrinfo)); + hints.ai_flags = AI_PASSIVE; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + if ((iRet = getaddrinfo (host, serv, &hints, &res)) != 0) + { + return -1; + } + ressave = res; + + do + { + iUDPSocket = socket (res->ai_family, res->ai_socktype, res->ai_protocol); + if (iUDPSocket < 0) + continue; /* error, try next one */ + + if (bind (iUDPSocket, res->ai_addr, res->ai_addrlen) == 0) + break; /* success */ + + close (iUDPSocket); /* bind error, close and try next one */ + } + while ((res = res->ai_next) != NULL); + + if (res == NULL) /* errno from final socket() or bind() */ + return -1; + //err_sys("udp_server error for %s, %s", host, serv); + + if (addrlenp) + *addrlenp = res->ai_addrlen; /* return size of protocol address */ + + freeaddrinfo (ressave); + + if (iUDPSocket < 0) + { + return -1; + //err_sys("UDP_GetSocket error : %s", strerror(errno)); + } + return iUDPSocket; +} + +int udp_server (const char *pszHost, unsigned short usPort) +{ + int udpsock; + struct hostent *hostinfo; + struct in_addr *addp; + struct sockaddr_in sockname; + + memset ((char *) &sockname, 0, sizeof (sockname)); + if (pszHost == NULL) + { + hostinfo = NULL; + } + else if ((hostinfo = gethostbyname (pszHost)) == NULL) + { + //err_msg("Cannot find %s - %s",pszHost,strerror(errno)); + return -1; + } + + udpsock = socket (AF_INET, SOCK_DGRAM, 0); + if (udpsock < 0) + { + //err_msg("Error opening socket - %s",strerror(errno)); + return -1; + } + //setsockopt(udpsock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + if (hostinfo != NULL) + { + addp = (struct in_addr *) *(hostinfo->h_addr_list); + sockname.sin_addr = *addp; + } + else + { + sockname.sin_addr.s_addr = INADDR_ANY; + } + sockname.sin_family = AF_INET; + sockname.sin_port = htons (usPort); + + if ((bind (udpsock, (struct sockaddr *) &sockname, sizeof (sockname))) == + -1) + { + close (udpsock); + //err_msg("Cannot bind port %i at %s -%s",usPort,pszHost,strerror(errno)); + return -1; + } + + return (udpsock); +} + +int check_socket (int iSocket, fd_set * pStReadFds, int iNfd) +{ + struct timeval stTimeVal; + + FD_ZERO (pStReadFds); + FD_SET (iSocket, pStReadFds); + stTimeVal.tv_sec = 0; + stTimeVal.tv_usec = 5000; + + if (select (iNfd, pStReadFds, NULL, NULL, &stTimeVal) > 0) + { + return 0; + } + return -1; +} + +int check_socket_with_timeout (int iSocket, fd_set * pStReadFds, int iNfd, + int sec, int usec) +{ + struct timeval stTimeVal; + + FD_ZERO (pStReadFds); + FD_SET (iSocket, pStReadFds); + stTimeVal.tv_sec = sec; + stTimeVal.tv_usec = usec; + + if (select (iNfd, pStReadFds, NULL, NULL, &stTimeVal) > 0) + { + return 0; + } + return -1; +} + +int check_and_process_socket (int iSocket, fd_set * pStReadFds, char *cPkgBuf, + const unsigned int uiMaxLen, + unsigned int *pPkgLen) +{ + if (FD_ISSET (iSocket, pStReadFds)) + { + struct sockaddr_in stFromAddr; + socklen_t iAddrLength = sizeof (stFromAddr); + *pPkgLen = 0; + //LOGSYS(RMB_LOG_DEBUG, " sizeof(cPkgBuf)=%lu", sizeof(cPkgBuf)); + + int iRet = recvfrom (iSocket, cPkgBuf, uiMaxLen, + 0, (struct sockaddr *) &stFromAddr, &iAddrLength); + if (iRet > 0) + { + *pPkgLen = iRet; + } + return iRet; + } + return 0; +} + +int tcp_nodelay (int iSockfd) +{ + int i; + + if ((i = fcntl (iSockfd, F_GETFL, 0)) == -1) + return (-1); + else if (fcntl (iSockfd, F_SETFL, i | FNDELAY) == -1) + return (-1); + return 0; +} + +int get_host_name (char *hostName, unsigned int uiHostNameLen) +{ + struct hostent *host; //���������Ϣ +// while () +// { +// +// } + + if ((host = gethostent ()) == NULL) + { + LOGRMB (RMB_LOG_ERROR, " fail to get host's information"); + return -1; + } + strncpy (hostName, host->h_name, uiHostNameLen); + + while ((host = gethostent ()) != NULL) + { + } + endhostent (); + //LOGSYS(LOG_ERROR, "%s hostName: %s,%s,uiHostName=%u" , __func__, hostName, host->h_name, uiHostNameLen); + return 0; +} + +int get_local_ip (char *addr, unsigned int uiAddrLen) +{ + int i = 0; + int sockfd; + struct ifconf ifconf; + char buf[512]; + struct ifreq *ifreq; + char *ip; + + ifconf.ifc_len = 512; + ifconf.ifc_buf = buf; + + if ((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) + { + return -1; + } + ioctl (sockfd, SIOCGIFCONF, &ifconf); + close (sockfd); + + ifreq = (struct ifreq *) buf; + for (i = (ifconf.ifc_len / sizeof (struct ifreq)); i > 0; i--) + { + ip = inet_ntoa (((struct sockaddr_in *) &(ifreq->ifr_addr))->sin_addr); + + if (strcmp (ip, "127.0.0.1") == 0) + { + ifreq++; + continue; + } + + strncpy (addr, ip, uiAddrLen); + //LOGSYS(LOG_ERROR, "%s HostIp: %s,%s,len=%u" , __func__, addr,ip, uiAddrLen); + return 0; + } + + return -1; +} + +/** + * 2.0.10版本增加,逻辑为: + * 通过获取环境变量networkInterface的值,来获取对应的ip + * 如果失败,则返回默认值 + * 默认获取方式: bond1 > eth1 > eth0 + */ +int get_local_ip_v2 (char *addr, unsigned int uiAddrLen) +{ + char *val = NULL; + + val = getenv ("networkInterface"); + + int i = 0; + int sockfd; + struct ifconf ifconf; + char buf[512]; + struct ifreq *ifreq; + char *ip; + + ifconf.ifc_len = 512; + ifconf.ifc_buf = buf; + + if ((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) + { + return -1; + } + ioctl (sockfd, SIOCGIFCONF, &ifconf); + close (sockfd); + + //first getenv + if (val != NULL) + { + ifreq = (struct ifreq *) buf; + for (i = (ifconf.ifc_len / sizeof (struct ifreq)); i > 0; i--) + { + if (strcmp (ifreq->ifr_name, val) != 0) + { + ifreq++; + continue; + } + + ip = inet_ntoa (((struct sockaddr_in *) &(ifreq->ifr_addr))->sin_addr); + + if (strcmp (ip, "127.0.0.1") == 0) + { + ifreq++; + continue; + } + + strncpy (addr, ip, uiAddrLen); + //LOGSYS(LOG_ERROR, "%s HostIp: %s,%s,len=%u" , __func__, addr,ip, uiAddrLen); + return 0; + } + } + + //bond1 + { + ifreq = (struct ifreq *) buf; + for (i = (ifconf.ifc_len / sizeof (struct ifreq)); i > 0; i--) + { + if (strcmp (ifreq->ifr_name, "bond1") != 0) + { + ifreq++; + continue; + } + + ip = inet_ntoa (((struct sockaddr_in *) &(ifreq->ifr_addr))->sin_addr); + + if (strcmp (ip, "127.0.0.1") == 0) + { + ifreq++; + continue; + } + + strncpy (addr, ip, uiAddrLen); + //LOGSYS(LOG_ERROR, "%s HostIp: %s,%s,len=%u" , __func__, addr,ip, uiAddrLen); + return 0; + } + } + + //eth1 + { + ifreq = (struct ifreq *) buf; + for (i = (ifconf.ifc_len / sizeof (struct ifreq)); i > 0; i--) + { + if (strcmp (ifreq->ifr_name, "eth1") != 0) + { + ifreq++; + continue; + } + + ip = inet_ntoa (((struct sockaddr_in *) &(ifreq->ifr_addr))->sin_addr); + + if (strcmp (ip, "127.0.0.1") == 0) + { + ifreq++; + continue; + } + + strncpy (addr, ip, uiAddrLen); + //LOGSYS(LOG_ERROR, "%s HostIp: %s,%s,len=%u" , __func__, addr,ip, uiAddrLen); + return 0; + } + } + + ifreq = (struct ifreq *) buf; + for (i = (ifconf.ifc_len / sizeof (struct ifreq)); i > 0; i--) + { + ip = inet_ntoa (((struct sockaddr_in *) &(ifreq->ifr_addr))->sin_addr); + + if (strcmp (ip, "127.0.0.1") == 0) + { + ifreq++; + continue; + } + + strncpy (addr, ip, uiAddrLen); + //LOGSYS(LOG_ERROR, "%s HostIp: %s,%s,len=%u" , __func__, addr,ip, uiAddrLen); + return 0; + } + + return -1; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_vector.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_vector.c new file mode 100644 index 0000000000..5e0b35b84f --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_vector.c @@ -0,0 +1,84 @@ +// 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. + +#include "rmb_vector.h" +#include +#include +#include +#include +#include "rmb_msg.h" + +void Init (Array * this) +{ + this->Input = _input; + + this->get_array_size = _get_size; + this->return_index_value = _return_index_value; + + this->Constructor = _constructor; + this->Destructor = _destructor; + this->Constructor (this); +} + +void _constructor (Array * this) +{ + this->size = 0; + this->max_size = MAX_SIZE_PER_TIME; + this->Data = (DataType *) malloc (this->max_size * sizeof (DataType)); + memset (this->Data, 0x00, this->max_size * sizeof (DataType)); +} + +void _input (DataType data, Array * this) +{ + int i; + DataType *ptr; + + ptr = + (DataType *) malloc ((this->max_size + MAX_SIZE_PER_TIME) * + sizeof (DataType)); + memset (ptr, 0x00, + (this->max_size + MAX_SIZE_PER_TIME) * sizeof (DataType)); + for (i = 0; i < this->max_size; i++) + ptr[i] = this->Data[i]; + free (this->Data); + this->Data = ptr; + + snprintf (this->Data[this->max_size].unique_id, sizeof (data.unique_id), + "%s", data.unique_id); + snprintf (this->Data[this->max_size].biz_seq, sizeof (data.biz_seq), "%s", + data.biz_seq); + this->Data[this->max_size].flag = 1; + this->Data[this->max_size].timeStamp = data.timeStamp; + this->Data[this->max_size].timeout = data.timeout; + this->max_size += MAX_SIZE_PER_TIME; +} + +int _get_size (Array * this) +{ + assert (this != NULL); + return this->max_size; +} + +DataType _return_index_value (Array * this, int index) +{ + assert (this != NULL); + return (this->Data[index]); +} + +void _destructor (Array * this) +{ + assert (this != NULL); + free (this->Data); +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/wemq_fifo.c b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_fifo.c new file mode 100644 index 0000000000..e8b806129d --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_fifo.c @@ -0,0 +1,350 @@ +// 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. + +/* + * A generic kernel FIFO implementation + * + * Copyright (C) 2009/2010 Stefani Seibold + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +/* +#include +#include +#include +#include +#include +#include +#include +*/ +//#include "wemq_fifo.h" +#include "rmb_define.h" +#define min(x,y) ({\ + typeof(x) _x = (x);\ + typeof(y) _y = (y);\ + (void)(&_x == &_y);\ + _x < _y ? _x : _y;}) +#define max(x,y) ({\ + typeof(x) _x = (x);\ + typeof(y) _y = (y);\ + (void)(&_x == &_y);\ + _x > _y ? _x : _y;}) +/* + * internal helper to calculate the unused elements in a fifo + */ +static inline unsigned int wemq_kfifo_unused (struct __wemq_kfifo *fifo) +{ + return (fifo->mask + 1) - (fifo->in - fifo->out); +} + +int __wemq_kfifo_alloc (struct __wemq_kfifo *fifo, unsigned int size, + size_t esize) +{ + /* + * round down to the next power of 2, since our 'let the indices + * wrap' technique works only in this case. + */ + size = roundup_pow_of_two (size); + + fifo->in = 0; + fifo->out = 0; + fifo->esize = esize; + + if (size < 2) + { + fifo->data = NULL; + fifo->mask = 0; + return -KFIFO_EINVAL; + } + + fifo->data = malloc (size * esize); + + if (!fifo->data) + { + fifo->mask = 0; + return -KFIFO_ENOMEM; + } + fifo->mask = size - 1; + + return 0; +} + +////EXPORT_SYMBOL(__wemq_kfifo_alloc); + +void __wemq_kfifo_free (struct __wemq_kfifo *fifo) +{ + free (fifo->data); + fifo->in = 0; + fifo->out = 0; + fifo->esize = 0; + fifo->data = NULL; + fifo->mask = 0; +} + +////EXPORT_SYMBOL(__wemq_kfifo_free); + +int __wemq_kfifo_init (struct __wemq_kfifo *fifo, void *buffer, + unsigned int size, size_t esize) +{ + size /= esize; + + size = roundup_pow_of_two (size); + + fifo->in = 0; + fifo->out = 0; + fifo->esize = esize; + fifo->data = buffer; + + if (size < 2) + { + fifo->mask = 0; + return -KFIFO_EINVAL; + } + fifo->mask = size - 1; + + return 0; +} + +//EXPORT_SYMBOL(__wemq_kfifo_init); + +static void wemq_kfifo_copy_in (struct __wemq_kfifo *fifo, const void *src, + unsigned int len, unsigned int off) +{ + unsigned int size = fifo->mask + 1; + unsigned int esize = fifo->esize; + unsigned int l; + + off &= fifo->mask; + if (esize != 1) + { + off *= esize; + size *= esize; + len *= esize; + } + l = min (len, size - off); + + memcpy (fifo->data + off, src, l); + memcpy (fifo->data, src + l, len - l); + /* + * make sure that the data in the fifo is up to date before + * incrementing the fifo->in index counter + */ + //smp_wmb(); +} + +unsigned int __wemq_kfifo_in (struct __wemq_kfifo *fifo, + const void *buf, unsigned int len) +{ + unsigned int l; + + l = wemq_kfifo_unused (fifo); + if (len > l) + len = l; + + wemq_kfifo_copy_in (fifo, buf, len, fifo->in); + fifo->in += len; + return len; +} + +//EXPORT_SYMBOL(__wemq_kfifo_in); + +static void wemq_kfifo_copy_out (struct __wemq_kfifo *fifo, void *dst, + unsigned int len, unsigned int off) +{ + unsigned int size = fifo->mask + 1; + unsigned int esize = fifo->esize; + unsigned int l; + + off &= fifo->mask; + if (esize != 1) + { + off *= esize; + size *= esize; + len *= esize; + } + l = min (len, size - off); + + memcpy (dst, fifo->data + off, l); + memcpy (dst + l, fifo->data, len - l); + /* + * make sure that the data is copied before + * incrementing the fifo->out index counter + */ + //smp_wmb(); +} + +unsigned int __wemq_kfifo_out_peek (struct __wemq_kfifo *fifo, + void *buf, unsigned int len) +{ + unsigned int l; + + l = fifo->in - fifo->out; + if (len > l) + len = l; + + wemq_kfifo_copy_out (fifo, buf, len, fifo->out); + return len; +} + +//EXPORT_SYMBOL(__wemq_kfifo_out_peek); + +unsigned int __wemq_kfifo_out (struct __wemq_kfifo *fifo, + void *buf, unsigned int len) +{ + len = __wemq_kfifo_out_peek (fifo, buf, len); + fifo->out += len; + return len; +} + +//EXPORT_SYMBOL(__wemq_kfifo_out); + +unsigned int __wemq_kfifo_max_r (unsigned int len, size_t recsize) +{ + unsigned int max = (1 << (recsize << 3)) - 1; + + if (len > max) + return max; + return len; +} + +//EXPORT_SYMBOL(__wemq_kfifo_max_r); + +#define __WEMQ_KFIFO_PEEK(data, out, mask) \ + ((data)[(out) & (mask)]) +/* + * __wemq_kfifo_peek_n internal helper function for determinate the length of + * the next record in the fifo + */ +static unsigned int __wemq_kfifo_peek_n (struct __wemq_kfifo *fifo, + size_t recsize) +{ + unsigned int l; + unsigned int mask = fifo->mask; + unsigned char *data = fifo->data; + + l = __WEMQ_KFIFO_PEEK (data, fifo->out, mask); + + if (--recsize) + l |= __WEMQ_KFIFO_PEEK (data, fifo->out + 1, mask) << 8; + + return l; +} + +#define __WEMQ_KFIFO_POKE(data, in, mask, val) \ + ( \ + (data)[(in) & (mask)] = (unsigned char)(val) \ + ) + +/* + * __wemq_kfifo_poke_n internal helper function for storeing the length of + * the record into the fifo + */ +static void __wemq_kfifo_poke_n (struct __wemq_kfifo *fifo, unsigned int n, + size_t recsize) +{ + unsigned int mask = fifo->mask; + unsigned char *data = fifo->data; + + __WEMQ_KFIFO_POKE (data, fifo->in, mask, n); + + if (recsize > 1) + __WEMQ_KFIFO_POKE (data, fifo->in + 1, mask, n >> 8); +} + +unsigned int __wemq_kfifo_len_r (struct __wemq_kfifo *fifo, size_t recsize) +{ + return __wemq_kfifo_peek_n (fifo, recsize); +} + +//EXPORT_SYMBOL(__wemq_kfifo_len_r); + +unsigned int __wemq_kfifo_in_r (struct __wemq_kfifo *fifo, const void *buf, + unsigned int len, size_t recsize) +{ + if (len + recsize > wemq_kfifo_unused (fifo)) + return 0; + + __wemq_kfifo_poke_n (fifo, len, recsize); + + wemq_kfifo_copy_in (fifo, buf, len, fifo->in + recsize); + fifo->in += len + recsize; + return len; +} + +//EXPORT_SYMBOL(__wemq_kfifo_in_r); + +static unsigned int wemq_kfifo_out_copy_r (struct __wemq_kfifo *fifo, + void *buf, unsigned int len, + size_t recsize, unsigned int *n) +{ + *n = __wemq_kfifo_peek_n (fifo, recsize); + + if (len > *n) + len = *n; + + wemq_kfifo_copy_out (fifo, buf, len, fifo->out + recsize); + return len; +} + +unsigned int __wemq_kfifo_out_peek_r (struct __wemq_kfifo *fifo, void *buf, + unsigned int len, size_t recsize) +{ + unsigned int n; + + if (fifo->in == fifo->out) + return 0; + + return wemq_kfifo_out_copy_r (fifo, buf, len, recsize, &n); +} + +//EXPORT_SYMBOL(__wemq_kfifo_out_peek_r); + +unsigned int __wemq_kfifo_out_r (struct __wemq_kfifo *fifo, void *buf, + unsigned int len, size_t recsize) +{ + unsigned int n; + + if (fifo->in == fifo->out) + return 0; + + len = wemq_kfifo_out_copy_r (fifo, buf, len, recsize, &n); + fifo->out += n + recsize; + return len; +} + +//EXPORT_SYMBOL(__wemq_kfifo_out_r); + +void __wemq_kfifo_skip_r (struct __wemq_kfifo *fifo, size_t recsize) +{ + unsigned int n; + + n = __wemq_kfifo_peek_n (fifo, recsize); + fifo->out += n + recsize; +} + +//EXPORT_SYMBOL(__wemq_kfifo_skip_r); diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/wemq_proto.c b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_proto.c new file mode 100644 index 0000000000..74c79aba74 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_proto.c @@ -0,0 +1,748 @@ +// 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. + +#include "common.h" +#include "wemq_proto.h" + +unsigned long long htonll_z (unsigned long long host) +{ + union64HN u; + u.src[0] = htonl (host >> 32); + u.src[1] = htonl (host & 0xFFFFFFFF); + return u.dest; +} + +unsigned long long ntohll_z (unsigned long long net) +{ + union64HN u; + u.src[0] = ntohl (net >> 32); + u.src[1] = ntohl (net & 0xFFFFFFFF); + return u.dest; +} + +//***************************0x01 心跳************************** +//请求 + +int GetStHeartBeatReqBaseLegth () +{ + return sizeof (int) + sizeof (unsigned int) + sizeof (char); +} + +int GetStHeartBeatReqLegth (const StHeartBeatReq * pReq) +{ + return GetStHeartBeatReqBaseLegth () + pReq->cReseveLength; +} + +//return -1.空间不足 +int EncodeStHeartBeatReq (char *buf, int *pBufLen, + const StHeartBeatReq * pReq) +{ + if (*pBufLen < GetStHeartBeatReqLegth (pReq)) + { + return -1; + } + *pBufLen = GetStHeartBeatReqLegth (pReq); + ENCODE_INT (buf, pReq->pid); + ENCODE_INT (buf, pReq->uiCount); + ENCODE_CSTR_MEMCPY (buf, pReq->strReserve, pReq->cReseveLength); + return 0; +} + +//return -1,空间不足 +//return -2,buf长度不够 +int DecodeHeartBeatReq (StHeartBeatReq * pReq, const char *buf, + const int bufLen) +{ + if (bufLen < GetStHeartBeatReqBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pReq->pid, buf, &iTmpLen); + DECODE_INT (pReq->uiCount, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strReserve, pReq->cReseveLength, buf, &iTmpLen); + return 0; +} + +//回复 + +int GetStHeartBeatRspBaseLegth () +{ + return 3 * sizeof (unsigned int) + sizeof (char); +} + +int GetStHeartBeatRspLegth (const StHeartBeatRsp * pRsp) +{ + return GetStHeartBeatRspBaseLegth () + pRsp->cReseveLength; +} + +//return -1.空间不足 +int EncodeStHeartBeatRsp (char *buf, int *pBufLen, + const StHeartBeatRsp * pRsp) +{ + if (*pBufLen < GetStHeartBeatRspLegth (pRsp)) + { + return -1; + } + *pBufLen = GetStHeartBeatRspLegth (pRsp); + ENCODE_INT (buf, pRsp->uiResult); + ENCODE_INT (buf, pRsp->pid); + ENCODE_INT (buf, pRsp->uiCount); + ENCODE_CSTR_MEMCPY (buf, pRsp->strReserve, pRsp->cReseveLength); + return 0; +} + +int DecodeHeartBeatRsp (StHeartBeatRsp * pRsp, const char *buf, + const int bufLen) +{ + if (bufLen < GetStHeartBeatRspBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pRsp->uiResult, buf, &iTmpLen); + DECODE_INT (pRsp->pid, buf, &iTmpLen); + DECODE_INT (pRsp->uiCount, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pRsp->strReserve, pRsp->cReseveLength, buf, &iTmpLen); + return 0; +} + +//***************************0x02 注册,建立连接************************** +//请求 + +int GetRegisterReqBaseLegth () +{ + return sizeof (int) + 10 * sizeof (char); +} + +int GetRegisterReqLegth (const StRegisterReq * pReq) +{ + return GetRegisterReqBaseLegth () + pReq->cSolaceHostLen + + pReq->cSolaceVpnLen + pReq->cSolaceUserLen + pReq->cSolacePwdLen + + pReq->cConsumerIpLen + pReq->cConsumerSysIdLen + pReq->cConsumerDcnLen + + pReq->cConsumerOrgIdLen + pReq->cConsumerVersionLen + pReq->cReseveLength; +} + +//return -1.空间不足 +int EncodeStRegisterReq (char *buf, int *pBufLen, const StRegisterReq * pReq) +{ + if (*pBufLen < GetRegisterReqLegth (pReq)) + { + return -1; + } + *pBufLen = GetRegisterReqLegth (pReq); + ENCODE_INT (buf, pReq->iPid); + ENCODE_CSTR_MEMCPY (buf, pReq->strSolaceHost, pReq->cSolaceHostLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strSolaceVpn, pReq->cSolaceVpnLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strSolaceUser, pReq->cSolaceUserLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strSolacePwd, pReq->cSolacePwdLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strConsumerIp, pReq->cConsumerIpLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strConsumerSysId, pReq->cConsumerSysIdLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strConsumerDcn, pReq->cConsumerDcnLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strConsumerOrgId, pReq->cConsumerOrgIdLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strConsumerVersion, + pReq->cConsumerVersionLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strReserve, pReq->cReseveLength); + return 0; +} + +int DecodeStRegisterReq (StRegisterReq * pReq, const char *buf, + const int bufLen) +{ + if (bufLen < GetRegisterReqBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pReq->iPid, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strSolaceHost, pReq->cSolaceHostLen, buf, + &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strSolaceVpn, pReq->cSolaceVpnLen, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strSolaceUser, pReq->cSolaceUserLen, buf, + &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strSolacePwd, pReq->cSolacePwdLen, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strConsumerIp, pReq->cConsumerIpLen, buf, + &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strConsumerSysId, pReq->cConsumerSysIdLen, buf, + &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strConsumerDcn, pReq->cConsumerDcnLen, buf, + &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strConsumerOrgId, pReq->cConsumerOrgIdLen, buf, + &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strConsumerVersion, pReq->cConsumerVersionLen, + buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strReserve, pReq->cReseveLength, buf, &iTmpLen); + return 0; +} + +int GetRegisterRspBaseLegth () +{ + return sizeof (char) + 3 * sizeof (int); +} + +int GetRegisterRsplength (const StRegisterRsp * pRsp) +{ + return GetRegisterRspBaseLegth () + pRsp->cReseveLength; +} + +int EncodeStRegisterRsp (char *buf, int *pBufLen, const StRegisterRsp * pRsp) +{ + if (*pBufLen < GetRegisterRsplength (pRsp)) + { + return -1; + } + *pBufLen = GetRegisterRsplength (pRsp); + ENCODE_INT (buf, pRsp->uiResult); + ENCODE_INT (buf, pRsp->uiCcdIndex); + ENCODE_INT (buf, pRsp->uiCcdFlow); + ENCODE_CSTR_MEMCPY (buf, pRsp->strReserve, pRsp->cReseveLength); + return 0; +} + +int DecodeStRegisterRsp (StRegisterRsp * pRsp, const char *buf, + const int bufLen) +{ + if (bufLen < GetRegisterRspBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pRsp->uiResult, buf, &iTmpLen); + DECODE_INT (pRsp->uiCcdIndex, buf, &iTmpLen); + DECODE_INT (pRsp->uiCcdFlow, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pRsp->strReserve, pRsp->cReseveLength, buf, &iTmpLen); + return 0; +} + +//***********************************0x06 注册接收连接*********************************** +int GetRegisterReceiveReqBaseLegth () +{ + return 2 * sizeof (int) + sizeof (char); +} + +int GetRegisterReceiveReqLegth (const StRegisterReceiveReq * pReq) +{ + return GetRegisterReceiveReqBaseLegth () + pReq->cReseveLength; +} + +//return -1.空间不足 +int EncodeStRegisterReceiveReq (char *buf, int *pBufLen, + const StRegisterReceiveReq * pReq) +{ + if (*pBufLen < GetRegisterReceiveReqLegth (pReq)) + { + return -1; + } + *pBufLen = GetRegisterReceiveReqLegth (pReq); + ENCODE_INT (buf, pReq->uiCcdIndex); + ENCODE_INT (buf, pReq->uiCcdFlow); + ENCODE_CSTR_MEMCPY (buf, pReq->strReserve, pReq->cReseveLength); + return 0; +} + +int DecodeStRegisterReceiveReq (StRegisterReceiveReq * pReq, const char *buf, + const int bufLen) +{ + if (bufLen < GetRegisterReceiveReqBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pReq->uiCcdIndex, buf, &iTmpLen); + DECODE_INT (pReq->uiCcdFlow, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strReserve, pReq->cReseveLength, buf, &iTmpLen); + return 0; +} + +int GetRegisterReceiveRspBaseLegth () +{ + return sizeof (char) + sizeof (int); +} + +int GetRegisterReceiveRsplength (const StRegisterReceiveRsp * pRsp) +{ + return GetRegisterReceiveRspBaseLegth () + pRsp->cReseveLength; +} + +int EncodeStRegisterReceiveRsp (char *buf, int *pBufLen, + const StRegisterReceiveRsp * pRsp) +{ + if (*pBufLen < GetRegisterReceiveRsplength (pRsp)) + { + return -1; + } + *pBufLen = GetRegisterReceiveRsplength (pRsp); + ENCODE_INT (buf, pRsp->uiResult); + ENCODE_CSTR_MEMCPY (buf, pRsp->strReserve, pRsp->cReseveLength); + return 0; +} + +int DecodeStRegisterReceiveRsp (StRegisterRsp * pRsp, const char *buf, + const int bufLen) +{ + if (bufLen < GetRegisterReceiveRspBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pRsp->uiResult, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pRsp->strReserve, pRsp->cReseveLength, buf, &iTmpLen); + return 0; +} + +int GetAddListenReqLegth (const StAddListenReq * pReq) +{ + return sizeof (pReq->strSceneId) + sizeof (pReq->strServiceId); +} + +//return -1.空间不足 +int EncodeAddListenReq (char *buf, int *pBufLen, const StAddListenReq * pReq) +{ + if (*pBufLen < GetAddListenReqLegth (pReq)) + { + return -1; + } + *pBufLen = GetAddListenReqLegth (pReq); + memcpy (buf, pReq->strServiceId, sizeof (pReq->strServiceId)); + buf = buf + sizeof (pReq->strServiceId); + memcpy (buf, pReq->strSceneId, sizeof (pReq->strSceneId)); + return 0; +} + +int DecodeAddListenReq (StAddListenReq * pReq, const char *buf, + const int bufLen) +{ + if (bufLen < GetAddListenReqLegth (pReq)) + { + return -1; + } + memcpy (pReq->strServiceId, buf, sizeof (pReq->strServiceId)); + memcpy (pReq->strSceneId, buf + sizeof (pReq->strServiceId), + sizeof (pReq->strSceneId)); + return 0; +} + +int GetAddListenRspBaseLegth () +{ + return sizeof (int); +} + +int GetAddListenRspLegth (const StAddListenRsp * pRsp) +{ + return GetAddListenRspBaseLegth () + sizeof (pRsp->strSceneId) + + sizeof (pRsp->strServiceId); +} + +//return -1.空间不足 +int EncodeAddListenRsp (char *buf, int *pBufLen, const StAddListenRsp * pRsp) +{ + if (*pBufLen < GetAddListenRspLegth (pRsp)) + { + return -1; + } + *pBufLen = GetAddListenRspLegth (pRsp); + ENCODE_INT (buf, pRsp->uiResult); + memcpy (buf, pRsp->strServiceId, sizeof (pRsp->strServiceId)); + memcpy (buf, pRsp->strSceneId, sizeof (pRsp->strSceneId)); + return 0; +} + +int DecodeAddListenRsp (StAddListenRsp * pRsp, const char *buf, + const int bufLen) +{ + if (bufLen < GetAddListenRspBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pRsp->uiResult, buf, &iTmpLen); + memcpy (pRsp->strServiceId, buf, sizeof (pRsp->strServiceId)); + memcpy (pRsp->strSceneId, buf, sizeof (pRsp->strSceneId)); + return 0; +} + +//***************************0x06 增加监听************************** +int GetAddManageBaseLength () +{ + return sizeof (char); +} + +int GetAddManageReqLegth (const StAddManageReq * pReq) +{ + return GetAddManageBaseLength () + pReq->cManageTopicLength; +} + +//return -1.空间不足 +int EncodeAddManageReq (char *buf, int *pBufLen, const StAddManageReq * pReq) +{ + if (*pBufLen < GetAddManageReqLegth (pReq)) + { + return -1; + } + *pBufLen = GetAddManageReqLegth (pReq); + ENCODE_CSTR_MEMCPY (buf, pReq->strManageTopic, pReq->cManageTopicLength); + return 0; +} + +int DecodeAddManageReq (StAddManageReq * pReq, const char *buf, + const int bufLen) +{ + if (bufLen < GetRegisterReceiveRspBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_CSTR_MEMCPY (pReq->strManageTopic, pReq->cManageTopicLength, buf, + &iTmpLen); + return 0; +} + +int GetAddManageRspBaseLegth () +{ + return sizeof (int) + sizeof (char); +} + +int GetAddManageRspLegth (const StAddManageRsp * pRsp) +{ + return GetAddManageRspBaseLegth () + pRsp->cManageTopicLength; +} + +//return -1.空间不足 +int EncodeAddManageRsp (char *buf, int *pBufLen, const StAddManageRsp * pRsp) +{ + if (*pBufLen < GetAddManageRspLegth (pRsp)) + { + return -1; + } + *pBufLen = GetAddManageRspLegth (pRsp); + ENCODE_INT (buf, pRsp->uiResult); + ENCODE_CSTR_MEMCPY (buf, pRsp->strManageTopic, pRsp->cManageTopicLength); + return 0; +} + +int DecodeAddManageRsp (StAddManageRsp * pRsp, const char *buf, + const int bufLen) +{ + if (bufLen < GetAddManageRspBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pRsp->uiResult, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pRsp->strManageTopic, pRsp->cManageTopicLength, buf, + &iTmpLen); + return 0; +} + +//***************************0x04 worker发包************************** + +int GetSendMsgReqBaseLength () +{ + return 3 * sizeof (int) + sizeof (char); +} + +int GetSendMsgReqLength (const StSendMsgReq * pReq) +{ + return GetSendMsgReqBaseLength () + pReq->uiWemqMsgLen + + pReq->cReseveLength; +} + +//return -1.空间不足 +int EncodeSendMsgReq (char *buf, int *pBufLen, const StSendMsgReq * pReq) +{ + if (*pBufLen < GetSendMsgReqLength (pReq)) + { + return -1; + } + *pBufLen = GetSendMsgReqLength (pReq); + ENCODE_INT (buf, pReq->uiMsgType); + ENCODE_INT (buf, pReq->uiSendMsgSeq); + ENCODE_DWSTR_MEMCPY (buf, pReq->strWemqMsg, pReq->uiWemqMsgLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strReserve, pReq->cReseveLength); + return 0; +} + +int DecodeSendMsgReq (StSendMsgReq * pReq, const char *buf, const int bufLen) +{ + if (bufLen < GetSendMsgReqBaseLength ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pReq->uiMsgType, buf, &iTmpLen); + DECODE_INT (pReq->uiSendMsgSeq, buf, &iTmpLen); + DECODE_DWSTR_MEMCPY (pReq->strWemqMsg, pReq->uiWemqMsgLen, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strReserve, pReq->cReseveLength, buf, &iTmpLen); + return 0; +} + +int GetSendMsgRspBaseLength () +{ + return 3 * sizeof (int) + sizeof (char); +} + +int GetSendMsgRspLength (const StSendMsgRsp * pRsp) +{ + return GetSendMsgRspBaseLength () + pRsp->cUuidLen; +} + +//return -1.空间不足 +int EncodeSendMsgRsp (char *buf, int *pBufLen, const StSendMsgRsp * pRsp) +{ + if (*pBufLen < GetSendMsgRspLength (pRsp)) + { + return -1; + } + *pBufLen = GetSendMsgRspLength (pRsp); + ENCODE_INT (buf, pRsp->uiResult); + ENCODE_INT (buf, pRsp->uiMsgType); + ENCODE_INT (buf, pRsp->uiRecvMsgSeq); + ENCODE_CSTR_MEMCPY (buf, pRsp->strUuid, pRsp->cUuidLen); + return 0; +} + +int DecodeSendMsgRsp (StSendMsgRsp * pRsp, const char *buf, const int bufLen) +{ + if (bufLen < GetSendMsgRspBaseLength ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pRsp->uiResult, buf, &iTmpLen); + DECODE_INT (pRsp->uiMsgType, buf, &iTmpLen); + DECODE_INT (pRsp->uiRecvMsgSeq, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pRsp->strUuid, pRsp->cUuidLen, buf, &iTmpLen); + return 0; +} + +//***************************0x05 worker发送消息ack************************** +//请求,为避免其他业务代码错误导致把其他人的msg ack掉, 因此这里将sessionId和sessionIndex flowIndex做核对 + +int GetAckMsgReqBaseLength () +{ + return 2 * sizeof (int) + 2 * sizeof (char) + sizeof (long); +} + +int GetAckMsgReqLength (const StAckMsgReq * pReq) +{ + return GetAckMsgReqBaseLength () + pReq->cUuidLen + pReq->cReseveLength; +} + +//return -1.空间不足 +int EncodeAckMsgReq (char *buf, int *pBufLen, const StAckMsgReq * pReq) +{ + if (*pBufLen < GetAckMsgReqLength (pReq)) + { + return -1; + } + *pBufLen = GetAckMsgReqLength (pReq); + ENCODE_INT (buf, pReq->uiSessionIndex); + ENCODE_INT (buf, pReq->uiFlowIndex); + ENCODE_LONG (buf, pReq->ulMsgId); + ENCODE_CSTR_MEMCPY (buf, pReq->strUuid, pReq->cUuidLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strReserve, pReq->cReseveLength); + return 0; +} + +int DecodeAckMsgReq (StAckMsgReq * pReq, const char *buf, const int bufLen) +{ + if (bufLen < GetAckMsgReqBaseLength ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pReq->uiSessionIndex, buf, &iTmpLen); + DECODE_INT (pReq->uiFlowIndex, buf, &iTmpLen); + DECODE_LONG (pReq->ulMsgId, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strUuid, pReq->cUuidLen, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strReserve, pReq->cReseveLength, buf, &iTmpLen); + return 0; +} + +//回包 + +int GetAckMsgRspBaseLength () +{ + return 3 * sizeof (int) + sizeof (char) + sizeof (unsigned long); +} + +int GetAckMsgRspLength (const StAckMsgRsp * pReq) +{ + return GetAckMsgRspBaseLength () + pReq->cUuidLen; +} + +//return -1.空间不足 +int EncodeAckMsgRsp (char *buf, int *pBufLen, const StAckMsgRsp * pRsp) +{ + if (*pBufLen < GetAckMsgRspLength (pRsp)) + { + return -1; + } + *pBufLen = GetAckMsgRspLength (pRsp); + ENCODE_INT (buf, pRsp->uiResult); + ENCODE_INT (buf, pRsp->uiSessionIndex); + ENCODE_INT (buf, pRsp->uiFlowIndex); + ENCODE_LONG (buf, pRsp->ulMsgId); + ENCODE_CSTR_MEMCPY (buf, pRsp->strUuid, pRsp->cUuidLen); + return 0; +} + +int DecodeAckMsgRsp (StAckMsgRsp * pRsp, const char *buf, const int bufLen) +{ + if (bufLen < GetAckMsgRspBaseLength ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pRsp->uiResult, buf, &iTmpLen); + DECODE_INT (pRsp->uiSessionIndex, buf, &iTmpLen); + DECODE_INT (pRsp->uiFlowIndex, buf, &iTmpLen); + DECODE_LONG (pRsp->ulMsgId, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pRsp->strUuid, pRsp->cUuidLen, buf, &iTmpLen); + return 0; +} + +//以下为proxy推送消息 +//***************************0x50 proxy下发消息************************** +int GetPushMsgReqBaseLegth () +{ + return (2 * sizeof (int) + 2 * sizeof (char)); +} + +int GetPushMsgReqLegth (const StPushMsgReq * pReq) +{ + return GetPushMsgReqBaseLegth () + pReq->uiWemqMsgLen + pReq->cReseveLength; +} + +//return -1.空间不足 +int EncodePushMsgReq (char *buf, int *pBufLen, const StPushMsgReq * pReq) +{ + if (*pBufLen < GetPushMsgReqLegth (pReq)) + { + return -1; + } + *pBufLen = GetPushMsgReqLegth (pReq); + ENCODE_CHAR (buf, pReq->cWemqMsgType); + ENCODE_INT (buf, pReq->uiSeq); + ENCODE_DWSTR_MEMCPY (buf, pReq->strWemqMsg, pReq->uiWemqMsgLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strReserve, pReq->cReseveLength); + return 0; +} + +int DecodePushMsgReq (StPushMsgReq * pReq, const char *buf, const int bufLen) +{ + if (bufLen < GetPushMsgReqBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_CHAR (pReq->cWemqMsgType, buf, &iTmpLen); + DECODE_INT (pReq->uiSeq, buf, &iTmpLen); + DECODE_DWSTR_MEMCPY (pReq->strWemqMsg, pReq->uiWemqMsgLen, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strReserve, pReq->cReseveLength, buf, &iTmpLen); + return 0; +} + +//回包 + +int GetPushMsgRspBaseLegth () +{ + return sizeof (int) + sizeof (char); +} + +int GetPushMsgRspLegth (const StPushMsgRsp * pRsp) +{ + return GetPushMsgRspBaseLegth () + pRsp->cUuidLen; +} + +//return -1.空间不足 +int EncodePushMsgRsp (char *buf, int *pBufLen, const StPushMsgRsp * pRsp) +{ + if (*pBufLen < GetPushMsgRspLegth (pRsp)) + { + return -1; + } + *pBufLen = GetPushMsgRspLegth (pRsp); + ENCODE_INT (buf, pRsp->uiResult); + ENCODE_CSTR_MEMCPY (buf, pRsp->strUuid, pRsp->cUuidLen); + return 0; +} + +int DecodePushMsgRsp (StPushMsgRsp * pRsp, const char *buf, const int bufLen) +{ + if (bufLen < GetPushMsgRspBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pRsp->uiResult, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pRsp->strUuid, pRsp->cUuidLen, buf, &iTmpLen); + return 0; +} + +//*************************************************wemq worker-proxy包格式***************************** +//msg的组成都是header + msgbuf, 其中header的头4个字节为长度 +int GetWemqHeaderLen () +{ + return 5 * sizeof (int) + sizeof (unsigned short); +} + +int EncodeWemqHeader (char *buf, int *pBufLen, const StWemqHeader * pHeader) +{ + if (*pBufLen < GetWemqHeaderLen ()) + { + return -1; + } + *pBufLen = GetWemqHeaderLen (); + + ENCODE_INT (buf, pHeader->uiPkgLen); + ENCODE_INT (buf, 0xFFFFFFFF); + ENCODE_SHORT (buf, pHeader->usCmd); + ENCODE_INT (buf, pHeader->uiSessionId); + ENCODE_INT (buf, pHeader->uiSeq); + ENCODE_INT (buf, pHeader->uiReserved); + return 0; +} + +int DecodeWemqHeader (StWemqHeader * pHeader, const char *buf, + const int bufLen) +{ + if (bufLen < GetWemqHeaderLen ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pHeader->uiPkgLen, buf, &iTmpLen); + DECODE_INT (pHeader->uiColorFlag, buf, &iTmpLen); + DECODE_SHORT (pHeader->usCmd, buf, &iTmpLen); + DECODE_INT (pHeader->uiSessionId, buf, &iTmpLen); + DECODE_INT (pHeader->uiSeq, buf, &iTmpLen); + DECODE_INT (pHeader->uiReserved, buf, &iTmpLen); + return 0; +} + +int DecodeWeMQMsg (StWeMQMSG * pMsg, const char *buf, const int bufLen) +{ + int iTmpLen = bufLen; + DECODE_INT (pMsg->uiTotalLen, buf, &iTmpLen); + DECODE_INT (pMsg->uiHeaderLen, buf, &iTmpLen); +/* + DECODE_DWSTR_MEMCPY(pMsg->cStrJsonHeader,pMsg->uiHeaderLen,buf,&iTmpLen); + pMsg->cStrJsonHeader[pMsg->uiHeaderLen] = '\0'; + DECODE_DWSTR_MEMCPY(pMsg->cStrJsonBody, pMsg->uiTotalLen - pMsg->uiHeaderLen - 8, buf, &iTmpLen); + pMsg->cStrJsonHeader[pMsg->uiTotalLen - pMsg->uiHeaderLen - 8] = '\0'; +*/ + return 0; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/wemq_tcp.c b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_tcp.c new file mode 100644 index 0000000000..971fec4c1e --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_tcp.c @@ -0,0 +1,773 @@ +// 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. + +#include "wemq_tcp.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rmb_define.h" + +// return=0: timeout; return<0: error; return>0: success. +static int check_recv (int fd, int iSec, int iMs) +{ + fd_set rset; + int ret; + + FD_ZERO (&rset); + FD_SET (fd, &rset); + + struct timeval tv; + tv.tv_sec = iSec; + tv.tv_usec = iMs * 1000; + + do + { + ret = select (fd + 1, &rset, NULL, NULL, &tv); + } + while (ret < 0 && errno == EINTR); + + // 如果rset只有一个socket, 不需要去判断FD_ISSET + if (ret > 0 && FD_ISSET (fd, &rset)) + { + return 1; + } + + return (ret == 0 ? 0 : -1); +} + +// return=0: timeout; return<0: error; return>0: success. +static int check_send (int fd, int iSec, int iMs) +{ + fd_set wset; + int ret; + + FD_ZERO (&wset); + FD_SET (fd, &wset); + + struct timeval tv; + tv.tv_sec = iSec; + tv.tv_usec = iMs * 1000; + + do + { + ret = select (fd + 1, NULL, &wset, NULL, &tv); + } + while (ret < 0 && errno == EINTR); + + // 如果rset只有一个socket, 不需要去判断FD_ISSET + if (ret > 0 && FD_ISSET (fd, &wset)) + { + return 1; + } + + return (ret == 0 ? 0 : -1); +} + +//************************************ +// Method: wemq_tcp_connect +// FullName: wemq_tcp_connect +// Access: public +// Returns: int if connect success return socket fd, else return -1 +// Qualifier: +// Parameter: const char * ip +// Parameter: uint16_t port +// Parameter: int timeout:单位为ms +//************************************ +int wemq_tcp_connect (const char *ip, uint16_t port, int timeout) +{ + int sockfd = -1; + struct sockaddr_in servaddr; + int flag = 0; + int ret = 0; + + if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) + { + return -1; + } + if (timeout > 0) + { + flag = fcntl (sockfd, F_GETFL) | O_NONBLOCK; + fcntl (sockfd, F_SETFL, flag); + } + + bzero (&servaddr, sizeof (servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons (port); + if (inet_pton (AF_INET, ip, &servaddr.sin_addr) <= 0) + { + close (sockfd); + return -2; + } + + do + { + ret = + connect (sockfd, (struct sockaddr *) &servaddr, + sizeof (struct sockaddr_in)); + } + while (ret < 0 && errno == EINTR); + if ((ret != 0) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS)) + { + close (sockfd); + return -3; + } + + // 判断是否需要超时 + if (timeout > 0) + { + fd_set write_set; + struct timeval tv; + int sock_err = 0; + int sock_err_len = sizeof (sock_err); + + FD_ZERO (&write_set); + FD_SET (sockfd, &write_set); + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + + do + { + ret = select (FD_SETSIZE, NULL, &write_set, NULL, &tv); + } + while (ret < 0 && errno == EINTR); + if (ret <= 0 || !FD_ISSET (sockfd, &write_set)) + { + close (sockfd); + return 0; + } + + //getscokopt: check socket connect + if (getsockopt + (sockfd, SOL_SOCKET, SO_ERROR, (char *) &sock_err, + (socklen_t *) & sock_err_len) != 0) + { + close (sockfd); + return -4; + } + if (sock_err != 0) + { + close (sockfd); + return -5; + } + + //block + flag &= ~O_NONBLOCK; + fcntl (sockfd, F_SETFL, flag); + } + return sockfd; +} + +//************************************ +// Method: wemq_tcp_send +// FullName: wemq_tcp_send +// Access: public +// Returns: int 0 for success, -1 for error +// Qualifier: +// Parameter: int fd connected socket +// Parameter: char * msg message buffer +// Parameter: uint32_t len message length +//************************************ +int wemq_tcp_send (int fd, void *msg, uint32_t totalLen, uint32_t headerLen, + int iTimeOut, SSL * ssl) +{ + //uint32_t uiHeadRemain = 4; + //uint32_t uiHeadSend = 0; + if (fd < 0 || msg == NULL) + { + return -1; + } + if (iTimeOut <= 0) + { + iTimeOut = 1000; + } + /* + while (uiHeadRemain > 0) + { + iRet = check_send(fd, iTimeOut/1000, iTimeOut%1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB(RMB_LOG_ERROR, "check_send error, errno=%d\n", errno); + return -2; + } + iRet = send(fd, "JSON", uiHeadRemain, 0); + if (iRet < 0) + { + LOGRMB(RMB_LOG_ERROR, "send error, errno=%d\n", errno); + return -2; + } + uiHeadSend += iRet; + uiHeadRemain -= iRet; + } + */ + int iRet; + uint32_t uiRemain = totalLen + 8; + uint32_t uiSend = 0; + char *msg_temp = (char *) malloc ((totalLen + 8) * sizeof (char)); + char *msg_new = msg_temp; + ENCODE_DWSTR_MEMCPY (msg_temp, "WEMQ", 4); + ENCODE_DWSTR_MEMCPY (msg_temp, "0000", 4); + ENCODE_DWSTR_MEMCPY (msg_temp, msg, totalLen); + // LOGRMB(RMB_LOG_DEBUG, "tcp data=%s\n", msg_temp); + //LOGRMB(RMB_LOG_DEBUG, "tcp data2=%s\n", (char *)msg); + while (uiRemain > 0) + { + iRet = check_send (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_send error, errno=%d\n", errno); + return -2; + } + if (NULL != ssl) + { + iRet = SSL_write (ssl, msg_new + uiSend, uiRemain); + } + else + { + iRet = send (fd, msg_new + uiSend, uiRemain, 0); + } + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "send error, errno=%d, iRet=%d\n", errno, iRet); + return -2; + } + uiSend += iRet; + uiRemain -= iRet; + } + free (msg_new); + return uiSend; +} + +int wemq_ssl_recv (int fd, void *msg, uint32_t * len, int iTimeOut, SSL * ssl) +{ + int iRet; + uint32_t uiRemain, uiRecved; + + uiRemain = 4; + uiRecved = 0; + if (fd < 0 || msg == NULL || len == NULL) + { + return -1; + } + if (iTimeOut <= 0) + { + iTimeOut = 1000; + } + while (uiRemain > 0) + { + int iRecv = 0; + iRet = check_recv (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_recv error, error=%d\n", errno); + return -2; + } + iRecv = SSL_read (ssl, msg + uiRecved, uiRemain); + if (iRecv < 0 && (errno != EAGAIN)) + { + LOGRMB (RMB_LOG_ERROR, "Recv error, fd close() error=%d, iRecv=%d\n", + errno, iRecv); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, "Peer close connect, fd close() errno=%d\n", + errno); + return -2; + } + if (iRet > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + } + + if (uiRecved != 4 || strcmp (msg, "WEMQ") != 0) + { + LOGRMB (RMB_LOG_ERROR, "recv msg header error,%u:%s", uiRecved, + (char *) msg); + return -3; + } + + uiRemain = 4; + uiRecved = 0; + while (uiRemain > 0) + { + int iRecv = 0; + iRecv = SSL_read (ssl, msg + uiRecved, uiRemain); + if (iRecv > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + if (0 == uiRemain) + { + break; + } + + iRet = check_recv (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_recv error, error=%d\n", errno); + return -2; + } + if (NULL != ssl) + { + iRecv = SSL_read (ssl, msg + uiRecved, uiRemain); + } + else + { + iRecv = recv (fd, msg + uiRecved, uiRemain, 0); + } + if (iRecv < 0 && (errno != EAGAIN)) + { + LOGRMB (RMB_LOG_ERROR, "Recv error, fd close() error=%d, iRecv=%d\n", + errno, iRecv); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, "Peer close connect, fd close() errno=%d\n", + errno); + return -2; + } + if (iRet > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + } + //LOGRMB(RMB_LOG_DEBUG, "Recv version = %s\n", (char *)msg); + if (uiRecved != 4) + { + LOGRMB (RMB_LOG_ERROR, "recv msg version error,%u:%s", uiRecved, + (char *) msg); + return -3; + } + + // read msg length + uiRemain = 4; + uiRecved = 0; + while (uiRemain > 0) + { + int iRecv = 0; + iRecv = SSL_read (ssl, msg + uiRecved, uiRemain); + if (iRecv > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + if (0 == uiRemain) + { + break; + } + iRet = check_recv (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_recv error, error=%d\n", errno); + return -2; + } + + if (NULL != ssl) + { + iRecv = SSL_read (ssl, msg + uiRecved, uiRemain); + } + else + { + iRecv = recv (fd, msg + uiRecved, uiRemain, 0); + } + if (iRecv < 0 && (errno != EAGAIN)) + { + LOGRMB (RMB_LOG_ERROR, "Recv error, fd close() error=%d, iRecv=%d\n", + errno, iRecv); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, "Peer close connect, fd close() errno=%d\n", + errno); + return -2; + } + if (iRet > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + } + + if (uiRecved != 4) + { + // can't read 4 bytes + LOGRMB (RMB_LOG_ERROR, "recv less than 4, recv %d bytes\n", uiRecved); + return -3; + } + + *len = ntohl (*(uint32_t *) msg); + + uiRemain = *len - 4; + while (uiRemain > 0) + { + int iRecv = 0; + iRecv = SSL_read (ssl, msg + uiRecved, uiRemain); + if (iRecv > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + if (0 == uiRemain) + { + break; + } + iRet = check_recv (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_recv error, error=%d\n", errno); + return -2; + } + + if (NULL != ssl) + { + iRecv = SSL_read (ssl, msg + uiRecved, uiRemain); + } + else + { + iRecv = recv (fd, msg + uiRecved, uiRemain, 0); + } + if (iRecv < 0 && (errno != EAGAIN)) + { + LOGRMB (RMB_LOG_ERROR, "Recv error, fd close() error=%d, iRecv=%d\n", + errno, iRecv); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, "Peer close connect, fd close() errno=%d\n", + errno); + return -2; + } + if (iRet > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + } + + if (uiRecved != *len) + { + // can't recv whole msg + return -3; + } + + return uiRecved; +} + +//************************************ +// Method: wemq_tcp_recv +// FullName: wemq_tcp_recv +// Access: public +// Returns: int 0 for success, -1 for error +// Qualifier: +// Parameter: int fd connected socket +// Parameter: void * msg receive message buffer +// Parameter: uint32_t * len receive message length +//************************************ +int wemq_tcp_recv (int fd, void *msg, uint32_t * len, int iTimeOut, SSL * ssl) +{ + int iRet; + uint32_t uiRemain, uiRecved; + + if (NULL != ssl) + { + return wemq_ssl_recv (fd, msg, len, iTimeOut, ssl); + } + + uiRemain = 4; + uiRecved = 0; + if (fd < 0 || msg == NULL || len == NULL) + { + return -1; + } + if (iTimeOut <= 0) + { + iTimeOut = 1000; + } + while (uiRemain > 0) + { + int iRecv = 0; + iRet = check_recv (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_recv error, error=%d\n", errno); + return -2; + } + iRecv = recv (fd, msg + uiRecved, uiRemain, 0); + if (iRecv < 0 && (errno != EAGAIN)) + { + LOGRMB (RMB_LOG_ERROR, "Recv error, fd close() error=%d, iRecv=%d\n", + errno, iRecv); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, "Peer close connect, fd close() errno=%d\n", + errno); + return -2; + } + if (iRet > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + } + + if (uiRecved != 4 || strcmp (msg, "WEMQ") != 0) + { + LOGRMB (RMB_LOG_ERROR, "recv msg header error,%u:%s", uiRecved, + (char *) msg); + return -3; + } + + uiRemain = 4; + uiRecved = 0; + if (fd < 0 || msg == NULL || len == NULL) + { + return -1; + } + if (iTimeOut <= 0) + { + iTimeOut = 1000; + } + while (uiRemain > 0) + { + int iRecv = 0; + iRet = check_recv (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_recv error, error=%d\n", errno); + return -2; + } + iRecv = recv (fd, msg + uiRecved, uiRemain, 0); + if (iRecv < 0 && (errno != EAGAIN)) + { + LOGRMB (RMB_LOG_ERROR, "Recv error, fd close() error=%d, iRecv=%d\n", + errno, iRecv); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, "Peer close connect, fd close() errno=%d\n", + errno); + return -2; + } + if (iRet > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + } + //LOGRMB(RMB_LOG_DEBUG, "Recv version = %s\n", (char *)msg); + if (uiRecved != 4) + { + LOGRMB (RMB_LOG_ERROR, "recv msg version error,%u:%s", uiRecved, + (char *) msg); + return -3; + } + + // read msg length + uiRemain = 4; + uiRecved = 0; + while (uiRemain > 0) + { + int iRecv = 0; + iRet = check_recv (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_recv error, error=%d\n", errno); + return -2; + } + + iRecv = recv (fd, msg + uiRecved, uiRemain, 0); + if (iRecv < 0 && (errno != EAGAIN)) + { + LOGRMB (RMB_LOG_ERROR, "Recv error, fd close() error=%d, iRecv=%d\n", + errno, iRecv); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, "Peer close connect, fd close() errno=%d\n", + errno); + return -2; + } + if (iRet > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + } + + if (uiRecved != 4) + { + // can't read 4 bytes + LOGRMB (RMB_LOG_ERROR, "recv less than 4, recv %d bytes\n", uiRecved); + return -3; + } + + *len = ntohl (*(uint32_t *) msg); + + uiRemain = *len - 4; + while (uiRemain > 0) + { + int iRecv = 0; + iRet = check_recv (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_recv error, error=%d\n", errno); + return -2; + } + + iRecv = recv (fd, msg + uiRecved, uiRemain, 0); + if (iRecv < 0 && (errno != EAGAIN)) + { + LOGRMB (RMB_LOG_ERROR, "Recv error, fd close() error=%d, iRecv=%d\n", + errno, iRecv); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, "Peer close connect, fd close() errno=%d\n", + errno); + return -2; + } + if (iRet > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + } + + if (uiRecved != *len) + { + // can't recv whole msg + return -3; + } + + return uiRecved; +} + +int wemq_tcp_close (int fd, SSL * ssl) +{ + if (NULL != ssl) + { + SSL_shutdown (ssl); + SSL_free (ssl); + } + if (fd >= 0) + { + close (fd); + } + + return 0; +} + +// 获取当前socket本地的IP和端口 +void wemq_getsockename (int fd, char *ip, uint32_t len, int *port) +{ + struct sockaddr_in guest; + socklen_t guest_len = sizeof (guest); + + if (fd <= 0 || port == NULL) + { + return; + } + if (getsockname (fd, (struct sockaddr *) &guest, (socklen_t *) & guest_len) + != 0) + { + return; + } + *port = ntohs (guest.sin_port); + if (ip != NULL && len > 0) + { + inet_ntop (AF_INET, &guest.sin_addr, ip, len); + } +} + +// 获取当前socket远端的IP和端口 +void wemq_getpeername (int fd, char *ip, uint32_t len, int *port) +{ + struct sockaddr_in svr; + socklen_t svr_len = sizeof (svr); + + if (fd <= 0 || port == NULL) + { + return; + } + if (getpeername (fd, (struct sockaddr *) &svr, (socklen_t *) & svr_len) != + 0) + { + return; + } + *port = ntohs (svr.sin_port); + if (ip != NULL && len > 0) + { + inet_ntop (AF_INET, &svr.sin_addr, ip, len); + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/wemq_thread.c b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_thread.c new file mode 100644 index 0000000000..7ca2c9c638 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_thread.c @@ -0,0 +1,5467 @@ +// 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. + +#include +#include +#include +#include +#include "common.h" +#include "wemq_thread.h" +#include "rmb_common.h" +#include "rmb_errno.h" +#include "wemq_tcp.h" +#include "rmb_pub.h" +#include "rmb_sub.h" +#include "rmb_access_config.h" +#define MAX_EVENTS 100 +#define HEART_BEAT_COUNT 300 +#define HEART_BEAT_PERIOD 15 +#define CHECK_RR_EMPTY_PERIOD 10 + +static enum _wemq_message_ret +{ + WEMQ_MESSAGE_RET_ERR = -1, + WEMQ_MESSAGE_RET_GOODBYE = 88, + WEMQ_MESSAGE_RET_CLIENTGOODBYE = 881, + WEMQ_MESSAGE_RET_SERVERGOODBYE = 882, + WEMQ_MESSAGE_RET_REDIRECT = 300, +}; + +extern const char *vecManageTopic[10]; +unsigned long long ullNow = 0; +char *STATE_MAP[10] = { + "THREAD_STATE_INIT", + "THREAD_STATE_CONNECT", + "THREAD_STATE_REGI", + "THREAD_STATE_OK", + "THREAD_STATE_CLOSE", + "THREAD_STATE_SERVER_BREAK", + "THREAD_STATE_BREAK", + "THREAD_STATE_RECONNECT", + "THREAD_STATE_DESTORY", + "THREAD_STATE_EXIT" +}; + +char *_wemq_cmd_map[] = { + "", + "CMD_BEAT", + "CMD_REGI", + "CMD_ADD_LISTEN", + "CMD_SEND_MSG", + "CMD_SEND_MSG_ACK", + "CMD_ADD_MANAGE", + "CMD_SEND_REQUEST", + "CMD_SEND_REQUEST_ASYNC", + "CMD_SEND_REPLY", + "CMD_SEND_PUSH", + "CMD_SEND_START" +}; + +static int32_t _wemq_thread_do_send_sync (WemqThreadCtx * pThreadCtx, + void *msg, uint32_t totalLen, + uint32_t headerLen); + +/* +unsigned long long _wemq_thread_get_cur_time() +{ + struct timeval _curTimeVal; + gettimeofday(&_curTimeVal, NULL); + ullNow = (unsigned long)_curTimeVal.tv_sec * (unsigned long)1000UL + (unsigned long)_curTimeVal.tv_usec / 1000UL; + return ullNow; +} +*/ + +static int _wemq_get_executable_path (char *processdir, size_t len) +{ + char *path_end; + if (readlink ("/proc/self/exe", processdir, len) <= 0) + return -1; + path_end = strrchr (processdir, '/'); + if (path_end == NULL) + return -1; + return (int) (path_end - processdir); +} + +static const char *_wemq_thread_get_cmd (unsigned int usCmd) +{ + const char *pRet = NULL; +// if (usCmd <= 0x50) +// { +// pRet = _wemq_cmd_map[usCmd]; +// } +// else +// { +// pRet = "CMD_PUSH"; +// } + + switch (usCmd) + { + case THREAD_MSG_CMD_BEAT: + case THREAD_MSG_CMD_REGI: + case THREAD_MSG_CMD_ADD_LISTEN: + case THREAD_MSG_CMD_SEND_MSG: + case THREAD_MSG_CMD_SEND_MSG_ACK: + case THREAD_MSG_CMD_ADD_MANAGE: + case THREAD_MSG_CMD_SEND_REQUEST: + case THREAD_MSG_CMD_SEND_REQUEST_ASYNC: + case THREAD_MSG_CMD_SEND_REPLY: + case THREAD_MSG_CMD_START: + pRet = _wemq_cmd_map[usCmd]; + break; + + case THREAD_MSG_CMD_SEND_PUSH: + pRet = "CMD_PUSH"; + break; + + default: + pRet = "CMD_ERROR"; + } + + return pRet; +} + +static int32_t _wemq_thread_check_init (WemqThreadCtx * pThreadCtx) +{ + return 0; +} + +static int32_t _wemq_thread_check_connect (WemqThreadCtx * pThreadCtx) +{ + return 0; +} + +static int32_t _wemq_thread_check_regi (WemqThreadCtx * pThreadCtx) +{ + return 0; +} + +static int32_t _wemq_thread_check_ok (WemqThreadCtx * pThreadCtx) +{ + return 0; +} + +static int32_t _wemq_thread_check_close (WemqThreadCtx * pThreadCtx) +{ + return 0; +} + +static int32_t _wemq_thread_check_reconnect (WemqThreadCtx * pThreadCtx) +{ + return 0; +} + +static int32_t _wemq_thread_check_break (WemqThreadCtx * pThreadCtx) +{ + return 0; +} + +static int32_t _wemq_thread_check_destory (WemqThreadCtx * pThreadCtx) +{ + return 0; +} + +/** + * 心跳包: + * cmd:HEARTBEAT_REQUEST + * headerJson={"code":0,"seq":"0160616463","command":"HEARTBEAT_REQUEST"}|bodyJson=null + * + */ +static int32_t _wemq_thread_make_heart_beat_pkg (WemqThreadCtx * pThreadCtx) +{ + StWemqThreadMsg *pThreadMsg = &pThreadCtx->m_stHeartBeat; + memset (pThreadMsg, 0, sizeof (StWemqThreadMsg)); + pThreadMsg->m_iCmd = THREAD_MSG_CMD_BEAT; + WEMQJSON *jsonHeader = json_object_new_object (); + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (HEARTBEAT_REQUEST)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + json_object_put (jsonHeader); + return -1; + } + pThreadMsg->m_iHeaderLen = strlen (header_str); + + pThreadMsg->m_pHeader = + (char *) malloc (pThreadMsg->m_iHeaderLen * sizeof (char) + 1); + if (pThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for heart beat header failed"); + json_object_put (jsonHeader); + return -1; + } + memcpy (pThreadMsg->m_pHeader, header_str, pThreadMsg->m_iHeaderLen); + pThreadMsg->m_pHeader[pThreadMsg->m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + + pThreadMsg->m_iBodyLen = 0; + pThreadMsg->m_pBody = NULL; + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] make heart beat pkg succ %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadMsg->m_pHeader); + return 0; +} + +/** + * 发送start listen命令: + * cmd:LISTEN_REQUEST + * headerJson={"code":0,"seq":"7542688344","command":"LISTEN_REQUEST"}|bodyJson=null + * + */ +static int32_t _wemq_thread_make_start_listen_pkg (WemqThreadCtx * pThreadCtx) +{ + StWemqThreadMsg *pThreadMsg = &pThreadCtx->m_stListen; + memset (pThreadMsg, 0, sizeof (StWemqThreadMsg)); + pThreadMsg->m_iCmd = THREAD_MSG_CMD_START; + WEMQJSON *jsonHeader = json_object_new_object (); + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (LISTEN_REQUEST)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + json_object_put (jsonHeader); + return -1; + } + pThreadMsg->m_iHeaderLen = strlen (header_str); + + pThreadMsg->m_pHeader = + (char *) malloc (pThreadMsg->m_iHeaderLen * sizeof (char) + 1); + if (pThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for listen header failed"); + json_object_put (jsonHeader); + return -1; + } + memcpy (pThreadMsg->m_pHeader, header_str, pThreadMsg->m_iHeaderLen); + pThreadMsg->m_pHeader[pThreadMsg->m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + + pThreadMsg->m_iBodyLen = 0; + pThreadMsg->m_pBody = NULL; + LOGRMB (RMB_LOG_DEBUG, "[%s] [Type:%d] [TID:%lu] make listen pkg succ %s", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadMsg->m_pHeader); + return 0; +} + +/** + * 发送SUBSCRIBE_REQUEST: + * cmd:SUBSCRIBE_REQUEST + * headerJson={"code":0,"seq":"1333580037","command":"SUBSCRIBE_REQUEST"}| + * bodyJson={"topicList":["PRX-e-10030002-05-3","PRX-e-10020002-02-2","PRX-s-10000002-01-0","PRX-e-10020002-06-2"]} + * + */ +static int32_t _wemq_thread_make_subscribe_pkg (WemqThreadCtx * pThreadCtx) +{ + StWemqThreadMsg *pThreadMsg = &pThreadCtx->m_stListen; + memset (pThreadMsg, 0, sizeof (StWemqThreadMsg)); + pThreadMsg->m_iCmd = THREAD_MSG_CMD_ADD_LISTEN; + WEMQJSON *jsonHeader = json_object_new_object (); + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (LISTEN_REQUEST)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + json_object_put (jsonHeader); + return -1; + } + pThreadMsg->m_iHeaderLen = strlen (header_str); + + pThreadMsg->m_pHeader = + (char *) malloc (pThreadMsg->m_iHeaderLen * sizeof (char) + 1); + if (pThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for listen header failed"); + json_object_put (jsonHeader); + return -1; + } + memcpy (pThreadMsg->m_pHeader, header_str, pThreadMsg->m_iHeaderLen); + pThreadMsg->m_pHeader[pThreadMsg->m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + + pThreadMsg->m_iBodyLen = 0; + pThreadMsg->m_pBody = NULL; + LOGRMB (RMB_LOG_DEBUG, "[%s] [Type:%d] [TID:%lu] make listen pkg succ %s", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadMsg->m_pHeader); + return 0; +} + +/** + * register package: + * cmd:THREAD_STATE_REGI + * headerJson={"code":0,"seq":"5160263626","command":"HELLO_REQUEST"} + * bodyJson={"subsystem":"5023","dcn":"AC0","path":"/data/app/umg_proxy","pid":32893,"host":"127.0.0.1", +* "port":8362,"version":"2.0.11","username":"PU4283","password":"dsaiubd"} + */ +static int32_t _wemq_thread_make_hello_pkg (WemqThreadCtx * pThreadCtx) +{ + StWemqThreadMsg *pThreadMsg = &pThreadCtx->m_stHelloWord; + memset (pThreadMsg, 0, sizeof (StWemqThreadMsg)); + pThreadMsg->m_iCmd = THREAD_STATE_REGI; + WEMQJSON *jsonHeader = json_object_new_object (); + + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (HELLO_REQUEST)); + + WEMQJSON *jsonBody = json_object_new_object (); + + json_object_object_add (jsonBody, "subsystem", + json_object_new_string (pRmbStConfig-> + cConsumerSysId)); + json_object_object_add (jsonBody, "dcn", + json_object_new_string (pRmbStConfig-> + cConsumerDcn)); + json_object_object_add (jsonBody, "host", + json_object_new_string (pRmbStConfig->cHostIp)); + json_object_object_add (jsonBody, "port", json_object_new_string ("")); + json_object_object_add (jsonBody, "version", + json_object_new_string (RMBVERSION)); + json_object_object_add (jsonBody, "username", + json_object_new_string (pRmbStConfig->cWemqUser)); + json_object_object_add (jsonBody, "password", + json_object_new_string (pRmbStConfig->cWemqPasswd)); + json_object_object_add (jsonBody, "idc", + json_object_new_string (pRmbStConfig->cRegion)); + json_object_object_add (jsonBody, "orgid", + json_object_new_string (pRmbStConfig->strOrgId)); + + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + json_object_object_add (jsonBody, "purpose", + json_object_new_string ("pub")); + else + json_object_object_add (jsonBody, "purpose", + json_object_new_string ("sub")); + + char processPath[1024]; + memset (processPath, 0x00, sizeof (processPath)); + _wemq_get_executable_path (processPath, 1024); + json_object_object_add (jsonBody, "path", + json_object_new_string (processPath)); + char pthread_id[32]; + snprintf (pthread_id, sizeof (pthread_id), "%u", pRmbStConfig->uiPid); + json_object_object_add (jsonBody, "pid", + json_object_new_string (pthread_id)); + + const char *header_str = json_object_get_string (jsonHeader); + const char *body_str = json_object_get_string (jsonBody); + + if (header_str == NULL) + { + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + if (body_str == NULL) + { + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + + pThreadMsg->m_iHeaderLen = strlen (header_str); + + pThreadMsg->m_pHeader = + (char *) malloc (pThreadMsg->m_iHeaderLen * sizeof (char) + 1); + if (pThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for hello header failed"); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + memcpy (pThreadMsg->m_pHeader, header_str, pThreadMsg->m_iHeaderLen); + pThreadMsg->m_pHeader[pThreadMsg->m_iHeaderLen] = '\0'; + + pThreadMsg->m_iBodyLen = strlen (body_str); + pThreadMsg->m_pBody = + (char *) malloc (pThreadMsg->m_iBodyLen * sizeof (char) + 1); + if (pThreadMsg->m_pBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for hello body failed"); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + memcpy (pThreadMsg->m_pBody, body_str, pThreadMsg->m_iBodyLen); + pThreadMsg->m_pBody[pThreadMsg->m_iBodyLen] = '\0'; + + json_object_put (jsonBody); + json_object_put (jsonHeader); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] make hello pkg succ, header = %s, body = %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadMsg->m_pHeader, pThreadMsg->m_pBody); + return 0; +} + +static inline int32_t _wemq_thread_state_trans (WemqThreadCtx * pThreadCtx, + int iState, int iNextState) +{ + ASSERT (pThreadCtx); + + LOGRMB (RMB_LOG_INFO, "[%s] [Type:%d] [TID:%lu] Thread State Trans to [%s]", + STATE_MAP[iState], + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, STATE_MAP[iNextState]); + + pThreadCtx->m_iState = iNextState; + pThreadCtx->m_iLastState = iState; + return 0; +} + +static int32_t _wemq_thread_set_fd_nonblock (WemqThreadCtx * pThreadCtx, + int fd) +{ + int opts; + opts = fcntl (fd, F_GETFL); + if (opts < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] set non block error:%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, errno); + return -1; + } + + opts = opts | O_NONBLOCK; + + if (fcntl (fd, F_SETFL, opts) < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] set non block error:%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, errno); + return -1; + } + return 0; +} + +static int32_t _wemq_thread_add_fd (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + pThreadCtx->m_stEv.events = EPOLLIN; + pThreadCtx->m_stEv.data.fd = pThreadCtx->m_iSockFd; + + LOGRMB (RMB_LOG_INFO, "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] fd:%d\n", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, pThreadCtx->m_iSockFd); + + int iRet = -1; + iRet = + epoll_ctl (pThreadCtx->m_iEpollFd, EPOLL_CTL_ADD, pThreadCtx->m_iSockFd, + &pThreadCtx->m_stEv); + if (iRet == -1) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] epoll ctl add error:%d\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, errno); + return -1; + } + + return 0; +} + +static int32_t _wemq_thread_del_fd (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + int iRet = -1; + iRet = + epoll_ctl (pThreadCtx->m_iEpollFd, EPOLL_CTL_DEL, pThreadCtx->m_iSockFd, + &pThreadCtx->m_stEv); + if (iRet == -1) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] epoll ctl del error: %d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, errno); + return -1; + } + + return 0; +} + +static int32_t _wemq_thread_del_old_fd (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + int iRet = -1; + iRet = + epoll_ctl (pThreadCtx->m_iEpollFd, EPOLL_CTL_DEL, + pThreadCtx->m_iSockFdOld, &pThreadCtx->m_stEv); + if (iRet == -1) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] epoll ctl del error: %d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, errno); + return -1; + } + + return 0; +} + +static int32_t _wemq_thread_reset_sockFd (WemqThreadCtx * pThreadCtx, + bool isRecvNewConnect) +{ + if (isRecvNewConnect) + { + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + pThreadCtx->m_iSockFdNew = -1; + pThreadCtx->sslNew = NULL; + + } + else + { + _wemq_thread_del_old_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFdOld, pThreadCtx->sslOld); + pThreadCtx->m_iSockFdOld = -1; + pThreadCtx->sslOld = NULL; + pThreadCtx->m_iSockFd = pThreadCtx->m_iSockFdNew; + pThreadCtx->ssl = pThreadCtx->sslNew; + } + + return 0; +} + +static inline void _wemq_thread_clear_thread_msg (StWemqThreadMsg * + pStWemqThreadMsg) +{ + if (NULL != pStWemqThreadMsg->m_pHeader) + { + free (pStWemqThreadMsg->m_pHeader); + pStWemqThreadMsg->m_pHeader = NULL; + } + if (NULL != pStWemqThreadMsg->m_pBody) + { + free (pStWemqThreadMsg->m_pBody); + pStWemqThreadMsg->m_pBody = NULL; + } + pStWemqThreadMsg->m_iCmd = 0; + pStWemqThreadMsg->m_iHeaderLen = 0; + pStWemqThreadMsg->m_iBodyLen = 0; +} + +static int32_t _wemq_thread_get_data_from_fifo (WemqThreadCtx * pThreadCtx) +{ + int32_t iRet = -1; + + if ((iRet = wemq_kfifo_is_empty (pThreadCtx->m_ptFifo))) + { + return 0; + } + if ((iRet = + wemq_kfifo_get (pThreadCtx->m_ptFifo, + &pThreadCtx->m_stWemqThreadMsg)) < 1) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] wemq_fifo is not empty, but get 0 bytes\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + return -1; + } + + ASSERT (iRet == 1); + pThreadCtx->m_iWemqThreadMsgHandled = 0; + return iRet; +} + +static int32_t _wemq_thread_dyed_msg_ack_to_access (WemqThreadCtx * + pThreadCtx, int seq, + int status, char *msgType, + StRmbMsg * ptSendMsg) +{ + char *buf = pThreadCtx->m_pSendBuff; + int iRet = -1; + WEMQJSON *jsonHeader = json_object_new_object (); + + // 组装消息 + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (msgType)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (seq)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (status)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + json_object_put (jsonHeader); + return -1; + } + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object return null"); + return -1; + } + int wemqMsgType = 0; + if (strcmp (msgType, REQUEST_TO_CLIENT) == 0 + || strcmp (msgType, ASYNC_MESSAGE_TO_CLIENT) + || strcmp (msgType, BROADCAST_MESSAGE_TO_CLIENT)) + { + wemqMsgType = THREAD_MSG_CMD_SEND_MSG_ACK; + } + else if (strcmp (msgType, RESPONSE_TO_CLIENT)) + { + wemqMsgType = THREAD_MSG_CMD_RECV_MSG_ACK; + } + + char cTopic[128]; + char serviceOrEvent = (*(ptSendMsg->strServiceId + 3) == '0') ? 's' : 'e'; + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", + ptSendMsg->strTargetDcn, serviceOrEvent, ptSendMsg->strServiceId, + ptSendMsg->strScenarioId, *(ptSendMsg->strServiceId + 3)); + json_object_object_add (jsonBody, MSG_BODY_TOPIC_STR, + json_object_new_string (cTopic)); + + WEMQJSON *jsonBodyProperty = + rmb_pub_encode_property_for_wemq (wemqMsgType, ptSendMsg); + if (jsonBodyProperty == NULL) + { + json_object_put (jsonHeader); + json_object_put (jsonBody); + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_property_for_wemq return null"); + return -1; + } + + json_object_object_add (jsonBody, MSG_BODY_PROPERTY_JSON, jsonBodyProperty); + + WEMQJSON *jsonByteBody = + rmb_pub_encode_byte_body_for_wemq (wemqMsgType, ptSendMsg); + if (jsonByteBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_byte_body_for_wemq return null"); + return -1; + } + const char *byteBodyStr = json_object_get_string (jsonByteBody); + + json_object_object_add (jsonBody, MSG_BODY_BYTE_BODY_JSON, + json_object_new_string (byteBodyStr)); + + const char *body_str = json_object_get_string (jsonBody); + if (body_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg body failed\n"); + json_object_put (jsonHeader); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + + return -1; + } + + int iHeaderLen = strlen (header_str); + int iBodyLen = strlen (body_str); + int iTotalLen = iHeaderLen + iBodyLen + 8; + + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, header_str, iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, body_str, iBodyLen); +// json_object_put(jsonHeader); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send:header_str:%s body_str:%s\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, header_str, + body_str); + json_object_put (jsonHeader); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + iHeaderLen); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_resp_ack_to_access error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + return 0; +} + +static int32_t _wemq_thread_dyed_msg_reply_to_access (WemqThreadCtx * + pThreadCtx, int seq, + int status, + char *msgType, + StRmbMsg * ptSendMsg) +{ + char *buf = pThreadCtx->m_pSendBuff; + int iRet = -1; + WEMQJSON *jsonHeader = json_object_new_object (); + + // 组装消息 + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (msgType)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (seq)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (status)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + json_object_put (jsonHeader); + return -1; + } + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object return null"); + return -1; + } + char cTopic[128]; + char serviceOrEvent = (*(ptSendMsg->strServiceId + 3) == '0') ? 's' : 'e'; + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", + ptSendMsg->strTargetDcn, serviceOrEvent, ptSendMsg->strServiceId, + ptSendMsg->strScenarioId, *(ptSendMsg->strServiceId + 3)); + json_object_object_add (jsonBody, MSG_BODY_TOPIC_STR, + json_object_new_string (cTopic)); + + WEMQJSON *jsonBodyProperty = + rmb_pub_encode_property_for_wemq (THREAD_MSG_CMD_SEND_REPLY, ptSendMsg); + if (jsonBodyProperty == NULL) + { + json_object_put (jsonHeader); + json_object_put (jsonBody); + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_property_for_wemq return null"); + return -1; + } + + json_object_object_add (jsonBody, MSG_BODY_PROPERTY_JSON, jsonBodyProperty); + + WEMQJSON *jsonByteBody = + rmb_pub_encode_byte_body_for_wemq (THREAD_MSG_CMD_SEND_REPLY, ptSendMsg); + if (jsonByteBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_byte_body_for_wemq return null"); + json_object_put (jsonHeader); + json_object_put (jsonBody); + return -1; + } + const char *byteBodyStr = json_object_get_string (jsonByteBody); + + json_object_object_add (jsonBody, MSG_BODY_BYTE_BODY_JSON, + json_object_new_string (byteBodyStr)); + + const char *body_str = json_object_get_string (jsonBody); + if (body_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg body failed\n"); + json_object_put (jsonHeader); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + + return -1; + } + + int iHeaderLen = strlen (header_str); + int iBodyLen = strlen (body_str); + int iTotalLen = iHeaderLen + iBodyLen + 8; + + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, header_str, iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, body_str, iBodyLen); +// json_object_put(jsonHeader); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send:header_str:%s body_str:%s\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, header_str, + body_str); + json_object_put (jsonHeader); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + iHeaderLen); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_resp_ack_to_access error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + return 0; +} + +static int32_t _wemq_thread_resp_ack_to_access (WemqThreadCtx * pThreadCtx, + int seq, int status, + char *msgType, + StRmbMsg * ptSendMsg) +{ + char *buf = pThreadCtx->m_pSendBuff; + int iRet = -1; + WEMQJSON *jsonHeader = json_object_new_object (); + + // 组装消息 + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (msgType)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (seq)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (status)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + json_object_put (jsonHeader); + return -1; + } + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object return null"); + return -1; + } + char cTopic[128]; + char serviceOrEvent = (*(ptSendMsg->strServiceId + 3) == '0') ? 's' : 'e'; + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", + ptSendMsg->strTargetDcn, serviceOrEvent, ptSendMsg->strServiceId, + ptSendMsg->strScenarioId, *(ptSendMsg->strServiceId + 3)); + json_object_object_add (jsonBody, MSG_BODY_TOPIC_STR, + json_object_new_string (cTopic)); + + WEMQJSON *jsonBodyProperty = + rmb_pub_encode_property_for_wemq (THREAD_MSG_CMD_RECV_MSG_ACK, ptSendMsg); + if (jsonBodyProperty == NULL) + { + json_object_put (jsonHeader); + json_object_put (jsonBody); + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_property_for_wemq return null"); + return -1; + } + + json_object_object_add (jsonBody, MSG_BODY_PROPERTY_JSON, jsonBodyProperty); + + WEMQJSON *jsonByteBody = + rmb_pub_encode_byte_body_for_wemq (THREAD_MSG_CMD_RECV_MSG_ACK, + ptSendMsg); + if (jsonByteBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_byte_body_for_wemq return null"); + json_object_put (jsonHeader); + json_object_put (jsonBody); + return -1; + } + const char *byteBodyStr = json_object_get_string (jsonByteBody); + + json_object_object_add (jsonBody, MSG_BODY_BYTE_BODY_JSON, + json_object_new_string (byteBodyStr)); + + const char *body_str = json_object_get_string (jsonBody); + if (body_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg body failed\n"); + json_object_put (jsonHeader); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + + return -1; + } + + int iHeaderLen = strlen (header_str); + int iBodyLen = strlen (body_str); + int iTotalLen = iHeaderLen + iBodyLen + 8; + + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, header_str, iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, body_str, iBodyLen); +// json_object_put(jsonHeader); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send:header_str:%s body_str:%s\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, header_str, + body_str); + json_object_put (jsonHeader); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + iHeaderLen); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_resp_ack_to_access error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + return 0; +} + +static int32_t _wemq_thread_send_error_log (WemqThreadCtx * pThreadCtx, + int seq, int errCode, + char *logPoint, char *errMsg, + StRmbMsg * ptSendMsg) +{ + char *buf = pThreadCtx->m_pSendBuff; + int iRet = -1; + WEMQJSON *jsonHeader = json_object_new_object (); + + // 组装消息 + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (TRACE_LOG_TO_LOGSERVER)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (seq)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (errCode)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + json_object_put (jsonHeader); + return -1; + } + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object return null"); + json_object_put (jsonHeader); + return -1; + } + WEMQJSON *jsonMessage = json_object_new_object (); + if (jsonMessage == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object return null"); + json_object_put (jsonHeader); + json_object_put (jsonBody); + return -1; + } + char cTopic[128]; + char serviceOrEvent = (*(ptSendMsg->strServiceId + 3) == '0') ? 's' : 'e'; + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", + ptSendMsg->strTargetDcn, serviceOrEvent, ptSendMsg->strServiceId, + ptSendMsg->strScenarioId, *(ptSendMsg->strServiceId + 3)); + json_object_object_add (jsonMessage, MSG_BODY_TOPIC_STR, + json_object_new_string (cTopic)); + + WEMQJSON *jsonBodyProperty = + rmb_pub_encode_property_for_wemq (THREAD_MSG_CMD_RECV_MSG_ACK, ptSendMsg); + if (jsonBodyProperty == NULL) + { + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonBody); + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_property_for_wemq return null"); + return -1; + } + + json_object_object_add (jsonMessage, MSG_BODY_PROPERTY_JSON, + jsonBodyProperty); + + WEMQJSON *jsonByteBody = + rmb_pub_encode_byte_body_for_wemq (THREAD_MSG_CMD_RECV_MSG_ACK, + ptSendMsg); + if (jsonByteBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_byte_body_for_wemq return null"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonBody); + return -1; + } + const char *byteBodyStr = json_object_get_string (jsonByteBody); + + json_object_object_add (jsonMessage, MSG_BODY_BYTE_BODY_JSON, + json_object_new_string (byteBodyStr)); + + const char *message_str = json_object_get_string (jsonMessage); + if (message_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg body failed\n"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + + return -1; + } + + json_object_object_add (jsonBody, "retCode", json_object_new_int (errCode)); + json_object_object_add (jsonBody, "retMsg", + json_object_new_string (errMsg)); + json_object_object_add (jsonBody, "level", + json_object_new_string ("error")); + json_object_object_add (jsonBody, "logPoint", + json_object_new_string (logPoint)); + json_object_object_add (jsonBody, "model", + json_object_new_string ("model")); + json_object_object_add (jsonBody, "lang", json_object_new_string ("c")); + json_object_object_add (jsonBody, "message", + json_object_new_string (message_str)); + + const char *body_str = json_object_get_string (jsonBody); + if (body_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg body failed\n"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + + return -1; + } + + int iHeaderLen = strlen (header_str); + int iBodyLen = strlen (body_str); + int iTotalLen = iHeaderLen + iBodyLen + 8; + + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, header_str, iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, body_str, iBodyLen); +// json_object_put(jsonHeader); + + LOGRMB (RMB_LOG_DEBUG, "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Send:%s\n", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, body_str); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + iHeaderLen); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_send log error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + return 0; +} + +/** + * access to api + * headerJson={"code":0,"seq":"0160616463","command":"REDIRECT_TO_CLIENT"}|bodyJson={"ip":"10.255.34.118", "port":10000} + */ +static int32_t _wemq_thread_on_message_redirect (WemqThreadCtx * pThreadCtx, + char *jsonBody) +{ + WEMQJSON *jsonRedirect = NULL; + WEMQJSON *jsonTmp = NULL; + int ret = 0; + + pThreadCtx->m_cRedirectIP[0] = '\0'; + pThreadCtx->m_iRedirectPort = 0; + //json_object_object_get_ex(jsonHeader ,MSG_HEAD_REDIRECT_OBJ, &jsonRedirect); + jsonRedirect = json_tokener_parse (jsonBody); + if (jsonRedirect == NULL) + { + LOGRMB (RMB_LOG_ERROR, "get redirect from body failed"); + return WEMQ_MESSAGE_RET_ERR; + } + + json_object_object_get_ex (jsonRedirect, "ip", &jsonTmp); + if (jsonTmp != NULL) + { + const char *ip = json_object_get_string (jsonTmp); + if (ip != NULL) + { + snprintf (pThreadCtx->m_cRedirectIP, sizeof (pThreadCtx->m_cRedirectIP), + "%s", ip); + json_object_object_get_ex (jsonRedirect, "port", &jsonTmp); + if (jsonTmp != NULL) + { + pThreadCtx->m_iRedirectPort = json_object_get_int (jsonTmp); + if (pThreadCtx->m_iRedirectPort > 0) + { +// pThreadCtx->m_lRedirect = true; + pThreadCtx->m_lRedirect = 1; + ret = WEMQ_MESSAGE_RET_REDIRECT; + } + else + { + pThreadCtx->m_cRedirectIP[0] = '\0'; + pThreadCtx->m_iRedirectPort = 0; + } + } + else + { + pThreadCtx->m_cRedirectIP[0] = '\0'; + } + } + } + + json_object_put (jsonRedirect); + return ret; +} + +static int32_t _wemq_thread_on_message (WemqThreadCtx * pThreadCtx, + bool isRecvNewConnect) +{ + ASSERT (pThreadCtx); + + stContextProxy *pContextProxy = pThreadCtx->m_ptProxyContext; + StWeMQMSG *pWemqHeader = &pThreadCtx->m_stWeMQMSG; + WEMQJSON *jsonHeader = NULL; + WEMQJSON *jsonTmp = NULL; + const char *usCmd; + int serRet = -1; + int bodyLen = 0; + int seq = -1; + long time = 0; + int ret = 0; + char cMsg[RMB_MAX_ERR_MSG_FROM_ACCESS]; + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] |access2wemq_thread|Recv header:%s body:%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + pWemqHeader->cStrJsonHeader, pWemqHeader->cStrJsonBody); + + bodyLen = pWemqHeader->uiTotalLen - pWemqHeader->uiHeaderLen - 8; + jsonHeader = json_tokener_parse (pWemqHeader->cStrJsonHeader); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] json_tokener_parse header error: %s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pWemqHeader->cStrJsonHeader) return -1; + } + //get command + json_object_object_get_ex (jsonHeader, MSG_HEAD_COMMAND_STR, &jsonTmp); + if (jsonTmp != NULL) + { + usCmd = json_object_get_string (jsonTmp); + } + //get code + json_object_object_get_ex (jsonHeader, MSG_HEAD_CODE_INT, &jsonTmp); + if (jsonTmp != NULL) + { + serRet = json_object_get_int (jsonTmp); + } + //get seq + json_object_object_get_ex (jsonHeader, MSG_HEAD_SEQ_INT, &jsonTmp); + if (jsonTmp != NULL) + { + seq = json_object_get_int (jsonTmp); + } + //get time + json_object_object_get_ex (jsonHeader, MSG_HEAD_TIME_LINT, &jsonTmp); + if (jsonTmp != NULL) + { + time = (long) json_object_get_int64 (jsonTmp); + } + memset (cMsg, 0x00, sizeof (cMsg)); + json_object_object_get_ex (jsonHeader, MSG_HEAD_MSG_STR, &jsonTmp); + if (jsonTmp != NULL) + { + strncpy (cMsg, json_object_get_string (jsonTmp), sizeof (cMsg) - 1); + } + if (strcmp (cMsg, "auth exception") == 0) + { // auth failed + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] Authentication error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + return -1; + } + if (serRet != RMB_CODE_SUSS) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Time:%ld] code from access !=0, cmd=%s, seq=%d, code=%d, msg=%s!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, time, usCmd, + seq, serRet, cMsg); + } + if (strcmp (usCmd, HEARTBEAT_RESPONSE) == 0) //心跳 + { + gettimeofday (&pThreadCtx->stTimeLastRecv, NULL); + pThreadCtx->m_uiHeartBeatCurrent = 0; + + } + else if (strcmp (usCmd, HELLO_RESPONSE) == 0) + { + ret = serRet; + + } + else if (strcmp (usCmd, CLIENT_GOODBYE_RESPONSE) == 0) + { + ret = WEMQ_MESSAGE_RET_CLIENTGOODBYE; + + } + else if (strcmp (usCmd, SERVER_GOODBYE_REQUEST) == 0) + { + ret = WEMQ_MESSAGE_RET_SERVERGOODBYE; + + } + else if (strcmp (usCmd, REDIRECT_TO_CLIENT) == 0) + { + ret = + _wemq_thread_on_message_redirect (pThreadCtx, + pWemqHeader->cStrJsonBody); + + } + else if (strcmp (usCmd, ASYNC_MESSAGE_TO_SERVER_ACK) == 0) //ack 单播 from access + { + if (serRet == RMB_CODE_SUSS) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] PublishAsyncMessage request success!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + + LOGRMB (RMB_LOG_DEBUG, "seq for event: %d", + pContextProxy->iSeqForEvent); + pthread_mutex_lock (&pContextProxy->eventMutex); + if (seq == pContextProxy->iSeqForEvent) + { + pContextProxy->iFlagForEvent = serRet; + pthread_cond_signal (&pContextProxy->eventCond); + } + pthread_mutex_unlock (&pContextProxy->eventMutex); + } + else if (serRet == RMB_CODE_AUT_FAIL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] PublishAsyncMessage request Authentication fail!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + + pthread_mutex_lock (&pContextProxy->eventMutex); + pContextProxy->iFlagForEvent = serRet; + pthread_cond_signal (&pContextProxy->eventCond); + pthread_mutex_unlock (&pContextProxy->eventMutex); + + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] PublishAsyncMessage request fail!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + + pthread_mutex_lock (&pContextProxy->eventMutex); + pContextProxy->iFlagForEvent = serRet; + pthread_cond_signal (&pContextProxy->eventCond); + pthread_mutex_unlock (&pContextProxy->eventMutex); + + } + if (pContextProxy->iFlagForEvent == -1) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] send event msg signal succ! iFlagForEvent=%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time, + serRet); + + } + + } + else if (strcmp (usCmd, ASYNC_MESSAGE_TO_CLIENT) == 0) //recv event message from proxy + { + if (serRet == 0) + { + StContext *pStContext; + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pStContext = (StContext *) (pContextProxy->pubContext); + } + else + { + pStContext = (StContext *) (pContextProxy->subContext); + } + + if (pStContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStContext is null"); + + } + + int iRet = 0; + if ((iRet = + trans_json_2_rmb_msg (pStContext->pReceiveWemqMsg, + pWemqHeader->cStrJsonBody, + ASYNC_MESSAGE_TO_CLIENT)) != 0) + { + LOGRMB (RMB_LOG_ERROR, "trans_json_2_rmb_msg failed,buf is:%s", + pWemqHeader->cStrJsonBody); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "trans_json_2_rmb_msg failed", + pStContext->pReceiveWemqMsg); + return -1; + } + pStContext->pReceiveWemqMsg->iMsgMode = RMB_MSG_FROM_WEMQ; + pStContext->pReceiveWemqMsg->cPkgType = QUEUE_PKG; + + pStContext->uiWemqPkgLen = MAX_LENTH_IN_A_MSG; + + set_extfields_2_rmb_msg (pStContext->pReceiveWemqMsg, + ASYNC_MESSAGE_TO_CLIENT, seq); + + iRet = + shift_msg_2_buf (pStContext->pWemqPkg, &pStContext->uiWemqPkgLen, + pStContext->pReceiveWemqMsg); + //LOGRMB(RMB_LOG_DEBUG, "appHeaderLen:%d", pStContext->pReceiveWemqMsg->iAppHeaderLen); + + //LOGRMB(RMB_LOG_DEBUG, "uiWemqPkgLen:%d", pStContext->uiWemqPkgLen); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "shift_msg_2_buf error!iRet=%d, %d, %s/%s/%s,unique_id=%s,mode=%d,receive=%s", + iRet, pStContext->pReceiveWemqMsg->iEventOrService, + pStContext->pReceiveWemqMsg->strTargetDcn, + pStContext->pReceiveWemqMsg->strServiceId, + pStContext->pReceiveWemqMsg->strScenarioId, + pStContext->pReceiveWemqMsg->sysHeader.cUniqueId, + pStContext->pReceiveWemqMsg->iMsgMode, + rmb_msg_print (pStContext->pReceiveWemqMsg)); + + } + //染色消息直接返回 + if (check_dyed_msg (pStContext->pReceiveWemqMsg) > 0) + { + _wemq_thread_dyed_msg_ack_to_access (pThreadCtx, seq, 0, + ASYNC_MESSAGE_TO_CLIENT_ACK, + pStContext->pReceiveWemqMsg); + LOGRMB (RMB_LOG_DEBUG, "get dyed msg:%s", pWemqHeader->cStrJsonBody); + return serRet; + } + int iMqIndex = req_mq_index; + LOGRMB (RMB_LOG_DEBUG, "WEMQ_CMD_ASYNCEVENT_SUB:Ready to enqueue"); + + if (pRmbStConfig->iFlagForReq == (int) MSG_IPC_MQ) + { + //if (bodyLen >= pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize - C_RMB_MQ_PKG_HEAD_SIZE) + if (pStContext->uiWemqPkgLen >= + pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize - + C_RMB_MQ_PKG_HEAD_SIZE) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] receive reqSize=%u bigger than shmSize=%u,discard", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pStContext->uiWemqPkgLen, + pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "receive reqSize bigger than shmSize", + pStContext->pReceiveWemqMsg); + } + else + { + while ((iRet = + rmb_context_enqueue (pStContext, + (const enum RmbMqIndex) iMqIndex, + pStContext->pWemqPkg, + pStContext->uiWemqPkgLen)) == -2) + { + // LOG + LOGRMB (RMB_LOG_DEBUG, "[Type:%d] [TID:%lu] req queue full!wait!", + pThreadCtx->m_contextType, pThreadCtx->m_threadID); + usleep (1000); + } + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] req wemq_context_enqueue error!enqueue failed=%d!receive=%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRet, + pWemqHeader->cStrJsonBody); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "req wemq_context_enqueue error!enqueue failed", + pStContext->pReceiveWemqMsg); + return 0; + } + else + { + LOGRMB (RMB_LOG_DEBUG, "[Type:%d] [TID:%lu] Enqueue succ, msg %s", + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pWemqHeader->cStrJsonBody); + } + } + } + else + { + iRet = + sendto (pStContext->iSocketForReq, pStContext->pWemqPkg, + pStContext->uiWemqPkgLen, 0, + (const struct sockaddr *) &pStContext->tmpReqAddr, + sizeof (pStContext->tmpReqAddr)); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] sendto failed=%d,message is:%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRet, + pWemqHeader->cStrJsonBody); + } + } + } + } + + else if (strcmp (usCmd, REQUEST_TO_CLIENT) == 0) //sub端收到RR请求消息 + { + if (serRet == 0) + { + StContext *pStContext; + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pStContext = (StContext *) (pContextProxy->pubContext); + } + else + { + pStContext = (StContext *) (pContextProxy->subContext); + } + + if (pStContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStContext is null"); + } + + int iRet = 0; + if ((iRet = + trans_json_2_rmb_msg (pStContext->pReceiveWemqMsg, + pWemqHeader->cStrJsonBody, + REQUEST_TO_CLIENT)) != 0) + { + LOGRMB (RMB_LOG_ERROR, "trans_json_2_rmb_msg failed,buf is:%s", + pWemqHeader->cStrJsonBody); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "trans_json_2_rmb_msg failed", + pStContext->pReceiveWemqMsg); + return -1; + } + + pStContext->pReceiveWemqMsg->iMsgMode = RMB_MSG_FROM_WEMQ; + pStContext->pReceiveWemqMsg->cPkgType = QUEUE_PKG; + + pStContext->uiWemqPkgLen = MAX_LENTH_IN_A_MSG; + + set_extfields_2_rmb_msg (pStContext->pReceiveWemqMsg, REQUEST_TO_CLIENT, + seq); + + iRet = + shift_msg_2_buf (pStContext->pWemqPkg, &pStContext->uiWemqPkgLen, + pStContext->pReceiveWemqMsg); + //LOGRMB(RMB_LOG_DEBUG, "uiWemqPkgLen:%d", pStContext->uiWemqPkgLen); + + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "shift_msg_2_buf error!iRet=%d, %d, %s/%s/%s,unique_id=%s,mode=%d,receive=%s", + iRet, pStContext->pReceiveWemqMsg->iEventOrService, + pStContext->pReceiveWemqMsg->strTargetDcn, + pStContext->pReceiveWemqMsg->strServiceId, + pStContext->pReceiveWemqMsg->strScenarioId, + pStContext->pReceiveWemqMsg->sysHeader.cUniqueId, + pStContext->pReceiveWemqMsg->iMsgMode, + rmb_msg_print (pStContext->pReceiveWemqMsg)); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "shift_msg_2_buf failed", + pStContext->pReceiveWemqMsg); + return -1; + } + + int iMqIndex = req_mq_index; + //染色消息直接返回 + if (check_dyed_msg (pStContext->pReceiveWemqMsg) > 0) + { + LOGRMB (RMB_LOG_DEBUG, "get dyed msg:%s", pWemqHeader->cStrJsonBody); + _wemq_thread_dyed_msg_ack_to_access (pThreadCtx, seq, 0, + REQUEST_TO_CLIENT_ACK, + pStContext->pReceiveWemqMsg); + _wemq_thread_dyed_msg_reply_to_access (pThreadCtx, seq, 0, + RESPONSE_TO_SERVER, + pStContext->pReceiveWemqMsg); + return serRet; + } + LOGRMB (RMB_LOG_DEBUG, "WEMQ_CMD_SYNCREQ:Ready to en queue"); + + if (pRmbStConfig->iFlagForReq == (int) MSG_IPC_MQ) + { + //if (bodyLen >= pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize - C_RMB_MQ_PKG_HEAD_SIZE) + if (pStContext->uiWemqPkgLen >= + pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize - + C_RMB_MQ_PKG_HEAD_SIZE) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] receive reqSize=%u bigger than shmSize=%u,discard", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pStContext->uiWemqPkgLen, + pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "receive reqSize bigger than shmSize", + pStContext->pReceiveWemqMsg); + } + else + { + while ((iRet = + rmb_context_enqueue (pStContext, + (const enum RmbMqIndex) iMqIndex, + pStContext->pWemqPkg, + pStContext->uiWemqPkgLen)) == -2) + { + // LOG + LOGRMB (RMB_LOG_DEBUG, "[Type:%d] [TID:%lu] req queue full!wait!", + pThreadCtx->m_contextType, pThreadCtx->m_threadID); + usleep (1000); + } + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] req wemq_context_enqueue error!enqueue failed=%d!receive=%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRet, + pWemqHeader->cStrJsonBody); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "req wemq_context_enqueue error!enqueue failed", + pStContext->pReceiveWemqMsg); + } + else + { + LOGRMB (RMB_LOG_DEBUG, + "[Type:%d] [TID:%lu] Enqueue succ, msg: header %s body %s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pWemqHeader->cStrJsonHeader, pWemqHeader->cStrJsonBody); + } + } + } + else + { + iRet = + sendto (pStContext->iSocketForReq, pStContext->pWemqPkg, + pStContext->uiWemqPkgLen, 0, + (const struct sockaddr *) &pStContext->tmpReqAddr, + sizeof (pStContext->tmpReqAddr)); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] sendto failed=%d,message is:%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRet, + pWemqHeader->cStrJsonBody); + } + } + } + } + else if (strcmp (usCmd, RESPONSE_TO_CLIENT) == 0) //rr请求端收到的回包 + { + if (serRet == 0) //rsp succ + { + WEMQJSON *jsonByteBody = NULL; + WEMQJSON *systemHeader = NULL; + WEMQJSON *sysExtFields = NULL; + WEMQJSON *jsonDecoder = NULL; + int rrType = 0; + WEMQJSON *jsonBody = json_tokener_parse (pWemqHeader->cStrJsonBody); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_tokener_parse failed!,buf is:%s", + pWemqHeader->cStrJsonBody); + return -1; + } + if (!json_object_object_get_ex + (jsonBody, MSG_BODY_BYTE_BODY_JSON, &jsonByteBody)) + { + LOGRMB (RMB_LOG_ERROR, "body json no byte body!"); + json_object_put (jsonBody); + return -1; + } //byte body json + + jsonByteBody = + json_tokener_parse (json_object_get_string (jsonByteBody)); + if (NULL == jsonByteBody + || !json_object_object_get_ex (jsonByteBody, + MSG_BODY_BYTE_BODY_SYSTEM_HEADER_CONTENT_JSON, + &systemHeader)) + { + LOGRMB (RMB_LOG_ERROR, "byte body json no system header content!"); + json_object_put (jsonBody); + if (NULL != jsonByteBody) + { + json_object_put (jsonByteBody); + } + return -1; + } //system header json + + systemHeader = + json_tokener_parse (json_object_get_string (systemHeader)); + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_EXTFIELDS_STR, &sysExtFields)) + { + sysExtFields = + json_tokener_parse (json_object_get_string (sysExtFields)); + if (json_object_object_get_ex + (sysExtFields, MSG_BODY_SYSTEM_RRTYPE_INT, &jsonDecoder)) + { + rrType = json_object_get_int (jsonDecoder); + } + } //system extFields RRtype + if (0 == rrType) + { + if (bodyLen >= (TCP_BUF_SIZE * sizeof (char))) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] get rsp too long,bodyLen=%d,buf_le=%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, + time, bodyLen, TCP_BUF_SIZE); + } + int i = 0; + int recvFlag = 0; + pthread_mutex_lock (&pContextProxy->rrMutex); + if (pContextProxy->iFlagForRR == -1) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] signal succ! iFlagForRR=0", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, + time); + memcpy (pContextProxy->mPubRRBuf, pWemqHeader->cStrJsonBody, + bodyLen); + pContextProxy->mPubRRBuf[bodyLen] = '\0'; + trans_json_2_rmb_msg (pContextProxy->pReplyMsg, + pContextProxy->mPubRRBuf, RESPONSE_TO_CLIENT); + //LOGRMB(RMB_LOG_DEBUG, "destname :%s", pContextProxy->pReplyMsg->dest.cDestName); + GetRmbNowLongTime (); + pContextProxy->pReplyMsg->sysHeader.ulReplyReceiveTime = + pRmbStConfig->ulNowTtime; + set_extfields_2_rmb_msg (pContextProxy->pReplyMsg, + RESPONSE_TO_CLIENT, seq); + if (pContextProxy->stUnique.flag == 1 + && strcmp (pContextProxy->stUnique.unique_id, + pContextProxy->pReplyMsg->sysHeader.cUniqueId) == 0) + { + if (check_dyed_msg (pContextProxy->pReplyMsg) > 0) + { + LOGRMB (RMB_LOG_DEBUG, "get dyed msg:%s", + pContextProxy->mPubRRBuf); + pContextProxy->iFlagForRR = RMB_CODE_DYED_MSG; + } + else + { + pContextProxy->iFlagForRR = serRet; + } + pContextProxy->stUnique.flag = 0; + pthread_cond_signal (&pContextProxy->rrCond); + recvFlag = 1; + + } + } + pthread_mutex_unlock (&pContextProxy->rrMutex); + if (recvFlag == 1) + { + _wemq_thread_resp_ack_to_access (pThreadCtx, seq, 0, + RESPONSE_TO_CLIENT_ACK, + pContextProxy->pReplyMsg); + //_wemq_thread_send_error_log(pThreadCtx, seq, 0, "ok", pContextProxy->pReplyMsg); + } + } + else //case WEMQ_CMD_ASYNCRSP RR异步消息,服务请求方收到回包 + { + StContext *pStContext = (StContext *) (pContextProxy->subContext); + pContextProxy->iFlagForRRAsync = 0; + if (pStContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "[TID:%lu] pStContext is null", + pThreadCtx->m_threadID); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + if (NULL != systemHeader) + { + json_object_put (systemHeader); + } + if (NULL != sysExtFields) + { + json_object_put (sysExtFields); + } + return -1; + } + + int iRet = 0; + + if ((iRet = + trans_json_2_rmb_msg (pStContext->pReceiveWemqMsgForRR, + pWemqHeader->cStrJsonBody, + RESPONSE_TO_CLIENT)) != 0) + { + LOGRMB (RMB_LOG_ERROR, "trans_json_2_rmb_msg failed,buf is:%s", + pWemqHeader->cStrJsonBody); + _wemq_thread_resp_ack_to_access (pThreadCtx, seq, -1, + RESPONSE_TO_CLIENT_ACK, + pStContext->pReceiveWemqMsgForRR); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "trans_json_2_rmb_msg failed", + pStContext->pReceiveWemqMsgForRR); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + if (NULL != systemHeader) + { + json_object_put (systemHeader); + } + if (NULL != sysExtFields) + { + json_object_put (sysExtFields); + } + return -1; + } + GetRmbNowLongTime (); + pStContext->pReceiveWemqMsgForRR->sysHeader.ulReplyReceiveTime = + pRmbStConfig->ulNowTtime; + int i; + set_extfields_2_rmb_msg (pStContext->pReceiveWemqMsgForRR, + RESPONSE_TO_CLIENT, seq); + int recvFlag = 0; + pthread_mutex_lock (&pContextProxy->rrMutex); + //因为在access goodbye的时候,消息可能在旧连接上,所以必须同时扫描新旧连接,不能只扫描新连接 + + //if(isRecvNewConnect) + //{ + for (i = 0; + i < + pContextProxy->pUniqueListForRRAsyncNew. + get_array_size (&pContextProxy->pUniqueListForRRAsyncNew); i++) + { + if (pContextProxy->pUniqueListForRRAsyncNew.Data[i].flag == 1 + && strcmp (pContextProxy->pUniqueListForRRAsyncNew.Data[i]. + unique_id, + pStContext->pReceiveWemqMsgForRR->sysHeader. + cUniqueId) == 0) + { + pContextProxy->pUniqueListForRRAsyncNew.Data[i].flag = 0; + recvFlag = 1; + break; + } + } + // }else + // { + for (i = 0; + i < + pContextProxy->pUniqueListForRRAsyncOld. + get_array_size (&pContextProxy->pUniqueListForRRAsyncOld); i++) + { + if (pContextProxy->pUniqueListForRRAsyncOld.Data[i].flag == 1 + && strcmp (pContextProxy->pUniqueListForRRAsyncOld.Data[i]. + unique_id, + pStContext->pReceiveWemqMsgForRR->sysHeader. + cUniqueId) == 0) + { + pContextProxy->pUniqueListForRRAsyncOld.Data[i].flag = 0; + recvFlag = 1; + break; + } + } + pthread_mutex_unlock (&pContextProxy->rrMutex); + //} + //已经超时,不回包给pub端 + if (recvFlag == 0) + { + LOGRMB (RMB_LOG_WARN, + "rr async response bizseq=%s, uniqueId=%s comes back, but request has timeout", + pStContext->pReceiveWemqMsgForRR->sysHeader.cBizSeqNo, + pStContext->pReceiveWemqMsgForRR->sysHeader.cUniqueId); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + if (NULL != systemHeader) + { + json_object_put (systemHeader); + } + if (NULL != sysExtFields) + { + json_object_put (sysExtFields); + } + return -1; + } + + pStContext->pReceiveWemqMsgForRR->cPkgType = RR_TOPIC_PKG; + pStContext->pReceiveWemqMsgForRR->iMsgMode = RMB_MSG_FROM_WEMQ; + pStContext->uiWemqPkgForRRAsyncLen = MAX_LENTH_IN_A_MSG; + iRet = + shift_msg_2_buf (pStContext->pWemqPkgForRRAsync, + &pStContext->uiWemqPkgForRRAsyncLen, + pStContext->pReceiveWemqMsgForRR); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "shift_msg_2_buf error!iRet=%d, %d, %s/%s/%s,unique_id=%s,mode=%d,receive=%s", + iRet, pStContext->pReceiveWemqMsgForRR->iEventOrService, + pStContext->pReceiveWemqMsgForRR->strTargetDcn, + pStContext->pReceiveWemqMsgForRR->strServiceId, + pStContext->pReceiveWemqMsgForRR->strScenarioId, + pStContext->pReceiveWemqMsgForRR->sysHeader.cUniqueId, + pStContext->pReceiveWemqMsgForRR->iMsgMode, + rmb_msg_print (pStContext->pReceiveWemqMsgForRR)); + _wemq_thread_resp_ack_to_access (pThreadCtx, seq, -1, + RESPONSE_TO_CLIENT_ACK, + pStContext->pReceiveWemqMsgForRR); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "shift_msg_2_buf error", + pStContext->pReceiveWemqMsgForRR); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + if (NULL != systemHeader) + { + json_object_put (systemHeader); + } + if (NULL != sysExtFields) + { + json_object_put (sysExtFields); + } + return -1; + } + if (check_dyed_msg (pStContext->pReceiveWemqMsgForRR) > 0) + { + LOGRMB (RMB_LOG_DEBUG, "get dyed msg:%s", + pWemqHeader->cStrJsonBody); + _wemq_thread_resp_ack_to_access (pThreadCtx, seq, 0, + RESPONSE_TO_CLIENT_ACK, + pStContext->pReceiveWemqMsgForRR); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + if (NULL != systemHeader) + { + json_object_put (systemHeader); + } + if (NULL != sysExtFields) + { + json_object_put (sysExtFields); + } + return serRet; + } + + int iMqIndex = rr_rsp_mq_index; + LOGRMB (RMB_LOG_DEBUG, + "WEMQ_CMD_ASYNCRSP:Recv rr rsp Ready to en queue"); + if (pRmbStConfig->iFlagForRRrsp == (int) MSG_IPC_MQ) + { + if (pStContext->uiWemqPkgForRRAsyncLen >= + pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize - + C_RMB_MQ_PKG_HEAD_SIZE) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] receive reqSize=%u bigger than shmSize=%u,discard", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pStContext->uiWemqPkgForRRAsyncLen, + pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize); + _wemq_thread_resp_ack_to_access (pThreadCtx, seq, -1, + RESPONSE_TO_CLIENT_ACK, + pStContext-> + pReceiveWemqMsgForRR); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "receive msg bigger than shmSize", + pStContext->pReceiveWemqMsgForRR); + } + else + { + while ((iRet = + rmb_context_enqueue (pStContext, + (const enum RmbMqIndex) iMqIndex, + pStContext->pWemqPkgForRRAsync, + pStContext-> + uiWemqPkgForRRAsyncLen)) == -2) + { + // LOG + LOGRMB (RMB_LOG_DEBUG, + "[Type:%d] [TID:%lu] req queue full!wait!", + pThreadCtx->m_contextType, pThreadCtx->m_threadID); + usleep (1000); + } + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] req wemq_context_enqueue error!enqueue failed=%d!receive=%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRet, + pWemqHeader->cStrJsonBody); + _wemq_thread_resp_ack_to_access (pThreadCtx, seq, -1, + RESPONSE_TO_CLIENT_ACK, + pStContext-> + pReceiveWemqMsgForRR); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, + LOG_ERROR_POINT, + "req wemq_context_enqueue error", + pStContext->pReceiveWemqMsgForRR); + } + else + { + LOGRMB (RMB_LOG_DEBUG, + "[Type:%d] [TID:%lu] Enqueue succ, msg: header %s body %s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pWemqHeader->cStrJsonHeader, pWemqHeader->cStrJsonBody); + _wemq_thread_resp_ack_to_access (pThreadCtx, seq, 0, + RESPONSE_TO_CLIENT_ACK, + pStContext-> + pReceiveWemqMsgForRR); + } + } + } + else + { + iRet = + sendto (pStContext->iSocketForRsp, pStContext->pWemqPkgForRRAsync, + pStContext->uiWemqPkgForRRAsyncLen, 0, + (const struct sockaddr *) &pStContext->tmpReplyAddr, + sizeof (pStContext->tmpReplyAddr)); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] sendto failed=%d,message is:%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRet, + pWemqHeader->cStrJsonBody); + } + } + } + json_object_put (jsonByteBody); + json_object_put (jsonBody); + if (NULL != systemHeader) + { + json_object_put (systemHeader); + } + if (NULL != sysExtFields) + { + json_object_put (sysExtFields); + } + } + else if (serRet == RMB_CODE_AUT_FAIL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] rr request ret Authentication fail", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + + pthread_mutex_lock (&pContextProxy->rrMutex); + pContextProxy->iFlagForRR = serRet; + pContextProxy->stUnique.flag = 0; + pthread_cond_signal (&pContextProxy->rrCond); + pthread_mutex_unlock (&pContextProxy->rrMutex); + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] rr request ret fail", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + + pthread_mutex_lock (&pContextProxy->rrMutex); + pContextProxy->iFlagForRR = serRet; + pContextProxy->stUnique.flag = 0; + pthread_cond_signal (&pContextProxy->rrCond); + pthread_mutex_unlock (&pContextProxy->rrMutex); + } + } + else if (strcmp (usCmd, BROADCAST_MESSAGE_TO_SERVER_ACK) == 0) //收到广播消息的ack + { + if (serRet == RMB_CODE_SUSS) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] Publish Broadcast Message request success", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + + } + else if (serRet == RMB_CODE_AUT_FAIL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] Publish Broadcast Message request Authentication fail!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] Publish Broadcast Message request failed!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + + } + + pthread_mutex_lock (&pContextProxy->eventMutex); + if (pContextProxy->iFlagForEvent == -1) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] send Broadcast msg signal succ! iFlagForEvent=%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time, + serRet); + LOGRMB (RMB_LOG_DEBUG, "seq for Broadcast: %d", + pContextProxy->iSeqForEvent); + if (seq == pContextProxy->iSeqForEvent) + { + pContextProxy->iFlagForEvent = serRet; + pthread_cond_signal (&pContextProxy->eventCond); + } + } + pthread_mutex_unlock (&pContextProxy->eventMutex); + } + + else if (strcmp (usCmd, BROADCAST_MESSAGE_TO_CLIENT) == 0) //收到广播消息 + { + if (serRet == 0) + { + StContext *pStContext = NULL; + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pStContext = (StContext *) (pContextProxy->pubContext); + } + else + { + pStContext = (StContext *) (pContextProxy->subContext); + } + + if (pStContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "[TID:%lu] pStContext is null", + pThreadCtx->m_threadID); + return -1; + } + + int iRet = 0; + + if ((iRet = + trans_json_2_rmb_msg (pStContext->pReceiveWemqMsgForBroadCast, + pWemqHeader->cStrJsonBody, + BROADCAST_MESSAGE_TO_CLIENT)) != 0) + { + LOGRMB (RMB_LOG_ERROR, "trans_json_2_rmb_msg failed,buf is:%s", + pWemqHeader->cStrJsonBody); + return -1; + } + + pStContext->pReceiveWemqMsgForBroadCast->cPkgType = BROADCAST_TOPIC_PKG; + pStContext->pReceiveWemqMsgForBroadCast->iMsgMode = RMB_MSG_FROM_WEMQ; + pStContext->uiWemqPkgLen = MAX_LENTH_IN_A_MSG; + + set_extfields_2_rmb_msg (pStContext->pReceiveWemqMsgForBroadCast, + BROADCAST_MESSAGE_TO_CLIENT, seq); + + iRet = + shift_msg_2_buf (pStContext->pWemqPkg, &pStContext->uiWemqPkgLen, + pStContext->pReceiveWemqMsgForBroadCast); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "shift_msg_2_buf error!iRet=%d, %d, %s/%s/%s,unique_id=%s,mode=%d,receive=%s", + iRet, + pStContext->pReceiveWemqMsgForBroadCast->iEventOrService, + pStContext->pReceiveWemqMsgForBroadCast->strTargetDcn, + pStContext->pReceiveWemqMsgForBroadCast->strServiceId, + pStContext->pReceiveWemqMsgForBroadCast->strScenarioId, + pStContext->pReceiveWemqMsgForBroadCast->sysHeader.cUniqueId, + pStContext->pReceiveWemqMsgForBroadCast->iMsgMode, + rmb_msg_print (pStContext->pReceiveWemqMsgForBroadCast)); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "shift_msg_2_buf error", + pStContext->pReceiveWemqMsgForBroadCast); + + return -1; + } + //染色消息直接返回 + if (check_dyed_msg (pStContext->pReceiveWemqMsgForBroadCast) > 0) + { + _wemq_thread_dyed_msg_ack_to_access (pThreadCtx, seq, 0, + BROADCAST_MESSAGE_TO_CLIENT_ACK, + pStContext->pReceiveWemqMsg); + LOGRMB (RMB_LOG_DEBUG, "get dyed msg:%s", pWemqHeader->cStrJsonBody); + return serRet; + } + + int iMqIndex = broadcast_mq_index; + LOGRMB (RMB_LOG_DEBUG, + "WEMQ_CMD_BROADCAST_SUB:Recv broadcast message ready to enqueue"); + if (pRmbStConfig->iFlagForBroadCast == (int) MSG_IPC_MQ) + { + if (pStContext->uiWemqPkgLen >= + pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize - + C_RMB_MQ_PKG_HEAD_SIZE) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] receive broadcast message reqSize=%u bigger than shmSize=%u,discard", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pStContext->uiWemqPkgLen, + pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "receive broadcast message reqSize bigger than shmSize", + pStContext-> + pReceiveWemqMsgForBroadCast); + } + else + { + while ((iRet = + rmb_context_enqueue (pStContext, + (const enum RmbMqIndex) iMqIndex, + pStContext->pWemqPkg, + pStContext->uiWemqPkgLen)) == -2) + { + //queue full + LOGRMB (RMB_LOG_ERROR, "[Type:%d] [TID:%lu] req queue full!wait!", + pThreadCtx->m_contextType, pThreadCtx->m_threadID); + usleep (1000); + } + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] req rmb_context_enqueue error!iRet=%d!receive=%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRet, + pWemqHeader->cStrJsonBody); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "req rmb_context_enqueue error", + pStContext-> + pReceiveWemqMsgForBroadCast); + } + else + { + LOGRMB (RMB_LOG_DEBUG, + "[Type:%d] [TID:%lu] enqueue succ, msg: header %s body %s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pWemqHeader->cStrJsonHeader, pWemqHeader->cStrJsonBody); + } + } + } + else + { + iRet = + sendto (pStContext->iSocketForBroadcast, pStContext->pWemqPkg, + pStContext->uiWemqPkgLen, 0, + (const struct sockaddr *) &pStContext->tmpBroadcastAddr, + sizeof (pStContext->tmpBroadcastAddr)); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] udp error!sendto failed=%d!receive message:%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRet, + pWemqHeader->cStrJsonBody); + } + } + } + } + else if (strcmp (usCmd, SUBSCRIBE_RESPONSE) == 0) // add subscribe response + { + if (serRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] add listen return failed, iRet=%d, errmsg=%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, serRet, cMsg); + } + + pthread_mutex_lock (&pContextProxy->regMutex); + if (pContextProxy->iFlagForReg == 0) + { + pContextProxy->iFlagForReg = 1; + pContextProxy->iResultForReg = serRet; + pthread_cond_signal (&pContextProxy->regCond); + } + pthread_mutex_unlock (&pContextProxy->regMutex); + } + else if (strcmp (usCmd, LISTEN_RESPONSE) == 0) // add listen start response + { + + if (serRet == RMB_CODE_OTHER_FAIL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] send start to access failed,iRet=%d, errmsg=%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, serRet, cMsg); + } + + if (serRet == RMB_CODE_AUT_FAIL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] send start to access authentication failed,iRet=%d, errmsg=%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, serRet, cMsg); + } + + pthread_mutex_lock (&pContextProxy->regMutex); + if (pContextProxy->iFlagForReg == 0) + { + pContextProxy->iFlagForReg = 1; + pContextProxy->iResultForReg = serRet; + pthread_cond_signal (&pContextProxy->regCond); + } + pthread_mutex_unlock (&pContextProxy->regMutex); + + } + + else + { + LOGRMB (RMB_LOG_ERROR, "[%s] [Type:%d] [TID:%lu] No Such Command:%s!", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, usCmd); + ret = -1; + } + + json_object_put (jsonHeader); + + return ret; +} + +static int32_t _wemq_thread_do_recv_sync (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + int timeout = pRmbStConfig->iWemqTcpSocketTimeout; + + unsigned int uiTimeOutTimes = 0; + unsigned int uiClosedByPeerTimes = 0; + while (1) + { + uint32_t iRecvLen; + int iRet = + wemq_tcp_recv (pThreadCtx->m_iSockFd, pThreadCtx->m_pRecvBuff, + &iRecvLen, timeout, pThreadCtx->ssl); + if (iRet == 0) + { + uiTimeOutTimes += 1; + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] TCP recv timeout!timeout_times=%u, fd=%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + uiTimeOutTimes, pThreadCtx->m_iSockFd); + if (uiTimeOutTimes >= 12) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] TCP continuity recv timeout times=%d, so close connect", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + uiTimeOutTimes); + uiTimeOutTimes = 0; + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + wemq_proxy_to_black_list (pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + return -2; + } + continue; + } + else if (iRet == -2) + { + uiClosedByPeerTimes += 1; + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] TCP conncet closed by peer(%d)", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, errno); + if (uiClosedByPeerTimes >= 3) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] TCP conncet continuity closed by peer times=%d, so close connect", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + uiClosedByPeerTimes); + uiClosedByPeerTimes = 0; + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + wemq_proxy_to_black_list (pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + return -2; + } + continue; + } + else if (iRet == -3) + { + // msg is not full + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] msg is not full", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + + return 1; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] wemq_tcp_recv error", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + return -1; + } + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] recv complete len %d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, iRet); + + //memset(&pThreadCtx->m_stWeMQMSG, 0, sizeof(pThreadCtx->m_stWeMQMSG)); + memset (&pThreadCtx->m_stWeMQMSG, 0, (sizeof (int) * 2)); + DecodeWeMQMsg (&pThreadCtx->m_stWeMQMSG, pThreadCtx->m_pRecvBuff, iRet); + if (pThreadCtx->m_stWeMQMSG.uiHeaderLen == 0 + || pThreadCtx->m_stWeMQMSG.uiHeaderLen >= MAX_WEMQ_HEADER_LEN) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] recv header len %u is 0 or too long", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + pThreadCtx->m_stWeMQMSG.uiHeaderLen); + return -1; + } + if (pThreadCtx->m_stWeMQMSG.uiHeaderLen > 0) + { + memcpy (pThreadCtx->m_stWeMQMSG.cStrJsonHeader, + pThreadCtx->m_pRecvBuff + 8, + pThreadCtx->m_stWeMQMSG.uiHeaderLen); + pThreadCtx->m_stWeMQMSG.cStrJsonHeader[pThreadCtx->m_stWeMQMSG. + uiHeaderLen] = '\0'; + } + unsigned int uiTmpBodyLen = + pThreadCtx->m_stWeMQMSG.uiTotalLen - + pThreadCtx->m_stWeMQMSG.uiHeaderLen - 8; + if (uiTmpBodyLen >= MAX_WEMQ_BODY_LEN) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] recv body len %d is too long", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + uiTmpBodyLen); + return -1; + } + if (uiTmpBodyLen == 0) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] recv body len is 0", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + } + //if (pThreadCtx->m_stWeMQMSG.uiTotalLen - pThreadCtx->m_stWeMQMSG.uiHeaderLen - 8 > 0) + if (uiTmpBodyLen > 0) + { + memcpy (pThreadCtx->m_stWeMQMSG.cStrJsonBody, + pThreadCtx->m_pRecvBuff + 8 + + pThreadCtx->m_stWeMQMSG.uiHeaderLen, + pThreadCtx->m_stWeMQMSG.uiTotalLen - + pThreadCtx->m_stWeMQMSG.uiHeaderLen - 8); + pThreadCtx->m_stWeMQMSG.cStrJsonBody[uiTmpBodyLen] = '\0'; + } + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Decode Wemq Header complete,total len %d, header len %d,header %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_stWeMQMSG.uiTotalLen, + pThreadCtx->m_stWeMQMSG.uiHeaderLen, + pThreadCtx->m_stWeMQMSG.cStrJsonHeader); + return 0; + } + return -1; +} + +static int32_t _wemq_thread_do_recv_async (WemqThreadCtx * pThreadCtx, + bool isRecvNewConnect) +{ + ASSERT (pThreadCtx); + + int nfds = + epoll_wait (pThreadCtx->m_iEpollFd, pThreadCtx->m_ptEvents, MAX_EVENTS, + 1); + if (nfds == -1) + { + LOGRMB (RMB_LOG_ERROR, "[%s] [Type:%d] [TID:%lu] epoll wait error:%d!", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, errno); + return -1; + } + if (nfds == 0) + { + return 0; + } + + unsigned long ulLastTime = 0; + unsigned long ulNowTime = 0; + struct timeval tv; + + int iTmp = 0; + int iRecvd = 0; + int iRemind = TCP_PKG_LEN_BTYES; + + for (iTmp = 0; iTmp < nfds; ++iTmp) + { + // 必须在此判断,如果新旧连接都有消息过来,后面会把当前fd改成新连接的fd,导致下次循环又会重新处理 + if (!isRecvNewConnect) + { + pThreadCtx->m_iSockFdNew = pThreadCtx->m_iSockFd; + pThreadCtx->sslNew = pThreadCtx->ssl; + pThreadCtx->m_iSockFd = pThreadCtx->m_iSockFdOld; + pThreadCtx->ssl = pThreadCtx->sslOld; + } + + if (pThreadCtx->m_ptEvents[iTmp].data.fd == pThreadCtx->m_iSockFd) + { + if (EPOLLIN == (pThreadCtx->m_ptEvents[iTmp].events & EPOLLIN)) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] EPOLLIN EVENT", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + gettimeofday (&tv, NULL); + ulLastTime = tv.tv_sec * 1000000 + tv.tv_usec; + ulNowTime = ulLastTime; + while (iRemind > 0) + { + int iRecv; + if (NULL != pThreadCtx->ssl) + { + iRecv = + SSL_read (pThreadCtx->ssl, pThreadCtx->m_pRecvBuff + iRecvd, + iRemind); + } + else + { + iRecv = + recv (pThreadCtx->m_iSockFd, pThreadCtx->m_pRecvBuff + iRecvd, + iRemind, 0); + } + //if (iRecv < 0 && (errno != EAGAIN)) + if (iRecv < 0) + { + if (errno == EAGAIN) + { + gettimeofday (&tv, NULL); + ulNowTime = tv.tv_sec * 1000000 + tv.tv_usec; + if ((ulNowTime - ulLastTime) > (1 * 60 * 1000000)) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv return < 0, errno %d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, errno); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + + usleep (100); + continue; + } + + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv return < 0, errno %d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, errno); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Peer close connect, fd close() ret=%d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, iRecv); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + if (iRecv > 0) + { + iRecvd += iRecv; + iRemind -= iRecv; + } + } + + if (iRecvd != 4 || strcmp (pThreadCtx->m_pRecvBuff, "WEMQ") != 0) + { + if (!isRecvNewConnect) + { + LOGRMB (RMB_LOG_ERROR, "IP: [old proxy ip:%s|old port:%d]", + pThreadCtx->m_cProxyIPOld, pThreadCtx->m_uiProxyPortOld); + } + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%d] recv header error, buf: %s, len: %d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + pThreadCtx->m_pRecvBuff, iRecvd); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + + gettimeofday (&tv, NULL); + ulLastTime = tv.tv_sec * 1000000 + tv.tv_usec; + ulNowTime = ulLastTime; + iRecvd = 0; + iRemind = TCP_PKG_LEN_BTYES; + while (iRemind > 0) + { + int iRecv; + if (NULL != pThreadCtx->ssl) + { + iRecv = + SSL_read (pThreadCtx->ssl, pThreadCtx->m_pRecvBuff + iRecvd, + iRemind); + } + else + { + iRecv = + recv (pThreadCtx->m_iSockFd, pThreadCtx->m_pRecvBuff + iRecvd, + iRemind, 0); + } + //if (iRecv < 0 && (errno != EAGAIN)) + if (iRecv < 0) + { + if (errno == EAGAIN) + { + gettimeofday (&tv, NULL); + ulNowTime = tv.tv_sec * 1000000 + tv.tv_usec; + if ((ulNowTime - ulLastTime) > (1 * 60 * 1000000)) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv return < 0, errno %d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, errno); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + + usleep (100); + continue; + } + + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv return < 0, errno %d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, errno); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Peer close connect, fd close() ret=%d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, iRecv); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + if (iRecv > 0) + { + iRecvd += iRecv; + iRemind -= iRecv; + } + } + + if (iRecvd != 4) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%d] recv version error, version=%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + pThreadCtx->m_pRecvBuff); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + + gettimeofday (&tv, NULL); + ulLastTime = tv.tv_sec * 1000000 + tv.tv_usec; + ulNowTime = ulLastTime; + + iRecvd = 0; + iRemind = TCP_PKG_LEN_BTYES; + while (iRemind > 0) + { + int iRecv; + if (NULL != pThreadCtx->ssl) + { + iRecv = + SSL_read (pThreadCtx->ssl, pThreadCtx->m_pRecvBuff + iRecvd, + iRemind); + } + else + { + iRecv = + recv (pThreadCtx->m_iSockFd, pThreadCtx->m_pRecvBuff + iRecvd, + iRemind, 0); + } + //if (iRecv < 0 && (errno != EAGAIN)) + if (iRecv < 0) + { + if (errno == EAGAIN) + { + gettimeofday (&tv, NULL); + ulNowTime = tv.tv_sec * 1000000 + tv.tv_usec; + if ((ulNowTime - ulLastTime) > (1 * 60 * 1000000)) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv return < 0, errno %d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, errno); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + + usleep (100); + continue; + } + + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv return < 0, errno %d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, errno); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Peer close connect, fd close() ret=%d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, iRecv); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + if (iRecv > 0) + { + iRecvd += iRecv; + iRemind -= iRecv; + } + } + //ASSERT (iRemind == 0); + if (iRemind != 0 || iRecvd != TCP_PKG_LEN_BTYES) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] get msg length failed", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + + gettimeofday (&tv, NULL); + ulLastTime = tv.tv_sec * 1000000 + tv.tv_usec; + ulNowTime = ulLastTime; + + iRemind = ntohl (*(uint32_t *) pThreadCtx->m_pRecvBuff); + iRemind -= TCP_PKG_LEN_BTYES; + while (iRemind > 0) + { + int iRecv; + if (NULL != pThreadCtx->ssl) + { + iRecv = + SSL_read (pThreadCtx->ssl, pThreadCtx->m_pRecvBuff + iRecvd, + iRemind); + } + else + { + iRecv = + recv (pThreadCtx->m_iSockFd, pThreadCtx->m_pRecvBuff + iRecvd, + iRemind, 0); + } + //if (iRecv < 0 && (errno != EAGAIN)) + if (iRecv < 0) + { + if (errno == EAGAIN) + { + gettimeofday (&tv, NULL); + ulNowTime = tv.tv_sec * 1000000 + tv.tv_usec; + if ((ulNowTime - ulLastTime) > (1 * 60 * 1000000)) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv return < 0, errno %d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, errno); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + + usleep (100); + continue; + } + + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv return < 0, errno %d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, errno); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Peer close connect, fd close() ret=%d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, iRecv); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + if (iRecv > 0) + { + iRecvd += iRecv; + iRemind -= iRecv; + } + } + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv complete len %d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, iRecvd); + if (!isRecvNewConnect) + { + pThreadCtx->m_iSockFd = pThreadCtx->m_iSockFdNew; + pThreadCtx->ssl = pThreadCtx->sslNew; + } + //memset(&pThreadCtx->m_stWeMQMSG, 0, sizeof(pThreadCtx->m_stWeMQMSG)); + memset (&pThreadCtx->m_stWeMQMSG, 0, (sizeof (int) * 2)); + int iRet = + DecodeWeMQMsg (&pThreadCtx->m_stWeMQMSG, pThreadCtx->m_pRecvBuff, + iRecvd); + + if (pThreadCtx->m_stWeMQMSG.uiHeaderLen == 0 + || pThreadCtx->m_stWeMQMSG.uiHeaderLen >= MAX_WEMQ_HEADER_LEN) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Decode Wemq Header complete, header len %d is 0 or too long", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_stWeMQMSG.uiHeaderLen); + return -1; + } + if (pThreadCtx->m_stWeMQMSG.uiHeaderLen > 0) + { + memcpy (pThreadCtx->m_stWeMQMSG.cStrJsonHeader, + pThreadCtx->m_pRecvBuff + 8, + pThreadCtx->m_stWeMQMSG.uiHeaderLen); + pThreadCtx->m_stWeMQMSG.cStrJsonHeader[pThreadCtx->m_stWeMQMSG. + uiHeaderLen] = '\0'; + } + LOGRMB (RMB_LOG_DEBUG, "cStrJsonHeader: %s", + pThreadCtx->m_stWeMQMSG.cStrJsonHeader); + unsigned int uiTmpBodyLen = + pThreadCtx->m_stWeMQMSG.uiTotalLen - + pThreadCtx->m_stWeMQMSG.uiHeaderLen - 8; + if (uiTmpBodyLen >= MAX_WEMQ_BODY_LEN) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Decode Wemq complete,body len %d is too long", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + uiTmpBodyLen); + return -1; + } + if (uiTmpBodyLen == 0) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Decode Wemq complete,body len is 0", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + } + //if (pThreadCtx->m_stWeMQMSG.uiTotalLen - pThreadCtx->m_stWeMQMSG.uiHeaderLen - 8 > 0) + if (uiTmpBodyLen > 0) + { + //set message source + pThreadCtx->m_stWeMQMSG.cStrJsonBody[0] = RMB_MSG_FROM_WEMQ; + memcpy (pThreadCtx->m_stWeMQMSG.cStrJsonBody, + pThreadCtx->m_pRecvBuff + 8 + + pThreadCtx->m_stWeMQMSG.uiHeaderLen, + pThreadCtx->m_stWeMQMSG.uiTotalLen - + pThreadCtx->m_stWeMQMSG.uiHeaderLen - 8); + pThreadCtx->m_stWeMQMSG.cStrJsonBody[uiTmpBodyLen] = '\0'; + } + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Decode Wemq Header complete,total len %d, header len %d,header %s, body %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_stWeMQMSG.uiTotalLen, + pThreadCtx->m_stWeMQMSG.uiHeaderLen, + pThreadCtx->m_stWeMQMSG.cStrJsonHeader, + pThreadCtx->m_stWeMQMSG.cStrJsonBody); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Decode Wemq Header ERROR", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -1; + } + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] epoll events %d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_ptEvents[iTmp].events); + } + + } + if (!isRecvNewConnect) + { + pThreadCtx->m_iSockFd = pThreadCtx->m_iSockFdNew; + pThreadCtx->ssl = pThreadCtx->sslNew; + } + } + return iRecvd; +} + +static int32_t _wemq_thread_do_send_sync (WemqThreadCtx * pThreadCtx, + void *msg, uint32_t totalLen, + uint32_t headerLen) +{ + int iRetry = 2; + int timeout = pRmbStConfig->iWemqTcpSocketTimeout; + + while (iRetry > 0) + { + int iRet = + wemq_tcp_send (pThreadCtx->m_iSockFd, msg, totalLen, headerLen, timeout, + pThreadCtx->ssl); + + if (iRet == 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Retry: %d] TCP send timeout!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, iRetry); + iRetry--; + continue; + } + else if (iRet == -2) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] TCP send error(%d)!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, errno); + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + return -1; + } + else if (iRet > 0) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] send complete len %d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, iRet); + return 0; + } + return -2; + } + + // 重试2次失败 + return -3; +} + +static int32_t _wemq_thread_do_cmd_add_listen_msg (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_ADD_LISTEN); + + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pBody, + pStWemqThreadMsg->m_iBodyLen); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send header:%s, body:%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pStWemqThreadMsg->m_pHeader, pStWemqThreadMsg->m_pBody); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] _wemq_thread_do_send_sync error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + return -2; + } + + return 0; +} + +static int32_t _wemq_thread_do_cmd_start_msg (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_START); + + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send:%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pStWemqThreadMsg->m_pHeader); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] _wemq_thread_do_send_sync error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + return -2; + } + + return 0; +} + +static int32_t _wemq_thread_do_cmd_client_goodbye_msg (WemqThreadCtx * + pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_SEND_CLIENT_GOODBYE); + + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send Client GoodBye:%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pStWemqThreadMsg->m_pHeader); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] _wemq_thread_do_send_sync client goodbye error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + return -2; + } + + return 0; +} + +static int32_t _wemq_thread_do_cmd_send_msg (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_SEND_MSG); + + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + if (NULL != pStWemqThreadMsg->m_pBody) + { + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pBody, + pStWemqThreadMsg->m_iBodyLen); + } + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send header:%s body:%s\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pStWemqThreadMsg->m_pHeader, pStWemqThreadMsg->m_pBody); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_do_send_sync error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + + return 0; +} + +static int32_t _wemq_thread_do_cmd_send_log (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_SEND_LOG); + + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + if (NULL != pStWemqThreadMsg->m_pBody) + { + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pBody, + pStWemqThreadMsg->m_iBodyLen); + } + + LOGRMB (RMB_LOG_DEBUG, "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Send:%s\n", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, pStWemqThreadMsg->m_pHeader); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_do_send_sync error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + + return 0; +} + +static int32_t _wemq_thread_do_cmd_send_async_request (WemqThreadCtx * + pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_SEND_REQUEST_ASYNC); + + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pBody, + pStWemqThreadMsg->m_iBodyLen); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send header:%s body:%s\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pStWemqThreadMsg->m_pHeader, pStWemqThreadMsg->m_pBody); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_do_send_sync error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + return 0; +} + +static int32_t _wemq_thread_do_cmd_send_request (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_SEND_REQUEST); + + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pBody, + pStWemqThreadMsg->m_iBodyLen); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send header:%s body:%s\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pStWemqThreadMsg->m_pHeader, pStWemqThreadMsg->m_pBody); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_do_send_sync error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + + return 0; +} + +static int32_t _wemq_thread_do_cmd_send_reply (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_SEND_REPLY); + + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pBody, + pStWemqThreadMsg->m_iBodyLen); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send header:%s body:%s\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pStWemqThreadMsg->m_pHeader, pStWemqThreadMsg->m_pBody); + + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_do_send_sync error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + return 0; +} + +static int32_t _wemq_thread_do_cmd_send_msg_ack (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_SEND_MSG_ACK); + int iRet = 0; + StRmbMsg *pSendMsg = rmb_msg_malloc (); + if ((iRet = + trans_json_2_rmb_msg (pSendMsg, pStWemqThreadMsg->m_pBody, + REQUEST_TO_CLIENT)) != 0) + { + LOGRMB (RMB_LOG_ERROR, "trans_json_2_rmb_msg failed,buf is:%s", + pStWemqThreadMsg->m_pBody); + return -1; + } + pSendMsg->iMsgMode = RMB_MSG_FROM_WEMQ; + pSendMsg->cPkgType = QUEUE_PKG; + + WEMQJSON *jsonDecoder = NULL; + WEMQJSON *sysExtFields = NULL; + int ack_seq = 0; + sysExtFields = json_tokener_parse (pSendMsg->sysHeader.cExtFields); + + if (json_object_object_get_ex + (sysExtFields, MSG_BODY_SYSTEM_ACK_SEQ, &jsonDecoder)) + { + ack_seq = json_object_get_int (jsonDecoder); + } + else + { + LOGRMB (RMB_LOG_ERROR, "get ack_seq failed!"); + return -1; + } + + switch (*(pSendMsg->strServiceId + 3)) + { + case '0': + iRet = + _wemq_thread_resp_ack_to_access (pThreadCtx, ack_seq, 0, + REQUEST_TO_CLIENT_ACK, pSendMsg); + break; + case '1': + iRet = + _wemq_thread_resp_ack_to_access (pThreadCtx, ack_seq, 0, + ASYNC_MESSAGE_TO_CLIENT_ACK, pSendMsg); + break; + case '3': + iRet = + _wemq_thread_resp_ack_to_access (pThreadCtx, ack_seq, 0, + BROADCAST_MESSAGE_TO_CLIENT_ACK, + pSendMsg); + break; + case '4': + iRet = + _wemq_thread_resp_ack_to_access (pThreadCtx, ack_seq, 0, + BROADCAST_MESSAGE_TO_CLIENT_ACK, + pSendMsg); + break; + default: + ; + } + + json_object_put (sysExtFields); + rmb_msg_free (pSendMsg); + + return iRet; +} + +static int32_t _wemq_thread_do_cmd_send_msg_reg (WemqThreadCtx * pThreadCtx) +{ + StWemqThreadMsg *pStWemqThreadMsg = &pThreadCtx->m_stHelloWord; + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pBody, + pStWemqThreadMsg->m_iBodyLen); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss| Send header:%s, body:%s, totalLen:%d, headerLen:%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pStWemqThreadMsg->m_pHeader, pStWemqThreadMsg->m_pBody, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_do_send_sync error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + //return _wemq_thread_state_trans(pThreadCtx, pThreadCtx->m_iState, THREAD_STATE_BREAK); + return -1; + } + + iRet = _wemq_thread_do_recv_sync (pThreadCtx); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_do_recv_sync error: %d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, iRet); + return -2; + } + + StWeMQMSG *pWemqHeader = &pThreadCtx->m_stWeMQMSG; + WEMQJSON *jsonHeader = NULL; + WEMQJSON *jsonTmp = NULL; + int usCmd = -1; + int serRet = -1; + int seq = -1; + long time = 0; + char cMessage[100]; + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] |access2wemq_thread|Recv: %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + pWemqHeader->cStrJsonHeader); + jsonHeader = json_tokener_parse (pWemqHeader->cStrJsonHeader); + if (jsonHeader == NULL) + { + // 消息不完整, json解析失败 + LOGRMB (RMB_LOG_ERROR, "[Type:%d] [TID:%lu] json_tokener_parse error: %s", + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pWemqHeader->cStrJsonHeader) return 1; + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_COMMAND_STR, &jsonTmp); + if (jsonTmp != NULL) + { + usCmd = json_object_get_int (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_CODE_INT, &jsonTmp); + if (jsonTmp != NULL) + { + serRet = json_object_get_int (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_SEQ_INT, &jsonTmp); + if (jsonTmp != NULL) + { + seq = json_object_get_int (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_TIME_LINT, &jsonTmp); + if (jsonTmp != NULL) + { + time = (long) json_object_get_int64 (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_MSG_STR, &jsonTmp); + if (jsonTmp != NULL) + { + memset (cMessage, 0x00, sizeof (cMessage)); + strncpy (cMessage, json_object_get_string (jsonTmp), + sizeof (cMessage) - 1); + } + json_object_put (jsonHeader); + + if (strcmp (cMessage, "auth exception") == 0) + { // wemq user/passwd error + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] Authentication error!user:%s, passwd:%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time, + pRmbStConfig->cWemqUser, pRmbStConfig->cWemqPasswd); + return -1; + } + if (serRet == RMB_CODE_OTHER_FAIL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] register proxy error:%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time, + serRet); + return -2; + } + + if (serRet == RMB_CODE_AUT_FAIL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] register proxy Authentication error:%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time, + serRet); + return -3; + } + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] register proxy success!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + + //hello world之后,心跳包可以延期 + gettimeofday (&pThreadCtx->stTimeLast, NULL); + gettimeofday (&pThreadCtx->stTimeLastRecv, NULL); + + return 0; + +} + +int wemq_thread_fifo_msg_is_empty (WemqThreadCtx * pThreadCtx) +{ + if (pThreadCtx == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pThreadCtx is null"); + return 0; + } + + /** + * fix bug:rmb_sub_reply的消息也需要上传完毕 + */ +// if ((pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) && (pThreadCtx->m_ptFifo != NULL)) { + //check wemq thrad msg empty + if (pThreadCtx->m_ptFifo != NULL) + { + if (wemq_kfifo_is_empty (pThreadCtx->m_ptFifo)) + { + LOGRMB (RMB_LOG_INFO, "pub:pThreadCtx->m_ptFifo is empty"); + return 0; + } + else + { + return 1; + } + } + + return 0; +} + +int wemq_thread_mq_msg_is_empty (WemqThreadCtx * pThreadCtx) +{ + if (pThreadCtx == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pThreadCtx==NULL"); + return NULL; + } + int result = wemq_thread_check_req_mq_is_null (pThreadCtx) + && wemq_thread_check_rr_rsp_mq_is_null (pThreadCtx) + && wemq_thread_check_broadcast_mq_is_null (pThreadCtx); + if (result == 0) + { + LOGRMB (RMB_LOG_INFO, "wemq_thread_mq_msg_is_empty"); + } + return result; + +} + +StMqInfo *wemq_thread_get_mq_by_type (WemqThreadCtx * pThreadCtx, int iType) +{ + stContextProxy *pContextProxy = pThreadCtx->m_ptProxyContext; + StContext *pStContext; + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pStContext = (StContext *) (pContextProxy->pubContext); + } + else + { + pStContext = (StContext *) (pContextProxy->subContext); + } + + return pStContext->fifoMq.mqIndex[iType]; +} + +StMqInfo *wemq_thread_get_receve_req_mq (WemqThreadCtx * pThreadCtx) +{ + if (pThreadCtx == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pThreadCtx==NULL"); + return NULL; + } + return wemq_thread_get_mq_by_type (pThreadCtx, (int) req_mq_index); +} + +StMqInfo *wemq_thread_get_rr_rsp_mq (WemqThreadCtx * pThreadCtx) +{ + if (pThreadCtx == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pThreadCtx==NULL"); + return NULL; + } + return wemq_thread_get_mq_by_type (pThreadCtx, (int) rr_rsp_mq_index); +} + +StMqInfo *wemq_thread_get_broadcast_mq (WemqThreadCtx * pThreadCtx) +{ + if (pThreadCtx == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pThreadCtx==NULL"); + return NULL; + } + return wemq_thread_get_mq_by_type (pThreadCtx, (int) broadcast_mq_index); +} + +/* +Function: rmb_sub_check_req_mq_is_null +Description:校验是否请求队列是否已经为空,如果为空,则返回0,非空,则返回1 +* Return: +* 空返回0,非空返回1 +*/ +int wemq_thread_check_req_mq_is_null (WemqThreadCtx * pThreadCtx) +{ + StMqInfo *p = wemq_thread_get_receve_req_mq (pThreadCtx); + if (p == NULL) + { + return 0; + } + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + usleep (1000); + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + return 0; +} + +/* +Function: wemq_thread_check_rr_rsp_mq_is_null +Description:校验rr_rsp队列是否已经为空,如果为空,则返回0,非空,则返回1 +* Return: +* 空返回0,非空返回1 +*/ +int wemq_thread_check_rr_rsp_mq_is_null (WemqThreadCtx * pThreadCtx) +{ + StMqInfo *p = wemq_thread_get_rr_rsp_mq (pThreadCtx); + if (p == NULL) + { + return 0; + } + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + usleep (1000); + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + return 0; +} + +/* +Function: wemq_thread_check_broadcast_mq_is_null +Description:校验broadcast队列是否已经为空,如果为空,则返回0,非空,则返回1 +* Return: +* 空返回0,非空返回1 +*/ +int wemq_thread_check_broadcast_mq_is_null (WemqThreadCtx * pThreadCtx) +{ + StMqInfo *p = wemq_thread_get_broadcast_mq (pThreadCtx); + if (p == NULL) + { + return 0; + } + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + usleep (1000); + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + return 0; +} + +int wemq_rr_msg_is_empty (stContextProxy * pContextProxy) +{ + + if (pContextProxy == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pContextProxy is null"); + return 0; + } + + if (pContextProxy->stUnique.flag == 1) + { //有未回复的rr同步消息 + LOGRMB (RMB_LOG_DEBUG, "rr sync message is not response"); + return 1; + } + + struct timeval tv_now; + gettimeofday (&tv_now, NULL); + unsigned long ulNowTime = tv_now.tv_sec * 1000 + tv_now.tv_usec / 1000; + + int i; + for (i = 0; + i < + pContextProxy->pUniqueListForRRAsyncOld. + get_array_size (&pContextProxy->pUniqueListForRRAsyncOld); i++) + { + if (pContextProxy->pUniqueListForRRAsyncOld.Data[i].flag == 1) + { //有未回复的rr异步消息 + if (ulNowTime >= pContextProxy->ulLastPrintOldListIsEmpty + 1 * 1000) + { + LOGRMB (RMB_LOG_DEBUG, "rr async is message not response"); + pContextProxy->ulLastPrintOldListIsEmpty = ulNowTime; + } + return 1; + } + } + + LOGRMB (RMB_LOG_DEBUG, "rr msg is empty"); + return 0; +} + +int wemq_rr_all_msg_is_empty (stContextProxy * pContextProxy) +{ + + if (pContextProxy == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pContextProxy is null"); + return 0; + } + + if (pContextProxy->stUnique.flag == 1) + { //有未回复的rr同步消息 + LOGRMB (RMB_LOG_DEBUG, "rr sync message is not response"); + return 1; + } + + int i; + + for (i = 0; + i < + pContextProxy->pUniqueListForRRAsyncNew. + get_array_size (&pContextProxy->pUniqueListForRRAsyncNew); i++) + { + + if (pContextProxy->pUniqueListForRRAsyncNew.Data[i].flag == 1) + { //有未回复的rr异步消息 + LOGRMB (RMB_LOG_DEBUG, + "rr async message in new session is not response"); + return 1; + } + } + for (i = 0; + i < + pContextProxy->pUniqueListForRRAsyncOld. + get_array_size (&pContextProxy->pUniqueListForRRAsyncOld); i++) + { + + if (pContextProxy->pUniqueListForRRAsyncOld.Data[i].flag == 1) + { //有未回复的rr异步消息 + LOGRMB (RMB_LOG_DEBUG, + "rr async message in old session is not response"); + return 1; + } + } + + LOGRMB (RMB_LOG_DEBUG, "rr msg is empty"); + return 0; +} + +int32_t _wemq_thread_do_cmd_send_heart_beat (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ +// ASSERT(pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_BEAT); + if (pThreadCtx == NULL || pStWemqThreadMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pThreadCtx or pStWemqThreadMsg is null"); + return -1; + } + + if (pStWemqThreadMsg->m_iCmd != THREAD_MSG_CMD_BEAT) + { + LOGRMB (RMB_LOG_ERROR, + "pStWemqThreadMsg->m_iCmd=%d, not THREAD_MSG_CMD_BEAT", + pStWemqThreadMsg->m_iCmd); + return -1; + } + + int iRet = -1; + int iTotalLen = pStWemqThreadMsg->m_iHeaderLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + //ENCODE_DWSTR_MEMCPY(buf, pStWemqThreadMsg->m_pBody, pStWemqThreadMsg->m_iBodyLen); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] |wemq_thread2accesss|Send:%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + pStWemqThreadMsg->m_pHeader); + + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_do_send_sync error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + return 0; +} + +static int32_t _wemq_thread_send_heart_beat (WemqThreadCtx * pThreadCtx) +{ + if (pThreadCtx == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pThreadCtx is null"); + //防止一直空转 + usleep (1000); + return -1; + } + +// if (pThreadCtx->m_iState == THREAD_STATE_INIT) +// { +// return 0; +// } + + if (pThreadCtx->m_iState != THREAD_STATE_OK) + { + return 0; + } + + if (pThreadCtx->m_iHeartBeatCount % HEART_BEAT_COUNT == 0) + { + pThreadCtx->m_iHeartBeatCount = 0; + gettimeofday (&pThreadCtx->stTimeNow, NULL); + + int time_inter = + pThreadCtx->stTimeNow.tv_sec - pThreadCtx->stTimeLast.tv_sec; + int time_inter_recv = + pThreadCtx->stTimeNow.tv_sec - pThreadCtx->stTimeLastRecv.tv_sec; + + //check heart beat time out + if (time_inter_recv >= pRmbStConfig->heartBeatTimeout) + { + //防止心跳超时日志多次打印 + pThreadCtx->stTimeLastRecv.tv_sec = pThreadCtx->stTimeNow.tv_sec; + LOGRMB (RMB_LOG_WARN, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] heart beat time out,current_times=%u!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + pThreadCtx->m_uiHeartBeatCurrent); + if (pThreadCtx->m_uiHeartBeatCurrent > 2) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] send two heart beat,but no receive!", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + pThreadCtx->m_uiHeartBeatCurrent = 0; + //add to black list + wemq_proxy_to_black_list (pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + + if (time_inter >= pRmbStConfig->heartBeatPeriod) + { + pThreadCtx->m_uiHeartBeatCurrent += 1; + int iRet = + _wemq_thread_do_cmd_send_heart_beat (pThreadCtx, + &pThreadCtx->m_stHeartBeat); + if (iRet == -2) + { + //_wemq_thread_del_fd(pThreadCtx); + //pThreadCtx->m_iSockFd = -1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + pThreadCtx->stTimeLast.tv_sec = pThreadCtx->stTimeNow.tv_sec; + pThreadCtx->stTimeLast.tv_usec = pThreadCtx->stTimeNow.tv_usec; + } + } + pThreadCtx->m_iHeartBeatCount++; + + return 0; +} + +static int32_t _wemq_thread_do_req (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * pStWemqThreadMsg) +{ + int iRet = -1; + switch (pStWemqThreadMsg->m_iCmd) + { + case THREAD_MSG_CMD_ADD_LISTEN: + { + iRet = + _wemq_thread_do_cmd_add_listen_msg (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread REQ CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + return iRet; + } + case THREAD_MSG_CMD_START: + { + iRet = _wemq_thread_do_cmd_start_msg (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread START CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + + return iRet; + } + case THREAD_MSG_CMD_SEND_MSG: + { + iRet = _wemq_thread_do_cmd_send_msg (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread REQ CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + return iRet; + } + + case THREAD_MSG_CMD_SEND_LOG: + { + iRet = _wemq_thread_do_cmd_send_log (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread REQ CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + return iRet; + } + + case THREAD_MSG_CMD_SEND_CLIENT_GOODBYE: + { + iRet = + _wemq_thread_do_cmd_client_goodbye_msg (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread REQ CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + return iRet; + } + case THREAD_MSG_CMD_SEND_REQUEST: + { + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] Thread REQ CMD THREAD_MSG_CMD_SEND_REQUEST", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + iRet = _wemq_thread_do_cmd_send_request (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread REQ CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + return iRet; + } + case THREAD_MSG_CMD_SEND_REQUEST_ASYNC: + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] Thread REQ CMD THREAD_MSG_CMD_SEND_REQUEST", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + iRet = + _wemq_thread_do_cmd_send_async_request (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread REQ CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + return iRet; + } + case THREAD_MSG_CMD_SEND_REPLY: + { + + iRet = _wemq_thread_do_cmd_send_reply (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread REQ CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + return iRet; + } + case THREAD_MSG_CMD_SEND_MSG_ACK: + { + LOGRMB (RMB_LOG_DEBUG, "[%s] [Type:%d] [TID:%lu] Do App ACK", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID); + + /* + iRet = _wemq_thread_do_cmd_send_msg_ack(pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg(pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + */ + iRet = _wemq_thread_do_cmd_send_msg_ack (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread REQ CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + else + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + LOGRMB (RMB_LOG_ERROR, + "data processing ERR cause _wemq_thread_do_cmd_send_msg_ack failed."); + } + } + return iRet; + } + default: + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] do req error no such type req cmd %d!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pStWemqThreadMsg->m_iCmd); + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + break; + } + return iRet; +} + +static int32_t _wemq_thread_do_last_failure_req (WemqThreadCtx * pThreadCtx) +{ + if (pThreadCtx->m_iWemqThreadMsgHandled == 1) + { + return 0; + } + else + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] do last failure req!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + int iRet = + _wemq_thread_do_req (pThreadCtx, &pThreadCtx->m_stWemqThreadMsg); + if (iRet == -2) + { + _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + return iRet; + } + } + return 0; +} + +int do_ssl_connect (WemqThreadCtx * pThreadCtx) +{ + int err; + int sd; + struct sockaddr_in sa; + + if (NULL == pThreadCtx->sslCtx) + { + SSL_METHOD *meth; + + SSL_load_error_strings (); + SSLeay_add_ssl_algorithms (); + meth = TLSv1_2_client_method (); + pThreadCtx->sslCtx = SSL_CTX_new (meth); + } + + sd = socket (AF_INET, SOCK_STREAM, 0); + + memset (&sa, '\0', sizeof (sa)); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = inet_addr (pThreadCtx->m_cProxyIP); /* Server IP */ + sa.sin_port = htons (pThreadCtx->m_uiProxyPort); /* Server Port number */ + + err = connect (sd, (struct sockaddr *) &sa, sizeof (sa)); + if (0 != err) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [host:%s|port:%u] tls tcp Connect Error, err=%d, errno=%d!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort, err, errno); + close (sd); + return -1; + } + else + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [host:%s|port:%u] tls tcp connect suc!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + } + + pThreadCtx->ssl = SSL_new (pThreadCtx->sslCtx); + SSL_set_fd (pThreadCtx->ssl, sd); + err = SSL_connect (pThreadCtx->ssl); + if (0 > err) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [host:%s|port:%u] tls Connect Error, err=%d, errno=%d!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort, err, errno); + wemq_tcp_close (sd, pThreadCtx->ssl); + pThreadCtx->ssl = NULL; + return -1; + } + + pThreadCtx->m_iSockFd = sd; + return 0; +} + +static int32_t _wemq_thread_do_connect (WemqThreadCtx * pThreadCtx) +{ + //随机sleep配置时间+0~9ms + struct timeval tv; + gettimeofday (&tv, NULL); + long now_time = tv.tv_sec * 1000000 + tv.tv_usec; + srand ((unsigned int) now_time); + int random_time = rand () % 10; + int retry = pRmbStConfig->iWemqTcpConnectRetryNum; + int sleep_time = pRmbStConfig->iWemqTcpConnectDelayTime * 1000; + int timeout = pRmbStConfig->iWemqTcpConnectTimeout + random_time; + + //memset(pThreadCtx->m_cProxyIP, 0, sizeof(pThreadCtx->m_cProxyIP)); + pThreadCtx->m_cProxyIP[0] = '\0'; + pThreadCtx->m_uiProxyPort = 0; + pThreadCtx->m_iLocalPort = 0; + + if (pThreadCtx->m_lRedirect == 0) + { + int iRet = 0; + do + { + iRet = + wemq_proxy_get_server (pThreadCtx->m_cProxyIP, + sizeof (pThreadCtx->m_cProxyIP), + &pThreadCtx->m_uiProxyPort); + if (iRet == 2) + { + LOGRMB (RMB_LOG_ERROR, "get proxy ip/port failed"); + sleep (1); + } + } + while (iRet == 2); + } + else + { + pThreadCtx->m_lRedirect = 0; + snprintf (pThreadCtx->m_cProxyIP, sizeof (pThreadCtx->m_cProxyIP), "%s", + pThreadCtx->m_cRedirectIP); + pThreadCtx->m_uiProxyPort = pThreadCtx->m_iRedirectPort; + } + + while (retry > 0) + { + if (0 != pRmbStConfig->tlsOnoff) + { + int err = do_ssl_connect (pThreadCtx); + if (0 != err) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [retry: %d|host:%s|port:%u] tls Connect Error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, retry, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + } + else + { + wemq_getsockename (pThreadCtx->m_iSockFd, NULL, 0, + &pThreadCtx->m_iLocalPort); + if (_wemq_thread_set_fd_nonblock (pThreadCtx, pThreadCtx->m_iSockFd) + != 0) + { + LOGRMB (RMB_LOG_ERROR, + "wemq thread set pThreadCtx->m_iSockFd=%d to nonblock failed", + pThreadCtx->m_iSockFd); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + } + else + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [host:%s|port:%u|local_port:%d] tls connect to proxy, fd=%d!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort, pThreadCtx->m_iLocalPort, + pThreadCtx->m_iSockFd); + //add fd to epoll + _wemq_thread_add_fd (pThreadCtx); + return 0; + } + } + } + else + { + int iSockFd = + wemq_tcp_connect (pThreadCtx->m_cProxyIP, + (uint16_t) pThreadCtx->m_uiProxyPort, timeout); + if (iSockFd > 0) + { + pThreadCtx->m_iSockFd = iSockFd; + wemq_getsockename (iSockFd, NULL, 0, &pThreadCtx->m_iLocalPort); + if (_wemq_thread_set_fd_nonblock (pThreadCtx, pThreadCtx->m_iSockFd) + != 0) + { + //exit(1); + LOGRMB (RMB_LOG_ERROR, + "wemq thread set pThreadCtx->m_iSockFd=%d to nonblock failed", + pThreadCtx->m_iSockFd); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + //return -1; + } + else + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [host:%s|port:%u|local_port:%d] connect to proxy!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort, pThreadCtx->m_iLocalPort); + //add fd to epoll + _wemq_thread_add_fd (pThreadCtx); + return 0; + } + } + } + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [retry: %d|host:%s|port:%u] Connect Error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, retry, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + retry--; + usleep (sleep_time); + if (retry == 0) + { + wemq_proxy_goodbye (pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [host:%s|port:%u] Connect Failed!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + return -1; + } + + } + return -2; +} + +int32_t wemq_thread_state_init (WemqThreadCtx * pThreadCtx) +{ +// ASSERT(pThreadCtx); + if (pThreadCtx == NULL) + { + LOGRMB (RMB_LOG_ERROR, "wemq_thread_state_init: pThreadCtx is null"); + return -1; + } + pThreadCtx->m_iHeartBeatCount = 0; + pThreadCtx->m_uiHeartBeatCurrent = 0; + + gettimeofday (&pThreadCtx->stTimeNow, NULL); + gettimeofday (&pThreadCtx->stTimeLast, NULL); + gettimeofday (&pThreadCtx->stTimeLastRecv, NULL); + + //pThreadCtx->m_iThreadId = pThreadCtx->m_contextType; + pThreadCtx->m_iWemqThreadMsgHandled = 1; + pThreadCtx->m_threadID = pthread_self (); + +// pThreadCtx->m_lRedirect = false; + pThreadCtx->m_lRedirect = 0; + pThreadCtx->m_cRedirectIP[0] = '\0'; + pThreadCtx->m_iRedirectPort = 0; + + pThreadCtx->m_pRecvBuff = (char *) malloc (TCP_BUF_SIZE * sizeof (char)); + if (pThreadCtx->m_pRecvBuff == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] pThreadCtx->m_pRecvBuff malloc error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + memset (pThreadCtx->m_pRecvBuff, 0x00, + sizeof (TCP_BUF_SIZE * sizeof (char))); + + pThreadCtx->m_pSendBuff = (char *) malloc (TCP_BUF_SIZE * sizeof (char)); + if (pThreadCtx->m_pSendBuff == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] pThreadCtx->m_pSendBuff malloc error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + memset (pThreadCtx->m_pSendBuff, 0x00, TCP_BUF_SIZE * sizeof (char)); + + pThreadCtx->m_iEpollFd = epoll_create (1); + if (pThreadCtx->m_iEpollFd < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] Create Epoll fd error:%d!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, errno); + return -3; + } + + pThreadCtx->m_ptEvents = + (struct epoll_event *) malloc (MAX_EVENT * sizeof (struct epoll_event)); + if (pThreadCtx->m_ptEvents == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] Create Malloc events error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + + pThreadCtx->sslCtx = NULL; + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + pThreadCtx->m_iSockFdNew = -1; + pThreadCtx->sslNew = NULL; + pThreadCtx->m_iSockFdOld = -1; + pThreadCtx->sslOld = NULL; + pThreadCtx->m_iSockFd = -1; + + /* + pThreadCtx->m_stReqForHeartBeat.pid = CMD_HEART_BEAT; + pThreadCtx->m_stReqForHeartBeat.uiCount = 0; + */ + _wemq_thread_make_heart_beat_pkg (pThreadCtx); + _wemq_thread_make_hello_pkg (pThreadCtx); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_CONNECT); +} + +int32_t wemq_thread_state_connect (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + ASSERT (pThreadCtx->m_iState == THREAD_STATE_CONNECT); + + int ret = _wemq_thread_do_connect (pThreadCtx); + + if (ret == 0) + { + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_REGI); + } + else if (ret < 0) + { + /** + * 1. 使用default ip/port时,如果连接失败,则通知前端连接失败 + * 2. 如果从配置中心获取ip list失败或者获取到的ip list数量小于2个,则通知前端连接失败 + */ + if (pRmbStConfig->iWemqUseHttpCfg != 1 + || ((ret = rmb_get_wemq_proxy_list_num ()) <= 1)) + { + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pthread_mutex_lock (&pThreadCtx->m_ptProxyContext->pubMutex); + if (pThreadCtx->m_ptProxyContext->iFlagForPub == 0) + { + pthread_cond_signal (&pThreadCtx->m_ptProxyContext->pubCond); + } + pthread_mutex_unlock (&pThreadCtx->m_ptProxyContext->pubMutex); + } + else if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_SUB) + { + pthread_mutex_lock (&pThreadCtx->m_ptProxyContext->subMutex); + if (pThreadCtx->m_ptProxyContext->iFlagForSub == 0) + { + pthread_cond_signal (&pThreadCtx->m_ptProxyContext->subCond); + } + pthread_mutex_unlock (&pThreadCtx->m_ptProxyContext->subMutex); + } + } + + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + return ret; +} + +int32_t wemq_thread_state_regi (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + ASSERT (pThreadCtx->m_iState == THREAD_STATE_REGI); + int iRet = -1; + + iRet = _wemq_thread_do_cmd_send_msg_reg (pThreadCtx); + if (iRet == 0) + { + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pthread_mutex_lock (&pThreadCtx->m_ptProxyContext->pubMutex); + if (pThreadCtx->m_ptProxyContext->iFlagForPub == 0) + { + pThreadCtx->m_ptProxyContext->iFlagForPub = 1; + pThreadCtx->m_ptProxyContext->iFlagForPublish = 1; + pthread_cond_signal (&pThreadCtx->m_ptProxyContext->pubCond); + } + pthread_mutex_unlock (&pThreadCtx->m_ptProxyContext->pubMutex); + } + else if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_SUB) + { + pthread_mutex_lock (&pThreadCtx->m_ptProxyContext->subMutex); + if (pThreadCtx->m_ptProxyContext->iFlagForSub == 0) + { + pThreadCtx->m_ptProxyContext->iFlagForSub = 1; + pthread_cond_signal (&pThreadCtx->m_ptProxyContext->subCond); + } + pthread_mutex_unlock (&pThreadCtx->m_ptProxyContext->subMutex); + } + + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_OK); + } + else if (iRet < 0) + { + wemq_proxy_to_black_list (pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + return -1; +} + +int32_t wemq_thread_state_ok (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + ASSERT (pThreadCtx->m_iState == THREAD_STATE_OK); + + int iRet = -1; + + if ((pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + && (pThreadCtx->m_ptProxyContext->iFlagForPublish == 0)) + { + pThreadCtx->m_ptProxyContext->iFlagForPublish = 1; + } + + iRet = _wemq_thread_do_last_failure_req (pThreadCtx); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] CALL DO LAST FAILURE REQ ERROR", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + return iRet; + } + + //旧连接还在 + if (pThreadCtx->m_iSockFdOld >= 0) + { + + wemq_thread_do_deal_with_old_connect (pThreadCtx); + } + + int iMsgNum = 0; + int iRecv = 0; + iMsgNum = _wemq_thread_get_data_from_fifo (pThreadCtx); + if (iMsgNum > 0) + { + iRet = _wemq_thread_do_req (pThreadCtx, &pThreadCtx->m_stWemqThreadMsg); + if (iRet == -2) + { + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + + } + + iRecv = _wemq_thread_do_recv_async (pThreadCtx, true); + if (iRecv > 0) + { + LOGRMB (RMB_LOG_DEBUG, "[%s] [Type:%d] [TID:%lu] RECV %d bytes", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRecv); + iRet = _wemq_thread_on_message (pThreadCtx, true); + if (iRet == WEMQ_MESSAGE_RET_GOODBYE) + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] RECV byebye cmd", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + wemq_proxy_goodbye (pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + else if (iRet == WEMQ_MESSAGE_RET_REDIRECT) + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] --> [redirect ip:%s|port:%d] RECV redirect cmd", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + pThreadCtx->m_cRedirectIP, pThreadCtx->m_iRedirectPort); + //_wemq_thread_del_fd(pThreadCtx); + //close(pThreadCtx->m_iSockFd); + //pThreadCtx->m_iSockFd = -1; + //return _wemq_thread_state_trans(pThreadCtx, pThreadCtx->m_iState, THREAD_STATE_BREAK); + wemq_proxy_goodbye (pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, THREAD_STATE_CLOSE); //停止发消息; + } + else if (iRet == WEMQ_MESSAGE_RET_SERVERGOODBYE) //access端主动离线 + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] RECV server goodbye cmd", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + //stContextProxy* pContextProxy = pThreadCtx->m_ptProxyContext; + + wemq_proxy_goodbye (pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + //wemq_thread_rr_msg_is_empty(pThreadCtx); + // _wemq_thread_del_fd(pThreadCtx); + // close(pThreadCtx->m_iSockFd); + // pThreadCtx->m_iSockFd = -1; + + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, THREAD_STATE_CLOSE); //停止发消息; + } + else if (iRet == WEMQ_MESSAGE_RET_CLIENTGOODBYE) //client端主动离线,收到回包 + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] RECV client goodbye cmd rsp", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + stContextProxy *pContextProxy = pThreadCtx->m_ptProxyContext; + pContextProxy->iFlagForGoodBye = 1; + pthread_cond_signal (&pContextProxy->goodByeCond); + // + //pContextProxy->iFlagForRun = 0; //停止运行状态机 + return 0; + } + } + else + { + //LOGWEMQ(WEMQ_LOG_ERROR, "[%s],[TID:%d],ERROR RECV %d bytes\n", STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_iThreadId, iRecv); + if (iRecv == -1) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu]Thread on Message ERROR", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + } + if (iRecv == -2) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] connect closed by peer", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + return 0; +} + +int32_t wemq_thread_state_close (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + ASSERT (pThreadCtx->m_iState == THREAD_STATE_CLOSE); + + stContextProxy *pContextProxy = pThreadCtx->m_ptProxyContext; + int iRet = -1; + + int iMsgNum = 0; + int iRecv = 0; + /* + if (wemq_rr_msg_is_empty(pThreadCtx->m_ptProxyContext) == 0 && pThreadCtx->m_ptProxyContext->iFlagForEvent == 0) //rr同步和异步消息和单播的ack都已全部回来 + { + LOGRMB(RMB_LOG_INFO, "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] RECV all rsp", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + //stContextProxy* pContextProxy = pThreadCtx->m_ptProxyContext; + + wemq_proxy_goodbye(pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + _wemq_thread_del_fd(pThreadCtx); + close(pThreadCtx->m_iSockFd); + pThreadCtx->m_iSockFd = -1; + return _wemq_thread_state_trans(pThreadCtx, pThreadCtx->m_iState, THREAD_STATE_BREAK); //停止 + } + */ + + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pThreadCtx->m_iSockFdOld = pThreadCtx->m_iSockFd; + pThreadCtx->sslOld = pThreadCtx->ssl; + memcpy (pThreadCtx->m_cProxyIPOld, pThreadCtx->m_cProxyIP, + strlen (pThreadCtx->m_cProxyIP)); + pThreadCtx->m_uiProxyPortOld = pThreadCtx->m_uiProxyPort; + + Array pTempList = pContextProxy->pUniqueListForRRAsyncNew; + pContextProxy->pUniqueListForRRAsyncNew = + pContextProxy->pUniqueListForRRAsyncOld; + pContextProxy->pUniqueListForRRAsyncOld = pTempList; + + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + } + else + { + struct timeval tv_now; + gettimeofday (&tv_now, NULL); + + unsigned long ulNowTime = tv_now.tv_sec * 1000 + tv_now.tv_usec / 1000; + unsigned long ulLastTime = tv_now.tv_sec * 1000 + tv_now.tv_usec / 1000; + unsigned long timeout = 4 * 1000; + + while ((ulNowTime - ulLastTime) < timeout) + { + iMsgNum = _wemq_thread_get_data_from_fifo (pThreadCtx); + if (iMsgNum > 0) + { + iRet = + _wemq_thread_do_req (pThreadCtx, &pThreadCtx->m_stWemqThreadMsg); + } + else + if (pRmbStConfig->mqIsEmpty == MQ_INIT + || pRmbStConfig->mqIsEmpty == MQ_IS_EMPTY) + break; + gettimeofday (&tv_now, NULL); + ulNowTime = tv_now.tv_sec * 1000 + tv_now.tv_usec / 1000; + } + + } + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, THREAD_STATE_BREAK); //停止 + +} + +int32_t wemq_thread_state_break (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + ASSERT (pThreadCtx->m_iState == THREAD_STATE_BREAK); + //ASSERT(pThreadCtx->m_iSockFd == -1); + if (pThreadCtx->m_iSockFd >= 0) + { + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + } + + int ret = -1; + + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pThreadCtx->m_ptProxyContext->iFlagForPublish = 0; + } + + usleep (1000); + if ((ret = _wemq_thread_do_connect (pThreadCtx)) == 0) + { + pThreadCtx->m_uiHeartBeatCurrent = 0; + pThreadCtx->m_iHeartBeatCount = 0; + gettimeofday (&pThreadCtx->stTimeNow, NULL); + gettimeofday (&pThreadCtx->stTimeLast, NULL); + gettimeofday (&pThreadCtx->stTimeLastRecv, NULL); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_RECONNECT); + } + + if (wemq_proxy_ip_is_connected () == 1) + { //所有iplist已经遍历过一次 + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pthread_mutex_lock (&pThreadCtx->m_ptProxyContext->pubMutex); + if (pThreadCtx->m_ptProxyContext->iFlagForPub == 0) + { + pthread_cond_signal (&pThreadCtx->m_ptProxyContext->pubCond); + } + pthread_mutex_unlock (&pThreadCtx->m_ptProxyContext->pubMutex); + } + else if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_SUB) + { + pthread_mutex_lock (&pThreadCtx->m_ptProxyContext->subMutex); + if (pThreadCtx->m_ptProxyContext->iFlagForSub == 0) + { + pthread_cond_signal (&pThreadCtx->m_ptProxyContext->subCond); + } + pthread_mutex_unlock (&pThreadCtx->m_ptProxyContext->subMutex); + } + } + + return ret; +} + +int32_t wemq_thread_state_reconnect (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + //TODO RECONNECT; + //sleep(1); + struct timeval tv; + gettimeofday (&tv, NULL); + long now_time = tv.tv_sec * 1000000 + tv.tv_usec; + srand ((unsigned int) now_time); + //随机sleep 30~50ms ,usleep 单位是纳秒 + int sleep_time = rand () % 20 + 30; + usleep (sleep_time * 1000); + // hello msg + { + int iRet = -1; + + iRet = _wemq_thread_do_cmd_send_msg_reg (pThreadCtx); + if (iRet > 0) + { + return -1; + } + else if (iRet < 0) + { + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + + /** + * 程序首次起来时,如果选择的第一个ip连接失败而第二个ip连接成功且hello world指令发送成功,则应该通知前端连接成功 + */ + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + if (pThreadCtx->m_ptProxyContext->iFlagForPublish == 0) + { + pThreadCtx->m_ptProxyContext->iFlagForPublish = 1; + } + pthread_mutex_lock (&pThreadCtx->m_ptProxyContext->pubMutex); + if (pThreadCtx->m_ptProxyContext->iFlagForPub == 0) + { + pThreadCtx->m_ptProxyContext->iFlagForPub = 1; + pthread_cond_signal (&pThreadCtx->m_ptProxyContext->pubCond); + } + pthread_mutex_unlock (&pThreadCtx->m_ptProxyContext->pubMutex); + } + else if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_SUB) + { + pthread_mutex_lock (&pThreadCtx->m_ptProxyContext->subMutex); + if (pThreadCtx->m_ptProxyContext->iFlagForSub == 0) + { + pThreadCtx->m_ptProxyContext->iFlagForSub = 1; + pthread_cond_signal (&pThreadCtx->m_ptProxyContext->subCond); + } + pthread_mutex_unlock (&pThreadCtx->m_ptProxyContext->subMutex); + } + + int flag = 0; + //regist topic list + StWemqTopicProp *ptTopicProp = NULL; + if (pThreadCtx->m_ptTopicList != NULL) + { + ptTopicProp = pThreadCtx->m_ptTopicList->next; + } + WEMQJSON *jsonTopicList = json_object_new_array (); + char cBroadcastDcn[10] = "000"; + while (ptTopicProp != NULL) + { + flag = 1; + char cTopic[200]; + //char serviceOrEvent = (*(ptTopicProp->cServiceId + 3) == '0') ? 'e' : 's'; + char serviceOrEvent = (*(ptTopicProp->cServiceId + 3) == '0') ? 's' : 'e'; + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", + pRmbStConfig->cConsumerDcn, serviceOrEvent, + ptTopicProp->cServiceId, ptTopicProp->cScenario, + *(ptTopicProp->cServiceId + 3)); + json_object_array_add (jsonTopicList, json_object_new_string (cTopic)); + //自动监听广播topic + if (serviceOrEvent == 'e') + { + memset (cTopic, 0x00, sizeof (cTopic)); + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", cBroadcastDcn, + serviceOrEvent, ptTopicProp->cServiceId, + ptTopicProp->cScenario, *(ptTopicProp->cServiceId + 3)); + json_object_array_add (jsonTopicList, json_object_new_string (cTopic)); + } + ptTopicProp = ptTopicProp->next; + } + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_ADD_LISTEN; + + WEMQJSON *jsonHeader = json_object_new_object (); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object for jsonHeader failed"); + return -1; + } + + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (SUBSCRIBE_REQUEST)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object for jsonBody failed"); + json_object_put (jsonHeader); + json_object_put (jsonTopicList); + return -1; + } + + json_object_object_add (jsonBody, MSG_BODY_TOPIC_LIST_JSON, jsonTopicList); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_get_string for header is null"); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -2; + } + stThreadMsg.m_iHeaderLen = strlen (header_str); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] Gen thread msg header succ, len %d, %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, stThreadMsg.m_iHeaderLen, header_str); + stThreadMsg.m_pHeader = + (char *) malloc (stThreadMsg.m_iHeaderLen * sizeof (char) + 1); + if (stThreadMsg.m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for header failed"); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + memcpy (stThreadMsg.m_pHeader, header_str, stThreadMsg.m_iHeaderLen); + stThreadMsg.m_pHeader[stThreadMsg.m_iHeaderLen] = '\0'; + json_object_put (jsonHeader); + + const char *body_str = json_object_get_string (jsonBody); + if (body_str == NULL) + { + json_object_put (jsonBody); + return -1; + } + + stThreadMsg.m_iBodyLen = strlen (body_str); + stThreadMsg.m_pBody = + (char *) malloc (stThreadMsg.m_iBodyLen * sizeof (char) + 1); + if (stThreadMsg.m_pBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for hello body failed"); + json_object_put (jsonBody); + return -1; + } + memcpy (stThreadMsg.m_pBody, body_str, stThreadMsg.m_iBodyLen); + stThreadMsg.m_pBody[stThreadMsg.m_iBodyLen] = '\0'; + + json_object_put (jsonBody); + + int iRet = _wemq_thread_do_cmd_add_listen_msg (pThreadCtx, &stThreadMsg); + if (iRet == -2) + { + free (stThreadMsg.m_pHeader); + free (stThreadMsg.m_pBody); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + iRet = _wemq_thread_do_recv_sync (pThreadCtx); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Decode Wemq Header ERROR", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + + StWeMQMSG *pWemqHeader = &pThreadCtx->m_stWeMQMSG; + jsonHeader = NULL; + WEMQJSON *jsonTmp = NULL; + char *usCmd; + char *msg; + int serRet = -1; + int seq = -1; + long time = 0; + + jsonHeader = json_tokener_parse (pWemqHeader->cStrJsonHeader); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] [LocalPort:%d] json_tokener_parse error: %s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, + pWemqHeader-> + cStrJsonHeader) return _wemq_thread_state_trans (pThreadCtx, + pThreadCtx-> + m_iState, + THREAD_STATE_BREAK); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_COMMAND_STR, &jsonTmp); + if (jsonTmp != NULL) + { + usCmd = json_object_get_string (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_CODE_INT, &jsonTmp); + if (jsonTmp != NULL) + { + serRet = json_object_get_int (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_SEQ_INT, &jsonTmp); + if (jsonTmp != NULL) + { + seq = json_object_get_int (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_MSG_STR, &jsonTmp); + if (jsonTmp != NULL) + { + msg = json_object_get_string (jsonTmp); + } + + json_object_put (jsonHeader); + + if ((serRet == 0) && strcmp (usCmd, SUBSCRIBE_RESPONSE) == 0) + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [msg:%s] [cmd:%s] register proxy success", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, msg, + usCmd); + + } + else + { + if (strcmp (usCmd, SUBSCRIBE_RESPONSE) == 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [msg:%s] [cmd:%s] [ret:%d] register proxy failed, iRet=%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, msg, + usCmd, serRet); + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [msg:%s] [cmd:%s]register proxy failed, unknown cmd", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, msg, + usCmd); + } + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + + //send start command + if (flag == 1) + { + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_START; + + WEMQJSON *jsonHeader = json_object_new_object (); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object failed"); + return -2; + } + //add command + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (LISTEN_REQUEST)); + //add seq + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + //add code + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "header is null"); + json_object_put (jsonHeader); + return -2; + } + + stThreadMsg.m_iHeaderLen = strlen (header_str); + LOGRMB (RMB_LOG_DEBUG, "Get thread msg header succ, len=%u, %s", + stThreadMsg.m_iHeaderLen, header_str) stThreadMsg.m_pHeader = + (char *) malloc ((stThreadMsg.m_iHeaderLen + 1) * sizeof (char)); + if (stThreadMsg.m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for stThreadMsg.m_pHeader failed"); + json_object_put (jsonHeader); + return -2; + } + memcpy (stThreadMsg.m_pHeader, header_str, stThreadMsg.m_iHeaderLen); + stThreadMsg.m_pHeader[stThreadMsg.m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + + stThreadMsg.m_iBodyLen = 0; + stThreadMsg.m_pBody = NULL; + + int iRet = _wemq_thread_do_cmd_start_msg (pThreadCtx, &stThreadMsg); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (&stThreadMsg); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + + iRet = _wemq_thread_do_recv_sync (pThreadCtx); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] Decode Wemq Header ERROR", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + + StWeMQMSG *pWemqHeader = &pThreadCtx->m_stWeMQMSG; + jsonHeader = NULL; + WEMQJSON *jsonTmp = NULL; + char *usCmd; + char *msg; + int serRet = -1; + int seq = -1; + long time = 0; + + jsonHeader = json_tokener_parse (pWemqHeader->cStrJsonHeader); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] [LocalPort:%d] json_tokener_parse error:%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, pWemqHeader->cStrJsonHeader); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + + json_object_object_get_ex (jsonHeader, MSG_HEAD_COMMAND_STR, &jsonTmp); + if (jsonTmp != NULL) + { + usCmd = json_object_get_string (jsonTmp); + } + + json_object_object_get_ex (jsonHeader, MSG_HEAD_CODE_INT, &jsonTmp); + if (jsonTmp != NULL) + { + serRet = json_object_get_int (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_SEQ_INT, &jsonTmp); + if (jsonTmp != NULL) + { + seq = json_object_get_int (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_MSG_STR, &jsonTmp); + if (jsonTmp != NULL) + { + msg = json_object_get_string (jsonTmp); + } + + json_object_put (jsonHeader); + + if (serRet != 0 || (strcmp (usCmd, LISTEN_RESPONSE) != 0)) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [Seq:%d] [msg:%s] [CMD:%d] reconnect send start listen error:%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, seq, msg, + usCmd, serRet); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_OK); +} + +int32_t wemq_thread_state_destory (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + free (pThreadCtx->m_pRecvBuff); + free (pThreadCtx->m_pSendBuff); + free (pThreadCtx->m_ptEvents); + + if (pThreadCtx->m_iSockFd != -1) + { + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + } + if (NULL != pThreadCtx->sslCtx) + { + SSL_CTX_free (pThreadCtx->sslCtx); + pThreadCtx->sslCtx = NULL; + } + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_EXIT); +} + +void wemq_thread_clear_timeout_rr_async_request (WemqThreadCtx * pThreadCtx) +{ + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_SUB) + return; + stContextProxy *pContextProxy = pThreadCtx->m_ptProxyContext; + struct timeval tv_now; + gettimeofday (&tv_now, NULL); + unsigned long ulNowTime = tv_now.tv_sec * 1000 + tv_now.tv_usec / 1000; + //int timeout = pRmbStConfig->rrAsyncTimeOut; + if (pThreadCtx->m_ptProxyContext->ulLastClearRRAysncMsgTime == 0) + { + pThreadCtx->m_ptProxyContext->ulLastClearRRAysncMsgTime = ulNowTime; + } + // 1s 清除一次 + if (ulNowTime >= + pThreadCtx->m_ptProxyContext->ulLastClearRRAysncMsgTime + 1 * 1000) + { + int i; + pthread_mutex_lock (&pContextProxy->rrMutex); + for (i = 0; + i < + pContextProxy->pUniqueListForRRAsyncNew. + get_array_size (&pContextProxy->pUniqueListForRRAsyncNew); i++) + { + if (pContextProxy->pUniqueListForRRAsyncNew.Data[i].flag == 1 + && ulNowTime >= + (pContextProxy->pUniqueListForRRAsyncNew.Data[i].timeStamp + + pContextProxy->pUniqueListForRRAsyncNew.Data[i].timeout)) + { //有超时的rr异步消息 + LOGRMB (RMB_LOG_WARN, + "rr async bizSeq:%s ,unique_id:%s time out, remove!", + pContextProxy->pUniqueListForRRAsyncNew.Data[i].biz_seq, + pContextProxy->pUniqueListForRRAsyncNew.Data[i].unique_id); + pContextProxy->pUniqueListForRRAsyncNew.Data[i].flag = 0; + } + } + for (i = 0; + i < + pContextProxy->pUniqueListForRRAsyncOld. + get_array_size (&pContextProxy->pUniqueListForRRAsyncOld); i++) + { + if (pContextProxy->pUniqueListForRRAsyncOld.Data[i].flag == 1 + && ulNowTime >= + (pContextProxy->pUniqueListForRRAsyncOld.Data[i].timeStamp + + pContextProxy->pUniqueListForRRAsyncOld.Data[i].timeout)) + { //有超时的rr异步消息 + LOGRMB (RMB_LOG_WARN, + "rr old async bizSeq:%s ,unique_id:%s time out, remove!", + pContextProxy->pUniqueListForRRAsyncOld.Data[i].biz_seq, + pContextProxy->pUniqueListForRRAsyncOld.Data[i].unique_id); + pContextProxy->pUniqueListForRRAsyncOld.Data[i].flag = 0; + } + } + pthread_mutex_unlock (&pContextProxy->rrMutex); + pThreadCtx->m_ptProxyContext->ulLastClearRRAysncMsgTime = ulNowTime; + } +} + +void wemq_thread_do_deal_with_old_connect (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + int iRecv = 0; + int iRet = -1; + if (pThreadCtx->m_iSockFdOld >= 0) + { + if (wemq_rr_msg_is_empty (pThreadCtx->m_ptProxyContext) == 0 && pThreadCtx->m_ptProxyContext->iFlagForEvent == 0) //rr同步和异步消息和单播的ack都已全部回来 + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] RECV all rsp", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIPOld, pThreadCtx->m_uiProxyPortOld); + //stContextProxy* pContextProxy = pThreadCtx->m_ptProxyContext; + + wemq_proxy_goodbye (pThreadCtx->m_cProxyIPOld, + pThreadCtx->m_uiProxyPortOld); + _wemq_thread_del_old_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFdOld, pThreadCtx->sslOld); + pThreadCtx->m_iSockFdOld = -1; + pThreadCtx->sslOld = NULL; + return; + } + + iRecv = _wemq_thread_do_recv_async (pThreadCtx, false); + if (iRecv > 0) + { + LOGRMB (RMB_LOG_DEBUG, "[%s] [Type:%d] [TID:%lu] RECV %d bytes", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRecv); + iRet = _wemq_thread_on_message (pThreadCtx, false); + + } + else + { + //LOGWEMQ(WEMQ_LOG_ERROR, "[%s],[TID:%d],ERROR RECV %d bytes\n", STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_iThreadId, iRecv); + if (iRecv == -1) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu]Thread on Message ERROR", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + } + if (iRecv == -2) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] connect closed by peer", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + wemq_proxy_goodbye (pThreadCtx->m_cProxyIPOld, + pThreadCtx->m_uiProxyPortOld); + _wemq_thread_del_old_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFdOld, pThreadCtx->sslOld); + pThreadCtx->m_iSockFdOld = -1; + pThreadCtx->sslOld = NULL; + + } + } + } +} + +int32_t wemq_thread_run (WemqThreadCtx * pThreadCtx) +{ +// ASSERT (pThreadCtx); + if (pThreadCtx == NULL) + { + LOGRMB (RMB_LOG_ERROR, "wemq_thread_run:pThreadCtx is null"); + return -1; + } + int iRet = 0; + int iRunFlag = 1; + int countDown = 0; + while (iRunFlag) +// while (pThreadCtx->m_ptProxyContext->iFlagForRun) + { + _wemq_thread_send_heart_beat (pThreadCtx); + switch (pThreadCtx->m_iState) + { + case THREAD_STATE_INIT: + { + _wemq_thread_check_init (pThreadCtx); + iRet = wemq_thread_state_init (pThreadCtx); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_thread_state_init failed,iRet=%d", + iRet); + return -1; + } + break; + } + case THREAD_STATE_CONNECT: + { + _wemq_thread_check_connect (pThreadCtx); + wemq_thread_state_connect (pThreadCtx); + break; + } + case THREAD_STATE_REGI: + { + _wemq_thread_check_regi (pThreadCtx); + wemq_thread_state_regi (pThreadCtx); + break; + } + case THREAD_STATE_OK: + { + _wemq_thread_check_ok (pThreadCtx); + wemq_thread_state_ok (pThreadCtx); + break; + } + case THREAD_STATE_CLOSE: + { + _wemq_thread_check_close (pThreadCtx); + wemq_thread_state_close (pThreadCtx); + break; + } + + case THREAD_STATE_BREAK: + { + _wemq_thread_check_break (pThreadCtx); + wemq_thread_state_break (pThreadCtx); + break; + } + case THREAD_STATE_RECONNECT: + { + _wemq_thread_check_reconnect (pThreadCtx); + wemq_thread_state_reconnect (pThreadCtx); + break; + } + case THREAD_STATE_DESTROY: + { + _wemq_thread_check_destory (pThreadCtx); + wemq_thread_state_destory (pThreadCtx); + break; + } + default: + iRunFlag = 0; + break; + } + wemq_thread_clear_timeout_rr_async_request (pThreadCtx); + if (pThreadCtx->m_ptProxyContext->iFlagForRun == 0) + { + if (wemq_thread_fifo_msg_is_empty (pThreadCtx) == 0 + && wemq_rr_all_msg_is_empty (pThreadCtx->m_ptProxyContext) == 0) + { + iRunFlag = 0; + } + else + { + GetRmbNowLongTime (); + unsigned long timeout = pRmbStConfig->ulExitTimeOut; //default:30s + //超过timeout直接退出 + if (pRmbStConfig->ulNowTtime >= + pThreadCtx->m_ptProxyContext->ulGoodByeTime + timeout) + { + iRunFlag = 0; + } + } + } + } + LOGRMB (RMB_LOG_INFO, "[%s] [Type:%d] [TID:%lu] THREAD EXIT!!!!", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID); + + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->ssl = NULL; + pThreadCtx->m_iSockFd = -1; + + return 0; +} + +int32_t check_dyed_msg (StRmbMsg * rmbMsg) +{ + if (rmbMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmbMsg is null"); + return -1; + } + if (strcmp (rmbMsg->isDyedMsg, "true") == 0) + { + return 1; + } + else + { + return 0; + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/wemq_topic_list.c b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_topic_list.c new file mode 100644 index 0000000000..7b3376e5e2 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_topic_list.c @@ -0,0 +1,237 @@ +// 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. + +#include +#include "wemq_topic_list.h" + +static int print_wemq_topic (StWemqTopicProp * pArg) +{ + if (pArg == NULL) + { + printf ("pArg is null\n"); + return -1; + } + + if (pArg->flag == 0) + { + printf ("Topic:\n\tflag=%d\n\tserviceid=%s\n\tscenario=%s\n", pArg->flag, + pArg->cServiceId, pArg->cScenario); + } + else if (pArg->flag == 1) + { + printf ("Topic:\n\tflag=%d\n\ttopic=%s\n", pArg->flag, pArg->cTopic); + } + else + { + printf ("unknown flag:%d\n", pArg->flag); + } + + return 0; +} + +static int wemq_topic_list_iter (StWemqTopicList * ptTopicList, + WEMQ_DEC_FUNC func) +{ + StWemqTopicProp *tmp = ptTopicList->next; + while (tmp != NULL) + { + func (tmp); + tmp = tmp->next; + } + return 1; +} + +inline int32_t wemq_topic_list_is_empty (StWemqTopicList * ptTopicList) +{ + return (ptTopicList->next == NULL) ? 1 : 0; +} + +void wemq_topic_list_init (StWemqTopicList * ptTopicList) +{ + if (!wemq_topic_list_is_empty (ptTopicList)) + { + wemq_topic_list_clear (ptTopicList); + } + ptTopicList->next = NULL; + ptTopicList->tail = NULL; +} + +int wemq_topic_list_clear (StWemqTopicList * ptTopicList) +{ + if (ptTopicList == NULL) + { + return 1; + } + + StWemqTopicProp *ptTemp1 = ptTopicList->next; + StWemqTopicProp *ptTemp2 = ptTopicList->next; + while (ptTemp1 != NULL) + { + ptTemp1 = ptTemp1->next; + ptTemp2->next = NULL; + free (ptTemp2); + ptTemp2 = ptTemp1; + } + + return 1; +} + +int32_t wemq_topic_list_add_node (StWemqTopicList * ptTopicList, + StWemqTopicProp * ptTopicProp) +{ + if (ptTopicProp == NULL) + { + return -1; + } + + if (ptTopicList == NULL) + { + return -1; + } + + if (wemq_topic_list_find_node (ptTopicList, ptTopicProp, NULL) != 1) + { + if (ptTopicList->tail == NULL) + { + StWemqTopicProp *tmp = + (StWemqTopicProp *) malloc (sizeof (StWemqTopicProp)); + if (tmp == NULL) + { + printf ("malloc for StTopicProp failed!\n"); + return -2; + } + memset (tmp, 0, sizeof (StWemqTopicProp)); + if (ptTopicProp->flag == 0) + { + strncpy (tmp->cServiceId, ptTopicProp->cServiceId, + strlen (ptTopicProp->cServiceId)); + strncpy (tmp->cScenario, ptTopicProp->cScenario, + strlen (ptTopicProp->cScenario)); + } + else + { + strncpy (tmp->cTopic, ptTopicProp->cTopic, + strlen (ptTopicProp->cTopic)); + } + tmp->flag = ptTopicProp->flag; + tmp->next = NULL; + ptTopicList->next = tmp; + ptTopicList->tail = tmp; + } + else + { + StWemqTopicProp *tmp = + (StWemqTopicProp *) malloc (sizeof (StWemqTopicProp)); + if (tmp == NULL) + { + printf ("malloc for StTopicProp failed!\n"); + return -2; + } + memset (tmp, 0, sizeof (StWemqTopicProp)); + if (ptTopicProp->flag == 0) + { + strncpy (tmp->cServiceId, ptTopicProp->cServiceId, + strlen (ptTopicProp->cServiceId)); + strncpy (tmp->cScenario, ptTopicProp->cScenario, + strlen (ptTopicProp->cScenario)); + } + else + { + strncpy (tmp->cTopic, ptTopicProp->cTopic, + strlen (ptTopicProp->cTopic)); + } + tmp->flag = ptTopicProp->flag; + tmp->next = NULL; + ptTopicList->tail->next = tmp; + ptTopicList->tail = tmp; + } + return 1; + } + else + { + return 2; + } +} + +int32_t wemq_topic_list_find_node (StWemqTopicList * ptTopicList, + StWemqTopicProp * ptTopicProp, + StWemqTopicProp ** pos) +{ + if (ptTopicList == NULL || ptTopicProp == NULL) + { + return -1; + } + + StWemqTopicProp *tmp = ptTopicList->next; + while (tmp != NULL) + { + if (tmp->flag == 0) + { + if ((strncmp + (tmp->cServiceId, ptTopicProp->cServiceId, + strlen (tmp->cServiceId)) == 0) + && + (strncmp + (tmp->cScenario, ptTopicProp->cScenario, + strlen (tmp->cScenario)) == 0)) + { + if (pos != NULL) + *pos = tmp; + return 1; + } + } + else + { + if (strncmp (tmp->cTopic, ptTopicProp->cTopic, strlen (tmp->cTopic)) == + 0) + { + if (pos != NULL) + *pos = tmp; + + return 1; + } + } + + tmp = tmp->next; + } + return -1; +} + +int32_t wemq_topic_list_del_node (StWemqTopicList * ptTopicList, + StWemqTopicProp * ptTopicProp) +{ + StWemqTopicProp *pos = NULL; + if (wemq_topic_list_find_node (ptTopicList, ptTopicProp, &pos) != 1) + { + return -1; + } + + StWemqTopicProp *tmp1 = pos; + StWemqTopicProp *tmp2 = ptTopicList->next; + if (tmp2 == tmp1) + { + ptTopicList->next = tmp1->next; + free (tmp1); + return 1; + } + + while ((tmp2->next != tmp1) && (tmp2->next != NULL)) + { + tmp2 = tmp2->next; + } + tmp2->next = tmp1->next; + free (tmp1); + return 1; +}