/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.integration.marketdata;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import net.sf.ehcache.CacheManager;
import org.fudgemsg.FudgeMsg;
import org.threeten.bp.ZonedDateTime;
import com.opengamma.bbg.livedata.AbstractBloombergLiveDataServer;
import com.opengamma.bbg.referencedata.ReferenceDataProvider;
import com.opengamma.bbg.replay.BloombergTick;
import com.opengamma.bbg.replay.BloombergTickReceiver;
import com.opengamma.bbg.replay.BloombergTicksReplayer;
import com.opengamma.bbg.replay.BloombergTicksReplayer.Mode;
import com.opengamma.livedata.LiveDataSpecification;
import com.opengamma.livedata.UserPrincipal;
import com.opengamma.livedata.entitlement.LiveDataEntitlementChecker;
/**
* Exposes a window of recorded Bloomberg data in an infinite loop to simulate a live data server.
*/
public class RecordedBloombergLiveDataServer extends AbstractBloombergLiveDataServer {
private final BloombergTicksReplayer _tickReplayer;
private final ReferenceDataProvider _referenceDataProvider;
/**
* Used to keep track of subscriptions ourself in a way that can be queried efficiently, every time a tick is
* replayed, to see whether it is required.
*/
private final ConcurrentMap<String, Object> _subscriptions = new ConcurrentHashMap<String, Object>();
/**
* Creates an instance, parsing the given times from ISO-8601 strings.
*
* @param rootTickPath the recorded ticks directory
* @param dataStart the tick start time
* @param dataEnd the tick end time
* @param referenceDataProvider a source of reference data
* @param cacheManager the cache manager, not null
*/
public RecordedBloombergLiveDataServer(String rootTickPath, String dataStart, String dataEnd, ReferenceDataProvider referenceDataProvider, CacheManager cacheManager) {
this(rootTickPath, ZonedDateTime.parse(dataStart), ZonedDateTime.parse(dataEnd), referenceDataProvider, cacheManager);
}
/**
* Creates an instance.
*
* @param rootTickPath the recorded ticks directory
* @param dataStart the tick start time
* @param dataEnd the tick end time
* @param referenceDataProvider a source of reference data
* @param cacheManager the cache manager, not null
*/
public RecordedBloombergLiveDataServer(String rootTickPath, ZonedDateTime dataStart, ZonedDateTime dataEnd, ReferenceDataProvider referenceDataProvider, CacheManager cacheManager) {
super(cacheManager);
BloombergTickReceiver tickReceiver = new BloombergTickReceiver() {
@Override
public void tickReceived(BloombergTick msg) {
RecordedBloombergLiveDataServer.this.tickReceived(msg.getBuid(), msg.getFields());
}
};
setEntitlementChecker(new LiveDataEntitlementChecker() {
@Override
public Map<LiveDataSpecification, Boolean> isEntitled(UserPrincipal user, Collection<LiveDataSpecification> requestedSpecifications) {
Map<LiveDataSpecification, Boolean> results = new HashMap<LiveDataSpecification, Boolean>();
for (LiveDataSpecification requestedSpec : requestedSpecifications) {
results.put(requestedSpec, true);
}
return results;
}
@Override
public boolean isEntitled(UserPrincipal user, LiveDataSpecification requestedSpecification) {
return true;
}
});
_tickReplayer = new BloombergTicksReplayer(Mode.ORIGINAL_LATENCY, rootTickPath, tickReceiver, dataStart, dataEnd, true, Collections.<String>emptySet());
_referenceDataProvider = referenceDataProvider;
}
@Override
protected void doConnect() {
_tickReplayer.start();
}
@Override
protected void doDisconnect() {
_tickReplayer.stop();
}
@Override
protected Map<String, Object> doSubscribe(Collection<String> uniqueIds) {
Map<String, Object> subscriptions = new HashMap<String, Object>();
for (String uniqueId : uniqueIds) {
subscriptions.put(uniqueId, uniqueId);
}
_subscriptions.putAll(subscriptions);
return subscriptions;
}
@Override
protected void doUnsubscribe(Collection<Object> subscriptionHandles) {
for (Object subscriptionHandle : subscriptionHandles) {
_subscriptions.remove(subscriptionHandle);
}
}
@Override
public ReferenceDataProvider getReferenceDataProvider() {
return _referenceDataProvider;
}
private void tickReceived(String buid, FudgeMsg fields) {
if (_subscriptions.containsKey(buid)) {
liveDataReceived(buid, fields);
}
}
}