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

org.yamcs.tctm.ArtemisParameterDataLink Maven / Gradle / Ivy

There is a newer version: 4.10.9
Show newest version
package org.yamcs.tctm;

import java.util.concurrent.atomic.AtomicLong;

import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.client.ClientConsumer;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.MessageHandler;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
import org.yamcs.ConfigurationException;
import org.yamcs.StandardTupleDefinitions;
import org.yamcs.YConfiguration;
import org.yamcs.api.artemis.Protocol;
import org.yamcs.artemis.AbstractArtemisTranslatorService;
import org.yamcs.logging.Log;
import org.yamcs.protobuf.Pvalue.ParameterData;
import org.yamcs.xtce.XtceDb;
import org.yamcs.xtceproc.XtceDbFactory;

import com.google.common.util.concurrent.AbstractService;

/**
 * receives data from ActiveMQ Artemis and publishes it into a yamcs stream
 * 
 * @author nm
 *
 */
public class ArtemisParameterDataLink extends AbstractService implements ParameterDataLink, MessageHandler {
    protected AtomicLong totalPpCount = new AtomicLong(0);
    protected volatile boolean disabled = false;

    protected Log log;
    private ParameterSink ppListener;
    final XtceDb ppdb;
    final String artemisAddress;
    ClientSession artemisSession;
    ServerLocator locator;
    ClientSessionFactory factory;
    YConfiguration config;
    final String linkName;
    ClientConsumer client;

    public ArtemisParameterDataLink(String instance, String name, String artemisAddress) throws ConfigurationException {
        log = new Log(getClass(), instance);
        log.setContext(name);
        ppdb = XtceDbFactory.getInstance(instance);
        this.artemisAddress = artemisAddress;
        this.linkName = name;
        locator = AbstractArtemisTranslatorService.getServerLocator(instance);
    }

    public ArtemisParameterDataLink(String instance, String name, YConfiguration config) {
        this(instance, name, config.getString("address"));
        this.config = config;
    }

    @Override
    public void setParameterSink(ParameterSink ppListener) {
        this.ppListener = ppListener;
    }

    @Override
    public Status getLinkStatus() {
        if (disabled) {
            return Status.DISABLED;
        } else {
            return Status.OK;
        }
    }

    @Override
    public void disable() {
        disabled = true;
    }

    @Override
    public void enable() {
        disabled = false;
    }

    @Override
    public boolean isDisabled() {
        return disabled;
    }

    @Override
    public String getDetailedStatus() {
        if (disabled) {
            return "DISABLED";
        } else {
            return "OK";
        }
    }

    @Override
    public long getDataInCount() {
        return totalPpCount.get();
    }

    @Override
    public long getDataOutCount() {
        return 0;
    }

    @Override
    public void resetCounters() {
        totalPpCount.set(0);
    }

    @Override
    public void onMessage(ClientMessage msg) {
        try {
            msg.acknowledge();
            if (disabled) {
                return;
            }
            ParameterData pd = (ParameterData) Protocol.decode(msg, ParameterData.newBuilder());
            long genTime;
            if (pd.hasGenerationTime()) {
                genTime = pd.getGenerationTime();
            } else {
                Long l = msg.getLongProperty(StandardTupleDefinitions.PARAMETER_COL_GENTIME);
                if (l != null) {
                    genTime = l;
                } else {
                    log.warn("Cannot find generation time either in the body or in the header of the message");
                    return;
                }
            }
            String ppGroup;
            if (pd.hasGroup()) {
                ppGroup = pd.getGroup();
            } else {
                ppGroup = msg.getStringProperty(StandardTupleDefinitions.PARAMETER_COL_GROUP);
                if (ppGroup == null) {
                    log.warn("Cannot find PP group either in the body or in the header of the message");
                    return;
                }
            }
            totalPpCount.addAndGet(pd.getParameterCount());
            ppListener.updateParams(genTime, ppGroup, pd.getSeqNum(), pd.getParameterList());
        } catch (Exception e) {
            log.warn("{} for message: {}", e.getMessage(), msg);
        }
    }

    @Override
    protected void doStart() {
        try {
            factory = locator.createSessionFactory();
            artemisSession = factory.createSession();
            String queue = artemisAddress + "-ArtemisPpProvider";
            log.debug("Starting artemis parameter data link connected to {}.{}", artemisAddress, queue);
            artemisSession.createTemporaryQueue(artemisAddress, queue);
            client = artemisSession.createConsumer(queue,
                    AbstractArtemisTranslatorService.UNIQUEID_HDR_NAME + "<>"
                            + AbstractArtemisTranslatorService.UNIQUEID);
            client.setMessageHandler(this);
            artemisSession.start();
            notifyStarted();
        } catch (Exception e) {
            log.error("Failed connect to artemis");
            notifyFailed(e);
        }
    }

    @Override
    protected void doStop() {
        try {
            artemisSession.close();
            notifyStopped();
        } catch (ActiveMQException e) {
            log.error("Got exception when quiting:", e);
            notifyFailed(e);
        }
    }

    @Override
    public String getName() {
        return linkName;
    }

    @Override
    public YConfiguration getConfig() {
        return config;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy