Search in sources :

Example 1 with JSONSchema

use of org.apache.pulsar.client.impl.schema.JSONSchema in project pulsar by apache.

the class ProducerImpl method connectionOpened.

@Override
public void connectionOpened(final ClientCnx cnx) {
    previousExceptions.clear();
    chunkMaxMessageSize = Math.min(chunkMaxMessageSize, ClientCnx.getMaxMessageSize());
    final long epoch;
    synchronized (this) {
        // as long as the change from current state to connecting is a valid state change.
        if (!changeToConnecting()) {
            return;
        }
        // We set the cnx reference before registering the producer on the cnx, so if the cnx breaks before creating
        // the producer, it will try to grab a new cnx. We also increment and get the epoch value for the producer.
        epoch = connectionHandler.switchClientCnx(cnx);
    }
    cnx.registerProducer(producerId, this);
    log.info("[{}] [{}] Creating producer on cnx {}", topic, producerName, cnx.ctx().channel());
    long requestId = client.newRequestId();
    PRODUCER_DEADLINE_UPDATER.compareAndSet(this, 0, System.currentTimeMillis() + client.getConfiguration().getOperationTimeoutMs());
    SchemaInfo schemaInfo = null;
    if (schema != null) {
        if (schema.getSchemaInfo() != null) {
            if (schema.getSchemaInfo().getType() == SchemaType.JSON) {
                // but now we have standardized on every schema to generate an Avro based schema
                if (Commands.peerSupportJsonSchemaAvroFormat(cnx.getRemoteEndpointProtocolVersion())) {
                    schemaInfo = schema.getSchemaInfo();
                } else if (schema instanceof JSONSchema) {
                    JSONSchema jsonSchema = (JSONSchema) schema;
                    schemaInfo = jsonSchema.getBackwardsCompatibleJsonSchemaInfo();
                } else {
                    schemaInfo = schema.getSchemaInfo();
                }
            } else if (schema.getSchemaInfo().getType() == SchemaType.BYTES || schema.getSchemaInfo().getType() == SchemaType.NONE) {
                // don't set schema info for Schema.BYTES
                schemaInfo = null;
            } else {
                schemaInfo = schema.getSchemaInfo();
            }
        }
    }
    cnx.sendRequestWithId(Commands.newProducer(topic, producerId, requestId, producerName, conf.isEncryptionEnabled(), metadata, schemaInfo, epoch, userProvidedProducerName, conf.getAccessMode(), topicEpoch, client.conf.isEnableTransaction(), conf.getInitialSubscriptionName()), requestId).thenAccept(response -> {
        String producerName = response.getProducerName();
        long lastSequenceId = response.getLastSequenceId();
        schemaVersion = Optional.ofNullable(response.getSchemaVersion());
        schemaVersion.ifPresent(v -> schemaCache.put(SchemaHash.of(schema), v));
        // set the cnx pointer so that new messages will be sent immediately
        synchronized (ProducerImpl.this) {
            if (getState() == State.Closing || getState() == State.Closed) {
                // Producer was closed while reconnecting, close the connection to make sure the broker
                // drops the producer on its side
                cnx.removeProducer(producerId);
                cnx.channel().close();
                return;
            }
            resetBackoff();
            log.info("[{}] [{}] Created producer on cnx {}", topic, producerName, cnx.ctx().channel());
            connectionId = cnx.ctx().channel().toString();
            connectedSince = DateFormatter.now();
            if (conf.getAccessMode() != ProducerAccessMode.Shared && !topicEpoch.isPresent()) {
                log.info("[{}] [{}] Producer epoch is {}", topic, producerName, response.getTopicEpoch());
            }
            topicEpoch = response.getTopicEpoch();
            if (this.producerName == null) {
                this.producerName = producerName;
            }
            if (this.msgIdGenerator == 0 && conf.getInitialSequenceId() == null) {
                // Only update sequence id generator if it wasn't already modified. That means we only want
                // to update the id generator the first time the producer gets established, and ignore the
                // sequence id sent by broker in subsequent producer reconnects
                this.lastSequenceIdPublished = lastSequenceId;
                this.msgIdGenerator = lastSequenceId + 1;
            }
            if (!producerCreatedFuture.isDone() && isBatchMessagingEnabled()) {
                // schedule the first batch message task
                batchTimerTask = cnx.ctx().executor().scheduleWithFixedDelay(catchingAndLoggingThrowables(() -> {
                    if (log.isTraceEnabled()) {
                        log.trace("[{}] [{}] Batching the messages from the batch container from " + "timer thread", topic, producerName);
                    }
                    // semaphore acquired when message was enqueued to container
                    synchronized (ProducerImpl.this) {
                        // schedule next timeout.
                        if (getState() == State.Closing || getState() == State.Closed) {
                            return;
                        }
                        batchMessageAndSend();
                    }
                }), 0, conf.getBatchingMaxPublishDelayMicros(), TimeUnit.MICROSECONDS);
            }
            resendMessages(cnx, epoch);
        }
    }).exceptionally((e) -> {
        Throwable cause = e.getCause();
        cnx.removeProducer(producerId);
        if (getState() == State.Closing || getState() == State.Closed) {
            // Producer was closed while reconnecting, close the connection to make sure the broker
            // drops the producer on its side
            cnx.channel().close();
            return null;
        }
        if (cause instanceof TimeoutException) {
            // Creating the producer has timed out. We need to ensure the broker closes the producer
            // in case it was indeed created, otherwise it might prevent new create producer operation,
            // since we are not necessarily closing the connection.
            long closeRequestId = client.newRequestId();
            ByteBuf cmd = Commands.newCloseProducer(producerId, closeRequestId);
            cnx.sendRequestWithId(cmd, closeRequestId);
        }
        if (cause instanceof PulsarClientException.ProducerFencedException) {
            if (log.isDebugEnabled()) {
                log.debug("[{}] [{}] Failed to create producer: {}", topic, producerName, cause.getMessage());
            }
        } else {
            log.error("[{}] [{}] Failed to create producer: {}", topic, producerName, cause.getMessage());
        }
        // Close the producer since topic does not exist.
        if (cause instanceof PulsarClientException.TopicDoesNotExistException) {
            closeAsync().whenComplete((v, ex) -> {
                if (ex != null) {
                    log.error("Failed to close producer on TopicDoesNotExistException.", ex);
                }
                producerCreatedFuture.completeExceptionally(cause);
            });
            return null;
        }
        if (cause instanceof PulsarClientException.ProducerBlockedQuotaExceededException) {
            synchronized (this) {
                log.warn("[{}] [{}] Topic backlog quota exceeded. Throwing Exception on producer.", topic, producerName);
                if (log.isDebugEnabled()) {
                    log.debug("[{}] [{}] Pending messages: {}", topic, producerName, pendingMessages.messagesCount());
                }
                PulsarClientException bqe = new PulsarClientException.ProducerBlockedQuotaExceededException(format("The backlog quota of the topic %s that the producer %s produces to is exceeded", topic, producerName));
                failPendingMessages(cnx(), bqe);
            }
        } else if (cause instanceof PulsarClientException.ProducerBlockedQuotaExceededError) {
            log.warn("[{}] [{}] Producer is blocked on creation because backlog exceeded on topic.", producerName, topic);
        }
        if (cause instanceof PulsarClientException.TopicTerminatedException) {
            setState(State.Terminated);
            synchronized (this) {
                failPendingMessages(cnx(), (PulsarClientException) cause);
            }
            producerCreatedFuture.completeExceptionally(cause);
            closeProducerTasks();
            client.cleanupProducer(this);
        } else if (cause instanceof PulsarClientException.ProducerFencedException) {
            setState(State.ProducerFenced);
            synchronized (this) {
                failPendingMessages(cnx(), (PulsarClientException) cause);
            }
            producerCreatedFuture.completeExceptionally(cause);
            closeProducerTasks();
            client.cleanupProducer(this);
        } else if (// 
        producerCreatedFuture.isDone() || (cause instanceof PulsarClientException && PulsarClientException.isRetriableError(cause) && System.currentTimeMillis() < PRODUCER_DEADLINE_UPDATER.get(ProducerImpl.this))) {
            // Either we had already created the producer once (producerCreatedFuture.isDone()) or we are
            // still within the initial timeout budget and we are dealing with a retriable error
            reconnectLater(cause);
        } else {
            setState(State.Failed);
            producerCreatedFuture.completeExceptionally(cause);
            closeProducerTasks();
            client.cleanupProducer(this);
            Timeout timeout = sendTimeout;
            if (timeout != null) {
                timeout.cancel();
                sendTimeout = null;
            }
        }
        return null;
    });
}
Also used : BatcherBuilder(org.apache.pulsar.client.api.BatcherBuilder) MathUtils(org.apache.pulsar.client.util.MathUtils) Broken(org.apache.pulsar.client.impl.MessageImpl.SchemaState.Broken) TimeoutException(org.apache.pulsar.client.api.PulsarClientException.TimeoutException) Commands.readChecksum(org.apache.pulsar.common.protocol.Commands.readChecksum) ScheduledFuture(io.netty.util.concurrent.ScheduledFuture) ByteBufPair(org.apache.pulsar.common.protocol.ByteBufPair) Producer(org.apache.pulsar.client.api.Producer) LoggerFactory(org.slf4j.LoggerFactory) MessageCryptoBc(org.apache.pulsar.client.impl.crypto.MessageCryptoBc) MessageCrypto(org.apache.pulsar.client.api.MessageCrypto) StringUtils(org.apache.commons.lang3.StringUtils) ByteBuffer(java.nio.ByteBuffer) ProtocolVersion(org.apache.pulsar.common.api.proto.ProtocolVersion) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Handle(io.netty.util.Recycler.Handle) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) RelativeTimeUtil(org.apache.pulsar.common.util.RelativeTimeUtil) Runnables.catchingAndLoggingThrowables(org.apache.pulsar.common.util.Runnables.catchingAndLoggingThrowables) Map(java.util.Map) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) Crc32cIntChecksum.computeChecksum(com.scurrilous.circe.checksum.Crc32cIntChecksum.computeChecksum) CompressionType(org.apache.pulsar.client.api.CompressionType) String.format(java.lang.String.format) Transaction(org.apache.pulsar.client.api.transaction.Transaction) PulsarByteBufAllocator(org.apache.pulsar.common.allocator.PulsarByteBufAllocator) Preconditions.checkState(com.google.common.base.Preconditions.checkState) Recycler(io.netty.util.Recycler) List(java.util.List) FutureUtil(org.apache.pulsar.common.util.FutureUtil) MessageMetadata(org.apache.pulsar.common.api.proto.MessageMetadata) ReferenceCountUtil(io.netty.util.ReferenceCountUtil) Optional(java.util.Optional) JSONSchema(org.apache.pulsar.client.impl.schema.JSONSchema) Queue(java.util.Queue) SchemaInfo(org.apache.pulsar.common.schema.SchemaInfo) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) CompressionCodec(org.apache.pulsar.common.compression.CompressionCodec) TopicName(org.apache.pulsar.common.naming.TopicName) AbstractReferenceCounted(io.netty.util.AbstractReferenceCounted) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Message(org.apache.pulsar.client.api.Message) SchemaType(org.apache.pulsar.common.schema.SchemaType) ArrayList(java.util.ArrayList) Commands(org.apache.pulsar.common.protocol.Commands) DateFormatter(org.apache.pulsar.common.util.DateFormatter) ByteBuf(io.netty.buffer.ByteBuf) Auto(org.apache.pulsar.client.impl.ProducerBase.MultiSchemaMode.Auto) Commands.hasChecksum(org.apache.pulsar.common.protocol.Commands.hasChecksum) TimerTask(io.netty.util.TimerTask) CompressionCodecProvider(org.apache.pulsar.common.compression.CompressionCodecProvider) SchemaHash(org.apache.pulsar.common.protocol.schema.SchemaHash) Crc32cIntChecksum.resumeChecksum(com.scurrilous.circe.checksum.Crc32cIntChecksum.resumeChecksum) CryptoException(org.apache.pulsar.client.api.PulsarClientException.CryptoException) Timeout(io.netty.util.Timeout) Logger(org.slf4j.Logger) Enabled(org.apache.pulsar.client.impl.ProducerBase.MultiSchemaMode.Enabled) Iterator(java.util.Iterator) TransactionImpl(org.apache.pulsar.client.impl.transaction.TransactionImpl) None(org.apache.pulsar.client.impl.MessageImpl.SchemaState.None) Semaphore(java.util.concurrent.Semaphore) ProducerCryptoFailureAction(org.apache.pulsar.client.api.ProducerCryptoFailureAction) IOException(java.io.IOException) AtomicLongFieldUpdater(java.util.concurrent.atomic.AtomicLongFieldUpdater) ReferenceCounted(io.netty.util.ReferenceCounted) ProducerConfigurationData(org.apache.pulsar.client.impl.conf.ProducerConfigurationData) Schema(org.apache.pulsar.client.api.Schema) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) MessageId(org.apache.pulsar.client.api.MessageId) ProducerAccessMode(org.apache.pulsar.client.api.ProducerAccessMode) VisibleForTesting(com.google.common.annotations.VisibleForTesting) ArrayDeque(java.util.ArrayDeque) Collections(java.util.Collections) ChecksumType(org.apache.pulsar.common.protocol.Commands.ChecksumType) Timeout(io.netty.util.Timeout) ByteBuf(io.netty.buffer.ByteBuf) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) JSONSchema(org.apache.pulsar.client.impl.schema.JSONSchema) SchemaInfo(org.apache.pulsar.common.schema.SchemaInfo) TimeoutException(org.apache.pulsar.client.api.PulsarClientException.TimeoutException)

