/*******************************************************************************
* 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 java.io.BufferedInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Timestamp;
import java.util.HashMap;
import org.apache.log4j.Logger;
import org.epics.archiverappliance.EventStream;
import org.epics.archiverappliance.common.TimeUtils;
import edu.stanford.slac.archiverappliance.PBOverHTTP.InputStreamBackedEventStream;
/**
* Client side class for retrieving data from the appliance archiver using the PB over HTTP protocol.
* This is mostly used by the unit tests where the ability to treat retrieval results as event streams is veru useful.
* Java clients should use the pbrawclient which is a lightweight implementation of the same.
* @author mshankar
*
*/
public class RawDataRetrievalAsEventStream implements DataRetrieval {
private static Logger logger = Logger.getLogger(RawDataRetrievalAsEventStream.class.getName());
private String accessURL = null;
public RawDataRetrievalAsEventStream(String accessURL) {
this.accessURL = accessURL;
}
@Override
public EventStream getDataForPVS(String[] pvNames, Timestamp startTime, Timestamp endTime, RetrievalEventProcessor retrievalEventProcessor) {
return getDataForPVS(pvNames, startTime, endTime, retrievalEventProcessor, false, null);
}
@Override
public EventStream getDataForPVS(String[] pvNames, Timestamp startTime, Timestamp endTime, RetrievalEventProcessor retrievalEventProcessor, boolean useReducedDataSet) {
return getDataForPVS(pvNames, startTime, endTime, retrievalEventProcessor, useReducedDataSet, null);
}
@Override
public EventStream getDataForPVS(String[] pvNames, Timestamp startTime, Timestamp endTime, RetrievalEventProcessor retrievalEventProcessor, boolean useReducedDataSet, HashMap<String, String> otherParams) {
StringWriter concatedPVs = new StringWriter();
boolean isFirstEntry = true;
for(String pvName : pvNames) {
if(isFirstEntry) {
isFirstEntry = false;
} else {
concatedPVs.append(",");
}
concatedPVs.append(pvName);
}
// We'll use java.net for now.
StringWriter buf = new StringWriter();
buf.append(accessURL)
.append("?pv=").append(concatedPVs.toString())
.append("&from=").append(TimeUtils.convertToISO8601String(startTime))
.append("&to=").append(TimeUtils.convertToISO8601String(endTime));
if(useReducedDataSet) {
buf.append("&usereduced=true");
}
if(otherParams != null) {
for(String key : otherParams.keySet()) {
buf.append("&");
buf.append(key);
buf.append("=");
buf.append(otherParams.get(key));
}
}
String getURL = buf.toString();
logger.info("URL to fetch data is " + getURL);
try {
URL url = new URL(getURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
if(connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream is = new BufferedInputStream(connection.getInputStream());
if(is.available() <= 0) {
logger.info("We got an empty stream as a response for PVs " + concatedPVs + " + using URL " + url.toString());
return null;
}
return new InputStreamBackedEventStream(is, startTime, retrievalEventProcessor);
} else {
logger.info("No data found for PVs " + concatedPVs + " + using URL " + url.toString());
return null;
}
} catch(Exception ex) {
logger.error("Exception fetching data from URL " + getURL, ex);
}
return null;
}
}