package org.yamcs.archive;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yamcs.YamcsException;
import org.yamcs.protobuf.Yamcs.NamedObjectId;
import org.yamcs.protobuf.Yamcs.ProtoDataType;
import org.yamcs.protobuf.Yamcs.ReplayRequest;
import org.yamcs.xtce.SequenceContainer;
import org.yamcs.xtce.XtceDb;
import org.yamcs.yarch.Tuple;
import com.google.protobuf.MessageLite;
/**
* Provides replay of the telemetry recorded by XtceTmRecorder
* @author nm
*
*/
public class XtceTmReplayHandler implements ReplayHandler {
Set<String> partitions=new HashSet<>();
final XtceDb xtcedb;
static Logger log=LoggerFactory.getLogger(XtceTmReplayHandler.class);
ReplayRequest request;
public XtceTmReplayHandler(XtceDb xtcedb) {
this.xtcedb=xtcedb;
}
@Override
public void setRequest(ReplayRequest newRequest) throws YamcsException {
this.request=newRequest;
if (newRequest.getPacketRequest().getNameFilterList().isEmpty()) {
partitions=null; //retrieve all
return;
}
partitions.clear();
SequenceContainer rootSc=xtcedb.getRootSequenceContainer();
addPartitions(newRequest.getPacketRequest().getNameFilterList(), rootSc);
}
private void addPartitions(List<NamedObjectId> pnois, SequenceContainer rootSc) throws YamcsException {
for(NamedObjectId pnoi : pnois) {
SequenceContainer sc=xtcedb.getSequenceContainer(pnoi);
if(sc==null) {
throw new YamcsException("Cannot find any sequence container for "+pnoi);
}
if(sc==rootSc) { //retrieve all
partitions=null;
break;
}
//go up in the XTCE hierarchy to find a container on the level one (i.e. is child of the root)
while(sc!=null) {
if(sc.getBaseContainer()==rootSc) {
partitions.add(sc.getQualifiedName());
break;
} else {
sc=sc.getBaseContainer();
}
}
}
}
@Override
public String getSelectCmd() {
StringBuilder sb=new StringBuilder();
sb.append("SELECT ").append(ProtoDataType.TM_PACKET.getNumber()).
append(",* from tm ");
if(partitions!=null) {
if(partitions.isEmpty()) {
return null;
}
sb.append("WHERE pname IN (");
boolean first=true;
for(String pn:partitions) {
if(first) {
first=false;
}
else sb.append(", ");
sb.append("'").append(pn).append("'");
}
sb.append(")");
appendTimeClause(sb, request, false);
} else {
if(request.hasStart() || (request.hasStop())) {
sb.append("WHERE ");
appendTimeClause(sb, request, true);
}
}
if(request.hasReverse() && request.getReverse()) {
sb.append(" ORDER DESC");
}
return sb.toString();
}
@Override
public MessageLite transform(Tuple tuple) {
return GPBHelper.tupleToTmPacketData(tuple);
}
static void appendTimeClause(StringBuilder sb, ReplayRequest request, boolean firstRestriction) {
if(request.hasStart() || (request.hasStop())) {
if(!firstRestriction) sb.append(" and ");
if(request.hasStart()) {
sb.append("gentime>="+request.getStart());
if(request.hasStop()) sb.append(" and gentime<"+request.getStop());
} else {
sb.append("gentime<"+request.getStop());
}
}
}
@Override
public void reset() {
}
}