use of com.ibm.streamsx.kafka.ControlPortJsonParseException in project streamsx.kafka by IBMStreams.
the class ControlPortAction method fromJSON.
/**
* Creates a ControlPortAction from a JSON formatted String
* @param json The JSON string
* @return a ControlPortAction object
* @throws ControlPortJsonParseException parsing JSON failed
*/
public static ControlPortAction fromJSON(String json) throws ControlPortJsonParseException {
JsonObject jsonObj = null;
try {
jsonObj = gson.fromJson(json, JsonObject.class);
} catch (Exception e) {
ControlPortJsonParseException exc = new ControlPortJsonParseException(e.getMessage(), e);
exc.setJson(json);
throw exc;
}
if (jsonObj == null) {
ControlPortJsonParseException exc = new ControlPortJsonParseException(Messages.getString("INVALID_JSON_MISSING_KEY", "action", json == null ? "null" : json));
exc.setJson(json);
throw exc;
}
final String jason = jsonObj.toString();
ControlPortActionType a = null;
JsonAction action = null;
if (jsonObj.has("action")) {
// $NON-NLS-1$
try {
// $NON-NLS-1$
action = JsonAction.valueOf(jsonObj.get("action").getAsString().toUpperCase());
} catch (Exception e) {
ControlPortJsonParseException exc = new ControlPortJsonParseException(e.getMessage(), e);
exc.setJson(json);
throw exc;
}
} else {
ControlPortJsonParseException exc = new ControlPortJsonParseException(Messages.getString("INVALID_JSON_MISSING_KEY", "action", json));
exc.setJson(json);
throw exc;
}
if (jsonObj.has("topicPartitionOffsets") && jsonObj.has("topics")) {
// $NON-NLS-1$
final ControlPortJsonParseException exc = new ControlPortJsonParseException(Messages.getString("INVALID_JSON", json));
exc.setJson(json);
throw exc;
}
if (!jsonObj.has("topicPartitionOffsets") && !jsonObj.has("topics")) {
// $NON-NLS-1$
trace.warn("expected \"topicPartitionOffsets\" or \"topics\" element in JSON: " + jason);
}
Map<TopicPartition, Long> topicPartitionOffsetMap = new HashMap<>();
Set<String> topics = new HashSet<>();
if (jsonObj.has("topicPartitionOffsets")) {
// $NON-NLS-1$
a = action == JsonAction.ADD ? ControlPortActionType.ADD_ASSIGNMENT : ControlPortActionType.REMOVE_ASSIGNMENT;
// $NON-NLS-1$
JsonArray arr = jsonObj.get("topicPartitionOffsets").getAsJsonArray();
Iterator<JsonElement> it = arr.iterator();
while (it.hasNext()) {
JsonObject tpo = it.next().getAsJsonObject();
if (!tpo.has("topic")) {
// $NON-NLS-1$
ControlPortJsonParseException exc = new ControlPortJsonParseException(Messages.getString("INVALID_JSON_MISSING_KEY", "topic", json));
exc.setJson(json);
throw exc;
}
if (!tpo.has("partition")) {
// $NON-NLS-1$
ControlPortJsonParseException exc = new ControlPortJsonParseException(Messages.getString("INVALID_JSON_MISSING_KEY", "partition", json));
exc.setJson(json);
throw exc;
}
try {
// $NON-NLS-1$
String topic = tpo.get("topic").getAsString();
// $NON-NLS-1$
int partition = tpo.get("partition").getAsInt();
// $NON-NLS-1$ //$NON-NLS-2$
long offset = tpo.has("offset") ? tpo.get("offset").getAsLong() : OffsetConstants.NO_SEEK;
topicPartitionOffsetMap.put(new TopicPartition(topic, partition), new Long(offset));
} catch (Exception e) {
// Handle Number format errors
ControlPortJsonParseException exc = new ControlPortJsonParseException(e.getMessage(), e);
exc.setJson(json);
throw exc;
}
}
return new ControlPortAction(jason, a, topicPartitionOffsetMap);
}
if (jsonObj.has("topics")) {
a = action == JsonAction.ADD ? ControlPortActionType.ADD_SUBSCRIPTION : ControlPortActionType.REMOVE_SUBSCRIPTION;
// $NON-NLS-1$
JsonArray arr = jsonObj.get("topics").getAsJsonArray();
Iterator<JsonElement> it = arr.iterator();
while (it.hasNext()) {
JsonObject tpc = it.next().getAsJsonObject();
if (!tpc.has("topic")) {
// $NON-NLS-1$
ControlPortJsonParseException exc = new ControlPortJsonParseException(Messages.getString("INVALID_JSON_MISSING_KEY", "topic", json));
exc.setJson(json);
throw exc;
}
try {
// $NON-NLS-1$
String topic = tpc.get("topic").getAsString();
topics.add(topic);
} catch (Exception e) {
// Handle Number format errors
ControlPortJsonParseException exc = new ControlPortJsonParseException(e.getMessage(), e);
exc.setJson(json);
throw exc;
}
}
return new ControlPortAction(jason, a, topics);
}
return new ControlPortAction(jason);
}
use of com.ibm.streamsx.kafka.ControlPortJsonParseException in project streamsx.kafka by IBMStreams.
the class AbstractKafkaConsumerOperator method process.
@Override
public void process(StreamingInput<Tuple> stream, Tuple tuple) throws Exception {
synchronized (monitor) {
logger.info("process >>> ENTRY");
boolean interrupted = false;
try {
final ConsumerClient consumer = consumerRef.get();
logger.info("current consumer implementation: " + consumer);
ControlPortAction actn = ControlPortAction.fromJSON(tuple.getString(0));
final ControlPortActionType action = actn.getActionType();
if (consumer.supports(actn)) {
logger.info("consumer implementation supports " + action);
consumer.onControlPortAction(actn);
} else {
if ((consumer instanceof DummyConsumerClient) && (action == ControlPortActionType.ADD_ASSIGNMENT || action == ControlPortActionType.ADD_SUBSCRIPTION)) {
logger.info("replacing ConsumerClient by a version that supports " + action);
// we can change the client implementation
if (consumer.isProcessing()) {
consumer.onShutdown(SHUTDOWN_TIMEOUT, SHUTDOWN_TIMEOUT_TIMEUNIT);
}
final ConsumerClientBuilder builder;
if (action == ControlPortActionType.ADD_SUBSCRIPTION) {
if (crContext != null) {
logger.error("topic subscription via control port is not supported when the operator is used in a consistent region. Ignoring " + actn.getJson());
nFailedControlTuples.increment();
logger.info("process <<< EXIT");
return;
}
builder = this.groupEnabledClientBuilder;
} else {
if (this.groupIdSpecified) {
logger.warn(MsgFormatter.format("A group.id is specified. The ''{0}'' operator " + "will NOT participate in a consumer group because the operator assigns partitions.", getOperatorContext().getName()));
}
builder = this.staticAssignClientBuilder;
}
logger.info("Using client builder: " + builder);
final ConsumerClient newClient = builder.build();
logger.info(MsgFormatter.format("consumer client {0} created", newClient.getClass().getName()));
try {
newClient.startConsumer();
if (consumerRef.compareAndSet(consumer, newClient)) {
logger.info(MsgFormatter.format("consumer client implementation {0} replaced by {1}", consumer.getClass().getName(), newClient.getClass().getName()));
newClient.onControlPortAction(actn);
} else {
logger.warn(MsgFormatter.format("consumer client replacement failed"));
newClient.onShutdown(SHUTDOWN_TIMEOUT, SHUTDOWN_TIMEOUT_TIMEUNIT);
nFailedControlTuples.increment();
}
} catch (KafkaClientInitializationException e) {
logger.error(e.getLocalizedMessage(), e);
logger.error("root cause: " + e.getRootCause());
nFailedControlTuples.increment();
throw e;
}
} else {
// unsupported action
logger.error("Could not process control tuple. Action " + action + " is not supported by the '" + consumer.getClass().getName() + "' ConsumerClient implementation. Tuple: '" + tuple + "'");
nFailedControlTuples.increment();
}
}
} catch (ControlPortJsonParseException e) {
logger.error("Could not process control tuple. Parsing JSON '" + e.getJson() + "' failed.");
logger.error(e.getLocalizedMessage(), e);
nFailedControlTuples.increment();
} catch (InterruptedException e) {
// interrupted during shutdown
interrupted = true;
nFailedControlTuples.increment();
} catch (Exception e) {
e.printStackTrace();
logger.error("Could not process control tuple: '" + tuple + "':" + e);
logger.error(e.getLocalizedMessage(), e);
nFailedControlTuples.increment();
} finally {
final ConsumerClient consumer = consumerRef.get();
if (!interrupted && consumer.isSubscribedOrAssigned()) {
logger.info("sendStartPollingEvent ...");
consumer.sendStartPollingEvent();
}
logger.info("process <<< EXIT");
}
}
}
Aggregations