Train_Identify_arm/nvidia_ascend_engine/common_engine/DataUploadEngine/ResultToHttpSrvEngine.cpp

446 lines
17 KiB
C++
Raw Normal View History

2024-06-19 06:35:05 +00:00
#include "ResultToHttpSrvEngine.h"
#include "myutils.h"
ResultToHttpSrvEngine::ResultToHttpSrvEngine() {}
ResultToHttpSrvEngine::~ResultToHttpSrvEngine() {}
APP_ERROR ResultToHttpSrvEngine::Init()
{
strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0";
strUsername_ = MyYaml::GetIns()->GetStringValue("username");
strPassword_ = MyYaml::GetIns()->GetStringValue("password");
strURL_ = MyYaml::GetIns()->GetStringValue("gc_http_url");
strGetTokenURL_ = MyYaml::GetIns()->GetStringValue("gc_gettoken_url");
strImageSrv_ = MyYaml::GetIns()->GetPathValue("gc_image_srv");
strPoundNo_ = MyYaml::GetIns()->GetStringValue("atlas_poundno");
strFailSavePath_ = MyYaml::GetIns()->GetPathValue("gc_result_path") + "httpfailcontent.csv";
strFailSaveBakPath_ = MyYaml::GetIns()->GetPathValue("gc_result_path") + "httpfailcontent_bak.csv";
LogInfo << "ResultToHttpSrvEngine Init ok";
return APP_ERR_OK;
}
APP_ERROR ResultToHttpSrvEngine::DeInit()
{
LogDebug << "curl_easy_cleanup";
curl_easy_cleanup(pCurl_);
/* 这个处理移动到main中 防止多线程调用
LogDebug << "内存清理";
curl_global_cleanup();
*/
LogInfo << "ResultToHttpSrvEngine DeInit ok";
return APP_ERR_OK;
}
/**
* libcurl回调函数
* inParam : void *pBuffer
: size_t size
2024-06-19 06:41:40 +00:00
: size_t nmemb
2024-06-19 06:35:05 +00:00
* outParam: std::string &strResp
* return :
*/
size_t ResultToHttpSrvEngine::WriteCallBack(void *pBuffer, size_t size, size_t nmemb, std::string &strResp)
2024-06-19 06:41:40 +00:00
{
2024-06-19 06:35:05 +00:00
size_t sizes = size * nmemb;
std::string strTemp((char*)pBuffer, sizes);
strResp += strTemp;
return sizes;
}
/**
* http接口获取token
2024-06-19 06:41:40 +00:00
* inParam :
* outParam: std::string &strBladeAuth token信息
2024-06-19 06:35:05 +00:00
* return : true:; false:
*/
bool ResultToHttpSrvEngine::GetToken(std::string &strBladeAuth)
{
//1. 获得curl操作符
if (nullptr == pCurl_)
{
LogDebug<<"pCurl_ is null, invoke curl_easy_init";
pCurl_ = curl_easy_init();
if (nullptr == pCurl_)
{
LogError << "curl_easy_init failed !";
return false;
}
}
//2. 设置head, 和表单
//设置head信息
struct curl_slist *pHeaderList = nullptr;
pHeaderList = curl_slist_append(pHeaderList, "Authorization:Basic Y2xpZW50X2VudGVycHJpc2U6Y2xpZW50X2VudGVycHJpc2Vfc2VjcmV0");
//设置表单信息
curl_mime *pMultipart = curl_mime_init(pCurl_);
curl_mimepart *pPart = curl_mime_addpart(pMultipart);
curl_mime_name(pPart, "username");
curl_mime_data(pPart, strUsername_.c_str(), CURL_ZERO_TERMINATED);
pPart = curl_mime_addpart(pMultipart);
curl_mime_name(pPart, "password");
curl_mime_data(pPart, strPassword_.c_str(), CURL_ZERO_TERMINATED);
pPart = curl_mime_addpart(pMultipart);
curl_mime_name(pPart, "tenantId");
curl_mime_data(pPart, "000000", CURL_ZERO_TERMINATED);
pPart = curl_mime_addpart(pMultipart);
curl_mime_name(pPart, "grant_type");
curl_mime_data(pPart, "password", CURL_ZERO_TERMINATED);
curl_easy_setopt(pCurl_, CURLOPT_CONNECTTIMEOUT, 1); //连接超时(1s连接不上服务器返回超时)
curl_easy_setopt(pCurl_, CURLOPT_URL, strGetTokenURL_.c_str()); //设置url
curl_easy_setopt(pCurl_, CURLOPT_HTTPHEADER, pHeaderList); //设置报文头
curl_easy_setopt(pCurl_, CURLOPT_MIMEPOST, pMultipart); //设置表单
//curl_easy_setopt(pCurl_, CURLOPT_POSTFIELDS, strBody.c_str()); //设置post内容
//curl_easy_setopt(pCurl_, CURLOPT_POST, 1); //设置操作为POST(为非0表示post)
curl_easy_setopt(pCurl_, CURLOPT_WRITEFUNCTION, WriteCallBack); //设置回调函数
std::string strResponse;
curl_easy_setopt(pCurl_, CURLOPT_WRITEDATA, &strResponse); //设置回调参数
//3. 执行http请求
CURLcode res = curl_easy_perform(pCurl_);
curl_slist_free_all(pHeaderList); //清除headerlist
curl_mime_free(pMultipart); //清除curl_mime
curl_easy_reset(pCurl_); //重置curl
if (res != CURLE_OK)
{
LogError << " curl_easy_perform fail:" << curl_easy_strerror(res);
return false;
}
//4. 执行成功解析响应内容
Json::CharReaderBuilder readerBuilder;
std::shared_ptr<Json::CharReader> reader(readerBuilder.newCharReader());
Json::Value jvResponse;
JSONCPP_STRING errs;
if (!reader->parse(strResponse.data(), strResponse.data() + strResponse.size(), &jvResponse, &errs))
{
LogError << " response content fail " << strResponse;
return false;
}
LogDebug << "GetToken resp:" << strResponse;
strBladeAuth += jvResponse["token_type"].asString();
strBladeAuth += " ";
strBladeAuth += jvResponse["access_token"].asString();
return true;
}
/**
* http接口
* inParam : Json::Value &jvRequest
2024-06-19 06:41:40 +00:00
* outParam:
2024-06-19 06:35:05 +00:00
* return : true:; false:
*/
bool ResultToHttpSrvEngine::ResultToHttpSrv(Json::Value &jvRequest)
{
//获取token
std::string strBladeAuth("blade-auth:");
if (!GetToken(strBladeAuth))
{
LogError << "comeTime:" << jvRequest["comeTime"].asString() << " carriageOrder:" << jvRequest["carriageOrder"].asInt() << " GetToken fail ";
return false;
}
LogDebug << "strBladeAuth:" << strBladeAuth;
//1. 获得curl操作符
if (nullptr == pCurl_)
{
LogDebug<<"pCurl_ is null, invoke curl_easy_init";
pCurl_ = curl_easy_init();
if (nullptr == pCurl_)
{
LogError << "curl_easy_init failed !";
return false;
}
}
//2. 设置http请求信息
Json::StreamWriterBuilder jswBuilder;
std::string strRequest = Json::writeString(jswBuilder, jvRequest);
LogDebug << "to http:" << strRequest;
std::string strResponse;
struct curl_slist *pHeaderList = nullptr;
pHeaderList = curl_slist_append(pHeaderList, "Accept:application/json");
pHeaderList = curl_slist_append(pHeaderList, "Content-Type:application/json");
pHeaderList = curl_slist_append(pHeaderList, "charset:utf-8");
pHeaderList = curl_slist_append(pHeaderList, strBladeAuth.c_str());
curl_easy_setopt(pCurl_, CURLOPT_CONNECTTIMEOUT, 1); //连接超时(1s连接不上服务器返回超时)
curl_easy_setopt(pCurl_, CURLOPT_URL, strURL_.c_str()); //设置url
2024-06-19 06:41:40 +00:00
curl_easy_setopt(pCurl_, CURLOPT_HTTPHEADER, pHeaderList); //设置报文头
2024-06-19 06:35:05 +00:00
curl_easy_setopt(pCurl_, CURLOPT_POSTFIELDS, strRequest.c_str()); //设置post内容
curl_easy_setopt(pCurl_, CURLOPT_POST, 1); //设置操作为POST(为非0表示post)
curl_easy_setopt(pCurl_, CURLOPT_WRITEFUNCTION, WriteCallBack); //设置回调函数
curl_easy_setopt(pCurl_, CURLOPT_WRITEDATA, &strResponse); //设置回调参数
//3. 执行http请求
CURLcode res = curl_easy_perform(pCurl_);
curl_slist_free_all(pHeaderList); //清除headerlist
curl_easy_reset(pCurl_); //重置curl
if (res != CURLE_OK)
{
LogError << "comeTime:" << jvRequest["comeTime"].asString() << " carriageOrder:" << jvRequest["carriageOrder"].asInt()
<< " curl_easy_perform fail:" << curl_easy_strerror(res);
return false;
}
//4. 执行成功解析响应内容
LogInfo << "http resp:" << strResponse;
Json::CharReaderBuilder readerBuilder;
std::shared_ptr<Json::CharReader> reader(readerBuilder.newCharReader());
Json::Value jvResponse;
JSONCPP_STRING errs;
if (!reader->parse(strResponse.data(), strResponse.data() + strResponse.size(), &jvResponse, &errs))
{
2024-06-19 06:41:40 +00:00
LogError << "comeTime:" << jvRequest["comeTime"].asString() << " carriageOrder:" << jvRequest["carriageOrder"].asInt()
2024-06-19 06:35:05 +00:00
<< " response content fail " << strResponse;
return false;
}
if (!jvResponse["success"].asBool())
{
2024-06-19 06:41:40 +00:00
LogError << "comeTime:" << jvRequest["comeTime"].asString() << " carriageOrder:" << jvRequest["carriageOrder"].asInt()
2024-06-19 06:35:05 +00:00
<< " response fail";
return false;
}
2024-06-19 06:41:40 +00:00
LogInfo << "comeTime:" << jvRequest["comeTime"].asString() << " carriageOrder:" << jvRequest["carriageOrder"].asInt()
2024-06-19 06:35:05 +00:00
<< " post success";
return true;
}
/**
*
* inParam : N/A
* outParam: N/A
* return : N/A
*/
void ResultToHttpSrvEngine::DealHttpFailInfo()
{
//队列有待处理数据,则先不处理异常数据。
if (inputQueMap_[strPort0_]->getSize() > 0)
{
LogDebug << "have new data to process";
return;
}
//文件不存在不处理
if (access(strFailSavePath_.c_str(), F_OK) == -1)
{
LogDebug << "no exit file:" << strFailSavePath_;
return;
}
bool bAllSucc = true;
std::ifstream inFile(strFailSavePath_.c_str(), std::ios::in);
if (!inFile.is_open())
{
LogError << strFailSavePath_ << " open fail";
return;
}
int iDealCnt = 0;
std::string strLine;
while (getline(inFile, strLine))
{
Json::CharReaderBuilder jsrBuilder;
std::shared_ptr<Json::CharReader> reader(jsrBuilder.newCharReader());
Json::Value jvRequest;
JSONCPP_STRING errs;
if (!reader->parse(strLine.data(), strLine.data() + strLine.size(), &jvRequest, &errs))
{
LogError << "json parse fail content:" << strLine;
return;
}
/*
*/
if (inputQueMap_[strPort0_]->getSize() > 0)
{
LogDebug << "Abnormal data processing, have new data to process";
if (0 == iDealCnt)
{
LogDebug << "Abnormal data processing not start";
inFile.close();
return;
}
SaveHttpFailInfo(jvRequest, strFailSaveBakPath_);
bAllSucc = false;
continue;
}
iDealCnt++;
if (!ResultToHttpSrv(jvRequest))
{
LogError << "re http post err:" << strLine;
//SaveHttpFailInfo(jvRequest, strFailSaveBakPath_);
// bAllSucc = false;
continue;
}
}
inFile.close();
2024-06-19 06:41:40 +00:00
2024-06-19 06:35:05 +00:00
if(bAllSucc)
{
//都处理成功,文件删除
remove(strFailSavePath_.c_str());
}
else
{
//部分处理成功,重命名后再次被处理
rename(strFailSaveBakPath_.c_str(), strFailSavePath_.c_str());
}
}
/**
* http上传失败的信息
* inParam : Json::Value &jvRequest http失败信息
* : std::string &strFilePath
* outParam: N/A
* return : true();false()
*/
bool ResultToHttpSrvEngine::SaveHttpFailInfo(Json::Value &jvRequest, std::string &strFilePath)
{
std::ofstream outFile;
outFile.open(strFilePath, std::ios::app);
if (!outFile.is_open())
{
LogError << strFilePath << " open fail";
return false;
}
Json::StreamWriterBuilder jswBuilder;
jswBuilder["indentation"] = "";
std::string strRequest = Json::writeString(jswBuilder, jvRequest);
outFile << strRequest << std::endl;
outFile.close();
return true;
}
APP_ERROR ResultToHttpSrvEngine::Process()
{
int iRet = APP_ERR_OK;
if (0 == MyYaml::GetIns()->GetIntValue("gc_http_open"))
{
LogDebug << " gc_http_open value is 0";
return APP_ERR_OK;
}
while (!isStop_)
{
std::shared_ptr<void> pVoidData0 = nullptr;
inputQueMap_[strPort0_]->pop(pVoidData0);
if (nullptr == pVoidData0)
{
usleep(1000); //1ms
2024-06-19 06:41:40 +00:00
2024-06-19 06:35:05 +00:00
//无数据大于1分钟
iNoDataCnt_++;
if (iNoDataCnt_ > (60 * 1000))
{
DealHttpFailInfo();
iNoDataCnt_ = 0;
}
continue;
}
iNoDataCnt_ = 0;
std::shared_ptr<Train> pTrain = std::static_pointer_cast<Train>(pVoidData0);
ai_matrix::DataSourceConfig dataSourceConfig = MyYaml::GetIns()->GetDataSourceConfigById(pTrain->trainNum.iDataSource); //获取摄像机参数
char szCameraNo[4] = {0};
sprintf(szCameraNo, "%03d", pTrain->trainNum.iDataSource + 1);
char szNumImgPath[64] = {0}; //车号最优图片路径
if (!pTrain->trainNum.strBestImg.empty())
{
sprintf(szNumImgPath, "/%03d/%s", pTrain->trainNum.iDataSource + 1, pTrain->trainNum.strBestImg.c_str());
}
char szProImgPath[64] = {0}; //属性最优图片路径
if (!pTrain->trainPro.strBestImg.empty())
{
sprintf(szProImgPath, "/%03d/%s", pTrain->trainPro.iDataSource + 1, pTrain->trainPro.strBestImg.c_str());
}
// char szChkDateImgPath[64] = {0}; //定检期最优图片路径
// if (!pTrain->chkDate.strBestImg.empty())
// {
// sprintf(szChkDateImgPath, "%03d/%s", pTrain->chkDate.iDataSource + 1, pTrain->chkDate.strBestImg.c_str());
// }
// char szContainer1ImgPath[64] = {0}; //集装箱1最优图片路径
// if (!pTrain->container1.strBestImg.empty())
// {
// sprintf(szContainer1ImgPath, "%03d/%s", pTrain->container1.iDataSource + 1, pTrain->container1.strBestImg.c_str());
// }
// char szContainer2ImgPath[64] = {0}; //集装箱2最优图片路径
// if (!pTrain->container2.strBestImg.empty())
// {
// sprintf(szContainer2ImgPath, "%03d/%s", pTrain->container2.iDataSource + 1, pTrain->container2.strBestImg.c_str());
// }
std::string strTime = pTrain->strTrainName;
strTime = MyUtils::getins()->replace_all_distinct(strTime, std::string("-"), std::string(":"));
int iCategory = 0;
if (pTrain->trainNum.iTrainTypeId == 3)
{
iCategory = 0;
}
else if(pTrain->trainNum.iTrainTypeId == 2)
{
iCategory = 1;
}
else if (pTrain->trainNum.iTrainTypeId == 6)
{
iCategory = 2;
}
else if (pTrain->trainNum.iTrainTypeId == 0)
{
iCategory = 3;
}
//组装post信息
Json::Value jvRequest;
Json::Value jvSubObj;
jvSubObj["poundNo"] = strPoundNo_; // 股道号
jvRequest["trainParams"] = jvSubObj;
jvRequest["carriageType"] = pTrain->trainNum.strTrainType; // 车型
jvRequest["carriageNumber"] = pTrain->trainNum.strTrainNum; // 车厢号
jvRequest["carriageOrder"] = pTrain->iCarXH; // 车节号
jvRequest["cameraNumber"] = szCameraNo; // 摄像头编号
jvRequest["carriageTareweight"] = pTrain->trainPro.strSelf; // 皮重
jvRequest["carriageLoad"] = pTrain->trainPro.strLoad; // 载重
jvRequest["carriageVolume"] = pTrain->trainPro.strVolume; // 容积
jvRequest["carriageChangelength"] = pTrain->trainPro.strChange; // 换长
jvRequest["proImageName"] = strImageSrv_ + pTrain->strTrainDate + "/" + pTrain->strTrainName + szProImgPath; // 属性图片
jvRequest["numImageName"] = strImageSrv_ + pTrain->strTrainDate + "/" + pTrain->strTrainName + szNumImgPath; // 车号图片
jvRequest["comeTime"] = pTrain->strTrainDate + " " + strTime; // 来车时间
jvRequest["carriageCategory"] = iCategory; // 车厢类别:0敞车,1:漏洞矿车,2:平车,3:车头
jvRequest["isTheLast"] = pTrain->bIsEnd ? 1 : 0; // 是否最后一节: 0:否,1:是
jvRequest["startFrame"] = pTrain->iStartFrameId; //车厢开始帧
jvRequest["endFrame"] = pTrain->iEndFrameId; //车厢结束帧
jvRequest["skipFrame"] = dataSourceConfig.iSkipInterval;
jvRequest["collectTime"] = MyUtils::getins()->Stamp2Time(pTrain->i64EndTimeStamp, true);//车厢切分的时间 //跳帧
if (!ResultToHttpSrv(jvRequest))
{
// SaveHttpFailInfo(jvRequest, strFailSavePath_);
}
//列车结束后再次处理失败的信息
if (pTrain->bIsEnd)
{
DealHttpFailInfo();
}
}
return APP_ERR_OK;
}