2017-01-14 4 views
2

Fiware Cygnusを使用して履歴データをMongoDBに保存します。しかし、Cygnusが通知を受け取ると、コレクションがすでに存在する場合に文書を追加するのではなく、新しいコレクションを作成したい場合があります。私はシグナスから、このエラーメッセージが表示されます。Fiware Cygnusは、通知を受け取ったときに常に新しいMongoDBコレクションを作成したいと考えています。

time=2017-01-14T20:58:11.785Z | lvl=WARN | corr=28eca6a8-da9c-11e6-841b-0242ac120009 | trans=9fa2d345-9aa1-4ff6-84df-75de5829a449 | srv=itg | subsrv=/building1 | comp=cygnus-ngsi | op=processNewBatches | msg=com.telefonica.iot.cygnus.sinks.NGSISink[590] : Command failed with error 48: 'a collection 'sth_itg.sth_/building1_TemperatureRoom1_room' already exists' on server iot-mongo:27017. The full response is { "ok" : 0.0, "errmsg" : "a collection 'sth_itg.sth_/building1_TemperatureRoom1_room' already exists", "code" : 48, "codeName" : "NamespaceExists" } 

これは私のagent.confファイルです:

cygnus-ngsi.sources = http-source 
cygnus-ngsi.sinks = mongo-sink 
cygnus-ngsi.channels = mongo-channel 

cygnus-ngsi.sources.http-source.type = org.apache.flume.source.http.HTTPSource 
cygnus-ngsi.sources.http-source.channels = mongo-channel 
cygnus-ngsi.sources.http-source.port = 5050 
cygnus-ngsi.sources.http-source.handler = com.telefonica.iot.cygnus.handlers.NGSIRestHandler 
cygnus-ngsi.sources.http-source.handler.notification_target = /notify 
cygnus-ngsi.sources.http-source.handler.default_service = default 
cygnus-ngsi.sources.http-source.handler.default_service_path =/
cygnus-ngsi.sources.http-source.interceptors = ts gi 
cygnus-ngsi.sources.http-source.interceptors.ts.type = timestamp 
cygnus-ngsi.sources.http-source.interceptors.gi.type = com.telefonica.iot.cygnus.interceptors.NGSIGroupingInterceptor$Builder 
cygnus-ngsi.sources.http-source.interceptors.gi.grouping_rules_conf_file = /opt/apache-flume/conf/grouping_rules.conf 


cygnus-ngsi.sinks.mongo-sink.type = com.telefonica.iot.cygnus.sinks.NGSIMongoSink 
cygnus-ngsi.sinks.mongo-sink.channel = mongo-channel 
#cygnus-ngsi.sinks.mongo-sink.enable_encoding = false 
#cygnus-ngsi.sinks.mongo-sink.enable_grouping = false 
#cygnus-ngsi.sinks.mongo-sink.enable_name_mappings = false 
#cygnus-ngsi.sinks.mongo-sink.enable_lowercase = false 
#cygnus-ngsi.sinks.mongo-sink.data_model = dm-by-entity 
#cygnus-ngsi.sinks.mongo-sink.attr_persistence = row 
cygnus-ngsi.sinks.mongo-sink.mongo_hosts = iot-mongo:27017 
cygnus-ngsi.sinks.mongo-sink.mongo_username = 
cygnus-ngsi.sinks.mongo-sink.mongo_password = 
#cygnus-ngsi.sinks.mongo-sink.db_prefix = sth_ 
#cygnus-ngsi.sinks.mongo-sink.collection_prefix = sth_ 
#cygnus-ngsi.sinks.mongo-sink.batch_size = 1 
#cygnus-ngsi.sinks.mongo-sink.batch_timeout = 30 
#cygnus-ngsi.sinks.mongo-sink.batch_ttl = 10 
#cygnus-ngsi.sinks.mongo-sink.data_expiration = 0 
#cygnus-ngsi.sinks.mongo-sink.collections_size = 0 
#cygnus-ngsi.sinks.mongo-sink.max_documents = 0 
#cygnus-ngsi.sinks.mongo-sink.ignore_white_spaces = true 

cygnus-ngsi.channels.mongo-channel.type = com.telefonica.iot.cygnus.channels.CygnusMemoryChannel 
cygnus-ngsi.channels.mongo-channel.capacity = 1000 
cygnus-ngsi.channels.mongo-channel.transactionCapacity = 100 

私が何か間違ったことをやっていますか?誰かがこれを助けることができますか?

ありがとうございます。

+0

あなたは何を試してみましたか? [最小、完全で検証可能な例](http://stackoverflow.com/help/mcve)を作成することが最善です。 –

+0

Orionでは、私は温度の値が変わるたびにCygnusに通知を送るサブスクリプションを作成しました。 CygnusはデータをMySQLに保存することができますが、上記で説明した問題のためMongoDBに保存することはできません。問題は単純に、Cygnusは新しい文書をMongoDBに追加するのではなく、MongoDBに新しいコレクションを作成することを常に望んでいることです。 – Thomas

答えて

0

データを挿入する前に、通知の受信時に常にコレクションを作成しようとします。どうして? MongoDBにコレクションの存在を依頼し、コレクションが存在しない場合にのみMongoDBにコレクションの作成を依頼するので、ドライバーによる2つの操作です。 MongoDBに常にコレクションを作成するよう要求するのはただの操作です。したがって、コレクションが存在する場合は、コレクションが存在することを示すDEBUGログ・トレースが表示されている場合は、OKである必要があります。 (*)

https://github.com/telefonicaid/fiware-cygnus/blob/master/cygnus-ngsi/src/main/java/com/telefonica/iot/cygnus/sinks/NGSIMongoSink.java#L364

try { 
    backend.createDatabase(dbName); 
    backend.createCollection(dbName, collectionName, collectionsSize, maxDocuments, dataExpiration); 
    backend.insertContextDataRaw(dbName, collectionName, aggregation); 
} catch (Exception e) { 
    throw new CygnusPersistenceError("-, " + e.getMessage()); 
} // try catch 

問題は、あなたが悪いですWARNログトレースを、経験しているです。 MongoDBのどのバージョンを使用していますか?コードを確認すると、エラーコードに基づいていないコレクション作成時にMongoDBレスポンスを解釈するときに問題になる可能性があります.MongoDBが期待したものとは異なるメッセージを返すと、エラーが発生します。これは必ず改善する必要があります。

https://github.com/telefonicaid/fiware-cygnus/blob/master/cygnus-common/src/main/java/com/telefonica/iot/cygnus/backends/mongo/MongoBackendImpl.java#L106

// create the collection 
try { 
    db.createCollection(collectionName); 
} catch (Exception e) { 
    if (e.getMessage().contains("collection already exists")) { 
     LOGGER.debug("Collection already exists, nothing to create"); 
    } else { 
     throw e; 
    } // if else 
} // try catch 

(*)これは、既に作成されたデータベースとコレクションの "キャッシュ" を使用することによって改善することができます。このようなキャッシュは、MongoDBドライバを介して多くの操作を節約します。この考え方は、CKANとMySQLのシンクですでに実装されています。

+0

この回答にコメントされた問題は、最終的にhttps://github.com/telefonicaid/fiware-cygnus/issues/1377で修正されました – frb

関連する問題