Example 2 with JSONSchema

use of org.apache.pulsar.client.impl.schema.JSONSchema in project pulsar by apache.

the class TestJsonDecoder method testCyclicDefinitionDetect.

@Test(singleThreaded = true)
public void testCyclicDefinitionDetect() {
    JSONSchema cyclicSchema = JSONSchema.of(DecoderTestMessage.CyclicFoo.class);
    PrestoException exception = expectThrows(PrestoException.class, () -> {
        decoderFactory.extractColumnMetadata(topicName, cyclicSchema.getSchemaInfo(), PulsarColumnHandle.HandleKeyValueType.NONE);
    });
    assertEquals("Topic " + topicName.toString() + " schema may contains cyclic definitions.", exception.getMessage());
}
Also used : JSONSchema(org.apache.pulsar.client.impl.schema.JSONSchema) PrestoException(io.prestosql.spi.PrestoException) DecoderTestMessage(org.apache.pulsar.sql.presto.decoder.DecoderTestMessage) Test(org.testng.annotations.Test)

Example 3 with JSONSchema

use of org.apache.pulsar.client.impl.schema.JSONSchema in project pulsar-flink by streamnative.

the class FlinkPulsarTableITest method testWriteThenRead.

@Test(timeout = 40 * 1000L)
public void testWriteThenRead() throws Exception {
    String tp = newTopic();
    String tableName = TopicName.get(tp).getLocalName();
    StreamExecutionEnvironment see = StreamExecutionEnvironment.getExecutionEnvironment();
    see.setParallelism(1);
    DataStreamSource ds = see.fromCollection(fooList);
    ds.addSink(new FlinkPulsarSink(serviceUrl, adminUrl, Optional.of(tp), getSinkProperties(), new PulsarSerializationSchemaWrapper.Builder<>((SerializationSchema<SchemaData.Foo>) element -> {
        JSONSchema<SchemaData.Foo> jsonSchema = JSONSchema.of(SchemaData.Foo.class);
        return jsonSchema.encode(element);
    }).usePojoMode(SchemaData.Foo.class, RecordSchemaType.JSON).build()));
    see.execute("write first");
    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
    env.setParallelism(1);
    StreamTableEnvironment tEnv = StreamTableEnvironment.create(env);
    TableSchema tSchema = getTableSchema(tp);
    tEnv.executeSql(createTableSql(tableName, tp, tSchema, "json")).print();
    Table t = tEnv.sqlQuery("select i, f, bar from " + tableName);
    tEnv.toDataStream(t, SchemaData.Foo.class).map(new FailingIdentityMapper<>(fooList.size())).addSink(new SingletonStreamSink.StringSink<>()).setParallelism(1);
    TestUtils.tryExecute(env, "count elements from topics");
    SingletonStreamSink.compareWithList(fooList.subList(0, fooList.size() - 1).stream().map(Objects::toString).collect(Collectors.toList()));
}
Also used : StreamTableEnvironment(org.apache.flink.table.api.bridge.java.StreamTableEnvironment) Arrays(java.util.Arrays) RecordSchemaType(org.apache.flink.streaming.connectors.pulsar.config.RecordSchemaType) Producer(org.apache.pulsar.client.api.Producer) PulsarSerializationSchemaWrapper(org.apache.flink.streaming.connectors.pulsar.serialization.PulsarSerializationSchemaWrapper) SchemaInfoImpl(org.apache.pulsar.client.impl.schema.SchemaInfoImpl) SchemaData.flList(org.apache.flink.streaming.connectors.pulsar.SchemaData.flList) IncompatibleSchemaException(org.apache.flink.streaming.connectors.pulsar.internal.IncompatibleSchemaException) SuccessException(org.apache.flink.test.util.SuccessException) Map(java.util.Map) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) SchemaData.fmList(org.apache.flink.streaming.connectors.pulsar.SchemaData.fmList) ProtobufNativeSchemaUtils(org.apache.pulsar.client.impl.schema.ProtobufNativeSchemaUtils) TableTestMatchers.deepEqualTo(org.apache.flink.table.utils.TableTestMatchers.deepEqualTo) SinkFunction(org.apache.flink.streaming.api.functions.sink.SinkFunction) Timestamp(java.sql.Timestamp) TableSchema(org.apache.flink.table.api.TableSchema) Table(org.apache.flink.table.api.Table) Collectors(java.util.stream.Collectors) ByteString(com.google.protobuf.ByteString) Objects(java.util.Objects) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) TestUtils(org.apache.flink.streaming.connectors.pulsar.testutils.TestUtils) ClientConfigurationData(org.apache.pulsar.client.impl.conf.ClientConfigurationData) Assert.assertFalse(org.junit.Assert.assertFalse) ValidationException(org.apache.flink.table.api.ValidationException) TOPIC_SINGLE_OPTION_KEY(org.apache.flink.streaming.connectors.pulsar.internal.PulsarOptions.TOPIC_SINGLE_OPTION_KEY) SingletonStreamSink(org.apache.flink.streaming.connectors.pulsar.testutils.SingletonStreamSink) Optional(java.util.Optional) JSONSchema(org.apache.pulsar.client.impl.schema.JSONSchema) Row(org.apache.flink.types.Row) SchemaInfo(org.apache.pulsar.common.schema.SchemaInfo) SerializationSchema(org.apache.flink.api.common.serialization.SerializationSchema) StreamExecutionEnvironment(org.apache.flink.streaming.api.environment.StreamExecutionEnvironment) TopicName(org.apache.pulsar.common.naming.TopicName) PulsarMetadataReader(org.apache.flink.streaming.connectors.pulsar.internal.PulsarMetadataReader) LocalDateTime(java.time.LocalDateTime) HashMap(java.util.HashMap) PulsarAdmin(org.apache.pulsar.client.admin.PulsarAdmin) SimpleTest(org.apache.flink.formats.protobuf.testproto.SimpleTest) DataStreamSource(org.apache.flink.streaming.api.datastream.DataStreamSource) SchemaType(org.apache.pulsar.common.schema.SchemaType) MessageFormat(java.text.MessageFormat) ArrayList(java.util.ArrayList) TableColumn(org.apache.flink.table.api.TableColumn) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) FailingIdentityMapper(org.apache.flink.streaming.connectors.pulsar.testutils.FailingIdentityMapper) Before(org.junit.Before) RowData(org.apache.flink.table.data.RowData) Properties(java.util.Properties) SchemaData.faList(org.apache.flink.streaming.connectors.pulsar.SchemaData.faList) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) SchemaData.fooList(org.apache.flink.streaming.connectors.pulsar.SchemaData.fooList) Test(org.junit.Test) PulsarOptions(org.apache.flink.streaming.connectors.pulsar.internal.PulsarOptions) BOOLEAN_LIST(org.apache.flink.streaming.connectors.pulsar.SchemaData.BOOLEAN_LIST) Schema(org.apache.pulsar.client.api.Schema) DataStream(org.apache.flink.streaming.api.datastream.DataStream) TimeUnit(java.util.concurrent.TimeUnit) MessageId(org.apache.pulsar.client.api.MessageId) SimpleSchemaTranslator(org.apache.flink.streaming.connectors.pulsar.internal.SimpleSchemaTranslator) Assert(org.junit.Assert) PulsarTableTestUtils(org.apache.flink.streaming.connectors.pulsar.testutils.PulsarTableTestUtils) Assert.assertEquals(org.junit.Assert.assertEquals) Table(org.apache.flink.table.api.Table) TableSchema(org.apache.flink.table.api.TableSchema) DataStreamSource(org.apache.flink.streaming.api.datastream.DataStreamSource) ByteString(com.google.protobuf.ByteString) Objects(java.util.Objects) StreamExecutionEnvironment(org.apache.flink.streaming.api.environment.StreamExecutionEnvironment) JSONSchema(org.apache.pulsar.client.impl.schema.JSONSchema) StreamTableEnvironment(org.apache.flink.table.api.bridge.java.StreamTableEnvironment) SimpleTest(org.apache.flink.formats.protobuf.testproto.SimpleTest) Test(org.junit.Test)

