All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.yamcs.cascading.YamcsTmLink Maven / Gradle / Ivy

There is a newer version: 5.10.9
Show newest version
package org.yamcs.cascading;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.yamcs.YConfiguration;
import org.yamcs.TmPacket;
import org.yamcs.client.ClientException;
import org.yamcs.client.ContainerSubscription;
import org.yamcs.client.MessageListener;
import org.yamcs.client.YamcsClient;
import org.yamcs.protobuf.ContainerData;
import org.yamcs.protobuf.SubscribeContainersRequest;
import org.yamcs.tctm.AbstractTmDataLink;
import org.yamcs.tctm.AggregatedDataLink;
import org.yamcs.utils.TimeEncoding;

/**
 * 
 * Yamcs TM link - subscribes to realtime telemetry
 *
 */
public class YamcsTmLink extends AbstractTmDataLink {
    YamcsLink parentLink;

    public void setContainers(List containers) {
        this.containers = containers;
    }

    List containers;
    ContainerSubscription subscription;

    public YamcsTmLink(YamcsLink parentLink) {
        this.parentLink = parentLink;
    }

    public void init(String instance, String name, YConfiguration config) {
        config = swapConfig(config, "tmRealtimeStream", "tmStream", "tm_realtime");
        super.init(instance, name, config);
    }

    // a little bit of a hack: because we use only one config for the parent,
    // we generate a new one for the sublink with the name tmRealtimeStream/tmArchiveStream changed to tmStream
    // depending on which link it is
    static YConfiguration swapConfig(YConfiguration config, String oldKey, String newKey, String defaultValue) {
        Map root = new HashMap<>(config.getRoot());
        String value = (String) root.remove(oldKey);
        if (value == null) {
            value = defaultValue;
        }

        root.put(newKey, value);
        return YConfiguration.wrap(root);
    }

    @Override
    protected void doStart() {
        if (!isEffectivelyDisabled()) {
            doEnable();
        }
        notifyStarted();
    }

    @Override
    public void doDisable() {
        if (subscription != null) {
            subscription.cancel(true);
            subscription = null;
        }
    }

    @Override
    public void doEnable() {
        if (subscription != null && !subscription.isDone()) {
            return;
        }

        if (containers != null) {
            subscribeContainers();
        }
    }

    void subscribeContainers() {
        YamcsClient yclient = parentLink.getClient();

        subscription = yclient.createContainerSubscription();
        subscription.addMessageListener(new MessageListener() {
            @Override
            public void onMessage(ContainerData data) {
                processContainerData(data);
            }

            public void onError(Throwable t) {
                if (t instanceof ClientException) {
                    eventProducer.sendWarning("Got error when subscribing to containers: " + t.getMessage());
                } else {
                    log.warn("Got error when subscribing to containers: " + t.getMessage());
                }
            }
        });

        subscription.sendMessage(SubscribeContainersRequest.newBuilder()
                .setInstance(parentLink.getUpstreamInstance())
                .setProcessor(parentLink.getUpstreamProcessor())
                .addAllNames(containers).build());

    }

    private void processContainerData(ContainerData data) {
        long rectime = timeService.getMissionTime();
        byte[] pktData = data.getBinary().toByteArray();

        TmPacket pkt = new TmPacket(rectime, pktData);
        if (data.hasGenerationTime()) {
            pkt.setGenerationTime(TimeEncoding.fromProtobufTimestamp(data.getGenerationTime()));
        }
        pkt.setSequenceCount(data.getSeqCount());
        packetCount.incrementAndGet();
        processPacket(pkt);
    }

    @Override
    protected void doStop() {
        if (!isDisabled()) {
            doDisable();
        }
        notifyStopped();
    }

    @Override
    protected Status connectionStatus() {
        Status parentStatus = parentLink.connectionStatus();
        if (parentStatus == Status.OK) {
            boolean ok = subscription != null && !subscription.isDone();
            return ok ? Status.OK : Status.UNAVAIL;
        } else {
            return parentStatus;
        }
    }

    @Override
    public AggregatedDataLink getParent() {
        return parentLink;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy