Search in sources :

Example 1 with KeyValue

use of org.apache.pulsar.common.api.proto.PulsarApi.KeyValue in project incubator-pulsar by apache.

the class PersistentTopicsImpl method getIndividualMsgsFromBatch.

private List<Message<byte[]>> getIndividualMsgsFromBatch(String msgId, byte[] data, Map<String, String> properties) {
    List<Message<byte[]>> ret = new ArrayList<>();
    int batchSize = Integer.parseInt(properties.get(BATCH_HEADER));
    for (int i = 0; i < batchSize; i++) {
        String batchMsgId = msgId + ":" + i;
        PulsarApi.SingleMessageMetadata.Builder singleMessageMetadataBuilder = PulsarApi.SingleMessageMetadata.newBuilder();
        ByteBuf buf = Unpooled.wrappedBuffer(data);
        try {
            ByteBuf singleMessagePayload = Commands.deSerializeSingleMessageInBatch(buf, singleMessageMetadataBuilder, i, batchSize);
            SingleMessageMetadata singleMessageMetadata = singleMessageMetadataBuilder.build();
            if (singleMessageMetadata.getPropertiesCount() > 0) {
                for (KeyValue entry : singleMessageMetadata.getPropertiesList()) {
                    properties.put(entry.getKey(), entry.getValue());
                }
            }
            ret.add(new MessageImpl<>(batchMsgId, properties, singleMessagePayload, Schema.IDENTITY));
        } catch (Exception ex) {
            log.error("Exception occured while trying to get BatchMsgId: {}", batchMsgId, ex);
        }
        buf.release();
        singleMessageMetadataBuilder.recycle();
    }
    return ret;
}
Also used : KeyValue(org.apache.pulsar.common.api.proto.PulsarApi.KeyValue) Message(org.apache.pulsar.client.api.Message) SingleMessageMetadata(org.apache.pulsar.common.api.proto.PulsarApi.SingleMessageMetadata) ArrayList(java.util.ArrayList) ByteBuf(io.netty.buffer.ByteBuf) NotFoundException(org.apache.pulsar.client.admin.PulsarAdminException.NotFoundException) ClientErrorException(javax.ws.rs.ClientErrorException) WebApplicationException(javax.ws.rs.WebApplicationException) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) ExecutionException(java.util.concurrent.ExecutionException) ServerErrorException(javax.ws.rs.ServerErrorException)

Example 2 with KeyValue

use of org.apache.pulsar.common.api.proto.PulsarApi.KeyValue in project incubator-pulsar by apache.

the class PersistentTopicsBase method internalPeekNthMessage.

protected Response internalPeekNthMessage(String subName, int messagePosition, boolean authoritative) {
    if (topicName.isGlobal()) {
        validateGlobalNamespaceOwnership(namespaceName);
    }
    PartitionedTopicMetadata partitionMetadata = getPartitionedTopicMetadata(topicName, authoritative);
    if (partitionMetadata.partitions > 0) {
        throw new RestException(Status.METHOD_NOT_ALLOWED, "Peek messages on a partitioned topic is not allowed");
    }
    validateAdminOperationOnTopic(authoritative);
    if (!(getTopicReference(topicName) instanceof PersistentTopic)) {
        log.error("[{}] Not supported operation of non-persistent topic {} {}", clientAppId(), topicName, subName);
        throw new RestException(Status.METHOD_NOT_ALLOWED, "Skip messages on a non-persistent topic is not allowed");
    }
    PersistentTopic topic = (PersistentTopic) getTopicReference(topicName);
    PersistentReplicator repl = null;
    PersistentSubscription sub = null;
    Entry entry = null;
    if (subName.startsWith(topic.replicatorPrefix)) {
        repl = getReplicatorReference(subName, topic);
    } else {
        sub = (PersistentSubscription) 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", DateFormatter.format(metadata.getPublishTime()));
        }
        if (metadata.hasEventTime()) {
            responseBuilder.header("X-Pulsar-event-time", DateFormatter.format(metadata.getEventTime()));
        }
        if (metadata.hasNumMessagesInBatch()) {
            responseBuilder.header("X-Pulsar-num-batch-message", metadata.getNumMessagesInBatch());
        }
        // 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, topicName, subName, exception);
        throw new RestException(exception);
    } finally {
        if (entry != null) {
            entry.release();
        }
    }
}
Also used : PersistentReplicator(org.apache.pulsar.broker.service.persistent.PersistentReplicator) KeyValue(org.apache.pulsar.common.api.proto.PulsarApi.KeyValue) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) OutputStream(java.io.OutputStream) RestException(org.apache.pulsar.broker.web.RestException) StreamingOutput(javax.ws.rs.core.StreamingOutput) ByteBuf(io.netty.buffer.ByteBuf) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) NotAllowedException(org.apache.pulsar.broker.service.BrokerServiceException.NotAllowedException) NotFoundException(org.apache.pulsar.client.admin.PulsarAdminException.NotFoundException) PreconditionFailedException(org.apache.pulsar.client.admin.PulsarAdminException.PreconditionFailedException) RestException(org.apache.pulsar.broker.web.RestException) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) SubscriptionBusyException(org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException) WebApplicationException(javax.ws.rs.WebApplicationException) KeeperException(org.apache.zookeeper.KeeperException) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) TopicBusyException(org.apache.pulsar.broker.service.BrokerServiceException.TopicBusyException) PulsarServerException(org.apache.pulsar.broker.PulsarServerException) Entry(org.apache.bookkeeper.mledger.Entry) MessageMetadata(org.apache.pulsar.common.api.proto.PulsarApi.MessageMetadata) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) CompressionCodec(org.apache.pulsar.common.compression.CompressionCodec) ResponseBuilder(javax.ws.rs.core.Response.ResponseBuilder) PartitionedTopicMetadata(org.apache.pulsar.common.partition.PartitionedTopicMetadata)

