mongoBackend ライブラリ
- イントロダクション
- リクエスト処理モジュール- mongoUpdateContext(SR) および- mongoNotifyContext(SR)
- mongoQueryContext(SR)
- mongoQueryTypes(SR および SR2)
- mongoCreateSubscription(SR2)
- mongoUpdateSubscription(SR2)
- mongoGetSubscriptions(SR2)
- mongoUnsubscribeContext(SR および SR2)
- mongoSubscribeContext(SR)
- mongoUpdateContextSubscription(SR)
- mongoRegisterContext(SR) および- mongoNotifyContextAvailability(SR)
- mongoDiscoverContextAvailability(SR)
- mongoSubscribeContextAvailability(SR)
- mongoUpdateContextAvailabilitySubscription(SR)
- mongoUnsubscribeContextAvailability(SR)
- mongoRegistrationGet(SR2)
- mongoRegistrationCreate(SR2)
- mongoRegistrationDelete(SR2)
 
- コネクション・プール管理
- DB インタラクションに関連するロー・レベルのモジュール
- 特定目的のモジュール
- MongoGlobalモジュール
イントロダクション
mongoBackend ライブラリは、すべてのデータベースとの対話が行われる場所です。それ以上に、Orion Context Broker が公開するさまざまなオペレーションの実際の処理の大部分が行われます。ある意味では、それは Orion の "脳" のようなものです。
このライブラリのエントリ・ポイントは次のとおりです :
- serviceRoutines と serviceRoutinesV2。これらは最も重要なエントリ・ポイントです
- 初期化ルーチンやヘルパーメソッドなど他の場所からの他のエントリ・ポイント
このライブラリは、MongoDB C++ driver を大量に使用し、データベースに操作を送信し、BSONデータ (これらの操作で使用される基本的な構造体のデータ・タイプ) を処理します。ライブラリの仕組みを理解するには、このドライバに精通している必要があります。
このライブラリは、キャッシュ・ライブラリ (サブスクリプション・キャッシュが有効な場合、つまり、グローバルの bool 変数 noCache に false が設定されている場合)にも2つの異なる方法で関連しています :
- サブスクリプション・キャッシュの内容を変更するコンテキストの作成/変更/削除モジュール
- サブスクリプションをトリガするためにサブスクリプション・キャッシュをチェックするエンティティの作成/更新ロジック
サブスクリプション・キャッシュはコンテキストのサブスクリプションにのみ適用されます。コンテキスト・アベイラビリティのサブスクリプションは、まったくキャッシュを使用しません。
このライブラリに含まれるさまざまなモジュールは、次のセクションで分析されます。
リクエスト処理モジュール
これらのモジュールは、さまざまな Context Broker のリクエストを実装します。これらは、サービス・ルーチン・ライブラリの、serviceRoutines またはserviceRoutinesV2 ライブラリのいずれかによってリクエスト処理フロー全体の中で呼び出されます。次のサブセクションでは、各モジュールについて説明します。SR はモジュールが serviceRoutines から呼び出されたことを意味し、SR2 はモジュールが serviceRoutineV2 から呼び出されたことを意味します。両方のライブラリからモジュールが呼び出されないことに注意してください。
このセクションでは、いくつかの他のリクエスト処理モジュールと高度に結合された共通の機能を提供する、MongoCommonRegister および MongoCommonUpdate モジュールについても説明します。特に : 
- MongoCommonRegisterは、- mongoRegisterContextおよび- mongoNotifyContextAvailabilityモジュールに共通の機能を提供します
- MongoCommonUpdateは、- mongoUpdateContextおよび- mongoNotifyContextモジュールに共通の機能を提供します
mongoUpdateContext(SR) および mongoNotifyContext(SR)
mongoUpdateContext モジュールは、ヘッダファイル lib/mongoBackend/mongoUpdateContext.h で定義された mongoUpdateContext() によって更新コンテキスト操作処理ロジックのエントリ・ポイントを提供しますが、mongoNotifyContext モジュールは、 ヘッダファイル lib/ mongoBackend/mongoNotifyContext.hに定義されている mongoNotifyContext() によってコンテキスト通知処理ロジックを呼び出します。しかし、コンテキスト通知は "APPEND" アクション・タイプの更新コンテキストと同じ方法で処理されるので、mongoUpdateContext() と mongoNotifyContext() は基本的に  processContextElement() (実際の作業を行うのは  MongoCommonUpdate モジュールの単一の外部関数) のラッパー関数の最後にあります。
このモジュールの実行フローは、明確にするために5つの異なるサブケースに基づいて記述されているいくつかの条件に依存します :
- ケース1 : アクション・タイプが "UPDATE "または "REPLACE" であり、エンティティが見つかった場合
- ケース2 : アクション・タイプが "UPDATE" または "REPLACE" であり、エンティティが見つからない場合
- ケース3 : アクション・タイプが "APPEND" または "APPEND_STRICT" で、エンティティが見つかった場合
- ケース4 : アクション・タイプが "APPEND" または "APPEND_STRICT" で、エンティティが見つからない場合
- ケース5 : アクション・タイプは、エンティティの一部の属性を部分的に削除するための "DELETE" です
- ケース6 : アクション・タイプは、エンティティを削除する "DELETE" です
mongoUpdateContext() は6つすべてのケースに適用されますが、mongoNotifyContext() はケース3と4にのみ適用されます。
ケース1 : アクション・タイプが "UPDATE" または "REPLACE" であり、エンティティが見つかった場合。
MB-01: エンティティが見つかった、mongoUpdate UPDATE/REPLACE のケース
- mongoUpdateContext()はサービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (書き込みモード) (ステップ2)。詳細については、このドキュメントを参照してください
- ループの中では、processContextElement()が、着信リクエストの各Entityオブジェクトに対して呼び出されます (ステップ3)
- 事前の条件チェックの後、processContextElement()は個々のエンティティを処理します。まず、そのエンティティに対応するエンティティが、connectionOperationsモジュールでcollectionQuery()を使ってデータベース内で検索されます (ステップ4と5)。エンティティが見つかったとしましょう (ステップ6)
- 実行フローは、エンティティ更新の実行を担当する updateEntity()に渡されます (ステップ7)。updateEntity()は順番にエンティティへの属性を処理するためにフローをprocessContextAttributeVector()に渡します (ステップ8)
- processContextAttributeVector()は、エンティティ内の個々の属性を処理するための- updateContextAttributeItem()を呼び出すループを含んでいます (ステップ9)。後でこの処理を実装するために使用された戦略を詳しく説明します
- 属性の処理が完了すると、 processContextAttributeVector()はaddTriggeredSubscriptions()を呼び出して更新オペレーションによってトリガーされたサブスクリプションを検出します (ステップ10)。これについては後で詳しく説明します
- 最後に、データベース内の実体を実際に更新するために、connectionOperationsモジュール内でcollectionUpdate()を呼び出してコントロールをupdateEntity()に返します (ステップ11と12)
- 次のステップは、更新オペレーションによってトリガされた通知を送信することです。これは processSubscriptions()によって行われます(ステップ13)。これに関する詳細は (図表MD-01) を参照してください
- 最後に、searchContextProviders()が呼び出されて、データベース内に見つからなかったエンティティの各属性に対して適切なコンテキスト・プロバイダを見つけます (ステップ14)。この情報は、コンテキスト・プロバイダのドキュメント で説明されているように、更新処理をコンテキスト・プロバイダに転送するために、呼び出し側のサービス・ルーチンによって使用されます。詳細は、図 MD-02 のsearchContextProviders()です。
- ステップ2でリクエスト・セマフォが取得された場合は、リクエスト・セマフォが戻される前に解放されます (ステップ15)
ケース2 : アクション・タイプが "UPDATE" または "REPLACE" であり、エンティティが見つからない場合
MB-02: エンティティが見つからない場合の、mongoUpdate UPDATE/REPLACE のケース
- mongoUpdateContext()はサービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (書き込みモード) (ステップ2)。詳細については、このドキュメントを参照してください
- ループの中では、processContextElement()が、着信リクエストの各Entityオブジェクト (要するにエンティティ) に対して呼び出されます (ステップ3)
- 前提条件のチェックの後、processContextElement()は個々のエンティティを処理します。まず、そのエンティティに対応するエンティティが、connectionOperationsモジュールでcollectionQuery()を使ってデータベース内で検索されます (ステップ4と5)。エンティティが見つからないと仮定しましょう (ステップ6)
- searchContextProviders()は、エンティティの適切なコンテキスト・プロバイダを見つけるために呼び出されます (ステップ7)。この情報は、コンテキスト・プロバイダのドキュメントで説明されているように、コール・サービス・ルーチンが更新オペレーションをコンテキスト・プロバイダに転送するために使用されます。詳細は、図 MD-02 の- searchContextProviders()実装を参照してください
- リクエスト・セマフォがステップ2で取得された場合、リクエスト・セマフォは戻される前に解放されます (ステップ8)
ケース3 : アクション・タイプが "APPEND" または "APPEND_STRICT" で、エンティティが見つかった場合
MB-03: エンティティが見つかった場合の mongoUpdate APPEND/APPEND_STRICT のケース
- mongoUpdateContext()または- mongoNotifyContext()はサービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエストセマフォが取られます (書き込みモード) (ステップ2)。詳細については、このドキュメントを参照してください
- ループの中では、processContextElement()が着信リクエストの各Entityオブジェクト (要するにエンティティ) に対して呼び出されます (ステップ3)
- 前提条件のチェックの後、processContextElement()は個々のエンティティを処理します。まず、そのエンティティに対応するエンティティが、connectionOperationsモジュールでcollectionQuery()を使ってデータベース内で検索されます (ステップ4と5)。エンティティが見つかったとしましょう (ステップ6)
- 実行フローは、エンティティ更新の実行を担当する updateEntity()に渡されます (ステップ7)updateEntity()は、エンティティの属性を処理するために、フローをprocessContextAttributeVector()に渡します(ステップ8)
- processContextAttributeVector()は、ループ内で- appendContextAttributeItem()を呼び出して、エンティティの個々の属性を処理します (ステップ9)。後でこの処理を実装するために使用された戦略に関する詳細を説明します
- 属性の処理が完了すると、processContextAttributeVector()はaddTriggeredSubscriptions()を呼び出して更新オペレーションによってトリガーされたサブスクリプションを検出します (ステップ10)。これについては後で詳しく説明します
- コントロールが updateEntity()に返されると、connectionOperationsモジュールのcollectionUpdate()が呼び出されて、データベースの実体を実際に更新します (ステップ11と12)
- 次のステップは、更新オペレーションによってトリガされた通知を送信することです。これは  processSubscriptions()によって行われます (ステップ13)。これに関する詳細は、図 MD-01 を参照してください
- ステップ2でリクエスト・セマフォが取得された場合、リクエスト・セマフォは戻される前に解放されます (ステップ14)
ケース4 : アクション・タイプが"APPEND"または"APPEND_STRICT"で、エンティティが見つからない場合
MB-04: 新しいエンティティの場合での mongoUpdate APPEND/APPEND_STRICT のケース
- mongoUpdateContext()または- mongoNotifyContext()はサービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (書き込みモード) (ステップ2)。詳細については、このドキュメントを参照してください
- ループの中では、processContextElement()が着信リクエストの各Entityオブジェクト (要するにエンティティ)に対して呼び出されます (ステップ3)
- 前提条件のチェックの後、processContextElement()は個々のエンティティを処理します。まず、そのエンティティに対応するエンティティが、connectionOperationsモジュールでcollectionQuery()を使ってデータベース内で検索されます (ステップ4と5)。エンティティが見つからないと仮定しましょう (ステップ6)
- 実行フローは、エンティティの作成を担当する createEntity()に渡されます(ステップ7)。データベース内の実体の実際の作成は、connectionOperationsモジュールのcollectionInsert()によって行われます (ステップ8と9)
- 制御は processContextElement()に返され、更新オペレーションによってトリガーされたサブスクリプションを検出するためにaddTriggeredSubscriptions()を呼び出します (ステップ10)。これについては後で詳しく説明します
- 次のステップは、 processSubscriptions()を呼び出すことによって、更新オペレーションによってトリガーされた通知を送信することです (ステップ11)。これに関する詳細は、図 MD-01 を参照してください
- リクエスト・セマフォがステップ2で取得された場合は、リクエスト・セマフォが戻される前に解放されます (ステップ12)
ケース5 : アクション・タイプは、エンティティの一部の属性を部分的に削除するための "DELETE" です
MB-05: エンティティを削除しない mongoUpdate DELETE
- mongoUpdateContext()は、サービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyにしたがって、リクエスト・セマフォが取られます (書き込みモード) (ステップ2)。詳細については、このドキュメントを参照してください
- ループでは、processContextElement()が着信リクエストの各Entityオブジェクト (要するにエンティティ) に対して呼び出されます (ステップ3)
- 前提条件のチェックの後、processContextElement()は個々のエンティティを処理します。まず、そのエンティティに対応するエンティティは、connectionOperationsモジュールのcollectionQuery()を呼び出すことによってデータベース内で検索されます (ステップ4と5)。エンティティが見つかったとしましょう (ステップ6)
- 実行フローは、エンティティ更新の実行を担当する updateEntity()に渡されます(ステップ7)。updateEntity()は、エンティティの属性を処理するために、processContextAttributeVector()にフローを渡します (ステップ8)
- processContextAttributeVector()はエンティティ内の個々の属性に対するループで- deleteContextAttributeItem()を呼び出します(ステップ9)。後でこの処理を実装するために使用された戦略に関する詳細を説明します
- 属性の処理が完了すると、processContextAttributeVector()は、更新オペレーション (ステップ10) によってトリガーされたサブスクリプションを検出するためにaddTriggeredSubscriptions()を呼び出します。これについては後で詳しく説明します
- コントロールが updateEntity()に返されると、connectionOperationsモジュールのcollectionUpdate()が呼び出され、データベース内のエンティティを更新します (ステップ11と12)
- 次のステップは、processSubscriptions()を呼び出すことによって、更新オペレーションによって引き起こされた通知を送信することです (ステップ13)。これに関する詳細は、図 MD-01 を参照してください
- ステップ2でリクエスト・セマフォが取得された場合、リクエスト・セマフォは戻される前に解放されます (ステップ14)
ケース6 : アクション・タイプは、エンティティを削除する "DELETE" です
MB-06: エンティティを削除する mongoUpdate DELETE
- mongoUpdateContext()はサービスルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (書き込みモード) (ステップ2)。詳細については、このドキュメントを参照してください
- ループの中では、processContextElement()が着信リクエストの各Entityオブジェクト (要するにエンティティ) に対して呼び出されます (ステップ3)
- 前提条件のチェックの後、processContextElement()は個々のエンティティを処理します。まず、そのエンティティに対応するエンティティは、connectionOperationsモジュールでcollectionQuery()を呼び出すことによってデータベース内で検索されます (ステップ4と5)。エンティティが見つかったとしましょう (ステップ6)
- 実行フローは、エンティティ更新の実行を担当する updateEntity()に渡されます (ステップ7)。updateEntity()は実際のエンティティの削除を行うためにremoveEntity()にフローを渡します (ステップ8)
- removeEntity()は、実際にデータベース内のエンティティを削除するために、- connectionOperationsモジュール内で- collectionRemove()を呼び出します (ステップ9と10)
- ステップ2でリクエスト・セマフォが取得された場合、リクエスト・セマフォは戻される前に解放されます (ステップ11)
次に、上でで説明したいくつかのケースに共通する実装の側面について説明します。
エンティティの更新を実装するために processContextAttributeVector() で使用される戦略に関して、この関数は、データベースのエンティティに適用される変更の "delta" を保持するいくつかの変数を持っています、特に :
- toSet:- $setオペレータを使って、データベースのエンティティの- attrsフィールドに追加または更新をする必要がある属性
- toUnset:- $unsetオペレータを使って、データベース内のエンティティの- attrsフィールドから削除する必要のある属性
- toPush:- $addToSetオペレータ と- $eachオペレータ を使って、データベース内のエンティティ- attrsNameフィールド (属性名のリスト) に追加する必要がある属性
- toPull:- $pullAllオペレータを使って、データベース内の- attrsNameフィールド (属性名のリスト) から削除する必要のある属性
- locAttrと- geoJsonは、エンティティに関連するジオロケーション情報の変更 (データベースのエンティティ- locationフィールド) に関連しています
- dateExpirationと- dateExpirationInPayloadは、一時的なエンティティ (データベース内のエンティティ- expDateフィールド) に関連する TTL 有効期限情報の変更に関連しています
この更新は、同じエンティティに対するデータベース内で、同じ CB プロセス内の異なるリクエスト・スレッドによって、または異なるエンティティ間で異なるリクエスト・スレッドによって、更新が同時に実行されることがあるため、 attrs および attrsName 全体を設定するのではなく、"delta" に基づいています。あるスレッドによって設定された attrs/attrsName は 他のスレッドの attrs/attrsName を破壊する可能性があります。
これらの変数は、出力パラメータとして updateEntity() に返され、データベースのエンティティ更新オペレーションで使用されます。上記の図を参照してください。
toSet, toUnset などを満たすために processContextAttributeVector() は着信エンティティの属性を処理します。各属性処理の実行は、属性ごとの処理関数に委譲されます。
- updateContextAttributeItem()、アクション・タイプが UPDATE または REPLACE の場合。- updateAttribute()はヘルパー関数として内部的に使用されます。データベースの属性情報と着信エンティティをマージするために- mergeAttrInfo()を使用します
- appendContextAttributeItem()、アクション・タイプが APPEND または APPEND_STRICT の場合- appendAttribute()は内部的にヘルパー関数として使用され、属性がエンティティに既に存在し、実際の追加でない場合は、ボールを- updateAttribute()に渡します
- deleteContextAttributeItem()、アクション・タイプがDELETEの場合。- deleteAttribute()はヘルパー関数として内部的に使用されます
更新プロセス中に、新しいエンティティを作成する場合や既存のエンティティを更新する場合は、コンテキスト・サブスクリプションがトリガされるため、通知が送信されます。これを有効にするために、更新ロジックはトリガーされたサブスクリプションを保持するマップ  subsToNotify を保持します。addTriggeredSubscriptions() は新しいサブスクリプションをマップに追加する役割を担いますが、subsToNotify マップの内容に基づいてプロセスが終了すると、processSubscriptions() は通知を送信します。上記の図のさまざまな実行フローの場合、 addTriggeredSubscriptions() と processSubscriptions()の両方の呼び出しが表示されます。
- 
addTriggeredSubscriptions()。実際には、この関数には2つのバージョンがあります。addTriggeredSubscriptions()自体は単なるディスパッチャです。サブスクリプション・キャッシュを使用して特定のエンティティの変更がサブスクリプションをトリガするかどうかをチェックする_withCache()バージョンと、チェックを行うためにデータベースのcsubsコレクションをチェックする_noCache()です。 明らかに、使用されるバージョンは、サブスクリプション・キャッシュが有効かどうか、すなわちグローバルなnoCacheブール変数の値によって異なります。_withCache()バージョンでは、サブスクリプション・キャッシュ・セマフォを取得または提供する必要があります。詳細はこのドキュメントを参照してください
- 
processSubscriptions()。subsToNotifyマップとは別に、この関数のもう1つの重要なパラメータは、notifyCerPです。これは、送信する通知を記入するために使用されるコンテキスト要素レスポンス (CER) への参照です。新しいエンティティの場合、この CER は、更新リクエストの着信エンティティの内容から構築されます。既存のエンティティを更新する場合には、ロジックは、CER で始まり、toSet,toUnsetなどのフィールドが構築されると同時に更新されます。言い換えれば、CE 属性が処理されている間、ロジックは常に更新された CER を保持します。updateContextAttributeItem()とupdateContextAttributeItem()で使用されるupdateAttrInNotifyCer()とdeleteContextAttributeItem()で使用されるdeleteAttrInNotifyCer()は、このタスクを行うのに使われるヘルパー関数です。これに関する詳細は以下のシーケンス図に示されています。
MD-01: processSubscriptions() 機能の詳細
- processSubscriptions()がいくつかの場所から呼び出されます(ステップ1)。図 MB-01, MB-03, MB-04 および MB-05 を参照してください。トリガされた個々のサブスクリプションは、- processOnChangeConditionForUpdateContext()を呼び出すことでループで処理されます
- processOnChangeConditionForUpdateContext()が呼び出され (ステップ2)、Notifierオブジェクト (ngsiNotify ライブラリ) を使用して通知を送信します (ステップ3)。詳細は図 NF-01 と NF-03 に記載されています
- 次のステップは、通知が実際に送信された場合にのみ実行されます。キャッシュの使用状況に応じて:- サブスクリプション・キャッシュが使用されていない場合、データベースの最後の通知時間とカウントは connectionOperationsモジュールのcollectionUpdate()を使ってデータベース内で更新されます (ステップ4と5)
- サブスクリプション・キャッシュが使用されている場合、サブスクリプションはサブスクリプション・キャッシュから  subCacheItemLookup()を呼び出して取得されます (ステップ7)。次に、最後の通知時間とカウントがサブスクリプション・キャッシュで変更されます。次のサブスクリプション・キャッシュの最新表示時にデータベースに統合されます。詳細はこのドキュメントを参照してください。サブスクリプション・キャッシュへのアクセスは、サブスクリプション・キャッシュ・セマフォによって保護されます。サブスクリプション・キャッシュ・セマフォは、それぞれステップ6と8で取得され、解放されます。詳細はこのドキュメントを参照してください。
 
- サブスクリプション・キャッシュが使用されていない場合、データベースの最後の通知時間とカウントは 
最後に、アクション・タイプ "UPDATE/REPLACE" の場合、コンテキスト更新のロジックは、コンテキスト・プロバイダ情報を有するローカル・データベース内の存在しないエンティティ/属性について "ギャップを埋める" ことができる。これは searchContextProviders() で行われます。詳細は以下のシーケンス図に示されています。
MD-02: searchContextProviders() 機能の詳細
- 4つの可能なフローの1つから searchContextProviders()が呼び出されます (ステップ1)。図 MB-01, MB-02, MB-03 および MB-05 を参照してください。searchContextProviders()は、processContextAttributeVector()が失敗した場合 (つまりエンティティが実際にローカルで変更されていないことを意味します)、updateEntity()から呼び出すことができるので注意してください。コンテキスト・プロバイダを検索することは意味があります
- 少なくとも一つの属性で foundフラグがfalseに設定されている場合、MongoGlobalモジュールでregistrationsQuery()を呼び出すことで、特定の属性 (つまり、"EA" 形式) に基づいて一致するレジストレーションを検索します (ステップ2)。この関数はconnectionOperationsモジュールのcollectionRangedQuery()を使ってデータベースを検索します (ステップ3と4)
- 次に、一致するレジストレーションで見つからない属性を埋めるために MongoGlobalモジュールのfillContextProviders()が呼び出されます (ステップ5)
- 少なくとも1つの属性で foundフラグがfalseに設定されている場合は、新しいルック・アップ・ラウンドが行われます。今回は、エンティティ全体を検索します (つまり、"E-null" 形式)。再度、registrationsQuery()が使われます(ステップ6)。この関数は、connectionOperationsモジュールのcollectionRangedQuery()を使ってデータベースを検索します (ステップ7と8)
- 次に、一致した新しいレジストレーションで、見つからない属性を埋めることを試みるために、MongoGlobalモジュールのfillContextProviders()が再び呼び出されます (ステップ9)
mongoQueryContext (SR)
mongoQueryContextは、コンテキストのクエリ・オペレーションのロジックをカプセル化します。
ヘッダ・ファイルには、 QueryContextRequest オブジェクトを入力パラメータとして使用し、QueryContextResponse を出力パラメータとして使用する mongoQueryContext() という関数だけが含まれています。その目的は、リクエスト・オブジェクトとローカル検索された情報のエンティティと、データベース内に存在する呼び出し元の serviceRoutine の転送ロジックで使用されるコンテキスト・プロバイダへの "ポインタ" のレジストレーションに基づいてレスポンス・オブジェクトを構築することです。
詳細は以下のシーケンス図に示されています。
MB-07: mongoQueryContext
- mongoQueryContext()は、サービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (読み取りモード) (ステップ2)。詳細については、このドキュメントを参照してください
- 実行フローは MongoGlobalモジュールのentitiesQuery()に渡されます (ステップ3)
- entitiesQuery()は基本的にデータベース内のエンティティ (管理ドキュメントのデータベース・モデルの一部として記述されている- entitiesコレクション) を検索します。この関数の詳細は、- MongoGlobalモジュールのセクションを参照してください。データベース内の実際のクエリを実行するために、- connectionOperationsモジュールの- collectionRangedQuery()に応じています (ステップ4,5,6)。データベース内のクエリの後、- found属性フラグ (詳細はソースコードを参照してください) を使用して、関数の一部が結果に注釈を付けて、呼び出し側の関数によって行われたコンテキスト・プロバイダの検索に役立ちます。結果は、出力パラメータとして、- ContextElementResponseVectorオブジェクトで提供されます
- ステップ7〜11は、コンテキスト・プロバイダのルックアップに関連し、データベースにエンティティが見つからなかった場合にのみ実行されます
- MongoGlobalモジュール(ステップ7)で- registrationsQuery()を呼び出すことで、特定の属性 (つまり、"E-A" 形式)に基づいて一致するレジストレーションを検索します。この関数は- connectionOperationsモジュールの- collectionRangedQuery()を使ってデータベースを検索します (ステップ8と9)
- processGenericEntities()はジェネリック・エンティティに対応するコンテキスト・プロバイダを追加するために呼び出されます (ステップ10)
- ジェネリック・エンティティに対するループが実装され、addContextProviders()を使ってそのようなエンティティごとにコンテキスト・プロバイダを追加します (ステップ11)
- ステップ12〜17は、少なくとも1つの属性に foundフラグがfalseに設定されている場合にのみ実行されます
- MongoGlobalモジュール (ステップ12) で- registrationsQuery()を呼び出すことで、特定の属性 (つまり、"E-A" 形式) に基づいて一致するレジストレーションの検索が行われます。この関数は、- connectionOperationsモジュールの- collectionRangedQuery()を使ってデータベースを検索します (ステップ13と14)
- その後、MongoGlobalモジュールのfillContextProviders()が呼び出されて、見つからない属性を一致するレジストレーションで埋めようとします (ステップ15)
- processGenericEntities()はジェネリック・エンティティに対応するコンテキスト・プロバイダを追加するために呼び出されます (ステップ16)
- 一般的なエンティティのループは、addContextProviders()を呼び出すことによって、そのような各エンティティのコンテキスト・プロバイダを追加するために実装されます (ステップ17)
- ステップ18〜21は、少なくとも1つの属性に、foundフラグがfalseに設定されている場合にのみ実行されます
- MongoGlobalモジュール (ステップ18) で- registrationsQuery()を呼び出すことで、全エンティティに基づく一致レジストレーション (すなわち、"E-<null>" 形式) のクエリが行われる。この関数は、- connectionOperationsモジュールで- collectionRangedQuery()を使ってデータベースを検索します (ステップ19とステップ20)
- その後、MongoGlobalモジュール内のfillContextProviders()が呼び出されて、一致したレジストレーションで見つからない属性を埋めることを試みます (ステップ21)
- ステップ22〜25は、リクエストに属性のヌル・リストが含まれている場合、つまりエンティティ全体を問い合せる場合にのみ実行されます
- 空の属性リストとのクエリのためのルックアップが行われ、MongoGlobalモジュールでregistrationsQuery()を呼び出します (ステップ22)。この関数は、connectionOperationsモジュールのcollectionRangedQuery()を使ってデータベースを検索します (ステップ23と24)
- コンテキスト・プロバイダは、addContextProviders()によって直接追加されます (ステップ25)
- 見つからない要素を削除するために、つまり、ローカル・データベースからもコンテキスト・プロバイダからも結果を削除するために、"pruning" ステップが実行されます。これは MongoGlobalモジュールのpruneContextElements()によって行われます (ステップ26)
- リクエスト・セマフォがステップ2で取られた場合、それは戻される前に解放されます (ステップ27)
上記の一般的なエンティティとは、次のいずれかを意味します :
- パターンではない、通常の id と null タイプのエンティティ
- パターン化された id と null タイプではないエンティティ
- パターン化された id と null タイプのエンティティ
mongoQueryTypes (SR and SR2)
mongoQueryTypes は、タイプ・ブラウジングを可能にする NGSIv1 および NGSIv2 API の様々なオペレーションのロジックをカプセル化します。
ヘッダファイルには、次の3つの機能があります :
- mongoEntityTypes()(SR と SR2) :- GET /v1/contextTypesと- options = valuesを持たない、- GET /v2/typesオペレーションを提供します
- mongoEntityTypesValues()(SR2):- GET /v2/types?options=valuesオペレーションを提供します
- mongoAttributesForEntityType()(SRとSR2):- GET /v1/contextTypes/{type}と- GET /v2/types/{type}のオペレーションを行います
mongoEntityTypes() の詳細は次の図のとおりです。
MB-08: mongoEntityTypes
- mongoEntityTypes()は、サービス・ルーチンから呼び出されます (ステップ1)。これは、- lib/serviceRoutines/getEntityTypes.cppにある- getEntityTypes()や- lib/serviceRoutinesV2/getEntityAllTypes.cppにある- getEntityAllTypes()のいずれかである可能性があります
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (読み取りモード) (ステップ2)。詳細については、このドキュメントを参照してください
- それぞれのエンティティ・タイプに属するエンティティ・タイプと属性のリストは、connectionOperationsモジュールでrunCollectionCommand()を使ってデータベースから検索され、集約コマンドを実行します (ステップ3と4)
- 属性の詳細が有効になっている場合 (つまり、noAttrDetailがfalseに設定されている場合)、ループはすべてのエンティティ・タイプのすべての属性を反復します
- getAttributeTypes()を呼び出して、同じエンティティ・タイプのエンティティと一緒にさまざまnタイプの属性を取得します (ステップ5)
- 情報は connectionsOperationモジュールのcollectionQuery()を使ってデータベースから取得されます (ステップ6と7)
- リクエスト・セマフォがステップ2で取得された場合、リクエスト・セマフォは戻される前に解放されます (ステップ8)
mongoEntityTypesValues() の詳細は次の図のとおりです。
MB-09: mongoEntityTypesValues
- mongoEntityTypesValues()は、サービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (読み取りモード) (ステップ2)。詳細については、このドキュメントを参照してください。
- エンティティ・タイプのリストはデータベースから検索され、connectionOperationsモジュールでrunCollectionCommand()を使って集約コマンドを実行します (ステップ3と4)
- リクエスト・セマフォがステップ2で取得された場合、リクエスト・セマフォは戻される前に解放されます (ステップ5)
mongoAttributesForEntityType() の詳細は次の図のとおりです。
MB-10: mongoAttributesForEntityType
- mongoAttributesForEntityType()は、サービス・ルーチンから呼び出されます (ステップ1)。これは、- lib/serviceRoutinesV2/getEntityType.cppにある- getEntityType()や、- lib/serviceRoutines/getAttributesForEntityType.cppにある- getAttributesForEntityType()のいずれかである可能性があります
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (読み取りモード) (ステップ2)。詳細については、このドキュメントを参照してください。
- エンティティ・タイプに対応するエンティティ属性のリストはデータベースから検索され、connectionOperationsモジュールでrunCollectionCommand()を使用して、集約コマンドを実行します (ステップ3と4)
- 属性の詳細が有効になっている場合 (つまり、noAttrDetailがfalseに設定されている場合)、ループはすべての属性を繰り返し処理します
- getAttributeTypes()を呼び出して、同じエンティティ・タイプのエンティティと一緒にさまざまなタイプの属性を取得します (ステップ5)
- 情報は connectionsOperationモジュールのcollectionQuery()を使ってデータベースから取得されます (ステップ6と7)
- リクエスト・セマフォがステップ2で取得された場合、リクエスト・セマフォは戻される前に解放されます (ステップ8)
これらの関数は、結果を呼び出しているサービス・ルーチンに返すために、EntityTypeVectorResponse (2つの最初のケース) と EntityTypeResponse オブジェクトを使用します。
getAttributeTypes() によって実装されたエンティティ・タイプに関連付けられた属性の型を取得するために、潜在的にコストのかかるプロセスを避けるために、mongoEntityTypes() および mongoAttributesForEntityType() の noAttrDetails パラメータの使用に注意してください。
上記のすべての関数は、MongoDB集約フレームワークに大きく依存しています。 関数の仕組みを理解するためには、このフレームワークと管理ドキュメントのデータベース・モデルの一部として記述されている entities コレクション構造に精通している必要があります。
mongoCreateSubscription (SR2)
mongoCreateSubscription は、コンテキスト・サブスクリプションの作成ロジックをカプセル化します。
ヘッダファイルには mongoCreateSubscription()関数のみが含まれています。基本的に Subscriptionオブジェクトから情報を取得し、管理ドキュメントのデータベース・モデルの一部として記述されているデータベースのcsubsコレクションに挿入します。 キャッシュが有効になっている場合は、新しいサブスクリプションもサブスクリプションキャッシュに挿入されます。
MB-11: mongoCreateSubscription
- mongoCreateSubscription()は、サービス・ルーチンから呼び出されます(ステップ1)。これは- lib/serviceRoutinesV2/postSubscriptions.cppの- postSubscriptions()または- lib/mongoBackend/mongoSubscribeContext.cppの- mongoSubscribeContext()のいずれかです
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (書き込みモード) (ステップ2)。詳細については、このドキュメントを参照してください。
- この関数は、setExpiration(),setHttpInfo()などの異なるset*()関数を使用してデータベースに永続化される BSON オブジェクトを構築します。これらの関数の1つであるsetCondsAndInitialNotify()は、作成されているサブスクリプション (ステップ3で呼び出されたもの) に対応する初期通知を送る可能性があるという副作用があります
- processConditionVector()は実際に通知を送信するために呼び出されます (ステップ4)。その詳細は- MongoGlobalモジュール・セクションの一部として記述されます。図 MD-03 を参照してください
- 新しいサブスクリプションに対応する BSON オブジェクトは、connectionOperationsモジュールのcollectionInsert()を使ってデータベースに挿入されます (ステップ5と6)
- サブスクリプション・キャッシュが有効になっている場合 (つまり、noCacheがfalseに設定されている場合)、新しいサブスクリプションがサブスクリプション・キャッシュに挿入されます (ステップ7)。insertInCache()はサブスクリプション・キャッシュ・セマフォを内部的に使用します。詳細はこのドキュメントを参照してください
- リクエスト・セマフォがステップ2で取得された場合、リクエスト・セマフォは戻される前に解放されます (ステップ8)
潜在的な通知はサブスクリプションをデータベース/キャッシュに挿入する前に送信されるため、最後の通知時間とカウントに関する正しい情報が考慮されます。
mongoUpdateSubscription (SR2)
mongoUpdateSubscription は、コンテキスト・サブスクリプションの更新ロジックをカプセル化します。
ヘッダファイルには、mongoUpdateSubscription() という名前の関数だけが含まれています。この関数は、基本的に mongoUpdateSubscription オブジェクトから情報を取得し、それを使って、管理ドキュメントのデータベース・モデルの一部に記述されているデータベースの csubs コレクションの対応するドキュメントを更新します。サブスクリプション・キャッシュが有効な場合、サブスクリプション・キャッシュ内でサブスクリプションも更新されます。
MB-12: mongoUpdateSubscription
- mongoUpdateSubscription()は、サービス・ルーチンから呼び出されます (ステップ1)。これは、- lib/serviceRoutinesV2/patchSubscription.cppの- patchSubscription()または- lib/mongoBackend/mongoUpdateContextSubscription.cppの- mongoUpdateContextSubscription()のいずれかです
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (書き込みモード) (ステップ2)。詳細については、このドキュメントを参照してください
- 更新されるサブスクリプションは、connectionOperationsモジュールのcollectionFindOne()を使ってデータベースから取得されます (ステップ3と4)
- サブスクリプション・キャッシュが有効な場合 (つまり、noCacheがfalseに設定されている場合)、サブスクリプション・キャッシュのオブジェクトはcacheモジュールのsubCacheItemLoopkup()を使用してサブスクリプション・キャッシュから取得されます (ステップ5)
- オリジナル・サブスクリプションの BSON オブジェクトは、サブスクリプションの作成ケース setExpiration(),setHttpInfo()と同様の異なるset*()関数を使用して、元のサブスクリプションの BSON オブジェクトに基づいて構築されます。これらの関数の1つ、setCondsAndInitialNotify()は、ステップ6で呼び出された更新されたサブスクリプションに対応する初期通知を送信する可能性のある "副作用" を持っています
- この関数は MongoGlobalモジュール・セクションの一部として記述された通知を実際に送信するためにprocessConditionVector()を順番に使用します (ステップ7)。図 MD-03 を参照してください
- update,- countおよび- lastNotificationフィールドはサブスクリプションキャッシュで更新されます (ステップ9)。この操作は、ステップ8とステップ10で受け入れられて受け入れられたサブスクリプション・キャッシュ・セマフォによって保護されます。セマフォの詳細はこのドキュメント を参照してください
- 更新されたサブスクリプションに対応する BSON オブジェクトは、connectionOperationsモジュールのcollectionUpdate()を使ってデータベース内で更新されます (ステップ11と12)
- サブスクリプション・キャッシュが有効になっている場合 (つまり、noCacheがfalseに設定されている場合)、サブスクリプション・キャッシュ内で新しいサブスクリプションが更新されます(ステップ13)。updatetInCache()はサブスクリプション・キャッシュ・セマフォを内部的に使用します
- ステップ2でリクエスト・セマフォが取得された場合、リクエスト・セマフォは戻される前に解放されます (ステップ14)
潜在的な通知は、データベース/キャッシュ内のサブスクリプションを更新する前に送信されるため、最後の通知時間とカウントに関する正しい情報が考慮されます。
mongoGetSubscriptions (SR2)
mongoGetSubscriptions は、サブスクリプションを取得するロジックをカプセル化します。
ヘッダ・ファイルには2つの機能があります :
- mongoGetSubscription(),id によって個々のサブスクリプションを取得します
- mongoListSubscriptions(), すべてのサブスクリプションを取得します
結果をすべて取得する場合には、両方とも Subscription オブジェクトまたは Subscription オブジェクトのベクトルを返します。
いずれの場合も、実装は csubs コレクションに関するクエリに基づいています。管理ドキュメントのデータベース・モデルの一部として記述されています。
mongoGetSubscription() について : 
MB-13: mongoGetSubscription
- mongoGetSubscription()は、サービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (読み取りモード) (ステップ2)。詳細については、このドキュメントを参照してください
- サブスクリプションは、connectionOperationsモジュールのcollectionQuery()を使ってデータベースから取得されます (ステップ3と4)
- いくつかの set*()関数は、返されるSubscriptionオブジェクトを埋めるために使われます。その中で (ソースコード内の詳細)、サブスクリプション・キャッシュ・セマフォーを内部的に使用するため、setNotification()を強調したい (ステップ5)。詳細についてはこのドキュメントを参照してください
- リクエスト・セマフォがステップ2で取得された場合、リクエスト・セマフォは戻される前に解放されます (ステップ6)
mongoListSubscriptions() について : 
MB-14: mongoListSubscriptions
- mongoListSubscriptions()は、サービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (読み取りモード) (ステップ2)。詳細については、このドキュメントを参照してください
- サブスクリプションは、connectionOperationsモジュールのcollectionRangedQuery()を使ってデータベースから取得されます (ステップ3と4)
- 各サブスクリプションが返されるたびに、Subscriptionオブジェクトを満たすためにいくつかのset*()関数が使用されます。その中で (ソースコードの詳細)、サブスクリプション・キャッシュ・セマフォを内部的に使用するため、setNotification()を強調したい。詳細についてはこのドキュメントを参照してください
- リクエスト・セマフォがステップ2で取得された場合、リクエスト・セマフォは戻される前に解放されます (ステップ6)
mongoUnsubscribeContext (SR and SR2)
mongoUnsubscribeContext は、サブスクライブ解除コンテキストオペレーション (NGSIv1) およびサブスクリプション削除 (NGSIv2) のロジックをカプセル化します。
ヘッダ・ファイルには、UnsubscribeContextRequest オブジェクトを入力パラメータとして使用し、UnsubscribeContextResponse を出力パラメータとして使用する mongoUnsubscribeContext() 関数のみが含まれています。
その作業は、csubs コレクションのサブスクリプションに関連するドキュメントをデータベースから削除することです。キャッシュが有効な場合、サブスクリプションもキャッシュから削除されます。
MB-15: mongoUnsubscribeContext
- mongoUnsubscribeContext()は、サービス・ルーチンから呼び出されます (ステップ1)。これは- lib/serviceRoutines/postUnsubscribeContext.cppの- postUnsubscribeContext()または- lib/serviceRoutinesV2/deleteSubscription.cppの- mongoUpdateContextSubscription()のいずれかになります
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (書き込みモード) (ステップ2)。詳細については、このドキュメントを参照してください
- サブスクリプションは、connectionOperationsモジュールのcollectionFindOne()を使ってデータベースから取得します (ステップ3と4)
- subscriptionは connectionOperationsモジュールのcollectionRemove()を使ってデータベースから削除されます (ステップ5と6)
- サブスクリプションもサブスクリプション・キャッシュから削除されます (ステップ8および9)。キャッシュ・アクセスは、サブスクリプション・キャッシュ・セマフォ (セカンダリキャッシュ・セマフォ) によって保護されています。詳細については、このドキュメントを参照してください
- ステップ2でリクエスト・セマフォが取得された場合、リクエスト・セマフォは戻される前に解放されます (ステップ11)
ステップ6と7は noCache の値に関係なく実行されることに注意してください。これは動作しますが、非効率です。修正する必要があります。issueが作成されています。
mongoSubscribeContext (SR)
mongoSubscribeContext は、サブスクライブ・コンテキスト (NGSIv1 )オペレーションのロジックをカプセル化します。
ヘッダ・ファイルには、SubscribeContextRequest オブジェクトを入力パラメータとして使用し、SubscribeContextResponse を出力パラメータとして使用する mongoSubscribeContext() という関数のみが含まれています。
実際、この関数はこのオペレーションの NGSIv2 バージョンのラッパーです。つまり、mongoCreateSubscription module の mongoCreateSubscription() です。
MB-16: mongoSubscribeContext
- mongoSubscribeContext()は、 サービス・ルーチンから呼び出されます (ステップ1)
- 実行フローは、mongoCreateSubscription()に渡されます (ステップ2)。図 MB-11 を参照してください
mongoUpdateContextSubscription (SR)
mongoUpdateContextSubscription は、更新コンテキスト・サブスクリプション (NGSIv1) オペレーションのロジックをカプセル化します。
ヘッダ・ファイルには、UpdateContextSubscriptionRequest オブジェクトを入力パラメータとして使用し、UpdateContextSubscriptionResponse を出力パラメータとして使用する mongoUpdateContextSubscription() という関数だけが含まれています。
実際、この関数はこのオペレーションの NGSIv2 バージョンのラッパーです。つまり、mongoUpdateSubscriptionモジュール の mongoUpdateSubscription() です。
MB-17: mongoUpdateContextSubscription
- mongoUpdateContextSubscription()は、サービス・ルーチンから呼び出されます (ステップ1)
- 実行フローは、mongoUpdateSubscription()に渡されます (setp 2)。図 MB-12 を参照してください
mongoRegisterContext (SR) and mongoNotifyContextAvailability (SR)
mongoRegisterContext モジュールは、ヘッダ・ファイルに定義された mongoRegisterContext() によってレジスタ・コンテキスト・オペレーション処理ロジックのエントリポイントを提供し、mongoNotifyContextAvailability モジュールは、ヘッダファイルにmongoNotifyContextAvailability() を使って、コンテキスト・アベイラビリティ通知処理ロジックのエントリポイントを追加します。しかし、コンテキスト・アベイラビリティ通知がレジスタ・コンテキストと同じ方法で処理されるので、 mongoRegisterContext() と mongoNotifyContextAvailability() は基本的に processRegisterContext() の ラッパー (MongoCommonRegister モジュール) は、新しいレジストレーションを作成するか、管理文書のデータベース・モデルの一部として記述されているデータベースの registrations コレクションの既存のものを更新します。
MB-18: mongoRegisterContext
- mongoRegisterContext()または- mongoNotifyContextAvailabilityがサービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエスト・セマフォ が取られます (書き込みモード) (ステップ2)。詳細については、このドキュメントを参照してください
- mongoRegisterContext()の場合、リクエストにレジストレーション ID が指定されていれば、レジストレーション更新を示します。したがって、- registrationsモジュールは- collectionFindOne()を使ってデータベースから検索されます (ステップ3と4)
- processRegisterContext()がレジストレーションを処理するために呼び出されます (ステップ5)
- リクエストの各レジストレーションに対して、addTriggeredSubscriptions()が呼び出されます (ステップ6)。この関数はregistrationOperationsモジュールでcollectionQuery()を順番に使用して、レジストレーションがサブスクリプションをトリガするかどうかをチェックします (ステップ7と8)。subsToNotifyマップは、トリガーされたサブスクリプションを格納するために使用されます
- registrationドキュメントは、データベースで作成または更新されます。そうするために、- upsertパラメータを- trueに設定する- connectionOperationsモジュールの- collectionUpdate()が使われます (ステップ9と10)
- トリガされたサブスクリプションを処理するために processSubscriptions()が呼び出されます (ステップ11)。subsToNotifyマップはprocessAvailabilitySubscription()によって個々に処理するために反復されます (ステップ12)。このプロセスは、図 MD-04 に記載されています
- ステップ2でリクエスト・セマフォが取得された場合は、リクエスト・セマフォが戻される前に解放されます (ステップ13)
mongoDiscoverContextAvailability (SR)
mongoDiscoverContextAvailability は、コンテキスト・アベイラビリティ・ディスカバリー (NGSIv1) オペレーションのロジックをカプセル化します。
ヘッダ・ファイルには、DiscoverContextAvailabilityRequest オブジェクトを入力パラメータとして使用し、DiscoverContextAvailabilityResponse を出力パラメータとして使用する mongoDiscoverContextAvailability() という関数のみが含まれています。その作業は、入力リクエスト・オブジェクトとデータベースに存在するレジストレーションに基づいてレスポンス・オブジェクトを構築することです。
MB-19: mongoDiscoverContextAvailability
- mongoDiscoverContextAvailability()がサービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (読み取りモード) (ステップ2)。詳細については、このドキュメントを参照してください
- 実行フローは processDiscoverContextAvailability()に渡されます (ステップ3)
- レジストレーション検索は registrationQuery()を使って行います (ステップ4)。この関数はデータベースからレジストレーションを取り出すためにcollectionRangedQuery()を使います (ステップ5と6)
- ステップ2でリクエスト・セマフォが取得された場合は、リクエスト・セマフォが戻される前に解放されます (ステップ7)
mongoSubscribeContextAvailability (SR)
mongoSubscribeContextAvailability は、コンテキスト・アベイラビリティ・サブスクリプションの作成ロジックをカプセル化します。
ヘッダ・ファイルには、SubscribeContextAvailabilityRequest オブジェクトを入力パラメータとして使用し、SubscribeContextAvailabilityResponse を出力パラメータとして使用する mongoSubscribeContextAvailability() という関数だけが含まれています。その作業は、管理ドキュメントのデータベース・モデルの一部として記述されているデータベースの casubs コレクションで新しいコンテキスト・アベイラビリティ・サブスクリプションを作成することです。
MB-20: mongoSubscribeContextAvailability
- mongoSubscribeContextAvailability()は、サービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (書き込みモード) (ステップ2)。詳細については、このドキュメントを参照してください
- コンテキスト・アベイラビリティ・サブスクリプションのドキュメントがデータベースに作成されます。そうするために、 connectionOperationsモジュールのcollectionInsert()が使われます (ステップ3と4)
- この作成の結果、通知が発生する可能性があります。これは、図 MD-04 で説明されている  processAvailabilitySubscription()によって行われます (ステップ5)
- リクエスト・セマフォがステップ2で取得された場合、リクエスト・セマフォは戻される前に解放されます (ステップ6)
mongoUpdateContextAvailabilitySubscription (SR)
mongoUpdateContextAvailabilitySubscription は、更新コンテキストのアベイラビリティ・サブスクリプションのオペレーションのロジックをカプセル化します。
ヘッダ・ファイルには、UpdateContextAvailabilitySubscriptionRequest オブジェクトを入力パラメータとして使用し、UpdateContextAvailabilitySubscriptionResponse を出力パラメータとして使用する mongoUpdateContextAvailabilitySubscription() という関数だけが含まれています。 その作業は、管理ドキュメントのデータベース・モデルの一部として記述されているデータベース内の casubsコレクションで対応するコンテキスト・アベイラビリティ・サブスクリプションを更新することです。
MB-21: mongoUpdateContextAvailabilitySubscription
- mongoUpdateContextAvailabilitySubscription()は、サービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (書き込みモード) (ステップ2)。詳細については、このドキュメントを参照してください
- 更新するコンテキスト・アベイラビリティ・サブスクリプションのドキュメントは、connectionOperationsモジュールのcollectionFindOne()によってデータベースから取り出されます (ステップ3と4)
- コンテキスト・アベイラビリティ・サブスクリプションのドキュメントは、データベース内で更新されます。そうするために、 connectionOperationsモジュールのcollectionUpdate()が使われます (ステップ5と6)
- このアップデートの結果、通知が発生する可能性があります。 これは図 MD-04 で説明されている、processAvailabilitySubscription()によって行われます (ステップ7)
- リクエスト・セマフォがステップ2で取得された場合、リクエスト・セマフォは戻される前に解放されます (ステップ8)
mongoUnsubscribeContextAvailability (SR)
mongoUnsubscribeContextAvailability は、 コンテキスト・アベイラビリティのサブスクリプション解除のオペレーションのロジックをカプセル化します。
ヘッダ・ファイルには、UnsubscribeContextAvailabilityRequest オブジェクトを入力パラメータとして使用し、UnsubscribeContextAvailabilityResponse を出力パラメータとして使用する mongoUnsubscribeContextAvailability() という名前の関数のみが含まれています。
その作業は、casubs コレクションのサブスクリプションに関連するドキュメントをデータベースから削除することです。
MB-21: mongoUnsubscribeContextAvailability
- mongoUnsubscribeContextAvailability()は、サービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (書き込みモード) (ステップ2)。詳細については、このドキュメントを参照してください
- サブスクリプションは、connectionOperationsモジュールのcollectionFindOne()を使ってデータベースから取得します (ステップ3と4)
- サブスクリプションは connectionOperationsモジュールのcollectionRemove()を使ってデータベースから削除されます (ステップ5と6)
- ステップ2でリクエスト・セマフォが取得された場合は、リクエスト・セマフォが戻される前に解放されます (ステップ7)
mongoRegistrationGet (SR2)
mongoRegistrationGet は、NGSIv2 API のコンテキスト・レジストレーションを取得するためのロジックをカプセル化します。
ヘッダファイルには2つの機能があります。
- mongoRegistrationGet(), idによる個別のコンテキスト・レジストレーションを取得します
- mongoRegistrationsGet(), すべてのコンテキスト・レジストレーションを取得します
結果をすべて取得する場合には、両方とも Registration オブジェクト または Registration オブジェクトのベクトルを返します。
いずれの場合も、実装は管理ドキュメントのデータベース・モデルの一部として記述された registrations コレクションに関するクエリに基づいています。
mongoRegistrationGet() について : 
MB-23: mongoRegistrationGet
- mongoRegistrationGet()は、サービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (読み取りモード) (ステップ2)。詳細については、このドキュメントを参照してください
- レジストレーションは connectionOperationsモジュールのcollectionQuery()を使ってデータベースから検索されます (ステップ3と4)
- いくつかの set*()関数は、返されるRegistrationオブジェクトを埋めるために使われます
- リクエスト・セマフォがステップ2で取得された場合、リクエスト・セマフォは戻される前に解放されます (ステップ5)
mongoRegistrationsGet() について : 
MB-24: mongoRegistrationsGet
- mongoRegistrationsGet()は、サービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (読み取りモード) (ステップ2)。詳細については、このドキュメントを参照してください
- レジストレーションは connectionOperationsモジュールのcollectionRangedQuery()を使ってデータベースから検索されます (ステップ3と4)
- 返されるレジストレーションごとに、Registrationオブジェクトを埋めるためにいくつかのset *()関数が使われます
- リクエスト・セマフォがステップ2で取得された場合、リクエスト・セマフォは戻される前に解放されます (ステップ6)
mongoRegistrationCreate (SR2)
mongoRegistrationCreate は、NGSIv2 API 用のコンテキスト・レジストレーション作成ロジックをカプセル化します。
ヘッダ・ファイルには mongoRegistrationCreate() 関数のみが含まれており、基本的には Registration オブジェクトから情報を取得し、対応するドキュメントを、管理ドキュメントのデータベース・モデルの一部として記述されているデータベースの registrations コレクションに挿入することです。
MB-25: mongoRegistrationCreate
- mongoRegistrationCreate()は- postRegistrations()サービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (書き込みモード) (ステップ2)。詳細については、このドキュメントを参照してください
- この関数は、BSON オブジェクトを構築します。このオブジェクトは、setExpiration(),setRegistrationId()などのさまざまなset*()関数を使用してデータベースに保持されるものです。新しいレジストレーションに対応する BSON オブジェクトは、connectionOperationsモジュールのcollectionInsert()を使ってデータベースに挿入されます (ステップ3と4)
- リクエスト・セマフォがステップ2で取得された場合、リクエスト・セマフォは戻される前に解放されます (ステップ5)
mongoRegistrationDelete (SR2)
mongoRegistrationDelete は、レジストレーションを削除するロジックをカプセル化します。
ヘッダファイルには、レジストレーション ID (regId) をパラメータとして使用する mongoRegistrationDelete() という関数のみが含まれています。
その作業は、管理ドキュメンテーションのデータベース・モデルの一部として記述されている registrations コレクションのレジストレーションに関連するドキュメントをデータベースから削除することです。
MB-27: mongoRegistrationDelete
- mongoRegistrationDelete()は、サービス・ルーチンから呼び出されます (ステップ1)
- -reqMutexPolicyに応じて、リクエスト・セマフォが取られます (書き込みモード) (ステップ2)。詳細については、このドキュメントを参照してください
- レジストレーションは connectionOperationsモジュールのcollectionQuery()を使ってデータベースから検索されます (ステップ3と4)
- レジストレーションは connectionOperationsモジュールのcollectionRemove()を使ってデータベースから削除されます (ステップ5と6)
- ステップ2でリクエスト・セマフォが取得された場合は、リクエスト・セマフォが戻される前に解放されます (ステップ7)
コネクション・プール管理
モジュール mongoConnectionPoolは、データベース・コネクション・プールを管理します。プールの仕組みは重要であり、説明に値します。 基本的に、Orion Context Broker はデータベースへの接続のリスト (mongoConnectionPool.cpp で定義された connectionPool) を保持します。リストのサイズは、-dbPoolSize CLIパラメータ (デフォルトでは10)で指定します。リストの各要素は、このタイプのオブジェクトです :
typedef struct MongoConnection
{
  DBClientBase*  connection;
  bool           free;
} MongoConnection;
ここで、connection (DBClientBase は MongoDB ドライバのクラスです) は実際の接続であり、free は接続が現在使用中かどうかを知るフラグです。DBClientBase オブジェクトはスレッド・セーフではないので、これは重要です。そのため、Context Broker のロジックは、同じ接続が同時に2つのスレッドによって使用されていないことを保証する必要があります。詳しくは、StackOverflowのこの記事を参照してくだい。ので、Context Brokerロジックは、同じ接続が2つのスレッドによって同時に使用されていないことを保証する必要があります。
これを考慮すると、 mongoConnectionPool モジュールの主な機能は次の通りです (これ以上はありますが、残りはメトリック・ロジックに関連する2次モジュールです) :
- mongoConnectionPoolInit(): Context Broker のブートストラップ・ロジックから呼び出されたプールを初期化します
- mongoPoolConnectionGet(): プールからフリーのコネクションを取得します
- mongoPoolConnectionRelease(): 接続を解放します。このため、プールに戻り、- mongoConnectionGet()の次の呼び出しで再び選択できる状態になります
セマフォ・システムは、コネクションの使用を保護するために使用されます。詳細については、この別のドキュメントをご覧ください。
DB インタラクションに関連するロー・レベルのモジュール
- connectionOperations:データベース・オペレーションのラッパー (挿入、検索、更新など)、Orion 固有の側面の追加 (データベース接続プールの並行性管理、エラー処理、ロギングなど)、 データベースと対話する MongoDB ドライバ・メソッドは、直接使用するのではなく、このモジュールを使用する (または、カバーされていないオペレーションが必要な場合は展開する) べきです
- safeMongo:BSON オブジェクトからフィールドを取得する安全なメソッドです。MongoDB ドライバ・メソッドを使用した BSON オブジェクトへの直接アクセスは避けるべきです。代わりに- safeMongoモジュールを使用してください。または、カバーされていない BSON 情報にアクセスする別の方法が必要な場合は展開してください
- dbConstants(- .hのみ):データベース・レベルで使用されるフィールド名です。データベース・モデルのドキュメントで説明されている同じものがここで定義されています
- dbFieldsEncoding(- .hのみ):データベース・レベルでのエンコーディングとメタデータ文字列の分割を行うインライン・ヘルパー関数です
特定目的のモジュール
- MongoCommonSubscription:サブスクリプション・ロジックに関連するいくつかの他のモジュールによって使用される共通関数。このモジュールのほとんどの機能は、- Subscriptionsオブジェクトのフィールドを埋めるためのセット関数です
- location:データベース内の位置管理に関連する機能
- dateExpiration:データベースの TTL 有効期限管理に関連する機能
- mongoSubCache:データベースと対話するために キャッシュ・ライブラリによって使用される関数
- compoundResponsesと- compoundValueBson:BSON データと内部タイプ (主に ngsi ライブラリ) と viceversa の間の変換を助けるモジュール
- TriggeredSubscription:コンテキストまたはレジストレーションの作成/更新時にトリガーされたサブスクリプションに関連する情報をカプセル化するために、サブスクリプション・ロジック (コンテキストおよびコンテキストのアベイラビリティ・サブスクリプションの両方) によって使用されるヘルパークラス
MongoGlobal モジュール
最後に、他の mongoBackend モジュールや他のライブラリで使用されるヘルパー関数のセットを含む MongoGlobal モジュールを用意しました。これには約40個の個々の関数が含まれているので、現在のドキュメントですべての詳細を提供するのは意味がありません。しかし、私たちは最も重要なものを強調します。
mongoInit()
mongoInit() は、 contextBroker.cpp main() の CB 初期化ロジック(in contextBroker.cpp main())で使用され、データベース接続プールを初期化します。
entitiesQuery()
この関数は基本的に、データベース内のエンティティ (管理マニュアルのデータベース・モデルの一部として記述されている entitiesコレクション) を検索します。それは、サービス ("テナント" とも呼ばれます)、サービスパス、ページネーション および ソート・パラメータを考慮に入れます。MongoDB のクエリは、エンティティ、サービスパス、属性、スコープ (フィルタと地理的位置) のいくつかの部分で構成されています。
entitiesQuery() は、connectionOperations モジュールの collectionRangedQuery() を利用してデータベース内の実際のクエリを実行します。データベース内のクエリの後、found 属性フラグ (詳細はソースコード内を参照) を使用して、関数の一部が結果に注釈を付けて、呼び出し側関数によって行われた、コンテキスト・プロバイダの検索に役立ちます。結果は出力パラメータとして  ContextElementResponseVector オブジェクトに保存されます。
この関数は、次の場所から呼び出されます :
- mongoQueryContext()(- mongoQueryモジュール内で), クエリ・オペレーションの "コア" として使用します
- processOnChangeConditionForSubscription(), コンテキスト・サブスクリプションの作成/更新中に初期通知を "満たす" ようにエンティティを検索します
registrationsQuery()
この関数は基本的に、データベースの既存のレジストレーション (管理ドキュメントのデータベース・モデルの一部として記述されている registrations コレクション) を検索します。サービス ("テナント" とも呼ばれます)、サービスパス、ページ区切りパラメータを考慮します。
これはいくつかの関数によって使用されます :
- mongoDiscoverContextAvailability()(- mongoDiscoverContextAvailabilityモジュール内で) ディスカバリー・オペレーションの "コア" として使用します
- processAvailabilitySubscription()(- MongoGlobalモジュールの一部でもある) コンテキスト・アベイラビリティ通知をトリガするレジストレーションを検出するために使用します
- mongoQueryContextモジュールの- mongoQueryContext(), クエリの転送のためにコンテキスト・プロバイダを見つけるために使用します。転送は mongoBackend ライブラリ内ではなく、呼び出す serviceRoutine から行われることに注意してください
- MongoCommonUpdateモジュールの- searchContextProviders(), 更新の転送のためにコンテキスト・プロバイダを見つけるために使用します。転送は mongoBackend ライブラリ内ではなく、呼び出す serviceRoutine から行われることに注意してください
processConditionVector()
この関数は、コンテキスト・サブスクリプションの作成/更新時に呼び出され、サブスクリプションに関連付けられた初期通知を送信する可能性があります。
MD-03: processConditionVector() 機能の詳細
- processConditionVector()(ステップ1) は、mongoBackend 関数によって呼び出されます。図 MB-11 と MB-12 を参照してください
- ループは NotifyConditionVectorベクトル内の個々の条件に対して繰り返します。ほとんどの場合、このベクターには1つのアイテムしかありません
- processOnChangeConditionForSubscription()が個々の条件を処理するために呼び出されます (ステップ2)
- エンティティをデータベースから取得するために、entitiesQuery()が呼び出されてエンティティが通知に含まれるようにします (ステップ3)。これはconnectionOperationsモジュールのcollectionRangedQuery()に順番に依存します (ステップ4および5)。
- pruneContextElements()は、見つからなかった要素を取り除くために呼び出されます。通知にそれらを含めることは意味がありません (ステップ6)
- プルーニング (pruning) 後に送信するエンティティがある場合は、ステップ7〜11が実行されます- 特定の属性の条件 (空でない条件) の場合、2回目の検索は entitiesQuery()(ステップ7, 8, 9 および ステップ10のプルーニング) を使用して行われます
- 通知を実際に送信するために Notifyオブジェクト (ngsiNotify ライブラリから) を使用して通知が送信されます (ステップ11)。詳細は図 NF-01 または NF-03 に記載されています。特定の属性の条件の場合、前のチェックがOKだった場合にのみ通知が送信されます。すべての属性通知 (空の状態) の場合、通知は常に送信されます。
 
- 特定の属性の条件 (空でない条件) の場合、2回目の検索は 
processOnChangeConditionForSubscription() には初期以外の通知用の processOnChangeConditionForUpdateContext() という名前の "兄弟 "関数があることに注意してください。図 MD-01 を参照してください。
processAvailabilitySubscription()
processOnChangeConditionForSubscription() と processOnChangeConditionForUpdateContext() と同様に、この関数はコンテキスト・アベイラビリティ通知を効果的に作成する関数です。
次から呼ばれます :
- コンテキスト・アベイラビリティの作成/更新ロジック。したがって、一致するすべてのコンテキスト・レジストレーションの初期通知が送信されます
- 新しい、または更新された、コンテキスト・レジストレーションがアベイラビリティ・サブスクリプションと一致したとき、オペレーションのロジックをレジストレーションします
MD-04: processAvailabilitySubscription() 機能の詳細
- processAvailabilitySubscription()(ステップ1)。図 MB-18, MB-20, MB-21 を参照してください
- registrationsQuery()(ステップ2) を使用して、レジストレーションがサブスクリプションと一致するかどうかを確認します。この関数は、connectionOperations- モジュール内でcollectionRangeQuery()` を使って、データベースをチェックインします (ステップ3と4)
- レジストレーションが一致した場合、プロセスは続行されます。アベイラビリティ通知は、Notifierオブジェクト (ngsiNotify ライブラリから) を使用して送信されます (ステップ5)。これに関する詳細は図 NF-02 にあります
- 最後に、mongoUpdateCasubNewNotification()を呼び出すことによって、最後の通知とカウント統計が更新されます (ステップ6)。 この関数は、connectionOperationsモジュールでcollectionUpdate()を使用して、データベース内の対応するコンテキスト・アベイラビリティ・サブスクリプションのドキュメントを更新します (ステップ7と8)





























