package org.yamcs; import java.io.File; import java.io.FileReader; import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.yamcs.StreamConfig.StreamConfigEntry; import org.yamcs.alarms.AlarmServer; import org.yamcs.tctm.ParameterDataLinkInitialiser; import org.yamcs.tctm.TcUplinkerAdapter; import org.yamcs.tctm.TmDataLinkInitialiser; import org.yamcs.yarch.YarchDatabase; import org.yamcs.yarch.streamsql.ExecutionContext; import org.yamcs.yarch.streamsql.ParseException; import org.yamcs.yarch.streamsql.StreamSqlException; import org.yamcs.yarch.streamsql.StreamSqlParser; import org.yamcs.yarch.streamsql.StreamSqlStatement; import org.yamcs.yarch.streamsql.TokenMgrError; /** * Run at the very beginning of Yamcs startup; creates different streams required for Yamcs operation * * There are a number of "hardcoded" stream types that can be created without specifying the schema (because the schema has to match the definition expected by other services). * * Additional streams can be created by specifying a file containing StreamSQL commands. * * * @author nm * */ public class StreamInitializer { private static final Logger log = LoggerFactory.getLogger(StreamInitializer.class); final String yamcsInstance; YarchDatabase ydb; public static void createStreams(String yamcsInstance) throws IOException { StreamInitializer si = new StreamInitializer(yamcsInstance); try { si.createStreams(); } catch (StreamSqlException | ParseException e) { throw new ConfigurationException("Cannot create streams", e); } } public StreamInitializer(String yamcsInstance) throws ConfigurationException { ydb = YarchDatabase.getInstance(yamcsInstance); this.yamcsInstance = yamcsInstance; } public void createStreams() throws StreamSqlException, ParseException, IOException { StreamConfig sc = StreamConfig.getInstance(yamcsInstance); for(StreamConfigEntry sce: sc.getEntries()) { if(sce.type == StreamConfig.StandardStreamType.cmdHist) { createCmdHistoryStream(sce.name); } else if(sce.type == StreamConfig.StandardStreamType.tm) { createTmStream(sce.name); } else if(sce.type == StreamConfig.StandardStreamType.param) { createParamStream(sce.name); } else if(sce.type == StreamConfig.StandardStreamType.tc) { createTcStream(sce.name); } else if(sce.type == StreamConfig.StandardStreamType.event) { createEventStream(sce.name); } else if(sce.type == StreamConfig.StandardStreamType.alarm) { createAlarmStream(sce.name); } else if(sce.type == StreamConfig.StandardStreamType.sqlFile) { loadSqlFile(sce.name); //filename in fact } else { throw new IllegalArgumentException("Unknown stream type "+sce.type); } } } private void createEventStream(String streamName) throws StreamSqlException, ParseException { ydb.execute("create stream "+streamName+"(gentime timestamp, source enum, seqNum int, body PROTOBUF('org.yamcs.protobuf.Yamcs$Event'))"); } private void createTcStream(String streamName) throws StreamSqlException, ParseException { ydb.execute("create stream "+streamName+TcUplinkerAdapter.TC_TUPLE_DEFINITION.getStringDefinition()); } private void createTmStream(String streamName) throws StreamSqlException, ParseException { ydb.execute("create stream "+streamName+TmDataLinkInitialiser.TM_TUPLE_DEFINITION.getStringDefinition()); } private void createParamStream(String streamName) throws StreamSqlException, ParseException { ydb.execute("create stream "+streamName+ParameterDataLinkInitialiser.PARAMETER_TUPLE_DEFINITION.getStringDefinition()); } private void createCmdHistoryStream(String streamName) throws StreamSqlException, ParseException { ydb.execute("create stream "+streamName+TcUplinkerAdapter.TC_TUPLE_DEFINITION.getStringDefinition()); } private void createAlarmStream(String streamName) throws StreamSqlException, ParseException { ydb.execute("create stream " + streamName + AlarmServer.ALARM_TUPLE_DEFINITION.getStringDefinition()); } private void loadSqlFile(Object o) throws IOException, StreamSqlException, ParseException { if(!(o instanceof String)) { throw new ConfigurationException("Expected to have a filename to load as SQL File"); } log.debug("Loading SQL File {}", o); String filename = (String)o; File f = new File(filename); ExecutionContext context=new ExecutionContext(yamcsInstance); FileReader reader = new FileReader(f); StreamSqlParser parser=new StreamSqlParser(reader); try { StreamSqlStatement stmt; while((stmt = parser.StreamSqlStatement())!=null) { stmt.execute(context); } } catch (TokenMgrError e) { throw new ParseException(e.getMessage()); } } }