| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| #pragma once |
| |
| #include <pulsar/Message.h> |
| #include <pulsar/st/MessageId.h> |
| #include <pulsar/st/detail/MessageCore.h> |
| |
| #include <chrono> |
| #include <cstddef> |
| #include <cstdint> |
| #include <optional> |
| #include <span> |
| #include <string> |
| #include <string_view> |
| #include <utility> |
| |
| namespace pulsar::st { |
| |
| /** |
| * INTERNAL — the received message behind `detail::MessageCore`. |
| * |
| * A thin view over a classic `pulsar::Message` (which owns the payload and metadata) |
| * plus the segment-qualified `pulsar::st::MessageId` minted on the receive path. An |
| * optional `topicOverride` carries the scalable topic identity in namespace mode |
| * (a plain segment consumer reports the segment backing topic otherwise). |
| */ |
| class MessageImpl { |
| public: |
| MessageImpl(pulsar::Message message, MessageId id, |
| std::optional<std::string> topicOverride = std::nullopt) |
| : classic_(std::move(message)), id_(std::move(id)), topicOverride_(std::move(topicOverride)) {} |
| |
| std::span<const std::byte> data() const { |
| return {static_cast<const std::byte*>(classic_.getData()), classic_.getLength()}; |
| } |
| const MessageId& id() const { return id_; } |
| std::optional<std::string_view> key() const { |
| if (!classic_.hasPartitionKey()) return std::nullopt; |
| return std::string_view(classic_.getPartitionKey()); |
| } |
| const Properties& properties() const { return classic_.getProperties(); } |
| Timestamp publishTime() const { return fromMillis(classic_.getPublishTimestamp()); } |
| std::optional<Timestamp> eventTime() const { |
| const uint64_t millis = classic_.getEventTimestamp(); |
| return millis != 0 ? std::optional<Timestamp>(fromMillis(millis)) : std::nullopt; |
| } |
| // The classic public Message API does not expose the message's sequence id; populating it |
| // would require reaching into pulsar::MessageImpl's metadata, i.e. touching the classic API. |
| // TODO: revisit when the Stream consumer needs it (a classic Message::getSequenceId() accessor). |
| int64_t sequenceId() const { return -1; } |
| std::optional<std::string_view> producerName() const { |
| const std::string& name = classic_.getProducerName(); |
| return name.empty() ? std::nullopt : std::optional<std::string_view>(name); |
| } |
| std::string_view topic() const { |
| return topicOverride_ ? std::string_view(*topicOverride_) : std::string_view(classic_.getTopicName()); |
| } |
| int redeliveryCount() const { return classic_.getRedeliveryCount(); } |
| std::optional<std::string_view> replicatedFrom() const { |
| const std::optional<const std::string*> from = classic_.getReplicatedFrom(); |
| if (!from || *from == nullptr) return std::nullopt; |
| return std::string_view(**from); |
| } |
| |
| private: |
| static Timestamp fromMillis(uint64_t millis) { |
| return Timestamp(std::chrono::milliseconds(static_cast<std::int64_t>(millis))); |
| } |
| |
| pulsar::Message classic_; |
| MessageId id_; |
| std::optional<std::string> topicOverride_; |
| }; |
| |
| } // namespace pulsar::st |