/*******************************************************************************
* Copyright (C) 2016, International Business Machines Corporation
* All Rights Reserved
*******************************************************************************/
package com.ibm.streamsx.messaging.kafka;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.kafka.clients.producer.Callback;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import com.ibm.streams.operator.Tuple;
import com.ibm.streams.operator.logging.TraceLevel;
public abstract class KafkaProducerClient extends KafkaBaseClient {
protected AtomicBoolean messageException = new AtomicBoolean(false);
public KafkaProducerClient(AttributeHelper topicAH, AttributeHelper keyAH,
AttributeHelper messageAH, Properties props){
super(topicAH, keyAH, messageAH, props);
props = KafkaConfigUtilities.setDefaultSerializers(keyAH, messageAH, props);
}
abstract void send(Tuple tuple, List<String> topics) throws Exception;
abstract void send(Tuple tuple) throws Exception;
public boolean hasMessageException() {
return messageException.get();
}
protected Callback getMessageCallback() {
return new Callback() {
public void onCompletion(RecordMetadata metadata, Exception e) {
if(e != null){
e.printStackTrace();
trace.log(TraceLevel.ERROR, "Message exception: " + e.getMessage()); //$NON-NLS-1$
messageException.set(true);
}
}
};
}
public void resetMessageException() {
messageException.set(false);
}
}
class ProducerStringHelper extends KafkaProducerClient{
private KafkaProducer<String, String> producer = null;
public ProducerStringHelper(AttributeHelper topicAH, AttributeHelper keyAH,
AttributeHelper messageAH, Properties props) {
super(topicAH, keyAH, messageAH, props);
producer = new KafkaProducer<String, String>(props);
trace.log(TraceLevel.INFO, "Creating producer of type KafkaProducer\\<String,String\\>" ); //$NON-NLS-1$
}
@Override
void send(Tuple tuple) throws Exception {
String topic = topicAH.getString(tuple);
String message = messageAH.getString(tuple);
String key = keyAH.getString(tuple);
producer.send(new ProducerRecord<String, String>(topic ,key, message), getMessageCallback());
}
@Override
void send(Tuple tuple, List<String> topics) throws Exception {
String message = messageAH.getString(tuple);
String key = keyAH.getString(tuple);
for(String topic : topics) {
producer.send(new ProducerRecord<String, String>(topic ,key, message),
getMessageCallback());
}
}
@Override
void shutdown(){
if (producer != null)
producer.close();
}
}
class ProducerByteHelper extends KafkaProducerClient{
private KafkaProducer<byte[],byte[]> producer = null;
public ProducerByteHelper(AttributeHelper topicAH, AttributeHelper keyAH,
AttributeHelper messageAH, Properties props) {
super(topicAH, keyAH, messageAH, props);
producer = new KafkaProducer<byte[],byte[]>(props);
trace.log(TraceLevel.INFO, "Creating producer of type KafkaProducer\\<Byte,Byte\\>" ); //$NON-NLS-1$
}
@Override
void send(Tuple tuple) throws Exception {
String topic = topicAH.getString(tuple);
byte [] message = messageAH.getBytes(tuple);
byte [] key = keyAH.getBytes(tuple);
producer.send(new ProducerRecord<byte[],byte[]>(topic ,key, message),
getMessageCallback());
}
@Override
void send(Tuple tuple, List<String> topics) throws Exception {
byte [] message = messageAH.getBytes(tuple);
byte [] key = keyAH.getBytes(tuple);
for(String topic : topics) {
producer.send(new ProducerRecord<byte[],byte[]>(topic,key, message),
getMessageCallback());
}
}
@Override
void shutdown(){
if (producer != null)
producer.close();
}
}