Example 3 with KeyValue

use of org.apache.pulsar.common.api.proto.PulsarApi.KeyValue in project incubator-pulsar by apache.

the class MessageCrypto method encrypt.

/*
     * Encrypt the payload using the data key and update message metadata with the keyname & encrypted data key
     *
     * @param encKeys One or more public keys to encrypt data key
     *
     * @param msgMetadata Message Metadata
     *
     * @param payload Message which needs to be encrypted
     *
     * @return encryptedData if success
     */
public synchronized ByteBuf encrypt(Set<String> encKeys, CryptoKeyReader keyReader, MessageMetadata.Builder msgMetadata, ByteBuf payload) throws PulsarClientException {
    if (encKeys.isEmpty()) {
        return payload;
    }
    // Update message metadata with encrypted data key
    for (String keyName : encKeys) {
        if (encryptedDataKeyMap.get(keyName) == null) {
            // Attempt to load the key. This will allow us to load keys as soon as
            // a new key is added to producer config
            addPublicKeyCipher(keyName, keyReader);
        }
        EncryptionKeyInfo keyInfo = encryptedDataKeyMap.get(keyName);
        if (keyInfo != null) {
            if (keyInfo.getMetadata() != null && !keyInfo.getMetadata().isEmpty()) {
                List<KeyValue> kvList = new ArrayList<KeyValue>();
                keyInfo.getMetadata().forEach((key, value) -> {
                    kvList.add(KeyValue.newBuilder().setKey(key).setValue(value).build());
                });
                msgMetadata.addEncryptionKeys(EncryptionKeys.newBuilder().setKey(keyName).setValue(ByteString.copyFrom(keyInfo.getKey())).addAllMetadata(kvList).build());
            } else {
                msgMetadata.addEncryptionKeys(EncryptionKeys.newBuilder().setKey(keyName).setValue(ByteString.copyFrom(keyInfo.getKey())).build());
            }
        } else {
            // We should never reach here.
            log.error("{} Failed to find encrypted Data key for key {}.", logCtx, keyName);
        }
    }
    // Create gcm param
    // TODO: Replace random with counter and periodic refreshing based on timer/counter value
    secureRandom.nextBytes(iv);
    GCMParameterSpec gcmParam = new GCMParameterSpec(tagLen, iv);
    // Update message metadata with encryption param
    msgMetadata.setEncryptionParam(ByteString.copyFrom(iv));
    ByteBuf targetBuf = null;
    try {
        // Encrypt the data
        cipher.init(Cipher.ENCRYPT_MODE, dataKey, gcmParam);
        ByteBuffer sourceNioBuf = payload.nioBuffer(payload.readerIndex(), payload.readableBytes());
        int maxLength = cipher.getOutputSize(payload.readableBytes());
        targetBuf = PooledByteBufAllocator.DEFAULT.buffer(maxLength, maxLength);
        ByteBuffer targetNioBuf = targetBuf.nioBuffer(0, maxLength);
        int bytesStored = cipher.doFinal(sourceNioBuf, targetNioBuf);
        targetBuf.writerIndex(bytesStored);
    } catch (IllegalBlockSizeException | BadPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | ShortBufferException e) {
        targetBuf.release();
        log.error("{} Failed to encrypt message. {}", logCtx, e);
        throw new PulsarClientException.CryptoException(e.getMessage());
    }
    payload.release();
    return targetBuf;
}
Also used : KeyValue(org.apache.pulsar.common.api.proto.PulsarApi.KeyValue) InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) ArrayList(java.util.ArrayList) IllegalBlockSizeException(javax.crypto.IllegalBlockSizeException) ByteString(com.google.protobuf.ByteString) EncryptionKeyInfo(org.apache.pulsar.client.api.EncryptionKeyInfo) GCMParameterSpec(javax.crypto.spec.GCMParameterSpec) BadPaddingException(javax.crypto.BadPaddingException) ByteBuf(io.netty.buffer.ByteBuf) InvalidKeyException(java.security.InvalidKeyException) ByteBuffer(java.nio.ByteBuffer) CryptoException(org.apache.pulsar.client.api.PulsarClientException.CryptoException) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ShortBufferException(javax.crypto.ShortBufferException)

Example 4 with KeyValue

use of org.apache.pulsar.common.api.proto.PulsarApi.KeyValue in project incubator-pulsar by apache.

the class MessageCrypto method decrypt.

/*
     * Decrypt the payload using the data key. Keys used to encrypt data key can be retrieved from msgMetadata
     *
     * @param msgMetadata Message Metadata
     *
     * @param payload Message which needs to be decrypted
     *
     * @param keyReader KeyReader implementation to retrieve key value
     *
     * @return decryptedData if success, null otherwise
     */
public ByteBuf decrypt(MessageMetadata msgMetadata, ByteBuf payload, CryptoKeyReader keyReader) {
    // If dataKey is present, attempt to decrypt using the existing key
    if (dataKey != null) {
        ByteBuf decryptedData = getKeyAndDecryptData(msgMetadata, payload);
        // If decryption succeeded, data is non null
        if (decryptedData != null) {
            return decryptedData;
        }
    }
    // dataKey is null or decryption failed. Attempt to regenerate data key
    List<EncryptionKeys> encKeys = msgMetadata.getEncryptionKeysList();
    EncryptionKeys encKeyInfo = encKeys.stream().filter(kbv -> {
        byte[] encDataKey = kbv.getValue().toByteArray();
        List<KeyValue> encKeyMeta = kbv.getMetadataList();
        return decryptDataKey(kbv.getKey(), encDataKey, encKeyMeta, keyReader);
    }).findFirst().orElse(null);
    if (encKeyInfo == null || dataKey == null) {
        // Unable to decrypt data key
        return null;
    }
    return getKeyAndDecryptData(msgMetadata, payload);
}
Also used : KeyValue(org.apache.pulsar.common.api.proto.PulsarApi.KeyValue) ByteBuf(io.netty.buffer.ByteBuf) EncryptionKeys(org.apache.pulsar.common.api.proto.PulsarApi.EncryptionKeys)

Aggregations

ByteBuf (io.netty.buffer.ByteBuf)4 KeyValue (org.apache.pulsar.common.api.proto.PulsarApi.KeyValue)4 ArrayList (java.util.ArrayList)2 ExecutionException (java.util.concurrent.ExecutionException)2 WebApplicationException (javax.ws.rs.WebApplicationException)2 PulsarAdminException (org.apache.pulsar.client.admin.PulsarAdminException)2 NotFoundException (org.apache.pulsar.client.admin.PulsarAdminException.NotFoundException)2 PulsarClientException (org.apache.pulsar.client.api.PulsarClientException)2 ByteString (com.google.protobuf.ByteString)1 IOException (java.io.IOException)1 OutputStream (java.io.OutputStream)1 ByteBuffer (java.nio.ByteBuffer)1 InvalidAlgorithmParameterException (java.security.InvalidAlgorithmParameterException)1 InvalidKeyException (java.security.InvalidKeyException)1 BadPaddingException (javax.crypto.BadPaddingException)1 IllegalBlockSizeException (javax.crypto.IllegalBlockSizeException)1 ShortBufferException (javax.crypto.ShortBufferException)1 GCMParameterSpec (javax.crypto.spec.GCMParameterSpec)1 ClientErrorException (javax.ws.rs.ClientErrorException)1 ServerErrorException (javax.ws.rs.ServerErrorException)1