/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.bbg.referencedata.cache;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.fudgemsg.FudgeContext;
import org.fudgemsg.FudgeMsg;
import org.fudgemsg.mapping.FudgeDeserializer;
import org.fudgemsg.mapping.FudgeSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.opengamma.bbg.referencedata.ReferenceData;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.fudgemsg.OpenGammaFudgeContext;
import com.opengamma.util.mongo.MongoConnector;
/**
* A cache of String -> reference data in Mongo.
*/
public class MongoDBReferenceDataCache {
/** Logger. */
private static final Logger s_logger = LoggerFactory.getLogger(MongoDBReferenceDataCache.class);
/**
* Mongo field name.
*/
private static final String SECURITY_DES_KEY_NAME = "Security Description";
/**
* Mongo field name.
*/
private static final String FIELD_DATA_KEY_NAME = "Field Data";
/**
* The Mongo connector.
*/
private final MongoConnector _mongoConnector;
/**
* The Mongo collection.
*/
private final DBCollection _mongoCollection;
/**
* The Fudge context.
*/
private final FudgeContext _fudgeContext;
/**
* Creates an instance.
*
* @param mongoConnector the Mongo connector, not null
* @param collectionName the Mongo collection name, not null
*/
public MongoDBReferenceDataCache(final MongoConnector mongoConnector, final String collectionName) {
this(mongoConnector, collectionName, OpenGammaFudgeContext.getInstance());
}
/**
* Creates an instance.
*
* @param mongoConnector the Mongo connector, not null
* @param collectionName the Mongo collection name, not null
* @param fudgeContext the Fudge context, not null
*/
public MongoDBReferenceDataCache(final MongoConnector mongoConnector, final String collectionName, final FudgeContext fudgeContext) {
ArgumentChecker.notNull(mongoConnector, "mongoConnector");
ArgumentChecker.notNull(fudgeContext, "fudgeContext");
_fudgeContext = fudgeContext;
_mongoConnector = mongoConnector;
_mongoCollection = _mongoConnector.getDBCollection(collectionName);
_mongoCollection.ensureIndex(SECURITY_DES_KEY_NAME);
}
//-------------------------------------------------------------------------
public Set<String> getAllCachedSecurities() {
BasicDBObject query = new BasicDBObject();
query.put(SECURITY_DES_KEY_NAME, new BasicDBObject("$exists", 1));
BasicDBObject fields = new BasicDBObject();
fields.put(SECURITY_DES_KEY_NAME, 1);
DBCursor cursor = _mongoCollection.find(query, fields);
Set<String> result = new HashSet<String>();
while (cursor.hasNext()) {
DBObject dbObject = cursor.next();
String securityDes = (String) dbObject.get(SECURITY_DES_KEY_NAME);
result.add(securityDes);
}
return result;
}
//-------------------------------------------------------------------------
public void save(ReferenceData securityResult) {
FudgeDeserializer deserializer = new FudgeDeserializer(_fudgeContext);
String securityDes = securityResult.getIdentifier();
FudgeMsg fieldData = securityResult.getFieldValues();
if (securityDes != null && fieldData != null) {
s_logger.info("Persisting fields for \"{}\": {}", securityDes, securityResult.getFieldValues());
DBObject mongoDBObject = createMongoDBForResult(deserializer, securityResult);
s_logger.debug("dbObject={}", mongoDBObject);
BasicDBObject query = new BasicDBObject();
query.put(SECURITY_DES_KEY_NAME, securityDes);
_mongoCollection.update(query, mongoDBObject, true, false);
}
}
public Set<String> getAllCachedIdentifiers() {
BasicDBObject query = new BasicDBObject();
query.put(SECURITY_DES_KEY_NAME, new BasicDBObject("$exists", 1));
BasicDBObject fields = new BasicDBObject();
fields.put(SECURITY_DES_KEY_NAME, 1);
DBCursor cursor = _mongoCollection.find(query, fields);
Set<String> result = new HashSet<String>();
while (cursor.hasNext()) {
DBObject dbObject = cursor.next();
String securityDes = (String) dbObject.get(SECURITY_DES_KEY_NAME);
result.add(securityDes);
}
return result;
}
public Map<String, ReferenceData> load(Set<String> securities) {
Map<String, ReferenceData> result = new TreeMap<String, ReferenceData>();
FudgeSerializer serializer = new FudgeSerializer(_fudgeContext);
BasicDBObject query = new BasicDBObject();
query.put(SECURITY_DES_KEY_NAME, new BasicDBObject("$in", securities));
DBCursor cursor = _mongoCollection.find(query);
while (cursor.hasNext()) {
DBObject dbObject = cursor.next();
s_logger.debug("dbObject={}", dbObject);
String securityDes = (String) dbObject.get(SECURITY_DES_KEY_NAME);
s_logger.debug("Have security data for des {} in MongoDB", securityDes);
ReferenceData perSecResult = parseDBObject(serializer, securityDes, dbObject);
if (result.put(securityDes, perSecResult) != null) {
s_logger.warn("{}/{} Querying on des {} gave more than one document",
new Object[] {_mongoConnector.getName(), _mongoCollection.getName(), securityDes });
}
}
return result;
}
private ReferenceData parseDBObject(FudgeSerializer serializer, String securityDes, DBObject fromDB) {
ReferenceData result = new ReferenceData(securityDes);
DBObject fieldData = (DBObject) fromDB.get(FIELD_DATA_KEY_NAME);
result.setFieldValues(serializer.objectToFudgeMsg(fieldData));
return result;
}
private DBObject createMongoDBForResult(FudgeDeserializer deserializer, ReferenceData refDataResult) {
BasicDBObject result = new BasicDBObject();
result.put(SECURITY_DES_KEY_NAME, refDataResult.getIdentifier());
DBObject fieldData = deserializer.fudgeMsgToObject(DBObject.class, refDataResult.getFieldValues());
result.put(FIELD_DATA_KEY_NAME, fieldData);
return result;
}
}