2017-01-14 2 views
2

Fiware Cygnus를 사용하여 MongoDB에 내역 데이터를 저장하려고합니다. 그러나 Cygnus가 통지를받을 때마다 컬렉션이 이미 존재하면 문서를 추가하는 대신 새로운 컬렉션을 생성하려고합니다. 나는 너이 오류 메시지가 : 이것은 내 agent.conf 파일입니다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" } 

:

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에 새로운 문서를 추가하는 대신 새로운 컬렉션을 생성하려고한다는 것입니다. – Thomas

답변

0

Cygnus는 항상 데이터를 삽입하기 전에 알림 수신시 컬렉션을 생성하려고합니다. 왜? MongoDB에 콜렉션 존재 여부를 묻는 동시에 MongoDB에 콜렉션 작성을 요청하는 것은 콜렉션이 존재하지 않을 때만 드라이버를 통한 두 가지 조작입니다. MongoDB에게 항상 콜렉션을 생성 해달라고 요청하는 것은 하나의 작업 일뿐입니다. 따라서 콜렉션이 존재하면 콜렉션이 있음을 알리는 DEBUG 로그 추적이 있으면 확인해야합니다. (*)

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 응답을 해석 할 때 문제가 될 수 있습니다. 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