/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.integration.tool.marketdata;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.threeten.bp.LocalDate;
import com.google.common.collect.Maps;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.core.historicaltimeseries.HistoricalTimeSeries;
import com.opengamma.id.UniqueId;
import com.opengamma.master.historicaltimeseries.HistoricalTimeSeriesGetFilter;
import com.opengamma.master.historicaltimeseries.HistoricalTimeSeriesInfoSearchRequest;
import com.opengamma.master.historicaltimeseries.HistoricalTimeSeriesInfoSearchResult;
import com.opengamma.master.historicaltimeseries.HistoricalTimeSeriesMaster;
import com.opengamma.master.historicaltimeseries.ManageableHistoricalTimeSeries;
import com.opengamma.master.historicaltimeseries.ManageableHistoricalTimeSeriesInfo;
import com.opengamma.master.historicaltimeseries.impl.HistoricalTimeSeriesMasterUtils;
/**
* Class to copy all HTS from one master to another.
*/
public class HistoricalTimeSeriesMasterCopier {
private static final Logger s_logger = LoggerFactory.getLogger(HistoricalTimeSeriesMasterCopier.class);
private HistoricalTimeSeriesMaster _sourceMaster;
private HistoricalTimeSeriesMaster _destinationMaster;
public HistoricalTimeSeriesMasterCopier(HistoricalTimeSeriesMaster sourceMaster, HistoricalTimeSeriesMaster destinationMaster) {
_sourceMaster = sourceMaster;
_destinationMaster = destinationMaster;
}
public void copy(boolean fastCopy, boolean deleteDestinationSeriesNotInSource, boolean verbose, boolean noAdditions) {
HistoricalTimeSeriesInfoSearchRequest infoSearchRequest = new HistoricalTimeSeriesInfoSearchRequest();
HistoricalTimeSeriesInfoSearchResult sourceSearchResult = _sourceMaster.search(infoSearchRequest);
List<ManageableHistoricalTimeSeriesInfo> sourceInfoList = sourceSearchResult.getInfoList();
HistoricalTimeSeriesInfoSearchResult destSearchResult = _destinationMaster.search(infoSearchRequest);
List<ManageableHistoricalTimeSeriesInfo> destInfoList = destSearchResult.getInfoList();
Set<ManageableHistoricalTimeSeriesInfo> bothInfoSetSource = new TreeSet<ManageableHistoricalTimeSeriesInfo>(new ManageableHistoricalTimeSeriesInfoComparator());
bothInfoSetSource.addAll(sourceInfoList);
bothInfoSetSource.retainAll(destInfoList);
Set<ManageableHistoricalTimeSeriesInfo> bothInfoSetDestination = new TreeSet<ManageableHistoricalTimeSeriesInfo>(new ManageableHistoricalTimeSeriesInfoComparator());
bothInfoSetDestination.addAll(destInfoList);
bothInfoSetDestination.retainAll(sourceInfoList);
Map<ManageableHistoricalTimeSeriesInfo, UniqueId> infoToSourceUniqueIds = Maps.newHashMap();
// we have have two sets containing the TS in both, with the ids from the source in one and the ids from the dest in the other
// now build a map of info->source uid
for (ManageableHistoricalTimeSeriesInfo info : bothInfoSetSource) {
infoToSourceUniqueIds.put(info, info.getUniqueId());
}
// step through the destination results and look up the corresponding source id.
for (ManageableHistoricalTimeSeriesInfo info : bothInfoSetDestination) {
if (infoToSourceUniqueIds.containsKey(info)) {
if (verbose) {
System.out.println("Time series " + info + " is in source and destination");
}
UniqueId sourceId = infoToSourceUniqueIds.get(info);
UniqueId destinationId = info.getUniqueId();
diffAndCopy(sourceId, destinationId, fastCopy, verbose);
} else {
throw new OpenGammaRuntimeException("Couldn't find info in set, which is supposed to be impossible");
}
}
if (!noAdditions) {
Set<ManageableHistoricalTimeSeriesInfo> sourceNotDestinationInfo = new TreeSet<ManageableHistoricalTimeSeriesInfo>(new ManageableHistoricalTimeSeriesInfoComparator());
sourceNotDestinationInfo.addAll(sourceInfoList);
sourceNotDestinationInfo.removeAll(destInfoList);
for (ManageableHistoricalTimeSeriesInfo info : sourceNotDestinationInfo) {
if (verbose) {
System.out.println("Time series " + info + " is in source but not destination");
}
add(info, verbose);
}
}
if (deleteDestinationSeriesNotInSource) {
Set<ManageableHistoricalTimeSeriesInfo> destinationNotSourceInfo = new TreeSet<ManageableHistoricalTimeSeriesInfo>(new ManageableHistoricalTimeSeriesInfoComparator());
destinationNotSourceInfo.addAll(destInfoList);
destinationNotSourceInfo.removeAll(sourceInfoList);
for (ManageableHistoricalTimeSeriesInfo info : destinationNotSourceInfo) {
delete(info);
if (verbose) {
System.out.println("Deleted time series " + info + " which is in destination but not source");
}
}
}
}
private void delete(ManageableHistoricalTimeSeriesInfo info) {
_destinationMaster.remove(info.getUniqueId());
}
private void add(ManageableHistoricalTimeSeriesInfo sourceInfo, boolean verbose) {
HistoricalTimeSeriesMasterUtils destinationMasterUtils = new HistoricalTimeSeriesMasterUtils(_destinationMaster);
HistoricalTimeSeries series = _destinationMaster.getTimeSeries(sourceInfo.getUniqueId());
destinationMasterUtils.writeTimeSeries(sourceInfo.getName(),
sourceInfo.getDataSource(),
sourceInfo.getDataProvider(),
sourceInfo.getDataField(),
sourceInfo.getObservationTime(),
sourceInfo.getExternalIdBundle().toBundle(),
series.getTimeSeries());
if (verbose) {
System.out.println("Added new time series to destination with " + series.getTimeSeries().size() + " data points");
}
}
private boolean diffAndCopy(UniqueId sourceId, UniqueId destinationId, boolean fastCopy, boolean verbose) {
if (fastCopy) {
ManageableHistoricalTimeSeries sourceTimeSeries = _sourceMaster.getTimeSeries(sourceId, HistoricalTimeSeriesGetFilter.ofLatestPoint());
ManageableHistoricalTimeSeries destTimeSeries = _destinationMaster.getTimeSeries(destinationId, HistoricalTimeSeriesGetFilter.ofLatestPoint());
if (!sourceTimeSeries.getTimeSeries().equals(destTimeSeries.getTimeSeries())) {
HistoricalTimeSeriesGetFilter filter = new HistoricalTimeSeriesGetFilter();
LocalDate lastSourceDate = sourceTimeSeries.getTimeSeries().getLatestTime();
LocalDate lastDestinationDate = destTimeSeries.getTimeSeries().getLatestTime();
if (lastSourceDate.isAfter(lastDestinationDate)) {
filter.setEarliestDate(lastDestinationDate.plusDays(1));
filter.setLatestDate(lastSourceDate);
sourceTimeSeries = _sourceMaster.getTimeSeries(sourceId, filter);
// get JUST the new days
_destinationMaster.updateTimeSeriesDataPoints(destinationId, sourceTimeSeries.getTimeSeries());
if (verbose) {
System.out.println("Fast updating " + sourceTimeSeries.getTimeSeries().size() + " data points");
}
return true;
} else {
s_logger.warn("Destination for " + destinationId + " has more up to date data than source, skipping!");
return false;
}
} else {
if (verbose) {
System.out.println("Fast compare of source and destination show they are the same, skipping");
}
}
return false;
} else {
ManageableHistoricalTimeSeries sourceTimeSeries = _sourceMaster.getTimeSeries(sourceId);
ManageableHistoricalTimeSeries destTimeSeries = _destinationMaster.getTimeSeries(destinationId);
if (!sourceTimeSeries.getTimeSeries().equals(destTimeSeries.getTimeSeries())) {
sourceTimeSeries = _sourceMaster.getTimeSeries(sourceId);
HistoricalTimeSeriesMasterUtils masterUtils = new HistoricalTimeSeriesMasterUtils(_destinationMaster);
masterUtils.writeTimeSeries(destinationId, sourceTimeSeries.getTimeSeries());
if (verbose) {
System.out.println("Full (slow) copy of source data to destination");
} else {
System.out.println("Full (slow) compare of source and destination show they are the same, skipping");
}
}
return sourceTimeSeries.getTimeSeries().equals(destTimeSeries.getTimeSeries());
}
}
}