package org.yamcs.tctm; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.yamcs.Processor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.yamcs.ConfigurationException; import org.yamcs.InvalidIdentification; import org.yamcs.parameter.ParameterValue; import org.yamcs.parameter.ParameterProvider; import org.yamcs.parameter.ParameterRequestManager; import org.yamcs.protobuf.Yamcs.NamedObjectId; import org.yamcs.xtce.Parameter; import org.yamcs.xtce.XtceDb; import org.yamcs.xtceproc.XtceDbFactory; import org.yamcs.yarch.Stream; import org.yamcs.yarch.StreamSubscriber; import org.yamcs.yarch.Tuple; import org.yamcs.yarch.YarchDatabase; import com.google.common.util.concurrent.AbstractService; /** * Provides parameters from yarch streams (pp_realtime) to ParameterRequestManager. * * @author nm * */ public class StreamParameterProvider extends AbstractService implements StreamSubscriber, ParameterProvider { Stream stream; ParameterRequestManager paraListener; final XtceDb xtceDb; private static final Logger log = LoggerFactory.getLogger(StreamParameterProvider.class); public StreamParameterProvider(String archiveInstance, Map<String, String> config) throws ConfigurationException { YarchDatabase ydb=YarchDatabase.getInstance(archiveInstance); if(!config.containsKey("stream")) { throw new ConfigurationException("the config(args) for StreamPpProvider has to contain a parameter 'stream' - stream name for retrieving parameters from"); } String streamName = config.get("stream"); stream=ydb.getStream(streamName); if(stream==null) { throw new ConfigurationException("Cannot find a stream named "+streamName); } xtceDb=XtceDbFactory.getInstance(archiveInstance); } @Override protected void doStart() { stream.addSubscriber(this); notifyStarted(); } @Override protected void doStop() { stream.removeSubscriber(this); notifyStopped(); } /** * Make sure all parameters are defined in the XtceDB, otherwise the PRM will choke */ @Override public void onTuple(Stream s, Tuple tuple) {//the definition of the tuple is in PpProviderAdapter List<ParameterValue> params=new ArrayList<>(); for(int i=4; i<tuple.size(); i++) { Object o = tuple.getColumn(i); ParameterValue pv; if(o instanceof org.yamcs.protobuf.Pvalue.ParameterValue) { org.yamcs.protobuf.Pvalue.ParameterValue gpv=(org.yamcs.protobuf.Pvalue.ParameterValue)tuple.getColumn(i); String name = tuple.getColumnDefinition(i).getName(); Parameter ppdef = xtceDb.getParameter(name); if(ppdef==null) { continue; } pv = ParameterValue.fromGpb(ppdef, gpv); } else if(o instanceof ParameterValue) { pv = (ParameterValue)o; if(pv.getParameter()==null) { Parameter ppdef = xtceDb.getParameter(pv.getParameterQualifiedNamed()); if(ppdef==null) { continue; } pv.setParameter(ppdef); } } else { log.warn("Recieved data that is not parameter value but {}", o.getClass()); continue; } params.add(pv); } paraListener.update(params); } @Override public void streamClosed(Stream s) { notifyStopped(); } @Override public void setParameterListener(ParameterRequestManager paraListener) { this.paraListener = paraListener; } @Override public void stopProviding(Parameter paramDef) { } @Override public boolean canProvide(NamedObjectId id) { if(xtceDb.getParameter(id)!=null) { return true; } else return false; } @Override public boolean canProvide(Parameter p) { return xtceDb.getParameter(p.getQualifiedName())!=null; } @Override public Parameter getParameter(NamedObjectId id) throws InvalidIdentification { Parameter p=xtceDb.getParameter(id); if(p==null) { throw new InvalidIdentification(); } else return p; } @Override public void startProviding(Parameter paramDef) { // TODO Auto-generated method stub } @Override public void startProvidingAll() { // TODO Auto-generated method stub } @Override public void init(Processor processor) { //nothing to be done here } }