package org.yamcs.web.rest.archive;
import org.yamcs.archive.AlarmRecorder;
import org.yamcs.protobuf.Alarms.AlarmData;
import org.yamcs.protobuf.Rest.ListAlarmsResponse;
import org.yamcs.protobuf.SchemaRest;
import org.yamcs.web.HttpException;
import org.yamcs.web.rest.RestHandler;
import org.yamcs.web.rest.RestRequest;
import org.yamcs.web.rest.RestRequest.IntervalResult;
import org.yamcs.web.rest.RestStreamSubscriber;
import org.yamcs.web.rest.RestStreams;
import org.yamcs.web.rest.Route;
import org.yamcs.web.rest.SqlBuilder;
import org.yamcs.xtce.Parameter;
import org.yamcs.xtce.XtceDb;
import org.yamcs.xtceproc.XtceDbFactory;
import org.yamcs.yarch.Stream;
import org.yamcs.yarch.Tuple;
public class ArchiveAlarmRestHandler extends RestHandler {
@Route(path="/api/archive/:instance/alarms", method="GET")
@Route(path="/api/archive/:instance/alarms/:parameter*", method="GET")
//@Route(path="/api/archive/:instance/alarms/:parameter*/:triggerTime?", method="GET") // same comment as below
public void listAlarms(RestRequest req) throws HttpException {
String instance = verifyInstance(req, req.getRouteParam("instance"));
long pos = req.getQueryParameterAsLong("pos", 0);
int limit = req.getQueryParameterAsInt("limit", 100);
SqlBuilder sqlb = new SqlBuilder(AlarmRecorder.TABLE_NAME);
IntervalResult ir = req.scanForInterval();
if (ir.hasInterval()) {
sqlb.where(ir.asSqlCondition("triggerTime"));
}
if (req.hasRouteParam("parameter")) {
XtceDb mdb = XtceDbFactory.getInstance(instance);
Parameter p = verifyParameter(req, mdb, req.getRouteParam("parameter"));
sqlb.where("parameter = '" + p.getQualifiedName() + "'");
}
/*if (req.hasRouteParam("triggerTime")) {
sqlb.where("triggerTime = " + req.getDateRouteParam("triggerTime"));
}*/
sqlb.descend(req.asksDescending(true));
ListAlarmsResponse.Builder responseb = ListAlarmsResponse.newBuilder();
RestStreams.stream(instance, sqlb.toString(), new RestStreamSubscriber(pos, limit) {
@Override
public void processTuple(Stream stream, Tuple tuple) {
AlarmData alarm = ArchiveHelper.tupleToAlarmData(tuple);
responseb.addAlarm(alarm);
}
@Override
public void streamClosed(Stream stream) {
completeOK(req, responseb.build(), SchemaRest.ListAlarmsResponse.WRITE);
}
});
}
/*
Commented out because in its current form the handling is ambiguous to the previous
operation. Perhaps should use queryparams instead. and have parameter* always be terminal
@Route(path="/api/archive/:instance/alarms/:parameter* /:triggerTime/:seqnum", method="GET")
public ChannelFuture getAlarm(RestRequest req) throws HttpException {
String instance = verifyInstance(req, req.getRouteParam("instance"));
XtceDb mdb = XtceDbFactory.getInstance(instance);
Parameter p = verifyParameter(req, mdb, req.getRouteParam("parameter"));
long triggerTime = req.getDateRouteParam("triggerTime");
int seqNum = req.getIntegerRouteParam("seqnum");
String sql = new SqlBuilder(AlarmRecorder.TABLE_NAME)
.where("triggerTime = " + triggerTime)
.where("seqNum = " + seqNum)
.where("parameter = '" + p.getQualifiedName() + "'")
.toString();
List<AlarmData> alarms = new ArrayList<>();
RestStreams.streamAndWait(instance, sql, new RestStreamSubscriber(0, 2) {
@Override
public void processTuple(Stream stream, Tuple tuple) {
AlarmData alarm = ArchiveHelper.tupleToAlarmData(tuple);
alarms.add(alarm);
}
});
if (alarms.isEmpty()) {
throw new NotFoundException(req, "No alarm for id (" + p.getQualifiedName() + ", " + triggerTime + ", " + seqNum + ")");
} else if (alarms.size() > 1) {
throw new InternalServerErrorException("Too many results");
} else {
return sendOK(req, alarms.get(0), SchemaAlarms.AlarmData.WRITE);
}
}*/
}