Search in sources :

Example 6 with MessageMetadata

use of com.yahoo.pulsar.common.api.proto.PulsarApi.MessageMetadata in project pulsar by yahoo.

the class PersistentTopics method peekNthMessage.

@GET
@Path("/{property}/{cluster}/{namespace}/{destination}/subscription/{subName}/position/{messagePosition}")
@ApiOperation(value = "Peek nth message on a topic subscription.")
@ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"), @ApiResponse(code = 404, message = "Topic, subscription or the message position does not exist") })
public Response peekNthMessage(@PathParam("property") String property, @PathParam("cluster") String cluster, @PathParam("namespace") String namespace, @PathParam("destination") @Encoded String destination, @PathParam("subName") String subName, @PathParam("messagePosition") int messagePosition, @QueryParam("authoritative") @DefaultValue("false") boolean authoritative) {
    destination = decode(destination);
    DestinationName dn = DestinationName.get(domain(), property, cluster, namespace, destination);
    PartitionedTopicMetadata partitionMetadata = getPartitionedTopicMetadata(property, cluster, namespace, destination, authoritative);
    if (partitionMetadata.partitions > 0) {
        throw new RestException(Status.METHOD_NOT_ALLOWED, "Peek messages on a partitioned topic is not allowed");
    }
    validateAdminOperationOnDestination(dn, authoritative);
    PersistentTopic topic = getTopicReference(dn);
    PersistentReplicator repl = null;
    PersistentSubscription sub = null;
    Entry entry = null;
    if (subName.startsWith(topic.replicatorPrefix)) {
        repl = getReplicatorReference(subName, topic);
    } else {
        sub = getSubscriptionReference(subName, topic);
    }
    try {
        if (subName.startsWith(topic.replicatorPrefix)) {
            entry = repl.peekNthMessage(messagePosition).get();
        } else {
            entry = sub.peekNthMessage(messagePosition).get();
        }
        checkNotNull(entry);
        PositionImpl pos = (PositionImpl) entry.getPosition();
        ByteBuf metadataAndPayload = entry.getDataBuffer();
        // moves the readerIndex to the payload
        MessageMetadata metadata = Commands.parseMessageMetadata(metadataAndPayload);
        ResponseBuilder responseBuilder = Response.ok();
        responseBuilder.header("X-Pulsar-Message-ID", pos.toString());
        for (KeyValue keyValue : metadata.getPropertiesList()) {
            responseBuilder.header("X-Pulsar-PROPERTY-" + keyValue.getKey(), keyValue.getValue());
        }
        if (metadata.hasPublishTime()) {
            responseBuilder.header("X-Pulsar-publish-time", DATE_FORMAT.format(Instant.ofEpochMilli(metadata.getPublishTime())));
        }
        // Decode if needed
        CompressionCodec codec = CompressionCodecProvider.getCompressionCodec(metadata.getCompression());
        ByteBuf uncompressedPayload = codec.decode(metadataAndPayload, metadata.getUncompressedSize());
        // Copy into a heap buffer for output stream compatibility
        ByteBuf data = PooledByteBufAllocator.DEFAULT.heapBuffer(uncompressedPayload.readableBytes(), uncompressedPayload.readableBytes());
        data.writeBytes(uncompressedPayload);
        uncompressedPayload.release();
        StreamingOutput stream = new StreamingOutput() {

            @Override
            public void write(OutputStream output) throws IOException, WebApplicationException {
                output.write(data.array(), data.arrayOffset(), data.readableBytes());
                data.release();
            }
        };
        return responseBuilder.entity(stream).build();
    } catch (NullPointerException npe) {
        throw new RestException(Status.NOT_FOUND, "Message not found");
    } catch (Exception exception) {
        log.error("[{}] Failed to get message at position {} from {} {}", clientAppId(), messagePosition, dn, subName, exception);
        throw new RestException(exception);
    } finally {
        if (entry != null) {
            entry.release();
        }
    }
}
Also used : PersistentReplicator(com.yahoo.pulsar.broker.service.persistent.PersistentReplicator) KeyValue(com.yahoo.pulsar.common.api.proto.PulsarApi.KeyValue) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) OutputStream(java.io.OutputStream) RestException(com.yahoo.pulsar.broker.web.RestException) StreamingOutput(javax.ws.rs.core.StreamingOutput) ByteBuf(io.netty.buffer.ByteBuf) PersistentSubscription(com.yahoo.pulsar.broker.service.persistent.PersistentSubscription) RestException(com.yahoo.pulsar.broker.web.RestException) TopicBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.TopicBusyException) WebApplicationException(javax.ws.rs.WebApplicationException) PulsarClientException(com.yahoo.pulsar.client.api.PulsarClientException) PreconditionFailedException(com.yahoo.pulsar.client.admin.PulsarAdminException.PreconditionFailedException) SubscriptionBusyException(com.yahoo.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException) NotFoundException(com.yahoo.pulsar.client.admin.PulsarAdminException.NotFoundException) NotAllowedException(com.yahoo.pulsar.broker.service.BrokerServiceException.NotAllowedException) KeeperException(org.apache.zookeeper.KeeperException) IOException(java.io.IOException) Entry(org.apache.bookkeeper.mledger.Entry) MessageMetadata(com.yahoo.pulsar.common.api.proto.PulsarApi.MessageMetadata) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) DestinationName(com.yahoo.pulsar.common.naming.DestinationName) CompressionCodec(com.yahoo.pulsar.common.compression.CompressionCodec) ResponseBuilder(javax.ws.rs.core.Response.ResponseBuilder) PartitionedTopicMetadata(com.yahoo.pulsar.common.partition.PartitionedTopicMetadata) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 7 with MessageMetadata

