/*******************************************************************************
* Copyright (c) 2011 The Board of Trustees of the Leland Stanford Junior University
* as Operator of the SLAC National Accelerator Laboratory.
* Copyright (c) 2011 Brookhaven National Laboratory.
* EPICS archiver appliance is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*******************************************************************************/
package org.epics.archiverappliance.retrieval.client;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.sql.Timestamp;
import java.util.HashMap;
import org.apache.log4j.Logger;
import org.epics.archiverappliance.Event;
import org.epics.archiverappliance.EventStream;
import org.epics.archiverappliance.EventStreamDesc;
import org.epics.archiverappliance.TomcatSetup;
import org.epics.archiverappliance.common.BasicContext;
import org.epics.archiverappliance.common.TimeUtils;
import org.epics.archiverappliance.common.YearSecondTimestamp;
import org.epics.archiverappliance.config.ArchDBRTypes;
import org.epics.archiverappliance.config.ConfigService;
import org.epics.archiverappliance.config.ConfigServiceForTests;
import org.epics.archiverappliance.utils.nio.ArchPaths;
import org.epics.archiverappliance.utils.simulation.SimulationEventStream;
import org.epics.archiverappliance.utils.simulation.SineGenerator;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import edu.stanford.slac.archiverappliance.PB.data.PBCommonSetup;
import edu.stanford.slac.archiverappliance.PlainPB.PlainPBPathNameUtility;
import edu.stanford.slac.archiverappliance.PlainPB.PlainPBStoragePlugin;
/**
* Test retrieval across year spans.
* @author mshankar
*
*/
public class YearSpanRetrievalTest {
private static final Logger logger = Logger.getLogger(YearSpanRetrievalTest.class.getName());
private ConfigService configService;
PBCommonSetup pbSetup = new PBCommonSetup();
PlainPBStoragePlugin pbplugin = new PlainPBStoragePlugin();
TomcatSetup tomcatSetup = new TomcatSetup();
@Before
public void setUp() throws Exception {
configService = new ConfigServiceForTests(new File("./bin"));
pbSetup.setUpRootFolder(pbplugin);
tomcatSetup.setUpWebApps(this.getClass().getSimpleName());
generateDataForYears(ConfigServiceForTests.ARCH_UNIT_TEST_PVNAME_PREFIX + "yspan", (short) 2010, (short) 2013);
}
private void generateDataForYears(String pvName, short startyear, short endyear) throws IOException {
// We skip generation of the file only if all the files exist.
boolean deletefilesandgeneratedata = false;
for(short currentyear = startyear; currentyear <= endyear; currentyear++) {
if(!PlainPBPathNameUtility.getPathNameForTime(pbplugin, pvName, TimeUtils.getStartOfYearInSeconds(currentyear), new ArchPaths(), configService.getPVNameToKeyConverter()).toFile().exists()) {
logger.info("File for year " + currentyear + " does not exist. Generating data for all the years.");
deletefilesandgeneratedata = true;
break;
}
}
// Delete all the files for the specified span
if(deletefilesandgeneratedata) {
for(short currentyear = startyear; currentyear <= endyear; currentyear++) {
Files.deleteIfExists(PlainPBPathNameUtility.getPathNameForTime(pbplugin, pvName, TimeUtils.getStartOfYearInSeconds(currentyear), new ArchPaths(), configService.getPVNameToKeyConverter()));
}
SimulationEventStream simstream = new SimulationEventStream(ArchDBRTypes.DBR_SCALAR_DOUBLE, new SineGenerator(0), startyear, endyear);
// The pbplugin should handle all the rotation etc.
try(BasicContext context = new BasicContext()) {
pbplugin.appendData(context, pvName, simstream);
}
}
}
@After
public void tearDown() throws Exception {
tomcatSetup.tearDown();
}
static class YearCount {
int count = 0;
}
static long previousEpochSeconds = 0;
@Test
public void testYearSpan() {
RawDataRetrievalAsEventStream rawDataRetrieval = new RawDataRetrievalAsEventStream("http://localhost:" + ConfigServiceForTests.RETRIEVAL_TEST_PORT+ "/retrieval/data/getData.raw");
Timestamp start = TimeUtils.convertFromISO8601String("2011-12-31T08:00:00.000Z");
Timestamp end = TimeUtils.convertFromISO8601String("2012-01-01T08:00:00.000Z");
EventStream stream = null;
try {
stream = rawDataRetrieval.getDataForPVS(new String[] { ConfigServiceForTests.ARCH_UNIT_TEST_PVNAME_PREFIX + "yspan" }, start, end, new RetrievalEventProcessor() {
@Override
public void newPVOnStream(EventStreamDesc desc) {
logger.info("On the client side, switching to processing PV " + desc.getPvName());
previousEpochSeconds = 0;
}
});
// We are making sure that the stream we get back has times in sequential order...
HashMap<Short, YearCount> counts = new HashMap<Short, YearCount>();
for(Event e : stream) {
long actualSeconds = e.getEpochSeconds();
assertTrue(actualSeconds >= previousEpochSeconds);
previousEpochSeconds = actualSeconds;
YearSecondTimestamp actualYST = TimeUtils.convertToYearSecondTimestamp(actualSeconds);
YearCount ycount = counts.get(new Short(actualYST.getYear()));
if(ycount == null) {
ycount = new YearCount();
counts.put(new Short(actualYST.getYear()), ycount);
}
ycount.count++;
}
assertTrue(counts.get(new Short((short)2011)).count > 20000);
assertTrue(counts.get(new Short((short)2012)).count > 20000);
} finally {
if(stream != null) try { stream.close(); stream = null; } catch(Throwable t) { }
}
}
}