Example 4 with JSONSchema

use of org.apache.pulsar.client.impl.schema.JSONSchema in project incubator-pulsar by apache.

the class ProducerImpl method connectionOpened.

@Override
public void connectionOpened(final ClientCnx cnx) {
    previousExceptions.clear();
    chunkMaxMessageSize = Math.min(chunkMaxMessageSize, ClientCnx.getMaxMessageSize());
    final long epoch;
    synchronized (this) {
        // as long as the change from current state to connecting is a valid state change.
        if (!changeToConnecting()) {
            return;
        }
        // We set the cnx reference before registering the producer on the cnx, so if the cnx breaks before creating
        // the producer, it will try to grab a new cnx. We also increment and get the epoch value for the producer.
        epoch = connectionHandler.switchClientCnx(cnx);
    }
    cnx.registerProducer(producerId, this);
    log.info("[{}] [{}] Creating producer on cnx {}", topic, producerName, cnx.ctx().channel());
    long requestId = client.newRequestId();
    PRODUCER_DEADLINE_UPDATER.compareAndSet(this, 0, System.currentTimeMillis() + client.getConfiguration().getOperationTimeoutMs());
    SchemaInfo schemaInfo = null;
    if (schema != null) {
        if (schema.getSchemaInfo() != null) {
            if (schema.getSchemaInfo().getType() == SchemaType.JSON) {
                // but now we have standardized on every schema to generate an Avro based schema
                if (Commands.peerSupportJsonSchemaAvroFormat(cnx.getRemoteEndpointProtocolVersion())) {
                    schemaInfo = schema.getSchemaInfo();
                } else if (schema instanceof JSONSchema) {
                    JSONSchema jsonSchema = (JSONSchema) schema;
                    schemaInfo = jsonSchema.getBackwardsCompatibleJsonSchemaInfo();
                } else {
                    schemaInfo = schema.getSchemaInfo();
                }
            } else if (schema.getSchemaInfo().getType() == SchemaType.BYTES || schema.getSchemaInfo().getType() == SchemaType.NONE) {
                // don't set schema info for Schema.BYTES
                schemaInfo = null;
            } else {
                schemaInfo = schema.getSchemaInfo();
            }
        }
    }
    cnx.sendRequestWithId(Commands.newProducer(topic, producerId, requestId, producerName, conf.isEncryptionEnabled(), metadata, schemaInfo, epoch, userProvidedProducerName, conf.getAccessMode(), topicEpoch, client.conf.isEnableTransaction(), conf.getInitialSubscriptionName()), requestId).thenAccept(response -> {
        String producerName = response.getProducerName();
        long lastSequenceId = response.getLastSequenceId();
        schemaVersion = Optional.ofNullable(response.getSchemaVersion());
        schemaVersion.ifPresent(v -> schemaCache.put(SchemaHash.of(schema), v));
        // set the cnx pointer so that new messages will be sent immediately
        synchronized (ProducerImpl.this) {
            if (getState() == State.Closing || getState() == State.Closed) {
                // Producer was closed while reconnecting, close the connection to make sure the broker
                // drops the producer on its side
                cnx.removeProducer(producerId);
                cnx.channel().close();
                return;
            }
            resetBackoff();
            log.info("[{}] [{}] Created producer on cnx {}", topic, producerName, cnx.ctx().channel());
            connectionId = cnx.ctx().channel().toString();
            connectedSince = DateFormatter.now();
            if (conf.getAccessMode() != ProducerAccessMode.Shared && !topicEpoch.isPresent()) {
                log.info("[{}] [{}] Producer epoch is {}", topic, producerName, response.getTopicEpoch());
            }
            topicEpoch = response.getTopicEpoch();
            if (this.producerName == null) {
                this.producerName = producerName;
            }
            if (this.msgIdGenerator == 0 && conf.getInitialSequenceId() == null) {
                // Only update sequence id generator if it wasn't already modified. That means we only want
                // to update the id generator the first time the producer gets established, and ignore the
                // sequence id sent by broker in subsequent producer reconnects
                this.lastSequenceIdPublished = lastSequenceId;
                this.msgIdGenerator = lastSequenceId + 1;
            }
            resendMessages(cnx, epoch);
        }
    }).exceptionally((e) -> {
        Throwable cause = e.getCause();
        cnx.removeProducer(producerId);
        if (getState() == State.Closing || getState() == State.Closed) {
            // Producer was closed while reconnecting, close the connection to make sure the broker
            // drops the producer on its side
            cnx.channel().close();
            return null;
        }
        if (cause instanceof TimeoutException) {
            // Creating the producer has timed out. We need to ensure the broker closes the producer
            // in case it was indeed created, otherwise it might prevent new create producer operation,
            // since we are not necessarily closing the connection.
            long closeRequestId = client.newRequestId();
            ByteBuf cmd = Commands.newCloseProducer(producerId, closeRequestId);
            cnx.sendRequestWithId(cmd, closeRequestId);
        }
        if (cause instanceof PulsarClientException.ProducerFencedException) {
            if (log.isDebugEnabled()) {
                log.debug("[{}] [{}] Failed to create producer: {}", topic, producerName, cause.getMessage());
            }
        } else {
            log.error("[{}] [{}] Failed to create producer: {}", topic, producerName, cause.getMessage());
        }
        // Close the producer since topic does not exist.
        if (cause instanceof PulsarClientException.TopicDoesNotExistException) {
            closeAsync().whenComplete((v, ex) -> {
                if (ex != null) {
                    log.error("Failed to close producer on TopicDoesNotExistException.", ex);
                }
                producerCreatedFuture.completeExceptionally(cause);
            });
            return null;
        }
        if (cause instanceof PulsarClientException.ProducerBlockedQuotaExceededException) {
            synchronized (this) {
                log.warn("[{}] [{}] Topic backlog quota exceeded. Throwing Exception on producer.", topic, producerName);
                if (log.isDebugEnabled()) {
                    log.debug("[{}] [{}] Pending messages: {}", topic, producerName, pendingMessages.messagesCount());
                }
                PulsarClientException bqe = new PulsarClientException.ProducerBlockedQuotaExceededException(format("The backlog quota of the topic %s that the producer %s produces to is exceeded", topic, producerName));
                failPendingMessages(cnx(), bqe);
            }
        } else if (cause instanceof PulsarClientException.ProducerBlockedQuotaExceededError) {
            log.warn("[{}] [{}] Producer is blocked on creation because backlog exceeded on topic.", producerName, topic);
        }
        if (cause instanceof PulsarClientException.TopicTerminatedException) {
            setState(State.Terminated);
            synchronized (this) {
                failPendingMessages(cnx(), (PulsarClientException) cause);
            }
            producerCreatedFuture.completeExceptionally(cause);
            closeProducerTasks();
            client.cleanupProducer(this);
        } else if (cause instanceof PulsarClientException.ProducerFencedException) {
            setState(State.ProducerFenced);
            synchronized (this) {
                failPendingMessages(cnx(), (PulsarClientException) cause);
            }
            producerCreatedFuture.completeExceptionally(cause);
            closeProducerTasks();
            client.cleanupProducer(this);
        } else if (// 
        producerCreatedFuture.isDone() || (cause instanceof PulsarClientException && PulsarClientException.isRetriableError(cause) && System.currentTimeMillis() < PRODUCER_DEADLINE_UPDATER.get(ProducerImpl.this))) {
            // Either we had already created the producer once (producerCreatedFuture.isDone()) or we are
            // still within the initial timeout budget and we are dealing with a retriable error
            reconnectLater(cause);
        } else {
            setState(State.Failed);
            producerCreatedFuture.completeExceptionally(cause);
            closeProducerTasks();
            client.cleanupProducer(this);
            Timeout timeout = sendTimeout;
            if (timeout != null) {
                timeout.cancel();
                sendTimeout = null;
            }
        }
        return null;
    });
}
Also used : BatcherBuilder(org.apache.pulsar.client.api.BatcherBuilder) MathUtils(org.apache.pulsar.client.util.MathUtils) Broken(org.apache.pulsar.client.impl.MessageImpl.SchemaState.Broken) TimeoutException(org.apache.pulsar.client.api.PulsarClientException.TimeoutException) Commands.readChecksum(org.apache.pulsar.common.protocol.Commands.readChecksum) ScheduledFuture(io.netty.util.concurrent.ScheduledFuture) ByteBufPair(org.apache.pulsar.common.protocol.ByteBufPair) Producer(org.apache.pulsar.client.api.Producer) LoggerFactory(org.slf4j.LoggerFactory) MessageCryptoBc(org.apache.pulsar.client.impl.crypto.MessageCryptoBc) MessageCrypto(org.apache.pulsar.client.api.MessageCrypto) StringUtils(org.apache.commons.lang3.StringUtils) ByteBuffer(java.nio.ByteBuffer) ProtocolVersion(org.apache.pulsar.common.api.proto.ProtocolVersion) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Handle(io.netty.util.Recycler.Handle) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) RelativeTimeUtil(org.apache.pulsar.common.util.RelativeTimeUtil) Runnables.catchingAndLoggingThrowables(org.apache.pulsar.common.util.Runnables.catchingAndLoggingThrowables) Map(java.util.Map) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) Crc32cIntChecksum.computeChecksum(com.scurrilous.circe.checksum.Crc32cIntChecksum.computeChecksum) CompressionType(org.apache.pulsar.client.api.CompressionType) String.format(java.lang.String.format) Transaction(org.apache.pulsar.client.api.transaction.Transaction) PulsarByteBufAllocator(org.apache.pulsar.common.allocator.PulsarByteBufAllocator) Preconditions.checkState(com.google.common.base.Preconditions.checkState) Recycler(io.netty.util.Recycler) List(java.util.List) FutureUtil(org.apache.pulsar.common.util.FutureUtil) MessageMetadata(org.apache.pulsar.common.api.proto.MessageMetadata) ReferenceCountUtil(io.netty.util.ReferenceCountUtil) Optional(java.util.Optional) JSONSchema(org.apache.pulsar.client.impl.schema.JSONSchema) Queue(java.util.Queue) SchemaInfo(org.apache.pulsar.common.schema.SchemaInfo) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) CompressionCodec(org.apache.pulsar.common.compression.CompressionCodec) AtomicIntegerFieldUpdater(java.util.concurrent.atomic.AtomicIntegerFieldUpdater) TopicName(org.apache.pulsar.common.naming.TopicName) AbstractReferenceCounted(io.netty.util.AbstractReferenceCounted) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Message(org.apache.pulsar.client.api.Message) SchemaType(org.apache.pulsar.common.schema.SchemaType) ArrayList(java.util.ArrayList) Commands(org.apache.pulsar.common.protocol.Commands) DateFormatter(org.apache.pulsar.common.util.DateFormatter) ByteBuf(io.netty.buffer.ByteBuf) Auto(org.apache.pulsar.client.impl.ProducerBase.MultiSchemaMode.Auto) Commands.hasChecksum(org.apache.pulsar.common.protocol.Commands.hasChecksum) TimerTask(io.netty.util.TimerTask) CompressionCodecProvider(org.apache.pulsar.common.compression.CompressionCodecProvider) SchemaHash(org.apache.pulsar.common.protocol.schema.SchemaHash) Crc32cIntChecksum.resumeChecksum(com.scurrilous.circe.checksum.Crc32cIntChecksum.resumeChecksum) CryptoException(org.apache.pulsar.client.api.PulsarClientException.CryptoException) Timeout(io.netty.util.Timeout) Logger(org.slf4j.Logger) Enabled(org.apache.pulsar.client.impl.ProducerBase.MultiSchemaMode.Enabled) Iterator(java.util.Iterator) TransactionImpl(org.apache.pulsar.client.impl.transaction.TransactionImpl) None(org.apache.pulsar.client.impl.MessageImpl.SchemaState.None) Semaphore(java.util.concurrent.Semaphore) ProducerCryptoFailureAction(org.apache.pulsar.client.api.ProducerCryptoFailureAction) IOException(java.io.IOException) AtomicLongFieldUpdater(java.util.concurrent.atomic.AtomicLongFieldUpdater) ReferenceCounted(io.netty.util.ReferenceCounted) ProducerConfigurationData(org.apache.pulsar.client.impl.conf.ProducerConfigurationData) Schema(org.apache.pulsar.client.api.Schema) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) MessageId(org.apache.pulsar.client.api.MessageId) ProducerAccessMode(org.apache.pulsar.client.api.ProducerAccessMode) VisibleForTesting(com.google.common.annotations.VisibleForTesting) ArrayDeque(java.util.ArrayDeque) Collections(java.util.Collections) ChecksumType(org.apache.pulsar.common.protocol.Commands.ChecksumType) Timeout(io.netty.util.Timeout) ByteBuf(io.netty.buffer.ByteBuf) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) JSONSchema(org.apache.pulsar.client.impl.schema.JSONSchema) SchemaInfo(org.apache.pulsar.common.schema.SchemaInfo) TimeoutException(org.apache.pulsar.client.api.PulsarClientException.TimeoutException)

Example 5 with JSONSchema

use of org.apache.pulsar.client.impl.schema.JSONSchema in project incubator-pulsar by apache.

the class TestJsonDecoder method testCyclicDefinitionDetect.

@Test(singleThreaded = true)
public void testCyclicDefinitionDetect() {
    JSONSchema cyclicSchema = JSONSchema.of(DecoderTestMessage.CyclicFoo.class);
    PrestoException exception = expectThrows(PrestoException.class, () -> {
        decoderFactory.extractColumnMetadata(topicName, cyclicSchema.getSchemaInfo(), PulsarColumnHandle.HandleKeyValueType.NONE);
    });
    assertEquals("Topic " + topicName.toString() + " schema may contains cyclic definitions.", exception.getMessage());
}
Also used : JSONSchema(org.apache.pulsar.client.impl.schema.JSONSchema) PrestoException(io.prestosql.spi.PrestoException) DecoderTestMessage(org.apache.pulsar.sql.presto.decoder.DecoderTestMessage) Test(org.testng.annotations.Test)

Aggregations

JSONSchema (org.apache.pulsar.client.impl.schema.JSONSchema)7 ArrayList (java.util.ArrayList)4 HashMap (java.util.HashMap)4 List (java.util.List)4 Map (java.util.Map)4 Optional (java.util.Optional)4 TimeUnit (java.util.concurrent.TimeUnit)4 VisibleForTesting (com.google.common.annotations.VisibleForTesting)3 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)3 Preconditions.checkState (com.google.common.base.Preconditions.checkState)3 Crc32cIntChecksum.computeChecksum (com.scurrilous.circe.checksum.Crc32cIntChecksum.computeChecksum)3 Crc32cIntChecksum.resumeChecksum (com.scurrilous.circe.checksum.Crc32cIntChecksum.resumeChecksum)3 ByteBuf (io.netty.buffer.ByteBuf)3 AbstractReferenceCounted (io.netty.util.AbstractReferenceCounted)3 Recycler (io.netty.util.Recycler)3 Handle (io.netty.util.Recycler.Handle)3 ReferenceCountUtil (io.netty.util.ReferenceCountUtil)3 ReferenceCounted (io.netty.util.ReferenceCounted)3 Timeout (io.netty.util.Timeout)3 TimerTask (io.netty.util.TimerTask)3