/* * Example obtainting client stats from an E_CONNECT or E_STOP event */ void FmsAuthAdaptor::processStats(IFmsAuthEvent* pAev) { I64 statsHandle; FmsClientStats baseStats; if (!getI64Field(pAev, IFmsAuthEvent::F_CLIENT_STATS_HANDLE, statsHandle)) return; char* pAppName = getStringField(pAev, IFmsAuthEvent::F_APP_NAME); if (pAev->getType() == IFmsAuthEvent::E_CONNECT) { getStats(statsHandle, baseStats); // log data char buf[1024]; char hashKey[9]; memset(hashKey, 0, 9); memcpy(hashKey, &statsHandle, sizeof(statsHandle)); sprintf(buf, "client Stats Handle= %s, bytes_in= %f, bytes_out= %f\n", hashKey, static_cast<double>(baseStats.bytes_in), static_cast<double>(baseStats.bytes_out)); m_pFmsAuthServerContext->log(buf, IFmsServerContext::kInformation, false); } else if (pAev->getType() == IFmsAuthEvent::E_STOP) { getStats(statsHandle, baseStats); } }
COLORREF CppSQLite3Query::getColorField(int nField, COLORREF crNullValue /*= 0*/) { CString str = getStringField(nField); if (str.IsEmpty()) { return crNullValue; } else { return WizStringToColor(str); } }
void DatabasesCloner::_setAdminAsFirst(std::vector<BSONElement>& dbsArray) { auto adminIter = std::find_if(dbsArray.begin(), dbsArray.end(), [](BSONElement elem) { if (!elem.isABSONObj()) { return false; } auto bsonObj = elem.Obj(); std::string databaseName = bsonObj.getStringField("name"); return (databaseName == "admin"); }); if (adminIter != dbsArray.end()) { std::iter_swap(adminIter, dbsArray.begin()); } }
/* **************************************************************************** * * attributeType - * */ static std::string attributeType ( const std::string& tenant, const std::vector<std::string>& servicePathV, const std::string entityType, const std::string attrName ) { std::string idType = std::string("_id.") + ENT_ENTITY_TYPE; std::string idServicePath = std::string("_id.") + ENT_SERVICE_PATH; std::string attributeName = std::string(ENT_ATTRS) + "." + attrName; BSONObj query = BSON(idType << entityType << idServicePath << fillQueryServicePath(servicePathV) << attributeName << BSON("$exists" << true)); std::auto_ptr<DBClientCursor> cursor; std::string err; if (!collectionQuery(getEntitiesCollectionName(tenant), query, &cursor, &err)) { return ""; } while (cursor->more()) { BSONObj r; try { r = cursor->nextSafe(); } catch (const AssertionException &e) { // $err raised LM_E(("Runtime Error (assertion exception in nextSafe(): %s", e.what())); continue; } LM_T(LmtMongo, ("retrieved document: '%s'", r.toString().c_str())); /* It could happen that different entities within the same entity type may have attributes with the same name * but different types. In that case, one type (at random) is returned. A list could be returned but the * NGSIv2 operations only allow to set one type */ BSONObj attrs = getField(r, ENT_ATTRS).embeddedObject(); BSONObj attr = getField(attrs, attrName).embeddedObject(); return getStringField(attr, ENT_ATTRS_TYPE); } return ""; }
void Java_com_googlecode_eyesfree_textdetect_HydrogenTextDetector_nativeSetParameters( JNIEnv *env, jclass clazz, jlong nativePtr, jobject params) { if (DEBUG_MODE) LOGV(__FUNCTION__); HydrogenTextDetector *ptr = (HydrogenTextDetector *) nativePtr; HydrogenTextDetector::TextDetectorParameters *myParams = ptr->GetMutableParameters(); jclass paramClass = env->GetObjectClass(params); getStringField(env, paramClass, params, "out_dir", myParams->out_dir); myParams->debug = getBoolField(env, paramClass, params, "debug"); myParams->edge_tile_x = getIntField(env, paramClass, params, "edge_tile_x"); myParams->edge_tile_y = getIntField(env, paramClass, params, "edge_tile_y"); myParams->edge_thresh = getIntField(env, paramClass, params, "edge_thresh"); myParams->edge_avg_thresh = getIntField(env, paramClass, params, "edge_avg_thresh"); myParams->skew_enabled = getBoolField(env, paramClass, params, "skew_enabled"); myParams->skew_min_angle = getFloatField(env, paramClass, params, "skew_min_angle"); myParams->skew_sweep_range = getFloatField(env, paramClass, params, "skew_sweep_range"); myParams->skew_sweep_delta = getFloatField(env, paramClass, params, "skew_sweep_delta"); myParams->skew_sweep_reduction = getIntField(env, paramClass, params, "skew_sweep_reduction"); myParams->skew_search_reduction = getIntField(env, paramClass, params, "skew_search_reduction"); myParams->skew_search_min_delta = getFloatField(env, paramClass, params, "skew_search_min_delta"); myParams->single_min_aspect = getFloatField(env, paramClass, params, "single_min_aspect"); myParams->single_max_aspect = getFloatField(env, paramClass, params, "single_max_aspect"); myParams->single_min_area = getIntField(env, paramClass, params, "single_min_area"); myParams->single_min_density = getFloatField(env, paramClass, params, "single_min_density"); myParams->pair_h_ratio = getFloatField(env, paramClass, params, "pair_h_ratio"); myParams->pair_d_ratio = getFloatField(env, paramClass, params, "pair_d_ratio"); myParams->pair_h_dist_ratio = getFloatField(env, paramClass, params, "pair_h_dist_ratio"); myParams->pair_v_dist_ratio = getFloatField(env, paramClass, params, "pair_v_dist_ratio"); myParams->pair_h_shared = getFloatField(env, paramClass, params, "pair_h_shared"); myParams->cluster_width_spacing = getIntField(env, paramClass, params, "cluster_width_spacing"); myParams->cluster_shared_edge = getFloatField(env, paramClass, params, "cluster_shared_edge"); myParams->cluster_h_ratio = getFloatField(env, paramClass, params, "cluster_h_ratio"); myParams->cluster_min_blobs = getIntField(env, paramClass, params, "cluster_min_blobs"); myParams->cluster_min_aspect = getFloatField(env, paramClass, params, "cluster_min_aspect"); myParams->cluster_min_fdr = getFloatField(env, paramClass, params, "cluster_min_fdr"); myParams->cluster_min_edge = getIntField(env, paramClass, params, "cluster_min_edge"); myParams->cluster_min_edge_avg = getIntField(env, paramClass, params, "cluster_min_edge_avg"); }
void NetworkInterfaceIntegrationFixture::assertWriteError(StringData db, const BSONObj& cmd, ErrorCodes::Error reason, Milliseconds timeoutMillis) { RemoteCommandRequest request{ fixture().getServers()[0], db.toString(), cmd, BSONObj(), nullptr, timeoutMillis}; auto res = runCommandSync(request); ASSERT_OK(res.status); ASSERT_OK(getStatusFromCommandResult(res.data)); ASSERT(res.data["writeErrors"]); auto firstWriteError = res.data["writeErrors"].embeddedObject().firstElement().embeddedObject(); Status writeErrorStatus(ErrorCodes::Error(firstWriteError.getIntField("code")), firstWriteError.getStringField("errmsg")); ASSERT_EQ(reason, writeErrorStatus); }
COleDateTime CppSQLite3Query::getTimeField(int nField, time_t tNullValue /*= 0*/) { CString str = getStringField(nField); if (str.IsEmpty()) { if (0 == tNullValue) return WizGetCurrentTime(); else return COleDateTime(tNullValue); } else { return WizStringToDateTime(str); } }
void ParamItem::update() { double min = getDoubleField(1); double current = getDoubleField(2); double max = getDoubleField(3); Q_ASSERT(min <= max); Q_ASSERT(min <= current && current <= max); ui->paramName->setText(getStringField(0)); ui->MinLabel->setText(QString::number(min)); ui->CurrentValueEdit->setText(QString::number(current)); ui->MaxLabel->setText(QString::number(max)); int sliderCurrent = qRound64((current - min) / (max - min) * maxValue); Q_ASSERT(0 <= sliderCurrent && sliderCurrent <= maxValue); ui->paramSlider->setValue(sliderCurrent); }
int forOnAllTrade(lua_State *L) { if (!lua_istable(L, -1)) luaL_error(L, "OnAllTrade argument is not a table"); TradeData data; data.code = getStringField(L, "sec_code"); data.price = getNumberField(L, "price"); data.amount = (unsigned long) getNumberField(L, "qty"); data.trade_id = (unsigned long) getNumberField(L, "trade_num"); lua_getfield(L, -1, "datetime"); if (!lua_istable(L, -1)) { luaL_error(L, "datetime is not a table"); } int year = (int) getNumberField(L, "year"); int month = (int) getNumberField(L, "month"); int day = (int) getNumberField(L, "day"); int hour = (int) getNumberField(L, "hour"); int min = (int) getNumberField(L, "min"); int sec = (int) getNumberField(L, "sec"); int ms = (int) getNumberField(L, "ms"); //2015-11-06 18:44:59.473 if ( sprintf(data.dat_time, "%d-%.2d-%.2d %.2d:%.2d:%.2d:%.3d", year, month, day, hour, min, sec, ms) > dat_time_buf) luaL_error(L, "dat_time_buf overflow"); lua_pop(L, 1); //FORTS csv format for features: "code;contract;price;amount;dat_time;trade_id;Nosystem" printf("%s;;%f;%Iu;%s;%Iu;0\n", data.code, data.price, data.amount, data.dat_time, data.trade_id); fflush(stdout); return 0; }
const char* SqlStatement::ResultRow::getStringField(const char* szField, const char* szNullValue/*=""*/) const { return getStringField(fieldIndex(szField), szNullValue); }
void MyFmsNotifyEvent::notify() const { switch(m_pAev->getType()) { case IFmsAuthEvent::E_PLAY: { char* pAppName = getStringField(m_pAev, IFmsAuthEvent::F_APP_NAME); char* pAppInst = getStringField(m_pAev, IFmsAuthEvent::F_APP_INST); char* pAppUri = getStringField(m_pAev, IFmsAuthEvent::F_APP_URI); ///new prtmp fields I8 sValue; if (getI8Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP, sValue)) { bool isProtected = sValue != 0; } char* pCommonKeyPath = getStringField(m_pAev, IFmsAuthEvent::F_APP_PRTMP_COMMON_KEY_FILE); U32 u32Value; if (getU32Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP_VIDEO_ENC_LEVEL, u32Value)) { U32 videoEncyption = u32Value; } I32 iValue; if (getI32Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP_UPDATE_INTERVAL, iValue)) { I32 updateInterval = iValue; } if (getI8Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP_SWF_VERIFICATION, sValue)) { bool isPrtmpSwf = sValue != 0; } char* pWhiteListPath = getStringField(m_pAev, IFmsAuthEvent::F_APP_PRTMP_SWF_WHITELIST_FOLDER); //////// char* pClIp = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_IP); char* pClUri = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_URI); char* pClNewUri = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_REDIRECT_URI); char* pClVhost = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_VHOST); char* pClRef = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_REFERRER); char* pClPurl = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_PAGE_URL); char* pClAgent = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_USER_AGENT); char* pClRAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_READ_ACCESS); char* pClWAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_WRITE_ACCESS); char* pClAudioAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_AUDIO_SAMPLE_ACCESS); char* pClVideoAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_VIDEO_SAMPLE_ACCESS); char* pClProto = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_PROTO); char* pClUstem = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_URI_STEM); char* pStreamName = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME); char* pStreamType = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE); char* pStreamQuery = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_QUERY); char* pStreamPath = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_PATH); if (getI32Field(m_pAev, IFmsAuthEvent::F_CLIENT_AUDIO_CODECS, iValue)) { bool bADPCM = isADPCMSupported(iValue); } if (getI32Field(m_pAev, IFmsAuthEvent::F_CLIENT_VIDEO_CODECS, iValue)) { bool bVP6 = isVP6Supported(iValue); } if (getI32Field(m_pAev, IFmsAuthEvent::F_CLIENT_TYPE, iValue)) { bool bService = isService(iValue); } if (getI32Field(m_pAev, IFmsAuthEvent::F_STREAM_ID, iValue)) { I32 iStreamId = iValue; } float fValue; if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_LENGTH, fValue)) { float fLength = fValue; // in seconds } if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_POSITION, fValue)) { float iPosition = fValue; // in seconds } I64 lValue; if (getI64Field(m_pAev, IFmsAuthEvent::F_CLIENT_ID, lValue)) { I64 iClientId = lValue; } if (getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_SECURE, sValue)) { bool bSecure = sValue != 0; } if (getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_AMF_ENCODING, sValue)) { bool bAMF3 = isAMF3(sValue); } if (getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_READ_ACCESS_LOCK, sValue)) { bool bRead = sValue != 0; } if (getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_WRITE_ACCESS_LOCK, sValue)) { bool bWrite = sValue != 0; } if (getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_AUDIO_SAMPLE_ACCESS_LOCK, sValue)) { bool bAudioRead = sValue != 0; } if (getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_VIDEO_SAMPLE_ACCESS_LOCK, sValue)) { bool bVideoRead = sValue != 0; } if (getI8Field(m_pAev, IFmsAuthEvent::F_STREAM_RESET, sValue)) { bool bReset = sValue != 0; } if (getI8Field(m_pAev, IFmsAuthEvent::F_STREAM_IGNORE, sValue)) { bool bIgnore = sValue != 0; } } break; case IFmsAuthEvent::E_SEEK: { float fValue; if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_SEEK_POSITION, fValue)) { float fSeekTime = fValue; } // Disconnect Action example: disconnect the client that was // specified by the E_SEEK notify event FmsVariant field; if (m_pAev->getField(IFmsAuthEvent::F_CLIENT_ID, field) == IFmsAuthEvent::S_SUCCESS) { IFmsDisconnectAction* pAction = const_cast<IFmsAuthEvent*>(m_pAev)-> addDisconnectAction("Seek is not allowed. Blocked by adaptor"); pAction->setClientId(field); } } break; case IFmsAuthEvent::E_CODEC_CHANGE: { char* pAppName = getStringField(m_pAev, IFmsAuthEvent::F_APP_NAME); char* pAppInst = getStringField(m_pAev, IFmsAuthEvent::F_APP_INST); char* pAppUri = getStringField(m_pAev, IFmsAuthEvent::F_APP_URI); char* pClIp = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_IP); char* pClUri = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_URI); char* pClNewUri = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_REDIRECT_URI); char* pClVhost = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_VHOST); char* pClRef = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_REFERRER); char* pClPurl = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_PAGE_URL); char* pClAgent = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_USER_AGENT); char* pClRAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_READ_ACCESS); char* pClWAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_WRITE_ACCESS); char* pClAudioAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_AUDIO_SAMPLE_ACCESS); char* pClVideoAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_VIDEO_SAMPLE_ACCESS); char* pClProto = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_PROTO); char* pClUstem = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_URI_STEM); char* pStreamName = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME); char* pStreamType = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE); char* pStreamQuery = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_QUERY); char* pStreamPath = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_PATH); U16 fType; if (getU16Field(m_pAev, IFmsAuthEvent::F_STREAM_CODEC_TYPE, fType)) { U16 streamCodecType = fType; if (streamCodecType == kVIDEO_CODEC) { U16 fValue; if (getU16Field(m_pAev, IFmsAuthEvent::F_STREAM_CODEC, fValue)) { U16 streamCodecValue = fValue; if (streamCodecValue == VIDEO_CODEC_SORENSON) { // Disconnect Action example: Disallow clients trying // to publish content with the sorenson video codec. FmsVariant field; if (m_pAev->getField(IFmsAuthEvent::F_CLIENT_ID, field) == IFmsAuthEvent::S_SUCCESS) { IFmsDisconnectAction* pAction = const_cast<IFmsAuthEvent*>(m_pAev)-> addDisconnectAction("Sorenson is not allowed. Blocked by adaptor"); pAction->setClientId(field); } } } } } } break; case IFmsAuthEvent::E_RECORD_STOP: { char* pAppName = getStringField(m_pAev, IFmsAuthEvent::F_APP_NAME); char* pAppInst = getStringField(m_pAev, IFmsAuthEvent::F_APP_INST); char* pAppUri = getStringField(m_pAev, IFmsAuthEvent::F_APP_URI); char* pClIp = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_IP); char* pClUri = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_URI); char* pClNewUri = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_REDIRECT_URI); char* pClVhost = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_VHOST); char* pClRef = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_REFERRER); char* pClPurl = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_PAGE_URL); char* pClAgent = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_USER_AGENT); char* pClRAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_READ_ACCESS); char* pClWAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_WRITE_ACCESS); char* pClAudioAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_AUDIO_SAMPLE_ACCESS); char* pClVideoAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_VIDEO_SAMPLE_ACCESS); char* pClProto = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_PROTO); char* pClUstem = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_URI_STEM); char* pStreamName = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME); char* pStreamType = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE); char* pStreamQuery = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_QUERY); char* pStreamPath = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_PATH); float fValue; if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_RECORD_MAXSIZE, fValue)) { float recMaxSize = fValue; // in kilobytes } if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_RECORD_MAXDURATION, fValue)) { float recMaxDuration = fValue; // in seconds } } break; case IFmsAuthEvent::E_SWF_VERIFY_COMPLETE: { char* pClIp = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_IP); I8 version; // version of SWF verification getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_VERSION, version); I64 depth; // depth in the SWF file hashed getI64Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_DEPTH, depth); I32 ttl; // time to live of the SWF hash provided getI32Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_TTL, ttl); // digest provided to match against U8* buffer = getBufferField(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_DIGEST); // result of the attempted match-- see FmsAuthEvents.h enum // eSWFMatch for the meaning of this field I32 match; getI32Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_RESULT, match); std::stringstream stream; stream << "swf verification for client: " << std::string(pClIp) << " is complete, the result is: " << match; m_pFmsAuthServerContext->log(stream.str().c_str(), IFmsServerContext::kInformation, false); } break; case IFmsAuthEvent::E_APPSTART: case IFmsAuthEvent::E_APPSTOP: case IFmsAuthEvent::E_CONNECT: case IFmsAuthEvent::E_DISCONNECT: case IFmsAuthEvent::E_FILENAME_TRANSFORM: case IFmsAuthEvent::E_STOP: case IFmsAuthEvent::E_PAUSE: case IFmsAuthEvent::E_PUBLISH: case IFmsAuthEvent::E_UNPUBLISH: case IFmsAuthEvent::E_LOADSEGMENT: case IFmsAuthEvent::E_ACTION: case IFmsAuthEvent::E_RECORD: case IFmsAuthEvent::E_CLIENT_PAUSE: case IFmsAuthEvent::E_SWF_VERIFY: case IFmsAuthEvent::E_CLIENT_SEEK: case IFmsAuthEvent::E_START_TRANSMIT: case IFmsAuthEvent::E_STOP_TRANSMIT: case IFmsAuthEvent::E_MAXEVENT: break; } char buf[1024]; sprintf(buf, "Received notification type=%d id=%p\n", m_pAev->getType(), m_pAev); // log to the configured FMS log directory. If the third parameter is true, // also send the log to the system event log. m_pFmsAuthServerContext->log(buf, IFmsServerContext::kInformation, false); m_pFmsAuthServerContext->onNotify(m_pAev); }
void MyFmsAuthorizeEvent::authorize() { bool bAuthorized = true; // default authorization state switch(m_pAev->getType()) { case IFmsAuthEvent::E_APPSTART: { // only E_APPSTART allows changes to the following fields: // F_APP_PRTMP // F_APP_PRTMP_COMMON_KEY_FILE // F_APP_PRTMP_VIDEO_ENC_LEVEL // F_APP_PRTMP_UPDATE_INTERVAL // F_APP_PRTMP_SWF_VERIFICATION // F_APP_PRTMP_SWF_WHITELIST_FOLDER bool bSet; I8 sValue; if (getI8Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP, sValue)) { bSet = setI8Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP, sValue); } char* pCommonKeyPath = getStringField(m_pAev, IFmsAuthEvent::F_APP_PRTMP_COMMON_KEY_FILE); if (pCommonKeyPath) { bSet = setStringField(m_pAev, IFmsAuthEvent::F_APP_PRTMP_COMMON_KEY_FILE, pCommonKeyPath); } U32 uValue; if (getU32Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP_VIDEO_ENC_LEVEL, uValue)) { bSet = setU32Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP_VIDEO_ENC_LEVEL, uValue); } I32 iValue; if (getI32Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP_UPDATE_INTERVAL, iValue)) { bSet = setI32Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP_UPDATE_INTERVAL, iValue); } if (getI8Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP_SWF_VERIFICATION, sValue)) { bSet = setI8Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP_SWF_VERIFICATION, sValue); } char* pWhiteListPath = getStringField(m_pAev, IFmsAuthEvent::F_APP_PRTMP_SWF_WHITELIST_FOLDER); if (pWhiteListPath) { bSet = setStringField(m_pAev, IFmsAuthEvent::F_APP_PRTMP_SWF_WHITELIST_FOLDER, pWhiteListPath); } bAuthorized = true; } break; case IFmsAuthEvent::E_CONNECT: { // only E_CONNECT allows changes to the following fields: // F_CLIENT_AUDIO_SAMPLE_ACCESS // F_CLIENT_AUDIO_SAMPLE_ACCESS_LOCK // F_CLIENT_READ_ACCESS // F_CLIENT_READ_ACCESS_LOCK // F_CLIENT_VIDEO_SAMPLE_ACCESS // F_CLIENT_VIDEO_SAMPLE_ACCESS_LOCK // F_CLIENT_WRITE_ACCESS_LOCK // F_CLIENT_WRITE_ACCESS I8 iValue; if (getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_WRITE_ACCESS, iValue)) { setI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_WRITE_ACCESS, iValue); } // redirect connection example char* pUri = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_URI); if (pUri && !strcmp(pUri, "rtmp://localhost/streamtest")) { setStringField(m_pAev, IFmsAuthEvent::F_CLIENT_REDIRECT_URI, "rtmp://localhost:1935/streamtest"); bAuthorized = false; } // set DiffServ fields based on a client IP // char* pIp = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_IP); // if (pIp && !strcmp(pIp, "192.168.1.1")) { // set the DSCP bits and mask U8 m_diffServBits = 170; U8 m_diffServMask = 252; setU8Field(m_pAev, IFmsAuthEvent::F_CLIENT_DIFFSERV_BITS, m_diffServBits); setU8Field(m_pAev, IFmsAuthEvent::F_CLIENT_DIFFSERV_MASK, m_diffServMask); bAuthorized = true; } } break; case IFmsAuthEvent::E_PLAY: { char* pStreamName = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME); if (pStreamName) { setStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME, pStreamName); } char* pStreamType = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE); if (pStreamType) { setStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE, pStreamType); } char* pStreamQuery = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_QUERY); if (pStreamQuery) { setStringField(m_pAev, IFmsAuthEvent::F_STREAM_QUERY, pStreamQuery); } m_pFmsAuthServerContext->log(pStreamName, IFmsServerContext::kInformation, false); m_pFmsAuthServerContext->log(pStreamType, IFmsServerContext::kInformation, false); m_pFmsAuthServerContext->log(pStreamQuery, IFmsServerContext::kInformation, false); I8 iValue; if (getI8Field(m_pAev, IFmsAuthEvent::F_STREAM_RESET, iValue)) { // If iValue is 1 (true) the playlist will be reset and the // stream will be the only stream in the playlist; otherwise // 0 (false) means the stream will be added to the existing // playlist. setI8Field(m_pAev, IFmsAuthEvent::F_STREAM_RESET, iValue); } if (getI8Field(m_pAev, IFmsAuthEvent::F_STREAM_IGNORE, iValue)) { // If iValue is 1 (true) the stream timestamps will be ignored; // otherwise 0 (false) means the timestamps will be handled. setI8Field(m_pAev, IFmsAuthEvent::F_STREAM_IGNORE, iValue); } char* pStreamTransition = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TRANSITION); if (pStreamTransition && strlen(pStreamTransition)) { // MBR transition example if (!strcmp(pStreamTransition, "switch") || !strcmp(pStreamTransition, "swap")) { // get the old stream's properties char* pOldStreamName = getStringField(m_pAev, IFmsAuthEvent::F_OLD_STREAM_NAME); char* pOldStreamType = getStringField(m_pAev, IFmsAuthEvent::F_OLD_STREAM_TYPE); char* pOldStreamQuery = getStringField(m_pAev, IFmsAuthEvent::F_OLD_STREAM_QUERY); // if pOldStream is empty (optional for switch) current stream is in play // do we really want stream transition? { // no we do not allow transition // bAuthorized = false; // now transition will be turned off and old stream continue playing // break; } // doing nothing will execute transition mode as is // or you could modify transition by changing transition properties // set it to 1 to indicate they will be hooking up the stream, // but that it does not currently exist setI32Field(m_pAev, IFmsAuthEvent::F_STREAM_LIVE_PUBLISH_PENDING, 1); } // get the offset value if transition is set to offset mode for reconnect if (!strcmp(pStreamTransition, "resume")) { float fValue; if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_OFFSET, fValue)) { float offset = fValue; //offset value in seconds } } } else { // This is a regular play waiting for approval, which may be converted // into a play2 command by changing transition properties } } break; case IFmsAuthEvent::E_PUBLISH: { char* pStreamName = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME); if (pStreamName) { setStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME, pStreamName); } char* pStreamType = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE); if (pStreamType) { setStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE, pStreamType); } I32 iValue; if (getI32Field(m_pAev, IFmsAuthEvent::F_STREAM_PUBLISH_TYPE, iValue)) { // publish types: // 0 : record // 1 : append // 2 : appendWithGap // -1 : live setI32Field(m_pAev, IFmsAuthEvent::F_STREAM_PUBLISH_TYPE, iValue); } } break; case IFmsAuthEvent::E_FILENAME_TRANSFORM: { I64 iValue; if (getI64Field(m_pAev, IFmsAuthEvent::F_CLIENT_ID, iValue)) { // some fields are not eligible to be modified. The return // value will be false when trying to modify the F_CLIENT_ID. bool bSet = setI64Field(m_pAev, IFmsAuthEvent::F_CLIENT_ID, iValue); } char* pStreamName = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME); if (pStreamName) { // some fields are not eligible to be modified. The return // value will be false when trying to modify the F_STREAM_NAME. bool bSet = setStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME, pStreamName); } char* pStreamPath = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_PATH); if (pStreamPath) { setStringField(m_pAev, IFmsAuthEvent::F_STREAM_PATH, pStreamPath); } char* pStreamType = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE); if (pStreamType) { setStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE, pStreamType); } } break; case IFmsAuthEvent::E_PAUSE: { bAuthorized = false; // block all E_PAUSE events. float fValue; if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_PAUSE_TIME, fValue)) { float fPauseTime = fValue; // in seconds } I8 iValue; if (getI8Field(m_pAev, IFmsAuthEvent::F_STREAM_PAUSE, iValue)) { // 1 (true) means PAUSE // 0 (false) means UNPAUSE bool boolPause = iValue != 0; } if (getI8Field(m_pAev, IFmsAuthEvent::F_STREAM_PAUSE_TOGGLE, iValue)) { // 1 (true) means PAUSE_TOGGLE // 0 (false) means no PAUSE_TOGGLE was set bool boolPauseToggle = iValue != 0; } FmsVariant field; // Notify Action example: An IFmsNofifyAction is created to notify // server side action script (SSAS) of the E_PAUSE event by calling // the function name "method" in the script. In this example two // variables will be passed to "method" by calling addParam(field) // on the action. if (m_pAev->getField(IFmsAuthEvent::F_CLIENT_ID, field) == IFmsAuthEvent::S_SUCCESS) { I64 clientId = field.i64; IFmsNotifyAction* pAction = m_pAev->addNotifyAction("Notified by adaptor"); pAction->setClientId(field); const char mtd[] = "method"; field.setString(reinterpret_cast<I8*>(const_cast<char*>(mtd))); pAction->setMethodName(field); // create and insert a U16 "12345" as the first parameter field.setU16(12345); pAction->addParam(field); // create and insert clientId as a double as the second parameter field.setDouble((double)clientId); pAction->addParam(field); // Note: SSAS does not work with I64 or Buffer variants // field.setI64(clientId); // pAction->addParam(field); // incorrect } } break; case IFmsAuthEvent::E_SEEK: { bAuthorized = false; // block all E_SEEK events float fValue; if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_SEEK_POSITION, fValue)) { // Modification of the seek position example: // fValue + 3; will add 3 seconds to the initial seek posistion float fSeekTime = fValue; // value in seconds setFloatField(m_pAev, IFmsAuthEvent::F_STREAM_SEEK_POSITION, fSeekTime); } } break; case IFmsAuthEvent::E_LOADSEGMENT: { // bAuthorized = false; // block all E_LOADSEGMENT events // E_LOADSEGMENT is a read only event that substitutes E_PLAY on // FMS Origin servers for recorded streams. I64 iValue; if (getI64Field(m_pAev, IFmsAuthEvent::F_SEGMENT_START, iValue)) { I64 iStart = iValue; // in bytes } if (getI64Field(m_pAev, IFmsAuthEvent::F_SEGMENT_END, iValue)) { I64 iEnd = iValue; // in bytes } } break; case IFmsAuthEvent::E_RECORD: { // bAuthorized = false; // block all E_RECORD events float fValue; if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_RECORD_MAXSIZE, fValue)) { float recMaxSize = fValue; // in kilobytes setFloatField(m_pAev, IFmsAuthEvent::F_STREAM_RECORD_MAXSIZE, recMaxSize); } if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_RECORD_MAXDURATION, fValue)) { float recMaxDuration = fValue; // in seconds setFloatField(m_pAev, IFmsAuthEvent::F_STREAM_RECORD_MAXDURATION, recMaxDuration); } } break; case IFmsAuthEvent::E_SWF_VERIFY: { // SWF Verification example: // kAuthorizeSwfVerification is assigned false by default. The // target SWF file must be updated for this to work. if(kAuthorizeSwfVerification) { I8 swfvVersion = 0; if(getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_VERSION, swfvVersion)) { std::stringstream stream; stream << "Swf verification version is " << static_cast<int>(swfvVersion); m_pFmsAuthServerContext->log(stream.str().c_str(), IFmsServerContext::kInformation, false); } I64 swfvDepth; if(getI64Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_DEPTH, swfvDepth)) { I32 swfvTTL; if(getI32Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_TTL, swfvTTL)) { swfvTTL /= 2; setI32Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_TTL, swfvTTL); } U8 digest[kSHA256DigestLen]; // Target a real SWF file instead of sample.swf hashSwfFileAtDepth("C:\\sample.swf", swfvDepth, digest); FmsVariant field; field.setBuffer(digest, kSHA256DigestLen); m_pAev->setField(IFmsAuthEvent::F_CLIENT_SWFV_DIGEST, field); } } } break; case IFmsAuthEvent::E_APPSTOP: case IFmsAuthEvent::E_DISCONNECT: case IFmsAuthEvent::E_STOP: case IFmsAuthEvent::E_UNPUBLISH: case IFmsAuthEvent::E_ACTION: case IFmsAuthEvent::E_CODEC_CHANGE: case IFmsAuthEvent::E_RECORD_STOP: case IFmsAuthEvent::E_CLIENT_PAUSE: case IFmsAuthEvent::E_SWF_VERIFY_COMPLETE: case IFmsAuthEvent::E_CLIENT_SEEK: case IFmsAuthEvent::E_START_TRANSMIT: case IFmsAuthEvent::E_STOP_TRANSMIT: case IFmsAuthEvent::E_MAXEVENT: break; } IFmsAuthServerContext2::AuthFailureDesc* desc = NULL; if(!bAuthorized) { desc = new IFmsAuthServerContext2::AuthFailureDesc("Blocked by auth adaptor", IFmsAuthServerContext2::kDefaultStatus, -1); } char buf[1024]; const char* const action = bAuthorized ? "approved" : "rejected"; sprintf(buf, "Received dddd authorization type=%d id=%p %s\n", m_pAev->getType(), m_pAev, action); char tlog[1024]; sprintf(tlog,"bb\n"); m_pFmsAuthServerContext->log(tlog, IFmsServerContext::kInformation, false) // log to the configured FMS log directory. If the third parameter is true, // also send the log to the system event log. m_pFmsAuthServerContext->log(buf, IFmsServerContext::kInformation, false); m_pFmsAuthServerContext->onAuthorize(m_pAev, bAuthorized, desc); delete desc; }
/* **************************************************************************** * * mongoEntityTypes - */ HttpStatusCode mongoEntityTypes ( EntityTypeVectorResponse* responseP, const std::string& tenant, const std::vector<std::string>& servicePathV, std::map<std::string, std::string>& uriParams ) { unsigned int offset = atoi(uriParams[URI_PARAM_PAGINATION_OFFSET].c_str()); unsigned int limit = atoi(uriParams[URI_PARAM_PAGINATION_LIMIT].c_str()); std::string detailsString = uriParams[URI_PARAM_PAGINATION_DETAILS]; bool details = (strcasecmp("on", detailsString.c_str()) == 0)? true : false; bool reqSemTaken = false; LM_T(LmtMongo, ("Query Entity Types")); LM_T(LmtPagination, ("Offset: %d, Limit: %d, Details: %s", offset, limit, (details == true)? "true" : "false")); reqSemTake(__FUNCTION__, "query types request", SemReadOp, &reqSemTaken); /* Compose query based on this aggregation command: * * db.runCommand({aggregate: "entities", * pipeline: [ {$match: { "_id.servicePath": /.../ } }, * {$project: {_id: 1, "attrNames": 1} }, * {$project: { "attrNames" * {$cond: [ {$eq: [ "$attrNames", [ ] ] }, [null], "$attrNames"] } * } * }, * {$unwind: "$attrNames"}, * {$group: {_id: "$_id.type", attrs: {$addToSet: "$attrNames"}} }, * {$sort: {_id: 1} } * ] * }) * * The $cond part is hard... more information at http://stackoverflow.com/questions/27510143/empty-array-prevents-document-to-appear-in-query * As a consequence, some "null" values may appear in the resulting attrs vector, which are pruned by the result processing logic. * * FIXME P6: in the future, we can interpret the collapse parameter at this layer. If collapse=true so we don't need attributes, the * following command can be used: * * db.runCommand({aggregate: "entities", pipeline: [ {$group: {_id: "$_id.type"} }]}) * * * */ BSONObj result; // // Building the projection part of the query that includes types that have no attributes // See bug: https://github.com/telefonicaid/fiware-orion/issues/686 // BSONArrayBuilder emptyArrayBuilder; BSONArrayBuilder nulledArrayBuilder; nulledArrayBuilder.appendNull(); // We are using the $cond: [ .. ] and not the $cond: { .. } one, as the former is the only one valid in MongoDB 2.4 BSONObj projection = BSON( "$project" << BSON( ENT_ATTRNAMES << BSON( "$cond" << BSON_ARRAY( BSON("$eq" << BSON_ARRAY(S_ATTRNAMES << emptyArrayBuilder.arr()) ) << nulledArrayBuilder.arr() << S_ATTRNAMES ) ) ) ); BSONObj cmd = BSON("aggregate" << COL_ENTITIES << "pipeline" << BSON_ARRAY( BSON("$match" << BSON(C_ID_SERVICEPATH << fillQueryServicePath(servicePathV))) << BSON("$project" << BSON("_id" << 1 << ENT_ATTRNAMES << 1)) << projection << BSON("$unwind" << S_ATTRNAMES) << BSON("$group" << BSON("_id" << CS_ID_ENTITY << "attrs" << BSON("$addToSet" << S_ATTRNAMES))) << BSON("$sort" << BSON("_id" << 1)) ) ); std::string err; if (!runCollectionCommand(composeDatabaseName(tenant), cmd, &result, &err)) { responseP->statusCode.fill(SccReceiverInternalError, err); reqSemGive(__FUNCTION__, "query types request", reqSemTaken); return SccOk; } // Processing result to build response LM_T(LmtMongo, ("aggregation result: %s", result.toString().c_str())); std::vector<BSONElement> resultsArray = getField(result, "result").Array(); if (resultsArray.size() == 0) { responseP->statusCode.fill(SccContextElementNotFound); reqSemGive(__FUNCTION__, "query types request", reqSemTaken); return SccOk; } /* Another strategy to implement pagination is to use the $skip and $limit operators in the * aggregation framework. However, doing so, we don't know the total number of results, which can * be needed in the case of details=on (using that approach, we need to do two queries: one to get * the count and other to get the actual results with $skip and $limit, in the same "transaction" to * avoid incoherence between both if some entity type is created or deleted in the process). * * However, considering that the number of types will be small compared with the number of entities, * the current approach seems to be ok */ for (unsigned int ix = offset; ix < MIN(resultsArray.size(), offset + limit); ++ix) { BSONObj resultItem = resultsArray[ix].embeddedObject(); EntityType* entityType = new EntityType(getStringField(resultItem, "_id")); std::vector<BSONElement> attrsArray = getField(resultItem, "attrs").Array(); entityType->count = countEntities(tenant, servicePathV, entityType->type); if (!attrsArray[0].isNull()) { for (unsigned int jx = 0; jx < attrsArray.size(); ++jx) { /* This is where NULL elements in the resulting attrs vector are pruned */ if (attrsArray[jx].isNull()) { continue; } /* Note that we need and extra query() to the database (inside attributeType() function) to get each attribute type. * This could be unefficient, specially if the number of attributes is large */ std::string attrType = attributeType(tenant, servicePathV, entityType->type , attrsArray[jx].str()); ContextAttribute* ca = new ContextAttribute(attrsArray[jx].str(), attrType, ""); entityType->contextAttributeVector.push_back(ca); } } responseP->entityTypeVector.push_back(entityType); } char detailsMsg[256]; if (responseP->entityTypeVector.size() > 0) { if (details) { snprintf(detailsMsg, sizeof(detailsMsg), "Count: %d", (int) resultsArray.size()); responseP->statusCode.fill(SccOk, detailsMsg); } else { responseP->statusCode.fill(SccOk); } } else { if (details) { snprintf(detailsMsg, sizeof(detailsMsg), "Number of types: %d. Offset is %d", (int) resultsArray.size(), offset); responseP->statusCode.fill(SccContextElementNotFound, detailsMsg); } else { responseP->statusCode.fill(SccContextElementNotFound); } } reqSemGive(__FUNCTION__, "query types request", reqSemTaken); return SccOk; }
LPCTSTR CppSQLite3Query::getStringField(LPCTSTR szField, LPCTSTR szNullValue/*=""*/) { int nField = fieldIndex(szField); return getStringField(nField, szNullValue); }
StatusWith<ShardType> ShardingCatalogManager::_validateHostAsShard( OperationContext* opCtx, std::shared_ptr<RemoteCommandTargeter> targeter, const std::string* shardProposedName, const ConnectionString& connectionString) { auto swCommandResponse = _runCommandForAddShard( opCtx, targeter.get(), NamespaceString::kAdminDb, BSON("isMaster" << 1)); if (swCommandResponse.getStatus() == ErrorCodes::IncompatibleServerVersion) { return swCommandResponse.getStatus().withReason( str::stream() << "Cannot add " << connectionString.toString() << " as a shard because its binary version is not compatible with " "the cluster's featureCompatibilityVersion."); } else if (!swCommandResponse.isOK()) { return swCommandResponse.getStatus(); } // Check for a command response error auto resIsMasterStatus = std::move(swCommandResponse.getValue().commandStatus); if (!resIsMasterStatus.isOK()) { return resIsMasterStatus.withContext(str::stream() << "Error running isMaster against " << targeter->connectionString().toString()); } auto resIsMaster = std::move(swCommandResponse.getValue().response); // Fail if the node being added is a mongos. const std::string msg = resIsMaster.getStringField("msg"); if (msg == "isdbgrid") { return {ErrorCodes::IllegalOperation, "cannot add a mongos as a shard"}; } // Extract the maxWireVersion so we can verify that the node being added has a binary version // greater than or equal to the cluster's featureCompatibilityVersion. We expect an incompatible // binary node to be unable to communicate, returning an IncompatibleServerVersion error, // because of our internal wire version protocol. So we can safely invariant here that the node // is compatible. long long maxWireVersion; Status status = bsonExtractIntegerField(resIsMaster, "maxWireVersion", &maxWireVersion); if (!status.isOK()) { return status.withContext(str::stream() << "isMaster returned invalid 'maxWireVersion' " << "field when attempting to add " << connectionString.toString() << " as a shard"); } if (serverGlobalParams.featureCompatibility.getVersion() > ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo40) { // If the cluster's FCV is 4.2, or upgrading to / downgrading from, the node being added // must be a v4.2 binary. invariant(maxWireVersion == WireVersion::LATEST_WIRE_VERSION); } else { // If the cluster's FCV is 4.0, the node being added must be a v4.0 or v4.2 binary. invariant(serverGlobalParams.featureCompatibility.getVersion() == ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo40); invariant(maxWireVersion >= WireVersion::LATEST_WIRE_VERSION - 1); } // Check whether there is a master. If there isn't, the replica set may not have been // initiated. If the connection is a standalone, it will return true for isMaster. bool isMaster; status = bsonExtractBooleanField(resIsMaster, "ismaster", &isMaster); if (!status.isOK()) { return status.withContext(str::stream() << "isMaster returned invalid 'ismaster' " << "field when attempting to add " << connectionString.toString() << " as a shard"); } if (!isMaster) { return {ErrorCodes::NotMaster, str::stream() << connectionString.toString() << " does not have a master. If this is a replica set, ensure that it has a" << " healthy primary and that the set has been properly initiated."}; } const std::string providedSetName = connectionString.getSetName(); const std::string foundSetName = resIsMaster["setName"].str(); // Make sure the specified replica set name (if any) matches the actual shard's replica set if (providedSetName.empty() && !foundSetName.empty()) { return {ErrorCodes::OperationFailed, str::stream() << "host is part of set " << foundSetName << "; " << "use replica set url format " << "<setname>/<server1>,<server2>, ..."}; } if (!providedSetName.empty() && foundSetName.empty()) { return {ErrorCodes::OperationFailed, str::stream() << "host did not return a set name; " << "is the replica set still initializing? " << resIsMaster}; } // Make sure the set name specified in the connection string matches the one where its hosts // belong into if (!providedSetName.empty() && (providedSetName != foundSetName)) { return {ErrorCodes::OperationFailed, str::stream() << "the provided connection string (" << connectionString.toString() << ") does not match the actual set name " << foundSetName}; } // Is it a config server? if (resIsMaster.hasField("configsvr")) { return {ErrorCodes::OperationFailed, str::stream() << "Cannot add " << connectionString.toString() << " as a shard since it is a config server"}; } // If the shard is part of a replica set, make sure all the hosts mentioned in the connection // string are part of the set. It is fine if not all members of the set are mentioned in the // connection string, though. if (!providedSetName.empty()) { std::set<std::string> hostSet; BSONObjIterator iter(resIsMaster["hosts"].Obj()); while (iter.more()) { hostSet.insert(iter.next().String()); // host:port } if (resIsMaster["passives"].isABSONObj()) { BSONObjIterator piter(resIsMaster["passives"].Obj()); while (piter.more()) { hostSet.insert(piter.next().String()); // host:port } } if (resIsMaster["arbiters"].isABSONObj()) { BSONObjIterator piter(resIsMaster["arbiters"].Obj()); while (piter.more()) { hostSet.insert(piter.next().String()); // host:port } } for (const auto& hostEntry : connectionString.getServers()) { const auto& host = hostEntry.toString(); // host:port if (hostSet.find(host) == hostSet.end()) { return {ErrorCodes::OperationFailed, str::stream() << "in seed list " << connectionString.toString() << ", host " << host << " does not belong to replica set " << foundSetName << "; found " << resIsMaster.toString()}; } } } std::string actualShardName; if (shardProposedName) { actualShardName = *shardProposedName; } else if (!foundSetName.empty()) { // Default it to the name of the replica set actualShardName = foundSetName; } // Disallow adding shard replica set with name 'config' if (actualShardName == NamespaceString::kConfigDb) { return {ErrorCodes::BadValue, "use of shard replica set with name 'config' is not allowed"}; } // Retrieve the most up to date connection string that we know from the replica set monitor (if // this is a replica set shard, otherwise it will be the same value as connectionString). ConnectionString actualShardConnStr = targeter->connectionString(); ShardType shard; shard.setName(actualShardName); shard.setHost(actualShardConnStr.toString()); shard.setState(ShardType::ShardState::kShardAware); return shard; }
/* **************************************************************************** * * mongoConnect - * * Default value for writeConcern == 1 (0: unacknowledged, 1: acknowledged) */ static DBClientBase* mongoConnect ( const char* host, const char* db, const char* rplSet, const char* username, const char* passwd, bool multitenant, int writeConcern, double timeout ) { std::string err; DBClientBase* connection = NULL; LM_T(LmtMongo, ("Connection info: dbName='%s', rplSet='%s', timeout=%f", db, rplSet, timeout)); bool connected = false; int retries = RECONNECT_RETRIES; if (strlen(rplSet) == 0) { // Setting the first argument to true is to use autoreconnect connection = new DBClientConnection(true); // // Not sure of how to generalize the following code, // given that DBClientBase class doesn't have a common connect() method (surprisingly) // for (int tryNo = 0; tryNo < retries; ++tryNo) { if ( ((DBClientConnection*)connection)->connect(host, err)) { connected = true; break; } if (tryNo == 0) { LM_E(("Database Startup Error (cannot connect to mongo - doing %d retries with a %d microsecond interval)", retries, RECONNECT_DELAY)); } else { LM_T(LmtMongo, ("Try %d connecting to mongo failed", tryNo)); } usleep(RECONNECT_DELAY * 1000); // usleep accepts microseconds } } else { LM_T(LmtMongo, ("Using replica set %s", rplSet)); // autoReconnect is always on for DBClientReplicaSet connections. std::vector<std::string> hostTokens; int components = stringSplit(host, ',', hostTokens); std::vector<HostAndPort> rplSetHosts; for (int ix = 0; ix < components; ix++) { LM_T(LmtMongo, ("rplSet host <%s>", hostTokens[ix].c_str())); rplSetHosts.push_back(HostAndPort(hostTokens[ix])); } connection = new DBClientReplicaSet(rplSet, rplSetHosts, timeout); // // Not sure of to generalize the following code, // given that DBClientBase class hasn't a common connect() method (surprisingly) // for (int tryNo = 0; tryNo < retries; ++tryNo) { if ( ((DBClientReplicaSet*)connection)->connect()) { connected = true; break; } if (tryNo == 0) { LM_E(("Database Startup Error (cannot connect to mongo - doing %d retries with a %d microsecond interval)", retries, RECONNECT_DELAY)); } else { LM_T(LmtMongo, ("Try %d connecting to mongo failed", tryNo)); } usleep(RECONNECT_DELAY * 1000); // usleep accepts microseconds } } if (connected == false) { LM_E(("Database Error (connection failed, after %d retries: '%s')", retries, err.c_str())); return NULL; } LM_I(("Successful connection to database")); // // WriteConcern // mongo::WriteConcern writeConcernCheck; // // In the legacy driver, writeConcern is no longer an int, but a class. // We need a small conversion step here // mongo::WriteConcern wc = writeConcern == 1 ? mongo::WriteConcern::acknowledged : mongo::WriteConcern::unacknowledged; setWriteConcern(connection, wc, &err); getWriteConcern(connection, &writeConcernCheck, &err); if (writeConcernCheck.nodes() != wc.nodes()) { LM_E(("Database Error (Write Concern not set as desired)")); return NULL; } LM_T(LmtMongo, ("Active DB Write Concern mode: %d", writeConcern)); /* Authentication is different depending if multiservice is used or not. In the case of not * using multiservice, we authenticate in the single-service database. In the case of using * multiservice, it isn't a default database that we know at contextBroker start time (when * this connection function is invoked) so we authenticate on the admin database, which provides * access to any database */ if (multitenant) { if (strlen(username) != 0 && strlen(passwd) != 0) { if (!connectionAuth(connection, "admin", std::string(username), std::string(passwd), &err)) { return NULL; } } } else { if (strlen(db) != 0 && strlen(username) != 0 && strlen(passwd) != 0) { if (!connectionAuth(connection, std::string(db), std::string(username), std::string(passwd), &err)) { return NULL; } } } /* Get mongo version with the 'buildinfo' command */ BSONObj result; std::string extra; runCollectionCommand(connection, "admin", BSON("buildinfo" << 1), &result, &err); std::string versionString = std::string(getStringField(result, "version")); if (!versionParse(versionString, mongoVersionMayor, mongoVersionMinor, extra)) { LM_E(("Database Startup Error (invalid version format: %s)", versionString.c_str())); return NULL; } LM_T(LmtMongo, ("mongo version server: %s (mayor: %d, minor: %d, extra: %s)", versionString.c_str(), mongoVersionMayor, mongoVersionMinor, extra.c_str())); return connection; }
const char* CppSQLite3Query::getStringField(const char* szField, const char* szNullValue/*=""*/) { int nField = fieldIndex(szField); return getStringField(nField, szNullValue); }
StatusWith<std::set<NamespaceString>> RollbackImpl::_namespacesForOp(const OplogEntry& oplogEntry) { NamespaceString opNss = oplogEntry.getNamespace(); OpTypeEnum opType = oplogEntry.getOpType(); std::set<NamespaceString> namespaces; // No namespaces for a no-op. if (opType == OpTypeEnum::kNoop) { return std::set<NamespaceString>(); } // CRUD ops have the proper namespace in the operation 'ns' field. if (opType == OpTypeEnum::kInsert || opType == OpTypeEnum::kUpdate || opType == OpTypeEnum::kDelete) { return std::set<NamespaceString>({opNss}); } // If the operation is a command, then we need to extract the appropriate namespaces from the // command object, as opposed to just using the 'ns' field of the oplog entry itself. if (opType == OpTypeEnum::kCommand) { auto obj = oplogEntry.getObject(); auto firstElem = obj.firstElement(); // Does not handle 'applyOps' entries. invariant(oplogEntry.getCommandType() != OplogEntry::CommandType::kApplyOps, "_namespacesForOp does not handle 'applyOps' oplog entries."); switch (oplogEntry.getCommandType()) { case OplogEntry::CommandType::kRenameCollection: { // Add both the 'from' and 'to' namespaces. namespaces.insert(NamespaceString(firstElem.valuestrsafe())); namespaces.insert(NamespaceString(obj.getStringField("to"))); break; } case OplogEntry::CommandType::kDropDatabase: { // There is no specific namespace to save for a drop database operation. break; } case OplogEntry::CommandType::kDbCheck: case OplogEntry::CommandType::kConvertToCapped: case OplogEntry::CommandType::kEmptyCapped: { // These commands do not need to be supported by rollback. 'convertToCapped' should // always be converted to lower level DDL operations, and 'emptycapped' is a // testing-only command. std::string message = str::stream() << "Encountered unsupported command type '" << firstElem.fieldName() << "' during rollback."; return Status(ErrorCodes::UnrecoverableRollbackError, message); } case OplogEntry::CommandType::kCreate: case OplogEntry::CommandType::kDrop: case OplogEntry::CommandType::kCreateIndexes: case OplogEntry::CommandType::kDropIndexes: case OplogEntry::CommandType::kCollMod: { // For all other command types, we should be able to parse the collection name from // the first command argument. try { auto cmdNss = CommandHelpers::parseNsCollectionRequired(opNss.db(), obj); namespaces.insert(cmdNss); } catch (const DBException& ex) { return ex.toStatus(); } break; } case OplogEntry::CommandType::kApplyOps: default: // Every possible command type should be handled above. MONGO_UNREACHABLE } }
/* **************************************************************************** * * mongoUpdateContextAvailabilitySubscription - */ HttpStatusCode mongoUpdateContextAvailabilitySubscription ( UpdateContextAvailabilitySubscriptionRequest* requestP, UpdateContextAvailabilitySubscriptionResponse* responseP, Format notifyFormat, const std::string& tenant ) { bool reqSemTaken; LM_T(LmtMongo, ("Update Context Subscription, notifyFormat: '%s'", formatToString(notifyFormat))); reqSemTake(__FUNCTION__, "ngsi9 update subscription request", SemWriteOp, &reqSemTaken); /* Look for document */ BSONObj sub; std::string err; OID id; if (!safeGetSubId(requestP->subscriptionId, &id, &(responseP->errorCode))) { reqSemGive(__FUNCTION__, "ngsi9 update subscription request (mongo assertion exception)", reqSemTaken); if (responseP->errorCode.code == SccContextElementNotFound) { std::string details = std::string("invalid OID format: '") + requestP->subscriptionId.get() + "'"; alarmMgr.badInput(clientIp, details); } else // SccReceiverInternalError { LM_E(("Runtime Error (exception getting OID: %s)", responseP->errorCode.details.c_str())); } return SccOk; } if (!collectionFindOne(getSubscribeContextAvailabilityCollectionName(tenant), BSON("_id" << id), &sub, &err)) { reqSemGive(__FUNCTION__, "ngsi9 update subscription request (mongo db exception)", reqSemTaken); responseP->errorCode.fill(SccReceiverInternalError, err); return SccOk; } if (sub.isEmpty()) { responseP->errorCode.fill(SccContextElementNotFound); reqSemGive(__FUNCTION__, "ngsi9 update subscription request (no subscriptions found)", reqSemTaken); return SccOk; } /* We start with an empty BSONObjBuilder and process requestP for all the fields that can * be updated. I don't like too much this strategy (I would have preferred to start with * a copy of the original document, then modify as neded, but this doesn't seem to be easy * using the API provide by the Mongo C++ driver) * * FIXME: a better implementation strategy could be doing an findAndModify() query to do the * update, so detecting if the document was not found, instead of using findOne() + update() * with $set operation. One operations to MongoDb. vs two operations. */ BSONObjBuilder newSub; /* Entities (mandatory) */ BSONArrayBuilder entities; for (unsigned int ix = 0; ix < requestP->entityIdVector.size(); ++ix) { EntityId* en = requestP->entityIdVector[ix]; if (en->type == "") { entities.append(BSON(CASUB_ENTITY_ID << en->id << CASUB_ENTITY_ISPATTERN << en->isPattern)); } else { entities.append(BSON(CASUB_ENTITY_ID << en->id << CASUB_ENTITY_TYPE << en->type << CASUB_ENTITY_ISPATTERN << en->isPattern)); } } newSub.append(CASUB_ENTITIES, entities.arr()); /* Attributes (always taken into account) */ BSONArrayBuilder attrs; for (unsigned int ix = 0; ix < requestP->attributeList.size(); ++ix) { attrs.append(requestP->attributeList[ix]); } newSub.append(CASUB_ATTRS, attrs.arr()); /* Duration (optional) */ if (requestP->duration.isEmpty()) { newSub.append(CASUB_EXPIRATION, getField(sub, CASUB_EXPIRATION).numberLong()); } else { long long expiration = getCurrentTime() + requestP->duration.parse(); newSub.append(CASUB_EXPIRATION, expiration); LM_T(LmtMongo, ("New subscription expiration: %l", expiration)); } /* Reference is not updatable, so it is appended directly */ newSub.append(CASUB_REFERENCE, getStringField(sub, CASUB_REFERENCE)); int count = sub.hasField(CASUB_COUNT) ? getIntField(sub, CASUB_COUNT) : 0; /* The hasField check is needed due to lastNotification/count could not be present in the original doc */ if (sub.hasField(CASUB_LASTNOTIFICATION)) { newSub.append(CASUB_LASTNOTIFICATION, getIntField(sub, CASUB_LASTNOTIFICATION)); } if (sub.hasField(CASUB_COUNT)) { newSub.append(CASUB_COUNT, count); } /* Adding format to use in notifications */ newSub.append(CASUB_FORMAT, std::string(formatToString(notifyFormat))); /* Update document in MongoDB */ if (!collectionUpdate(getSubscribeContextAvailabilityCollectionName(tenant), BSON("_id" << OID(requestP->subscriptionId.get())), newSub.obj(), false, &err)) { reqSemGive(__FUNCTION__, "ngsi9 update subscription request (mongo db exception)", reqSemTaken); responseP->errorCode.fill(SccReceiverInternalError, err); return SccOk; } /* Send notifications for matching context registrations */ processAvailabilitySubscription(requestP->entityIdVector, requestP->attributeList, requestP->subscriptionId.get(), getStringField(sub, CASUB_REFERENCE), notifyFormat, tenant); /* Duration is an optional parameter, it is only added in the case they * was used for update */ if (!requestP->duration.isEmpty()) { responseP->duration = requestP->duration; } responseP->subscriptionId = requestP->subscriptionId; reqSemGive(__FUNCTION__, "ngsi9 update subscription request", reqSemTaken); return SccOk; }
const char* CSQLite3Query::getStringField(const char* pszField, const char* pszNullValue) { int iField = fieldIndex(pszField); return getStringField(iField, pszNullValue); }
const std::string SqliteQuery::getStringField(const std::string &fieldName, const std::string &nullValue) { int fieldIndex = getFieldIndexByName(fieldName); return getStringField(fieldIndex, nullValue); }