Search in sources :

Example 1 with ControlPortJsonParseException

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);
}
Also used : ControlPortJsonParseException(com.ibm.streamsx.kafka.ControlPortJsonParseException) HashMap(java.util.HashMap) JsonObject(com.google.gson.JsonObject) ControlPortJsonParseException(com.ibm.streamsx.kafka.ControlPortJsonParseException) JsonArray(com.google.gson.JsonArray) TopicPartition(org.apache.kafka.common.TopicPartition) JsonElement(com.google.gson.JsonElement) HashSet(java.util.HashSet)

Example 2 with ControlPortJsonParseException

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");
        }
    }
}
Also used : DummyConsumerClient(com.ibm.streamsx.kafka.clients.consumer.DummyConsumerClient) KafkaClientInitializationException(com.ibm.streamsx.kafka.KafkaClientInitializationException) ControlPortJsonParseException(com.ibm.streamsx.kafka.ControlPortJsonParseException) DummyConsumerClient(com.ibm.streamsx.kafka.clients.consumer.DummyConsumerClient) NonCrKafkaConsumerClient(com.ibm.streamsx.kafka.clients.consumer.NonCrKafkaConsumerClient) CrKafkaStaticAssignConsumerClient(com.ibm.streamsx.kafka.clients.consumer.CrKafkaStaticAssignConsumerClient) ConsumerClient(com.ibm.streamsx.kafka.clients.consumer.ConsumerClient) ControlPortActionType(com.ibm.streamsx.kafka.clients.consumer.ControlPortActionType) ControlPortAction(com.ibm.streamsx.kafka.clients.consumer.ControlPortAction) ControlPortJsonParseException(com.ibm.streamsx.kafka.ControlPortJsonParseException) KafkaOperatorResetFailedException(com.ibm.streamsx.kafka.KafkaOperatorResetFailedException) KafkaClientInitializationException(com.ibm.streamsx.kafka.KafkaClientInitializationException) KafkaConfigurationException(com.ibm.streamsx.kafka.KafkaConfigurationException) ConsumerClientBuilder(com.ibm.streamsx.kafka.clients.consumer.ConsumerClientBuilder)

Aggregations

ControlPortJsonParseException (com.ibm.streamsx.kafka.ControlPortJsonParseException)2 JsonArray (com.google.gson.JsonArray)1 JsonElement (com.google.gson.JsonElement)1 JsonObject (com.google.gson.JsonObject)1 KafkaClientInitializationException (com.ibm.streamsx.kafka.KafkaClientInitializationException)1 KafkaConfigurationException (com.ibm.streamsx.kafka.KafkaConfigurationException)1 KafkaOperatorResetFailedException (com.ibm.streamsx.kafka.KafkaOperatorResetFailedException)1 ConsumerClient (com.ibm.streamsx.kafka.clients.consumer.ConsumerClient)1 ConsumerClientBuilder (com.ibm.streamsx.kafka.clients.consumer.ConsumerClientBuilder)1 ControlPortAction (com.ibm.streamsx.kafka.clients.consumer.ControlPortAction)1 ControlPortActionType (com.ibm.streamsx.kafka.clients.consumer.ControlPortActionType)1 CrKafkaStaticAssignConsumerClient (com.ibm.streamsx.kafka.clients.consumer.CrKafkaStaticAssignConsumerClient)1 DummyConsumerClient (com.ibm.streamsx.kafka.clients.consumer.DummyConsumerClient)1 NonCrKafkaConsumerClient (com.ibm.streamsx.kafka.clients.consumer.NonCrKafkaConsumerClient)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 TopicPartition (org.apache.kafka.common.TopicPartition)1