package org.yamcs.artemis;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yamcs.ConfigurationException;
import org.yamcs.yarch.Stream;
import org.yamcs.yarch.StreamSubscriber;
import org.yamcs.yarch.Tuple;
import org.yamcs.yarch.YarchDatabase;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.yamcs.api.YamcsApiException;
import org.yamcs.api.artemis.YamcsClient;
import org.yamcs.api.artemis.YamcsSession;
import com.google.common.util.concurrent.AbstractService;
/**
* takes data from yarch streams and publishes it to artemis address (reverse of ActiveMQTmProvider)
*
*
*/
public class AbstractArtemisTranslatorService extends AbstractService {
final private TupleTranslator translator;
YamcsSession yamcsSession;
List<Stream> streams = new ArrayList<Stream>();
Map<Stream, StreamSubscriber> streamSubscribers = new HashMap<Stream, StreamSubscriber>();
static final public String UNIQUEID_HDR_NAME="_y_uniqueid";
static final public int UNIQUEID = new Random().nextInt();
Logger log=LoggerFactory.getLogger(this.getClass().getName());
String instance;
private final ThreadLocal<YamcsClient> yamcsClient =
new ThreadLocal<YamcsClient>() {
YamcsSession yamcsSession;
YamcsClient yClient;
@Override protected YamcsClient initialValue() {
try {
yamcsSession = YamcsSession.newBuilder().build();
yClient = yamcsSession.newClientBuilder().setDataProducer(true).build();
return yClient;
} catch (YamcsApiException e) {
throw new ConfigurationException("Cannot create a artemis client", e);
}
}
};
public AbstractArtemisTranslatorService(String instance, List<String> streamNames, TupleTranslator translator) throws ConfigurationException {
this.instance = instance;
YarchDatabase db = YarchDatabase.getInstance(instance);
for(String sn: streamNames) {
Stream s = db.getStream(sn);
if(s==null) {
throw new ConfigurationException("Cannot find stream '"+sn+"'");
}
streams.add(s);
}
this.translator = translator;
try {
} catch (Exception e) {
throw new ConfigurationException("Cannot create hornetq client", e);
}
}
@Override
public String toString() {
return "ActiveMQTmService";
}
@Override
protected void doStart() {
for(Stream s:streams) {
final SimpleString hornetAddress = new SimpleString(instance+"."+s.getName());
log.debug("Starting providing tuples from stream {} as messages on {} ActiveMQ address", s.getName(), hornetAddress.toString());
StreamSubscriber ss = new StreamSubscriber() {
@Override
public void onTuple(Stream stream, Tuple tuple) {
try {
ClientMessage msg=translator.buildMessage(yamcsClient.get().getYamcsSession().createMessage(false), tuple);
msg.putIntProperty(UNIQUEID_HDR_NAME, UNIQUEID);
yamcsClient.get().sendData(hornetAddress, msg);
} catch (IllegalArgumentException|YamcsApiException e) {
log.warn("Got exception when sending message:", e);
}
}
@Override
public void streamClosed(Stream stream) {
log.info("Stream "+stream +" closed");
}
};
s.addSubscriber(ss);
streamSubscribers.put(s, ss);
}
notifyStarted();
}
@Override
protected void doStop() {
for(Stream s:streams) {
s.removeSubscriber(streamSubscribers.get(s));
}
}
}