package org.yamcs.tctm;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.apache.activemq.artemis.api.core.client.MessageHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yamcs.ConfigurationException;
import org.yamcs.api.YamcsApiException;
import org.yamcs.api.artemis.Protocol;
import org.yamcs.api.artemis.YamcsClient;
import org.yamcs.api.artemis.YamcsSession;
import org.yamcs.artemis.AbstractArtemisTranslatorService;
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 volatile long totalPpCount = 0;
protected volatile boolean disabled=false;
protected Logger log=LoggerFactory.getLogger(this.getClass().getName());
private ParameterSink ppListener;
private YamcsSession yamcsSession;
final XtceDb ppdb;
final String hornetAddress;
public ArtemisParameterDataLink(String instance, String name, String hornetAddress) throws ConfigurationException {
ppdb = XtceDbFactory.getInstance(instance);
this.hornetAddress = hornetAddress;
}
@Override
public void setParameterSink(ParameterSink ppListener) {
this.ppListener=ppListener;
}
@Override
public String getLinkStatus() {
if (disabled) {
return "DISABLED";
} else {
return "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 getDataCount() {
return totalPpCount;
}
@Override
public void onMessage(ClientMessage msg) {
if(disabled) {
return;
}
try {
ParameterData pd = (ParameterData)Protocol.decode(msg, ParameterData.newBuilder());
long genTime;
if(pd.hasGenerationTime()) {
genTime = pd.getGenerationTime();
} else {
Long l = msg.getLongProperty(ParameterDataLinkInitialiser.PARAMETER_TUPLE_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(ParameterDataLinkInitialiser.PARAMETER_TUPLE_COL_GROUP);
if(ppGroup == null) {
log.warn("Cannot find PP group either in the body or in the header of the message");
return;
}
}
totalPpCount += 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 {
SimpleString queue=new SimpleString(hornetAddress+"-ActiveMQPpProvider");
yamcsSession = YamcsSession.newBuilder().build();
YamcsClient yclient = yamcsSession.newClientBuilder().setDataProducer(false).setDataConsumer(new SimpleString(hornetAddress), queue).
setFilter(new SimpleString(AbstractArtemisTranslatorService.UNIQUEID_HDR_NAME+"<>"+AbstractArtemisTranslatorService.UNIQUEID)).
build();
yclient.dataConsumer.setMessageHandler(this);
notifyStarted();
} catch (ActiveMQException|YamcsApiException e) {
log.error("Failed connect to artemis");
notifyFailed(e);
}
}
@Override
protected void doStop() {
try {
yamcsSession.close();
notifyStopped();
} catch (ActiveMQException e) {
log.error("Got exception when quiting:", e);
notifyFailed(e);
}
}
}