/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.integration.copier;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.mockito.stubbing.OngoingStubbing;
import org.testng.annotations.Test;
import org.threeten.bp.LocalDate;
import org.threeten.bp.format.DateTimeFormatter;
import org.threeten.bp.format.DateTimeFormatterBuilder;
import au.com.bytecode.opencsv.CSVReader;
import com.opengamma.id.ExternalId;
import com.opengamma.id.ExternalIdBundleWithDates;
import com.opengamma.id.ExternalIdSearch;
import com.opengamma.integration.copier.sheet.SheetFormat;
import com.opengamma.integration.copier.sheet.reader.SheetReader;
import com.opengamma.integration.copier.timeseries.reader.SingleSheetMultiTimeSeriesReader;
import com.opengamma.integration.copier.timeseries.reader.TimeSeriesReader;
import com.opengamma.integration.copier.timeseries.writer.MasterTimeSeriesWriter;
import com.opengamma.integration.copier.timeseries.writer.TimeSeriesWriter;
import com.opengamma.master.historicaltimeseries.HistoricalTimeSeriesInfoDocument;
import com.opengamma.master.historicaltimeseries.HistoricalTimeSeriesInfoSearchRequest;
import com.opengamma.master.historicaltimeseries.HistoricalTimeSeriesInfoSearchResult;
import com.opengamma.master.historicaltimeseries.HistoricalTimeSeriesMaster;
import com.opengamma.master.historicaltimeseries.ManageableHistoricalTimeSeriesInfo;
import com.opengamma.master.historicaltimeseries.impl.InMemoryHistoricalTimeSeriesMaster;
import com.opengamma.timeseries.date.localdate.ImmutableLocalDateDoubleTimeSeries;
import com.opengamma.timeseries.date.localdate.LocalDateDoubleTimeSeries;
import com.opengamma.util.test.TestGroup;
/**
* Test.
*/
@Test(groups = TestGroup.UNIT)
public class TimeSeriesLoaderTest {
private static final String FILENAME = "src/test/java/com/opengamma/integration/copier/TimeSeries.csv";
private static final String DATA_SOURCE = "source";
private static final String DATA_PROVIDER = "provider";
private static final String DATA_FIELD = "field";
private static final String OBSERVATION_TIME = "observation";
private static final String DATE_FORMAT = "yyyyMMdd";
private static final String ID_SCHEME = "scheme";
private static final ExternalId EXISTING_HTSINFO_EXTERNALID = ExternalId.of(ID_SCHEME, "abc");
private static final ExternalId NEW_HTSINFO_EXTERNALID = ExternalId.of(ID_SCHEME, "def");
/**
* Tests the time series readers in isolation through the use of a mock sheet reader and a mock time series writer.
* A time series is constructed, converted to a sheet (list of rows) and fed through the mock sheet reader into the
* time series reader, which should then reconstruct the time series and write it to the mock time series writer.
* We verify whether this actually happens for the particular test case.
* NOTE: this tests SingleSheetMultiTimeSeriesReader alone, the only reader in use at the moment
*/
@Test
public void testTimeSeriesReaders() {
// Build a mock sheet reader with some rows
LocalDate[] dates = {LocalDate.of(2010,1,1), LocalDate.of(2011,1,1)};
double[] times = {1.0, 2.0};
LocalDateDoubleTimeSeries lddts = ImmutableLocalDateDoubleTimeSeries.of(dates, times);
SheetReader mockSheetReader = buildMockSheetReader(lddts);
TimeSeriesReader reader = new SingleSheetMultiTimeSeriesReader(
mockSheetReader, DATA_SOURCE, DATA_PROVIDER, DATA_FIELD, OBSERVATION_TIME, ID_SCHEME, DATE_FORMAT);
// Write
TimeSeriesWriter mockTimeSeriesWriter = mock(TimeSeriesWriter.class);
reader.writeTo(mockTimeSeriesWriter);
// check sheet reader calls and ts writer calls
verify(mockTimeSeriesWriter, times(1)).writeDataPoints(
EXISTING_HTSINFO_EXTERNALID, DATA_SOURCE, DATA_PROVIDER, DATA_FIELD, OBSERVATION_TIME,
lddts);
}
/**
* Tests the time series writers in isolation through the use of a mock tool context that
* references a specially-created and populated InMemoryHistoricalTimeSeriesMaster. The time series writer
* to be tested is supplied with a time series to write, which already exists in the master, with some data points.
* We then attempt to retrieve the supposedly updated time series from the in-memory master and assert that this is
* the same as the one passed to the writer merged with its original data points.
* NOTE: this tests MasterTimeSeriesWriter alone, the only writer in use at the moment
*/
@Test
public void testTimeSeriesWritersExistingHts() {
// Build a mock master with an existing hts
LocalDate[] existingDates = {LocalDate.of(2010,1,1), LocalDate.of(2011,1,1)};
double[] existingValues = {1.0, 2.0};
LocalDateDoubleTimeSeries existingDataPoints = ImmutableLocalDateDoubleTimeSeries.of(existingDates, existingValues);
LocalDate[] newDates = {LocalDate.of(2010,2,1), LocalDate.of(2011,2,1)};
double[] newValues = {1.5, 2.5};
LocalDateDoubleTimeSeries newDataPoints = ImmutableLocalDateDoubleTimeSeries.of(newDates, newValues);
HistoricalTimeSeriesMaster htsMaster = buildHistoricalTimeSeriesMaster(existingDataPoints);
// Write the new data points to an existing hts
TimeSeriesWriter writer = new MasterTimeSeriesWriter(htsMaster);
writer.writeDataPoints(EXISTING_HTSINFO_EXTERNALID, DATA_SOURCE, DATA_PROVIDER, DATA_FIELD, OBSERVATION_TIME,
newDataPoints);
// Retrieve the hts contents from the master
HistoricalTimeSeriesInfoSearchRequest request = new HistoricalTimeSeriesInfoSearchRequest();
request.setExternalIdSearch(ExternalIdSearch.of(EXISTING_HTSINFO_EXTERNALID));
HistoricalTimeSeriesInfoSearchResult result = htsMaster.search(request);
LocalDateDoubleTimeSeries retrievedDataPoints = null;
if (result != null && result.getFirstInfo() != null) {
retrievedDataPoints = htsMaster.getTimeSeries(
htsMaster.get(result.getFirstInfo().getUniqueId()).getInfo().getTimeSeriesObjectId().atLatestVersion()).getTimeSeries();
}
// Assert that the retrieved contents is as expected (combined existing and new dates/values)
LocalDate[] combinedDates = {LocalDate.of(2010,1,1), LocalDate.of(2010,2,1), LocalDate.of(2011,1,1), LocalDate.of(2011,2,1)};
double[] combinedValues = {1.0, 1.5, 2.0, 2.5};
LocalDateDoubleTimeSeries combinedDataPoints = ImmutableLocalDateDoubleTimeSeries.of(combinedDates, combinedValues);
assert(combinedDataPoints.equals(retrievedDataPoints));
}
/**
* Tests the time series writers in isolation through the use of a mock tool context that
* references a specially-created and populated InMemoryHistoricalTimeSeriesMaster. The time series writer
* to be tested is supplied with a time series to write, which doesn't already exist in the master.
* We then attempt to retrieve the new time series from the in-memory master and assert that this is
* the same as the one passed to the writer.
* NOTE: this tests MasterTimeSeriesWriter alone, the only writer in use at the moment
*/
@Test
public void testTimeSeriesWritersNewHts() {
// Build a mock master with an existing hts
LocalDate[] dates = {LocalDate.of(2010,1,1), LocalDate.of(2011,1,1)};
double[] values = {1.0, 2.0};
LocalDateDoubleTimeSeries dataPoints = ImmutableLocalDateDoubleTimeSeries.of(dates, values);
HistoricalTimeSeriesMaster htsMaster = buildHistoricalTimeSeriesMaster(dataPoints);
// Write the new data points to an existing hts
TimeSeriesWriter writer = new MasterTimeSeriesWriter(htsMaster);
writer.writeDataPoints(NEW_HTSINFO_EXTERNALID, DATA_SOURCE, DATA_PROVIDER, DATA_FIELD, OBSERVATION_TIME,
dataPoints);
// Retrieve and check the hts master contents
HistoricalTimeSeriesInfoSearchRequest request = new HistoricalTimeSeriesInfoSearchRequest();
request.setExternalIdSearch(ExternalIdSearch.of(NEW_HTSINFO_EXTERNALID));
HistoricalTimeSeriesInfoSearchResult result = htsMaster.search(request);
LocalDateDoubleTimeSeries retrievedDataPoints = null;
if (result != null && result.getFirstInfo() != null) {
retrievedDataPoints = htsMaster.getTimeSeries(
htsMaster.get(result.getFirstInfo().getUniqueId()).getInfo().getTimeSeriesObjectId().atLatestVersion()).getTimeSeries();
}
assert(dataPoints.equals(retrievedDataPoints));
}
/**
* Tests the entire time series import pipeline, sending data points all the way from a test input file to
* an in-memory master and ensuring that the same points are retrieved.
*/
@Test
public void testTimeSeriesLoaderTool() throws FileNotFoundException {
// Build a mock master with an existing hts
LocalDate[] existingDates = {LocalDate.of(2010,1,1), LocalDate.of(2011,1,1)};
double[] existingValues = {1.0, 2.0};
LocalDateDoubleTimeSeries existingDataPoints = ImmutableLocalDateDoubleTimeSeries.of(existingDates, existingValues);
// Read in the time series directly from the file and construct a time series to compare with
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
builder.appendPattern(DATE_FORMAT);
DateTimeFormatter dateFormat = builder.toFormatter();
String readId = "";
List<LocalDate> dates = new ArrayList<LocalDate>();
List<Double> values = new ArrayList<Double>();
CSVReader csvReader = null;
try {
csvReader = new CSVReader(new FileReader(FILENAME));
csvReader.readNext(); // discard header row
String[] row;
while ((row = csvReader.readNext()) != null) {
// assume columns in this order: id, date, value; ignore id
dates.add(LocalDate.parse(row[1], dateFormat));
values.add(Double.parseDouble(row[2]));
readId = row[0];
}
} catch (Throwable ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
} finally {
IOUtils.closeQuietly(csvReader);
}
LocalDateDoubleTimeSeries compareDataPoints = ImmutableLocalDateDoubleTimeSeries.of(dates, values);
// Set up the reader to read from file and the writer to write to the in-memory master, and do the import
InputStream fileStream = new BufferedInputStream(new FileInputStream(FILENAME));
TimeSeriesReader reader = new SingleSheetMultiTimeSeriesReader(
SheetFormat.of(FILENAME), fileStream, DATA_SOURCE, DATA_PROVIDER, DATA_FIELD, OBSERVATION_TIME, ID_SCHEME, DATE_FORMAT);
HistoricalTimeSeriesMaster htsMaster = buildHistoricalTimeSeriesMaster(existingDataPoints);
TimeSeriesWriter writer = new MasterTimeSeriesWriter(htsMaster);
reader.writeTo(writer);
// Retrieve hts master contents
HistoricalTimeSeriesInfoSearchRequest request = new HistoricalTimeSeriesInfoSearchRequest();
request.setExternalIdSearch(ExternalIdSearch.of(ExternalId.of(ID_SCHEME, readId)));
HistoricalTimeSeriesInfoSearchResult result = htsMaster.search(request);
LocalDateDoubleTimeSeries retrievedDataPoints = null;
if (result != null && result.getFirstInfo() != null) {
retrievedDataPoints = htsMaster.getTimeSeries(
htsMaster.get(result.getFirstInfo().getUniqueId()).getInfo().getTimeSeriesObjectId().atLatestVersion()).getTimeSeries();
}
assert(compareDataPoints.equals(retrievedDataPoints));
}
private SheetReader buildMockSheetReader(LocalDateDoubleTimeSeries lddts) {
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
builder.appendPattern(DATE_FORMAT);
DateTimeFormatter dateFormat = builder.toFormatter();
SheetReader mock = mock(SheetReader.class);
OngoingStubbing<Map<String, String>> stub = when(mock.loadNextRow());
for (Map.Entry<LocalDate, Double> entry : lddts) {
Map<String, String> row = new HashMap<String, String>();
row.put("id", EXISTING_HTSINFO_EXTERNALID.getValue());
row.put("date", entry.getKey().toString(dateFormat));
row.put("value", entry.getValue().toString());
stub = stub.thenReturn(row);
}
stub.thenReturn(null);
return mock;
}
private HistoricalTimeSeriesMaster buildHistoricalTimeSeriesMaster(LocalDateDoubleTimeSeries lddts) {
// Create HTS info and infoDoc
ManageableHistoricalTimeSeriesInfo mHtsInfo = new ManageableHistoricalTimeSeriesInfo();
mHtsInfo.setDataField(DATA_FIELD);
mHtsInfo.setDataProvider(DATA_PROVIDER);
mHtsInfo.setDataSource(DATA_SOURCE);
mHtsInfo.setObservationTime(OBSERVATION_TIME);
mHtsInfo.setExternalIdBundle(ExternalIdBundleWithDates.of(EXISTING_HTSINFO_EXTERNALID.toBundle()));
mHtsInfo.setName("Test HTS");
HistoricalTimeSeriesInfoDocument htsInfoDoc = new HistoricalTimeSeriesInfoDocument(mHtsInfo);
// Create in memory HTS master and add HTS info/doc
HistoricalTimeSeriesMaster htsMaster = new InMemoryHistoricalTimeSeriesMaster();
htsInfoDoc = htsMaster.add(htsInfoDoc);
// Create the actual time series and add to HTS master
htsMaster.updateTimeSeriesDataPoints(htsInfoDoc.getInfo().getTimeSeriesObjectId(), lddts);
return htsMaster;
}
}