package org.yamcs.archive; import static org.yamcs.tctm.ParameterDataLinkInitialiser.PARAMETER_TUPLE_DEFINITION; import static org.yamcs.tctm.ParameterDataLinkInitialiser.PARAMETER_TUPLE_COL_GROUP; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.yamcs.ConfigurationException; import org.yamcs.StreamConfig; import org.yamcs.YConfiguration; import org.yamcs.StreamConfig.StandardStreamType; import org.yamcs.StreamConfig.StreamConfigEntry; import org.yamcs.tctm.ParameterDataLinkInitialiser; import org.yamcs.yarch.Stream; import org.yamcs.yarch.YarchDatabase; import com.google.common.util.concurrent.AbstractService; /** * ParameterRecorder * Records (processed) Parameters * * The base table definition is {@link ParameterDataLinkInitialiser} * * This records parameters as tuples - good for realtime recording but not very efficient for retrieval of a few parameters over long time periods. * * The {@link org.yamcs.parameterarchive} records parameters in a columnar fashion - not good for realtime but much more efficient for retrieval especially retrieval of few parameters over long time periods. * * @author nm * */ public class ParameterRecorder extends AbstractService { String yamcsInstance; Stream realtimeStream, dumpStream; static public final String TABLE_NAME = "pp"; List<String> streams = new ArrayList<String>(); public ParameterRecorder(String yamcsInstance) { this(yamcsInstance, null); } public ParameterRecorder(String yamcsInstance, Map<String, Object> config) { this.yamcsInstance=yamcsInstance; YarchDatabase ydb=YarchDatabase.getInstance(yamcsInstance); try { String cols = PARAMETER_TUPLE_DEFINITION.getStringDefinition1(); if(ydb.getTable(TABLE_NAME)==null) { String query="create table "+TABLE_NAME+"("+cols+", primary key(gentime, seqNum)) histogram("+PARAMETER_TUPLE_COL_GROUP+") partition by time_and_value(gentime"+XtceTmRecorder.getTimePartitioningSchemaSql()+",group) table_format=compressed"; ydb.execute(query); } StreamConfig sc = StreamConfig.getInstance(yamcsInstance); if(config==null || !config.containsKey("streams")) { List<StreamConfigEntry> sceList = sc.getEntries(StandardStreamType.param); for(StreamConfigEntry sce: sceList){ streams.add(sce.getName()); ydb.execute("insert_append into "+TABLE_NAME+" select * from "+sce.getName()); } } else if(config.containsKey("streams")){ List<String> streamNames = YConfiguration.getList(config, "streams"); for(String sn: streamNames) { StreamConfigEntry sce = sc.getEntry(StandardStreamType.param, sn); if(sce==null) { throw new ConfigurationException("No stream config found for '"+sn+"'"); } streams.add(sce.getName()); ydb.execute("insert into "+TABLE_NAME+" select * from "+sce.getName()); } } } catch (Exception e) { throw new ConfigurationException("exception when creating parameter input stream", e); } } @Override protected void doStart() { notifyStarted(); } @Override protected void doStop() { YarchDatabase ydb = YarchDatabase.getInstance(yamcsInstance); Utils.closeTableWriters(ydb, streams); notifyStopped(); } }