use of com.yahoo.pulsar.common.api.proto.PulsarApi.MessageMetadata in project pulsar by yahoo.

the class ServerCnxTest method testSendCommand.

@Test(timeOut = 30000)
public void testSendCommand() throws Exception {
    resetChannel();
    setChannelConnected();
    ByteBuf clientCommand = Commands.newProducer(successTopicName, 1, /* producer id */
    1, /* request id */
    "prod-name");
    channel.writeInbound(clientCommand);
    assertTrue(getResponse() instanceof CommandProducerSuccess);
    // test SEND success
    MessageMetadata messageMetadata = MessageMetadata.newBuilder().setPublishTime(System.currentTimeMillis()).setProducerName("prod-name").setSequenceId(0).build();
    ByteBuf data = Unpooled.buffer(1024);
    clientCommand = Commands.newSend(1, 0, 1, ChecksumType.None, messageMetadata, data);
    channel.writeInbound(Unpooled.copiedBuffer(clientCommand));
    clientCommand.release();
    assertTrue(getResponse() instanceof CommandSendReceipt);
    channel.finish();
}
Also used : MessageMetadata(com.yahoo.pulsar.common.api.proto.PulsarApi.MessageMetadata) CommandProducerSuccess(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandProducerSuccess) CommandSendReceipt(com.yahoo.pulsar.common.api.proto.PulsarApi.CommandSendReceipt) ByteBuf(io.netty.buffer.ByteBuf) Test(org.testng.annotations.Test)

Example 8 with MessageMetadata

use of com.yahoo.pulsar.common.api.proto.PulsarApi.MessageMetadata in project pulsar by yahoo.

the class ManagedLedgerTest method getMessageWithMetadata.

public ByteBuf getMessageWithMetadata(byte[] data) throws IOException {
    MessageMetadata messageData = MessageMetadata.newBuilder().setPublishTime(System.currentTimeMillis()).setProducerName("prod-name").setSequenceId(0).build();
    ByteBuf payload = Unpooled.wrappedBuffer(data, 0, data.length);
    int msgMetadataSize = messageData.getSerializedSize();
    int headersSize = 4 + msgMetadataSize;
    ByteBuf headers = PooledByteBufAllocator.DEFAULT.buffer(headersSize, headersSize);
    ByteBufCodedOutputStream outStream = ByteBufCodedOutputStream.get(headers);
    headers.writeInt(msgMetadataSize);
    messageData.writeTo(outStream);
    outStream.recycle();
    return DoubleByteBuf.get(headers, payload);
}
Also used : MessageMetadata(com.yahoo.pulsar.common.api.proto.PulsarApi.MessageMetadata) DoubleByteBuf(com.yahoo.pulsar.common.api.DoubleByteBuf) ByteBuf(io.netty.buffer.ByteBuf) ByteBufCodedOutputStream(com.yahoo.pulsar.common.util.protobuf.ByteBufCodedOutputStream)

Example 9 with MessageMetadata

use of com.yahoo.pulsar.common.api.proto.PulsarApi.MessageMetadata in project pulsar by yahoo.

the class ManagedLedgerImpl method checkBackloggedCursors.

@Override
public void checkBackloggedCursors() {
    // activate caught up cursors
    cursors.forEach(cursor -> {
        if (cursor.getNumberOfEntries() < maxActiveCursorBacklogEntries) {
            cursor.setActive();
        }
    });
    // deactivate backlog cursors
    Iterator<ManagedCursor> cursors = activeCursors.iterator();
    while (cursors.hasNext()) {
        ManagedCursor cursor = cursors.next();
        long backlogEntries = cursor.getNumberOfEntries();
        if (backlogEntries > maxActiveCursorBacklogEntries) {
            PositionImpl readPosition = (PositionImpl) cursor.getReadPosition();
            readPosition = isValidPosition(readPosition) ? readPosition : getNextValidPosition(readPosition);
            if (readPosition == null) {
                if (log.isDebugEnabled()) {
                    log.debug("[{}] Couldn't find valid read position [{}] {}", name, cursor.getName(), cursor.getReadPosition());
                }
                continue;
            }
            try {
                asyncReadEntry(readPosition, new ReadEntryCallback() {

                    @Override
                    public void readEntryFailed(ManagedLedgerException e, Object ctx) {
                        log.warn("[{}] Failed while reading entries on [{}] {}", name, cursor.getName(), e.getMessage(), e);
                    }

                    @Override
                    public void readEntryComplete(Entry entry, Object ctx) {
                        MessageMetadata msgMetadata = null;
                        try {
                            msgMetadata = Commands.parseMessageMetadata(entry.getDataBuffer());
                            long msgTimeSincePublish = (System.currentTimeMillis() - msgMetadata.getPublishTime());
                            if (msgTimeSincePublish > maxMessageCacheRetentionTimeMillis) {
                                cursor.setInactive();
                            }
                        } finally {
                            if (msgMetadata != null) {
                                msgMetadata.recycle();
                            }
                            entry.release();
                        }
                    }
                }, null);
            } catch (Exception e) {
                log.warn("[{}] Failed while reading entries from cache on [{}] {}", name, cursor.getName(), e.getMessage(), e);
            }
        }
    }
}
Also used : ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) Entry(org.apache.bookkeeper.mledger.Entry) MessageMetadata(com.yahoo.pulsar.common.api.proto.PulsarApi.MessageMetadata) ReadEntryCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.ReadEntryCallback) BKException(org.apache.bookkeeper.client.BKException) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) ManagedLedgerFencedException(org.apache.bookkeeper.mledger.ManagedLedgerException.ManagedLedgerFencedException) BadVersionException(org.apache.bookkeeper.mledger.ManagedLedgerException.BadVersionException) MetaStoreException(org.apache.bookkeeper.mledger.ManagedLedgerException.MetaStoreException) ManagedCursor(org.apache.bookkeeper.mledger.ManagedCursor)

Example 10 with MessageMetadata

use of com.yahoo.pulsar.common.api.proto.PulsarApi.MessageMetadata in project pulsar by yahoo.

the class PersistentTopicTest method testPublishMessageMLFailure.

@Test
public void testPublishMessageMLFailure() throws Exception {
    final String successTopicName = "persistent://prop/use/ns-abc/successTopic";
    final ManagedLedger ledgerMock = mock(ManagedLedger.class);
    doReturn(new ArrayList<Object>()).when(ledgerMock).getCursors();
    PersistentTopic topic = new PersistentTopic(successTopicName, ledgerMock, brokerService);
    MessageMetadata.Builder messageMetadata = MessageMetadata.newBuilder();
    messageMetadata.setPublishTime(System.currentTimeMillis());
    messageMetadata.setProducerName("prod-name");
    messageMetadata.setSequenceId(1);
    ByteBuf payload = Unpooled.wrappedBuffer("content".getBytes());
    final CountDownLatch latch = new CountDownLatch(1);
    // override asyncAddEntry callback to return error
    doAnswer(new Answer<Object>() {

        @Override
        public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
            ((AddEntryCallback) invocationOnMock.getArguments()[1]).addFailed(new ManagedLedgerException("Managed ledger failure"), invocationOnMock.getArguments()[2]);
            return null;
        }
    }).when(ledgerMock).asyncAddEntry(any(ByteBuf.class), any(AddEntryCallback.class), anyObject());
    topic.publishMessage(payload, (exception, ledgerId, entryId) -> {
        if (exception == null) {
            fail("publish should have failed");
        } else {
            latch.countDown();
        }
    });
    assertTrue(latch.await(1, TimeUnit.SECONDS));
}
Also used : ManagedLedger(org.apache.bookkeeper.mledger.ManagedLedger) Matchers.anyString(org.mockito.Matchers.anyString) ByteBuf(io.netty.buffer.ByteBuf) CountDownLatch(java.util.concurrent.CountDownLatch) MessageMetadata(com.yahoo.pulsar.common.api.proto.PulsarApi.MessageMetadata) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) InvocationOnMock(org.mockito.invocation.InvocationOnMock) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) Matchers.anyObject(org.mockito.Matchers.anyObject) AddEntryCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.AddEntryCallback) Test(org.testng.annotations.Test)

Aggregations

MessageMetadata (com.yahoo.pulsar.common.api.proto.PulsarApi.MessageMetadata)11 ByteBuf (io.netty.buffer.ByteBuf)7 Test (org.testng.annotations.Test)4 PulsarClientException (com.yahoo.pulsar.client.api.PulsarClientException)3 DoubleByteBuf (com.yahoo.pulsar.common.api.DoubleByteBuf)3 PersistentTopic (com.yahoo.pulsar.broker.service.persistent.PersistentTopic)2 Message (com.yahoo.pulsar.client.api.Message)2 IOException (java.io.IOException)2 Entry (org.apache.bookkeeper.mledger.Entry)2 ManagedLedgerException (org.apache.bookkeeper.mledger.ManagedLedgerException)2 NotAllowedException (com.yahoo.pulsar.broker.service.BrokerServiceException.NotAllowedException)1 SubscriptionBusyException (com.yahoo.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException)1 TopicBusyException (com.yahoo.pulsar.broker.service.BrokerServiceException.TopicBusyException)1 PersistentReplicator (com.yahoo.pulsar.broker.service.persistent.PersistentReplicator)1 PersistentSubscription (com.yahoo.pulsar.broker.service.persistent.PersistentSubscription)1 RestException (com.yahoo.pulsar.broker.web.RestException)1 PulsarAdminException (com.yahoo.pulsar.client.admin.PulsarAdminException)1 NotFoundException (com.yahoo.pulsar.client.admin.PulsarAdminException.NotFoundException)1 PreconditionFailedException (com.yahoo.pulsar.client.admin.PulsarAdminException.PreconditionFailedException)1 Consumer (com.yahoo.pulsar.client.api.Consumer)1