diff --git a/.travis.yml b/.travis.yml index 25cfece665809..90ad90ca16234 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,18 +1,24 @@ -language: java +language: java C++ jdk: - oraclejdk8 cache: directories: - $HOME/.m2 - + - $HOME/pulsar-dep # Reconstruct the gpg keys to sign the artifacts before_deploy: - echo $GPG_SECRET_KEYS | base64 --decode | $GPG_EXECUTABLE --import --batch || true - echo $GPG_OWNERTRUST | base64 --decode | $GPG_EXECUTABLE --import-ownertrust --batch || true +install: + - sudo bash -x $TRAVIS_BUILD_DIR/pulsar-client-cpp/travis-build.sh $HOME/pulsar-dep $TRAVIS_BUILD_DIR dep + +after_success: + - sudo bash -x $TRAVIS_BUILD_DIR/pulsar-client-cpp/travis-build.sh $HOME/pulsar-dep $TRAVIS_BUILD_DIR compile + deploy: - provider: script @@ -27,6 +33,7 @@ deploy: on: tags: true - + provider: releases api_key: secure: mIACMQlTzepBa9wWbKlME1Ig9/vKLHz63fn2zR2fbYjaAgXCPVe1lbTLbOZb62yB0XL7rUekyKIf0DEFH/cS1XjCb7aDKo4pLh6uiHdIIS8t1qEJJT54vbLwnWJXjo+14QHvaXgDlO/YoxpyOicrKI++b3fScD0zK2I8R6Lmwan/ZQze9uhRO0RKGChsDAszy+98C6JJxQXWQ0YjnUhwP5PtZX3Fm1rxtuCIk2Fl9gQdp9/j9U6vRKtWaO22Q2YaaaPGGoVyTwV6iMSOXDMb6zhjEQ3aiuJMJHUJRcGEU4fV7hkiUukWdo5+5C/mASNiJDYefG86KfCktMniPMzyAPXNc6hUzbOZuLNI1/f1QqBwzTJbH7NIUjz5f0hjNsHuYvkL8TcxE9pDA0Qkr8OIWR8M3+H7WKuiSTaVSeCobGBE8g6ymanlRvOQZblFpgw91B/KmZucsin0+rV5tVRlqTBYHL5f6fXEyhKdGYRiHaNR29mBBJsZng2tR6wVjPGqyEfdwFVOs44d2Rkt885VjZthap/Yw+SJKOvbJv1zaRglmbvbl629LvYOgT6ptYPDJyu/J/kzPrWnzvyTf72M6bR991Kx8gEkT4WRwCRBAuhg8i2bmIcsjbXtLcB0YRHgrBueJD0SuLREtcxJYvkgMI1UZon5UrCTkJDc0oFLO28= diff --git a/pom.xml b/pom.xml index 72de492e6d205..d2073b306c54f 100644 --- a/pom.xml +++ b/pom.xml @@ -466,6 +466,11 @@ flexible messaging model and an intuitive client API. logs/** **/*.versionsBackup **/circe/** + pulsar-client-cpp/lib/checksum/int_types.h + pulsar-client-cpp/lib/checksum/crc32c* + pulsar-client-cpp/lib/lz4/lz4.* + pulsar-client-cpp/lib/PulsarApi.pb.* + pulsar-client-cpp/CMakeFiles/** JAVADOC_STYLE diff --git a/pulsar-client-cpp/.gitignore b/pulsar-client-cpp/.gitignore new file mode 100644 index 0000000000000..b0dbd788e44ff --- /dev/null +++ b/pulsar-client-cpp/.gitignore @@ -0,0 +1,58 @@ +# Compiled Object files +*.slo +*.lo +*.o +*.obj +*.os +*.scons* + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll +*.so.1 + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# Dependency file +*.d + +# Mac swap file +*.DS_Store + +# Linux swap file +*.swp + +# Exclude compiled executables +/examples/SampleProducer +/examples/SampleConsumer +/examples/SampleAsyncProducer +/examples/SampleConsumerListener +/tests/main +/perf/PerfProducer +/perf/PerfConsumer +/system-test/SystemTest + +# Eclipse generated files +.cproject +.project +.settings/ +.pydevproject + +# doxygen files +apidocs/ + +# CMAKE +Makefile +cmake_install.cmake +CMakeFiles +CMakeCache.txt diff --git a/pulsar-client-cpp/CMakeLists.txt b/pulsar-client-cpp/CMakeLists.txt new file mode 100644 index 0000000000000..4e74dbc1a603c --- /dev/null +++ b/pulsar-client-cpp/CMakeLists.txt @@ -0,0 +1,65 @@ +# +# Copyright 2016 Yahoo Inc. +# +# Licensed 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. +# + +cmake_minimum_required(VERSION 2.8) +project (pulsar-cpp) + +set(Boost_NO_BOOST_CMAKE ON) + +set (CMAKE_CXX_FLAGS "-Wno-deprecated-declarations ${CMAKE_CXX_FLAGS}") + +find_package(Boost REQUIRED COMPONENTS program_options filesystem regex thread system) +find_package(OpenSSL REQUIRED) +find_package(ZLIB REQUIRED) +find_package(ProtoBuf QUIET) +if(NOT ProtoBuf_FOUND) + find_library(PROTOBUF_LIBRARIES protobuf) +endif() +find_library(LOG4CXX_LIBRARY_PATH log4cxx) +find_library(CURL_LIBRARY_PATH curl) +find_path(LOG4CXX_INCLUDE_PATH log4cxx/logger.h) + +include_directories( + ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/include + ${Boost_INCLUDE_DIR} + ${OPENSSL_INCLUDE_DIR} + ${ZLIB_INCLUDE_DIR} + ${PROTOBUF_INCLUDE_DIR} + ${LOG4CXX_INCLUDE_PATH} +) + +set(COMMON_LIBS + ${COMMON_LIBS} + ${Boost_LIBRARIES} + ${OPENSSL_LIBRARIES} + ${ZLIB_LIBRARIES} + ${PROTOBUF_LIBRARIES} + ${LOG4CXX_LIBRARY_PATH} + ${CURL_LIBRARY_PATH} +) + +link_directories(${CMAKE_BINARY_DIR}/lib) + +set(CLIENT_LIBS + ${COMMON_LIBS} + pulsar +) + +add_subdirectory(lib) +add_subdirectory(perf) +add_subdirectory(examples) +add_subdirectory(tests) diff --git a/pulsar-client-cpp/NOTICE b/pulsar-client-cpp/NOTICE new file mode 100644 index 0000000000000..9154f7fcf7bdb --- /dev/null +++ b/pulsar-client-cpp/NOTICE @@ -0,0 +1,33 @@ + +Pulsar C++ Client Library + +Copyright 2016 Yahoo Inc. + + Licensed 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. + + +This product contain sources from LZ4 - Fast LZ compression algorithm: + * Copyright (C) 2011-2015, Yann Collet. + * LICENSE: BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + * HOMEPAGE: https://github.com/Cyan4973/lz4 + + +This product contains sources from Circe CRC library: + * Copyright 2014 Trevor Robinson + * LICENSE : Apache License, Version 2.0 + * HOMEPAGE: https://github.com/trevorr/circe + +This product contains sources from Adler CRC32c implementation: + * Copyright (C) 2013 Mark Adler + * LICENSE: ZLib License (https://opensource.org/licenses/Zlib) + * HOMEPAGE: https://github.com/baruch/crcbench/blob/master/crc-mark-adler.c diff --git a/pulsar-client-cpp/README.md b/pulsar-client-cpp/README.md new file mode 100644 index 0000000000000..d9b8b3c128c9b --- /dev/null +++ b/pulsar-client-cpp/README.md @@ -0,0 +1,66 @@ + +### Pulsar C++ client library + +Examples for using the API to publish and consume messages can be found on +https://github.com/yahoo/pulsar/tree/master/pulsar-client-cpp/examples + +#### Requirements + + * CMake + * Boost + * [Protocol Buffer 2.6](https://developers.google.com/protocol-buffers/) + * [Log4CXX](https://logging.apache.org/log4cxx) + * LibCurl + * [GTest](https://github.com/google/googletest) + + +#### Compile on Ubuntu Server 16.04 + +Install all dependencies: + +```shell +apt-get install cmake libssl-dev libcurl4-openssl-dev liblog4cxx-dev \ + libprotobuf-dev libboost-all-dev libgtest-dev +``` + +Compile and install Google Test: + +```shell +cd /usr/src/gtest +sudo cmake . +sudo make +sudo cp *.a /usr/lib +``` + + +Compile Pulsar client library: + +```shell +cd pulsar/pulsar-client-cpp +cmake . +make +``` + +Client library will be placed in +``` +lib/libpulsar.so +lib/libpulsar.a +``` + +Tools : + +``` +perf/perfProducer +perf/perfConsumer +``` + +Tests: + +``` + 1. Start the standalone pulsar + export PULSAR_STANDALONE_CONF=tests/standalone.conf + ../bin/pulsar standalone + + 2. Run tests + tests/main +``` diff --git a/pulsar-client-cpp/eclipse-formatter.xml b/pulsar-client-cpp/eclipse-formatter.xml new file mode 100644 index 0000000000000..3df512ba46ffb --- /dev/null +++ b/pulsar-client-cpp/eclipse-formatter.xml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pulsar-client-cpp/examples/CMakeLists.txt b/pulsar-client-cpp/examples/CMakeLists.txt new file mode 100644 index 0000000000000..b5f36b5eab001 --- /dev/null +++ b/pulsar-client-cpp/examples/CMakeLists.txt @@ -0,0 +1,41 @@ +# +# Copyright 2016 Yahoo Inc. +# +# Licensed 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. +# + +set(SAMPLE_ASYNC_PRODUCER_SOURCES + SampleAsyncProducer.cc +) + +set(SAMPLE_CONSUMER_SOURCES + SampleConsumer.cc +) + +set(SAMPLE_CONSUMER_LISTENER_SOURCES + SampleConsumerListener.cc +) + +set(SAMPLE_PRODUCER_SOURCES + SampleProducer.cc +) + +add_executable(SampleAsyncProducer ${SAMPLE_ASYNC_PRODUCER_SOURCES}) +add_executable(SampleConsumer ${SAMPLE_CONSUMER_SOURCES}) +add_executable(SampleConsumerListener ${SAMPLE_CONSUMER_LISTENER_SOURCES}) +add_executable(SampleProducer ${SAMPLE_PRODUCER_SOURCES}) + +target_link_libraries(SampleAsyncProducer ${CLIENT_LIBS}) +target_link_libraries(SampleConsumer ${CLIENT_LIBS}) +target_link_libraries(SampleConsumerListener ${CLIENT_LIBS}) +target_link_libraries(SampleProducer ${CLIENT_LIBS}) diff --git a/pulsar-client-cpp/examples/SampleAsyncProducer.cc b/pulsar-client-cpp/examples/SampleAsyncProducer.cc new file mode 100644 index 0000000000000..16d5637e6e1e3 --- /dev/null +++ b/pulsar-client-cpp/examples/SampleAsyncProducer.cc @@ -0,0 +1,50 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include + +#include +#include + +#include + +DECLARE_LOG_OBJECT() + +using namespace pulsar; + +void callback(Result code, const Message& msg) { + LOG_INFO("Received code: " << code << " -- Msg: " << msg); +} + +int main() { + Client client("pulsar://localhost:6650"); + + Producer producer; + Result result = client.createProducer("persistent://prop/r1/ns1/my-topic", producer); + if (result != ResultOk) { + LOG_ERROR("Error creating producer: " << result); + return -1; + } + + // Send asynchronously + while (true) { + Message msg = MessageBuilder().setContent("content").setProperty("x", "1").build(); + producer.sendAsync(msg, callback); + + sleep(1); + } +} diff --git a/pulsar-client-cpp/examples/SampleConsumer.cc b/pulsar-client-cpp/examples/SampleConsumer.cc new file mode 100644 index 0000000000000..f8853710b2301 --- /dev/null +++ b/pulsar-client-cpp/examples/SampleConsumer.cc @@ -0,0 +1,46 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include + +#include + +#include + +DECLARE_LOG_OBJECT() + +using namespace pulsar; + +int main() { + + Client client("pulsar://localhost:6650"); + + Consumer consumer; + Result result = client.subscribe("persistent://prop/r1/ns1/my-topic", "consumer-1", consumer); + if (result != ResultOk) { + LOG_ERROR("Failed to subscribe: " << result); + return -1; + } + + Message msg; + + while (true) { + consumer.receive(msg); + LOG_INFO("Received: " << msg << " with payload '" << msg.getDataAsString() << "'"); + + consumer.acknowledge(msg); + } +} diff --git a/pulsar-client-cpp/examples/SampleConsumerListener.cc b/pulsar-client-cpp/examples/SampleConsumerListener.cc new file mode 100644 index 0000000000000..b9b427b9860ce --- /dev/null +++ b/pulsar-client-cpp/examples/SampleConsumerListener.cc @@ -0,0 +1,48 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include + +#include + +#include + +DECLARE_LOG_OBJECT() + +using namespace pulsar; + +void listener(Consumer consumer, const Message& msg) { + LOG_INFO("Got message " << msg << " with content '" << msg.getDataAsString() << "'"); + + consumer.acknowledge(msg.getMessageId()); +} + +int main() { + Client client("pulsar://localhost:6650"); + + Consumer consumer; + ConsumerConfiguration config; + config.setMessageListener(listener); + Result result = client.subscribe("persistent://prop/r1/ns1/my-topic", "consumer-1", config, consumer); + if (result != ResultOk) { + LOG_ERROR("Failed to subscribe: " << result); + return -1; + } + + // Wait + int n; + std::cin >> n; +} diff --git a/pulsar-client-cpp/examples/SampleProducer.cc b/pulsar-client-cpp/examples/SampleProducer.cc new file mode 100644 index 0000000000000..471ebfcc98384 --- /dev/null +++ b/pulsar-client-cpp/examples/SampleProducer.cc @@ -0,0 +1,43 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include + +#include +#include + +#include + +DECLARE_LOG_OBJECT() + +using namespace pulsar; + +int main() { + Client client("pulsar://localhost:6650"); + + Producer producer; + Result result = client.createProducer("persistent://prop/r1/ns1/my-topic", producer); + if (result != ResultOk) { + LOG_ERROR("Error creating producer: " << result); + return -1; + } + + // Send synchronously + Message msg = MessageBuilder().setContent("content").build(); + Result res = producer.send(msg); + LOG_INFO("Message sent: " << res); +} diff --git a/pulsar-client-cpp/generate_protobuf.sh b/pulsar-client-cpp/generate_protobuf.sh new file mode 100755 index 0000000000000..e565196d78f7c --- /dev/null +++ b/pulsar-client-cpp/generate_protobuf.sh @@ -0,0 +1,19 @@ +# +# Copyright 2016 Yahoo Inc. +# +# Licensed 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. +# + +PROTO_PATH=../pulsar-common/src/main/proto/ + +protoc --proto_path=$PROTO_PATH --cpp_out=lib $PROTO_PATH/PulsarApi.proto diff --git a/pulsar-client-cpp/include/pulsar/Auth.h b/pulsar-client-cpp/include/pulsar/Auth.h new file mode 100644 index 0000000000000..b305b22b26897 --- /dev/null +++ b/pulsar-client-cpp/include/pulsar/Auth.h @@ -0,0 +1,57 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef PULSAR_AUTH_H_ +#define PULSAR_AUTH_H_ + +#include +#include +#include +#include + +#pragma GCC visibility push(default) + +namespace pulsar { + +class Authentication { + public: + virtual ~Authentication(); + virtual const std::string getAuthMethodName() const = 0; + virtual Result getAuthData(std::string& authDataContent) const = 0; + + protected: + Authentication(); +}; + +typedef boost::shared_ptr AuthenticationPtr; + +class Auth { + public: + static AuthenticationPtr Disabled(); + static AuthenticationPtr create(const std::string& dynamicLibPath); + static AuthenticationPtr create(const std::string& dynamicLibPath, const std::string& params); + protected: + static bool isShutdownHookRegistered_; + static std::vector loadedLibrariesHandles_; + static void release_handles(); +}; + +} +// namespace pulsar + +#pragma GCC visibility pop + +#endif /* PULSAR_AUTH_H_ */ diff --git a/pulsar-client-cpp/include/pulsar/BatchMessageId.h b/pulsar-client-cpp/include/pulsar/BatchMessageId.h new file mode 100644 index 0000000000000..d21b94b50fddc --- /dev/null +++ b/pulsar-client-cpp/include/pulsar/BatchMessageId.h @@ -0,0 +1,56 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_BATCHMESSAGEID_H_ +#define LIB_BATCHMESSAGEID_H_ + +#include + +namespace pulsar { +class BatchMessageId : public MessageId { + public: + BatchMessageId(int64_t ledgerId, int64_t entryId, int batchIndex = -1) + : MessageId(ledgerId, entryId), + batchIndex_(batchIndex) { + } + + BatchMessageId() + : batchIndex_(-1) { + } + // These functions compare the message order as stored in bookkeeper + inline bool operator<(const BatchMessageId& mID) const; + inline bool operator<=(const BatchMessageId& mID) const; + protected: + friend class ConsumerImpl; + friend class Message; + friend class MessageImpl; + friend class PartitionedProducerImpl; + friend class PartitionedConsumerImpl; + friend class BatchAcknowledgementTracker; + friend class PulsarFriend; + int64_t batchIndex_; +}; + +bool BatchMessageId::operator<(const BatchMessageId& mID) const { + return (ledgerId_ < mID.ledgerId_) || (ledgerId_ == mID.ledgerId_ && entryId_ < mID.entryId_); +} + +bool BatchMessageId::operator<=(const BatchMessageId& mID) const { + return (ledgerId_ < mID.ledgerId_) || (ledgerId_ == mID.ledgerId_ && entryId_ <= mID.entryId_); +} + +} +#endif /* LIB_BATCHMESSAGEID_H_ */ diff --git a/pulsar-client-cpp/include/pulsar/Client.h b/pulsar-client-cpp/include/pulsar/Client.h new file mode 100644 index 0000000000000..18b1dc61ba830 --- /dev/null +++ b/pulsar-client-cpp/include/pulsar/Client.h @@ -0,0 +1,202 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef PULSAR_CLIENT_HPP_ +#define PULSAR_CLIENT_HPP_ + +#include +#include +#include +#include +#include +#include + +#include + +#pragma GCC visibility push(default) + +class PulsarFriend; + +namespace pulsar { + +typedef boost::function CreateProducerCallback; +typedef boost::function SubscribeCallback; +typedef boost::function CloseCallback; + +class ClientConfiguration { + public: + + ClientConfiguration(); + ~ClientConfiguration(); + ClientConfiguration(const ClientConfiguration&); + ClientConfiguration& operator=(const ClientConfiguration&); + + /** + * Set the authentication method to be used with the broker + * + * @param authentication the authentication data to use + */ + ClientConfiguration& setAuthentication(const AuthenticationPtr& authentication); + + /** + * @return the authentication data + */ + const Authentication& getAuthentication() const; + + /** + * Set timeout on client operations (subscribe, create producer, close, unsubscribe) + * Default is 30 seconds. + * + * @param timeout the timeout after which the operation will be considered as failed + */ + ClientConfiguration& setOperationTimeoutSeconds(int timeout); + + /** + * @return the client operations timeout in seconds + */ + int getOperationTimeoutSeconds() const; + + /** + * Set the number of IO threads to be used by the Pulsar client. Default is 1 + * thread. + * + * @param threads number of threads + */ + ClientConfiguration& setIOThreads(int threads); + + /** + * @return the number of IO threads to use + */ + int getIOThreads() const; + + /** + * Set the number of threads to be used by the Pulsar client when delivering messages + * through message listener. Default is 1 thread per Pulsar client. + * + * If using more than 1 thread, messages for distinct MessageListener will be + * delivered in different threads, however a single MessageListener will always + * be assigned to the same thread. + * + * @param threads number of threads + */ + ClientConfiguration& setMessageListenerThreads(int threads); + + /** + * @return the number of IO threads to use + */ + int getMessageListenerThreads() const; + + /** + * Initialize the log configuration + * + * @param logConfFilePath path of the configuration file + */ + ClientConfiguration& setLogConfFilePath(const std::string& logConfFilePath); + + /** + * Get the path of log configuration file (log4cpp) + */ + const std::string& getLogConfFilePath() const; + + private: + const AuthenticationPtr& getAuthenticationPtr() const; + + struct Impl; + boost::shared_ptr impl_; + friend class ClientImpl; +}; + +class ClientImpl; + +class Client { + public: + /** + * Create a Pulsar client object connecting to the specified cluster address and using the default configuration. + * + * @param serviceUrl the Pulsar endpoint to use (eg: http://brokerv2-pdev.messaging.corp.gq1.yahoo.com:4080 for Sandbox access) + */ + Client(const std::string& serviceUrl); + + /** + * Create a Pulsar client object connecting to the specified cluster address and using the specified configuration. + * + * @param serviceUrl the Pulsar endpoint to use (eg: http://brokerv2-pdev.messaging.corp.gq1.yahoo.com:4080 for Sandbox access) + * @param clientConfiguration the client configuration to use + */ + Client(const std::string& serviceUrl, const ClientConfiguration& clientConfiguration); + + /** + * Create a producer with default configuration + * + * @see createProducer(const std::string&, const ProducerConfiguration&, Producer&) + * + * @param topic the topic where the new producer will publish + * @param producer a non-const reference where the new producer will be copied + * @return ResultOk if the producer has been successfully created + * @return ResultError if there was an error + */ + Result createProducer(const std::string& topic, Producer& producer); + + /** + * Create a producer with specified configuration + * + * @see createProducer(const std::string&, const ProducerConfiguration&, Producer&) + * + * @param topic the topic where the new producer will publish + * @param conf the producer config to use + * @param producer a non-const reference where the new producer will be copied + * @return ResultOk if the producer has been successfully created + * @return ResultError if there was an error + */ + Result createProducer(const std::string& topic, const ProducerConfiguration& conf, + Producer& producer); + + void createProducerAsync(const std::string& topic, CreateProducerCallback callback); + + void createProducerAsync(const std::string& topic, ProducerConfiguration conf, + CreateProducerCallback callback); + + Result subscribe(const std::string& topic, const std::string& consumerName, Consumer& consumer); + Result subscribe(const std::string& topic, const std::string& consumerName, + const ConsumerConfiguration& conf, Consumer& consumer); + + void subscribeAsync(const std::string& topic, const std::string& consumerName, + SubscribeCallback callback); + void subscribeAsync(const std::string& topic, const std::string& consumerName, + const ConsumerConfiguration& conf, SubscribeCallback callback); + + /** + * + * @return + */ + Result close(); + + void closeAsync(CloseCallback callback); + + void shutdown(); + + private: + Client(const std::string& serviceUrl, const ClientConfiguration& clientConfiguration, bool poolConnections); + + friend class PulsarFriend; + boost::shared_ptr impl_; +}; + +} + +#pragma GCC visibility pop + +#endif /* PULSAR_CLIENT_HPP_ */ diff --git a/pulsar-client-cpp/include/pulsar/Consumer.h b/pulsar-client-cpp/include/pulsar/Consumer.h new file mode 100644 index 0000000000000..e7621fd9a7d32 --- /dev/null +++ b/pulsar-client-cpp/include/pulsar/Consumer.h @@ -0,0 +1,303 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef CONSUMER_HPP_ +#define CONSUMER_HPP_ + +#include +#include +#include +#include + +#pragma GCC visibility push(default) + +class PulsarFriend; + +namespace pulsar { + +class Consumer; + +/// Callback definition for non-data operation +typedef boost::function ResultCallback; + +/// Callback definition for MessageListener +typedef boost::function MessageListener; + +enum ConsumerType { + /** + * There can be only 1 consumer on the same topic with the same consumerName + */ + ConsumerExclusive, + + /** + * Multiple consumers will be able to use the same consumerName and the messages + * will be dispatched according to a round-robin rotation between the connected consumers + */ + ConsumerShared, + + /** Only one consumer is active on the subscription; Subscription can have N consumers + * connected one of which will get promoted to master if the current master becomes inactive + */ + + ConsumerFailover +}; + +/** + * Class specifying the configuration of a consumer. + */ +class ConsumerConfiguration { + public: + ConsumerConfiguration(); + ~ConsumerConfiguration(); + ConsumerConfiguration(const ConsumerConfiguration&); + ConsumerConfiguration& operator=(const ConsumerConfiguration&); + + /** + * Specify the consumer type. The consumer type enables + * specifying the type of subscription. In Exclusive subscription, + * only a single consumer is allowed to attach to the subscription. Other consumers + * will get an error message. In Shared subscription, multiple consumers will be + * able to use the same subscription name and the messages will be dispatched in a + * round robin fashion. In Failover subscription, a master-slave subscription model + * allows for multiple consumers to attach to a single subscription, though only one + * of them will be “master” at a given time. Only the master consumer will receive + * messages. When the master gets disconnected, one among the slaves will be promoted + * to master and will start getting messages. + */ + ConsumerConfiguration& setConsumerType(ConsumerType consumerType); + ConsumerType getConsumerType() const; + + /** + * A message listener enables your application to configure how to process + * and acknowledge messages delivered. A listener will be called in order + * for every message received. + */ + ConsumerConfiguration& setMessageListener(MessageListener messageListener); + MessageListener getMessageListener() const; + bool hasMessageListener() const; + + /** + * Sets the size of the consumer receive queue. + * + * The consumer receive queue controls how many messages can be accumulated by the Consumer before the + * application calls receive(). Using a higher value could potentially increase the consumer throughput + * at the expense of bigger memory utilization. + * + * Setting the consumer queue size as zero decreases the throughput of the consumer, by disabling pre-fetching of + * messages. This approach improves the message distribution on shared subscription, by pushing messages only to + * the consumers that are ready to process them. Neither receive with timeout nor Partitioned Topics can be + * used if the consumer queue size is zero. The receive() function call should not be interrupted when + * the consumer queue size is zero. + * + * Default value is 1000 messages and should be good for most use cases. + * + * @param size + * the new receiver queue size value + */ + void setReceiverQueueSize(int size); + int getReceiverQueueSize() const; + + void setConsumerName(const std::string&); + const std::string& getConsumerName() const; + + /** + * Set the timeout in milliseconds for unacknowledged messages, the timeout needs to be greater than + * 10 seconds. An Exception is thrown if the given value is less than 10000 (10 seconds). + * If a successful acknowledgement is not sent within the timeout all the unacknowledged messages are + * redelivered. + * @param timeout in milliseconds + */ + void setUnAckedMessagesTimeoutMs(const uint64_t milliSeconds); + + /** + * @return the configured timeout in milliseconds for unacked messages. + */ + long getUnAckedMessagesTimeoutMs() const; + private: + struct Impl; + boost::shared_ptr impl_; +}; + +class ConsumerImplBase; + +/** + * + */ +class Consumer { + public: + /** + * Construct an uninitialized consumer object + */ + Consumer(); + + /** + * @return the topic this consumer is subscribed to + */ + const std::string& getTopic() const; + + /** + * @return the consumer name + */ + const std::string& getSubscriptionName() const; + + /** + * Unsubscribe the current consumer from the topic. + * + * This method will block until the operation is completed. Once the consumer is + * unsubscribed, no more messages will be received and subsequent new messages + * will not be retained for this consumer. + * + * This consumer object cannot be reused. + * + * @see asyncUnsubscribe + * @return Result::ResultOk if the unsubscribe operation completed successfully + * @return Result::ResultError if the unsubscribe operation failed + */ + Result unsubscribe(); + + /** + * Asynchronously unsubscribe the current consumer from the topic. + * + * This method will block until the operation is completed. Once the consumer is + * unsubscribed, no more messages will be received and subsequent new messages + * will not be retained for this consumer. + * + * This consumer object cannot be reused. + * + * @param callback the callback to get notified when the operation is complete + */ + void unsubscribeAsync(ResultCallback callback); + + /** + * Receive a single message. + * + * If a message is not immediately available, this method will block until a new + * message is available. + * + * @param msg a non-const reference where the received message will be copied + * @return ResultOk when a message is received + * @return ResultInvalidConfiguration if a message listener had been set in the configuration + */ + Result receive(Message& msg); + + /** + * + * @param msg a non-const reference where the received message will be copied + * @param timeoutMs the receive timeout in milliseconds + * @return ResultOk if a message was received + * @return ResultTimeout if the receive timeout was triggered + * @return ResultInvalidConfiguration if a message listener had been set in the configuration + */ + Result receive(Message& msg, int timeoutMs); + + /** + * Acknowledge the reception of a single message. + * + * This method will block until an acknowledgement is sent to the broker. After + * that, the message will not be re-delivered to this consumer. + * + * @see asyncAcknowledge + * @param message the message to acknowledge + * @return ResultOk if the message was successfully acknowledged + * @return ResultError if there was a failure + */ + Result acknowledge(const Message& message); + Result acknowledge(const MessageId& messageId); + + /** + * Asynchronously acknowledge the reception of a single message. + * + * This method will initiate the operation and return immediately. The provided callback + * will be triggered when the operation is complete. + * + * @param message the message to acknowledge + * @param callback callback that will be triggered when the message has been acknowledged + */ + void acknowledgeAsync(const Message& message, ResultCallback callback); + void acknowledgeAsync(const MessageId& messageID, ResultCallback callback); + + /** + * Acknowledge the reception of all the messages in the stream up to (and including) + * the provided message. + * + * This method will block until an acknowledgement is sent to the broker. After + * that, the messages will not be re-delivered to this consumer. + * + * Cumulative acknowledge cannot be used when the consumer type is set to ConsumerShared. + * + * It's equivalent to calling asyncAcknowledgeCumulative(const Message&, ResultCallback) and + * waiting for the callback to be triggered. + * + * @param message the last message in the stream to acknowledge + * @return ResultOk if the message was successfully acknowledged. All previously delivered messages for this topic are also acknowledged. + * @return ResultError if there was a failure + */ + Result acknowledgeCumulative(const Message& message); + Result acknowledgeCumulative(const MessageId& messageId); + + /** + * Asynchronously acknowledge the reception of all the messages in the stream up to (and + * including) the provided message. + * + * This method will initiate the operation and return immediately. The provided callback + * will be triggered when the operation is complete. + * + * @param message the message to acknowledge + * @param callback callback that will be triggered when the message has been acknowledged + */ + void acknowledgeCumulativeAsync(const Message& message, ResultCallback callback); + void acknowledgeCumulativeAsync(const MessageId& messageId, ResultCallback callback); + + Result close(); + + void closeAsync(ResultCallback callback); + + /* + * Pause receiving messages via the messageListener, till resumeMessageListener() is called. + */ + Result pauseMessageListener(); + + /* + * Resume receiving the messages via the messageListener. + * Asynchronously receive all the messages enqueued from time pauseMessageListener() was called. + */ + Result resumeMessageListener(); + + /** + * Redelivers all the unacknowledged messages. In Failover mode, the request is ignored if the consumer is not + * active for the given topic. In Shared mode, the consumers messages to be redelivered are distributed across all + * the connected consumers. This is a non blocking call and doesn't throw an exception. In case the connection + * breaks, the messages are redelivered after reconnect. + */ + void redeliverUnacknowledgedMessages(); + + private: + typedef boost::shared_ptr ConsumerImplBasePtr; + friend class PulsarFriend; + ConsumerImplBasePtr impl_; + explicit Consumer(ConsumerImplBasePtr); + + friend class PartitionedConsumerImpl; + friend class ConsumerImpl; + friend class ClientImpl; + friend class ConsumerTest; +}; + +} + +#pragma GCC visibility pop + +#endif /* CONSUMER_HPP_ */ diff --git a/pulsar-client-cpp/include/pulsar/Message.h b/pulsar-client-cpp/include/pulsar/Message.h new file mode 100644 index 0000000000000..9218e2ca7be44 --- /dev/null +++ b/pulsar-client-cpp/include/pulsar/Message.h @@ -0,0 +1,143 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef MESSAGE_HPP_ +#define MESSAGE_HPP_ + +#include +#include + +#include +#include "BatchMessageId.h" + +#pragma GCC visibility push(default) + +namespace pulsar { +namespace proto { +class CommandMessage; +class MessageMetadata; +class SingleMessageMetadata; +} +} + +using namespace pulsar; + +namespace pulsar { + +class SharedBuffer; +class MessageBuilder; +class MessageImpl; + +class Message { + public: + typedef std::map StringMap; + + Message(); + + /** + * Return the properties attached to the message. + * Properties are application defined key/value pairs that will be attached to the message + * + * @return an unmodifiable view of the properties map + */ + const StringMap& getProperties() const; + + /** + * Check whether the message has a specific property attached. + * + * @param name the name of the property to check + * @return true if the message has the specified property + * @return false if the property is not defined + */ + bool hasProperty(const std::string& name) const; + + /** + * Get the value of a specific property + * + * @param name the name of the property + * @return the value of the property or null if the property was not defined + */ + const std::string& getProperty(const std::string& name) const; + + /** + * Get the content of the message + * + * + * @return the pointer to the message payload + */ + const void* getData() const; + + /** + * Get the length of the message + * + * @return the length of the message payload + */ + std::size_t getLength() const; + + /** + * Get string representation of the message + * + * @return the string representation of the message payload + */ + std::string getDataAsString() const; + + /** + * Get the unique message ID associated with this message. + * + * The message id can be used to univocally refer to a message without having to keep the entire payload in memory. + * + * Only messages received from the consumer will have a message id assigned. + * + */ + const MessageId& getMessageId() const; + + /** + * Get the partition key for this message + * @return key string that is hashed to determine message's destination partition + */ + const std::string& getPartitionKey() const; + bool hasPartitionKey() const; + + /** + * Get the UTC based timestamp in milliseconds referring to when the message was published by the client producer + */ + uint64_t getPublishTimestamp() const; + + private: + typedef boost::shared_ptr MessageImplPtr; + MessageImplPtr impl_; + + Message(MessageImplPtr& impl); + Message(const proto::CommandMessage& msg, proto::MessageMetadata& data, SharedBuffer& payload); + /// Used for Batch Messages + Message(const BatchMessageId& messageID, proto::MessageMetadata& metadata, SharedBuffer& payload, proto::SingleMessageMetadata& singleMetadata); + friend class PartitionedProducerImpl; + friend class PartitionedConsumerImpl; + friend class MessageBuilder; + friend class ConsumerImpl; + friend class ProducerImpl; + friend class Commands; + friend class BatchMessageContainer; + friend class BatchAcknowledgementTracker; + + friend std::ostream& operator<<(std::ostream& s, const StringMap& map); + friend std::ostream& operator<<(std::ostream& s, const Message& msg); +}; + +} + +#pragma GCC visibility pop +#endif /* MESSAGE_HPP_ */ diff --git a/pulsar-client-cpp/include/pulsar/MessageBuilder.h b/pulsar-client-cpp/include/pulsar/MessageBuilder.h new file mode 100644 index 0000000000000..e6872c3fd0a43 --- /dev/null +++ b/pulsar-client-cpp/include/pulsar/MessageBuilder.h @@ -0,0 +1,105 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef MESSAGE_BUILDER_H +#define MESSAGE_BUILDER_H + +#include +#include "Message.h" + +#pragma GCC visibility push(default) + +namespace pulsar { + +class MessageBuilder { + public: + + MessageBuilder(); + + typedef std::map StringMap; + + /** + * Finalize the immutable message + */ + Message build(); + + /** + * Set content of the message. The message contents will be managed by the system. + */ + MessageBuilder& setContent(const void* data, size_t size); + MessageBuilder& setContent(const std::string& data); + + /** + * Set content of the message to a buffer already allocated by the caller. No copies of + * this buffer will be made. The caller is responsible to ensure the memory buffer is + * valid until the message has been persisted (or an error is returned). + */ + MessageBuilder& setAllocatedContent(void* data, size_t size); + + /** + * Sets a new property on a message. + * @param name the name of the property + * @param value the associated value + */ + MessageBuilder& setProperty(const std::string& name, const std::string& value); + + /** + * Add all the properties in the provided map + */ + MessageBuilder& setProperties(const StringMap& properties); + + /* + * set partition key for the message routing + * @param hash of this key is used to determine message's destination partition + */ + MessageBuilder& setPartitionKey(const std::string& partitionKey); + + /** + * override namespace replication clusters. note that it is the + * caller's responsibility to provide valid cluster names, and that + * all clusters have been previously configured as destinations. + * + * given an empty list, the message will replicate per the namespace + * configuration. + * + * @param clusters where to send this message. + */ + MessageBuilder& setReplicationClusters(const std::vector& clusters); + + /** + * Do not replicate this message + * @param flag if true, disable replication, otherwise use default + * replication + */ + MessageBuilder& disableReplication(bool flag); + + /** + * create a empty message, with no properties or data + * + */ + MessageBuilder& create(); + private: + MessageBuilder(const MessageBuilder&); + void checkMetadata(); + + Message::MessageImplPtr impl_; +}; + +} + +#pragma GCC visibility pop + +#endif diff --git a/pulsar-client-cpp/include/pulsar/MessageId.h b/pulsar-client-cpp/include/pulsar/MessageId.h new file mode 100644 index 0000000000000..d3ffd0dbe9b17 --- /dev/null +++ b/pulsar-client-cpp/include/pulsar/MessageId.h @@ -0,0 +1,64 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef MESSAGE_ID_H +#define MESSAGE_ID_H + +#include +#include + +#pragma GCC visibility push(default) + +namespace pulsar { + +class ConsumerImpl; +class UnAckedMessageTrackerEnabled; + +class MessageId { + public: + MessageId& operator=(const MessageId&); + MessageId(); + // These functions compare the message order as stored in bookkeeper + inline bool operator<(const MessageId& mID) const; + inline bool operator==(const MessageId& mID) const; + protected: + friend class ConsumerImpl; + friend class Message; + friend class MessageImpl; + friend class PartitionedProducerImpl; + friend class PartitionedConsumerImpl; + friend class UnAckedMessageTrackerEnabled; + friend class BatchAcknowledgementTracker; + MessageId(int64_t, int64_t); + friend std::ostream& operator<<(std::ostream& s, const MessageId& messageId); + int64_t ledgerId_; + int64_t entryId_ :48; + short partition_ :16; +}; + +bool MessageId::operator<(const MessageId& mID) const { + return (ledgerId_ < mID.ledgerId_) || (ledgerId_ == mID.ledgerId_ && entryId_ < mID.entryId_); +} + +bool MessageId::operator==(const MessageId& mID) const { + return (ledgerId_ == mID.ledgerId_ && entryId_ == mID.entryId_); +} + +} + +#pragma GCC visibility pop + +#endif //MESSAGE_ID_H diff --git a/pulsar-client-cpp/include/pulsar/MessageRoutingPolicy.h b/pulsar-client-cpp/include/pulsar/MessageRoutingPolicy.h new file mode 100644 index 0000000000000..3c93cc339e13d --- /dev/null +++ b/pulsar-client-cpp/include/pulsar/MessageRoutingPolicy.h @@ -0,0 +1,42 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef PULSAR_MESSAGE_ROUTING_POLICY_HEADER_ +#define PULSAR_MESSAGE_ROUTING_POLICY_HEADER_ +#include "Message.h" +#include + +#pragma GCC visibility push(default) + +/* + * Implement this interface to define custom policy giving message to + * partition mapping. + */ +namespace pulsar { + +class MessageRoutingPolicy { + public: + virtual ~MessageRoutingPolicy() {} + + virtual int getPartition(const Message& msg) = 0; +}; + +typedef boost::shared_ptr MessageRoutingPolicyPtr; +} + +#pragma GCC visibility pop + +#endif // PULSAR_MESSAGE_ROUTING_POLICY_HEADER_ diff --git a/pulsar-client-cpp/include/pulsar/Producer.h b/pulsar-client-cpp/include/pulsar/Producer.h new file mode 100644 index 0000000000000..1e86b553d0393 --- /dev/null +++ b/pulsar-client-cpp/include/pulsar/Producer.h @@ -0,0 +1,175 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef PRODUCER_HPP_ +#define PRODUCER_HPP_ + +#include +#include +#include + +#include +#include +#include + +#pragma GCC visibility push(default) + +class PulsarFriend; + +namespace pulsar { + +typedef boost::function SendCallback; +typedef boost::function CloseCallback; + +enum CompressionType { + CompressionNone = 0, + CompressionLZ4 = 1, + CompressionZLib = 2 +}; + +/** + * Class that holds the configuration for a producer + */ +class ProducerConfiguration { + public: + enum PartitionsRoutingMode { + UseSinglePartition, + RoundRobinDistribution, + CustomPartition + }; + ProducerConfiguration(); + ~ProducerConfiguration(); + ProducerConfiguration(const ProducerConfiguration&); + ProducerConfiguration& operator=(const ProducerConfiguration&); + + ProducerConfiguration& setSendTimeout(int sendTimeoutMs); + int getSendTimeout() const; + + ProducerConfiguration& setCompressionType(CompressionType compressionType); + CompressionType getCompressionType() const; + + ProducerConfiguration& setMaxPendingMessages(int maxPendingMessages); + int getMaxPendingMessages() const; + + ProducerConfiguration& setPartitionsRoutingMode(const PartitionsRoutingMode& mode); + PartitionsRoutingMode getPartitionsRoutingMode() const; + + ProducerConfiguration& setMessageRouter(const MessageRoutingPolicyPtr& router); + const MessageRoutingPolicyPtr& getMessageRouterPtr() const; + + ProducerConfiguration& setBlockIfQueueFull(bool); + bool getBlockIfQueueFull() const; + + // Zero queue size feature will not be supported on consumer end if batching is enabled + ProducerConfiguration& setBatchingEnabled(const bool& batchingEnabled); + const bool& getBatchingEnabled() const; + + ProducerConfiguration& setBatchingMaxMessages(const unsigned int& batchingMaxMessages); + const unsigned int& getBatchingMaxMessages() const; + + ProducerConfiguration& setBatchingMaxAllowedSizeInBytes(const unsigned long& batchingMaxAllowedSizeInBytes); + const unsigned long& getBatchingMaxAllowedSizeInBytes() const; + + ProducerConfiguration& setBatchingMaxPublishDelayMs(const unsigned long& batchingMaxPublishDelayMs); + const unsigned long& getBatchingMaxPublishDelayMs() const; + private: + struct Impl; + boost::shared_ptr impl_; +}; + +class ProducerImplBase; + +class Producer { + public: + /** + * Construct an uninitialized Producer. + */ + Producer(); + + /** + * @return the topic to which producer is publishing to + */ + const std::string& getTopic() const; + + /** + * Publish a message on the topic associated with this Producer. + * + * This method will block until the message will be accepted and persisted + * by the broker. In case of errors, the client library will try to + * automatically recover and use a different broker. + * + * If it wasn't possible to successfully publish the message within the sendTimeout, + * an error will be returned. + * + * This method is equivalent to asyncSend() and wait until the callback is triggered. + * + * @param msg message to publish + * @return ResultOk if the message was published successfully + * @return ResultWriteError if it wasn't possible to publish the message + */ + Result send(const Message& msg); + + /** + * Asynchronously publish a message on the topic associated with this Producer. + * + * This method will initiate the publish operation and return immediately. The + * provided callback will be triggered when the message has been be accepted and persisted + * by the broker. In case of errors, the client library will try to + * automatically recover and use a different broker. + * + * If it wasn't possible to successfully publish the message within the sendTimeout, the + * callback will be triggered with a Result::WriteError code. + * + * @param msg message to publish + * @param callback the callback to get notification of the completion + */ + void sendAsync(const Message& msg, SendCallback callback); + + /** + * Close the producer and release resources allocated. + * + * No more writes will be accepted from this producer. Waits until + * all pending write requests are persisted. In case of errors, + * pending writes will not be retried. + * + * @return an error code to indicate the success or failure + */ + Result close(); + + /** + * Close the producer and release resources allocated. + * + * No more writes will be accepted from this producer. The provided callback will be + * triggered when all pending write requests are persisted. In case of errors, + * pending writes will not be retried. + */ + void closeAsync(CloseCallback callback); + + private: + typedef boost::shared_ptr ProducerImplBasePtr; + explicit Producer(ProducerImplBasePtr); + + friend class ClientImpl; + friend class PulsarFriend; + + ProducerImplBasePtr impl_; +}; + +} + +#pragma GCC visibility pop + +#endif /* PRODUCER_HPP_ */ diff --git a/pulsar-client-cpp/include/pulsar/Result.h b/pulsar-client-cpp/include/pulsar/Result.h new file mode 100644 index 0000000000000..959dd5bd75d4b --- /dev/null +++ b/pulsar-client-cpp/include/pulsar/Result.h @@ -0,0 +1,78 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef ERROR_HPP_ +#define ERROR_HPP_ + +#include + +#pragma GCC visibility push(default) + +namespace pulsar { + +/** + * Collection of return codes + */ +enum Result { + ResultOk, /// Operation successful + + ResultUnknownError, /// Unknown error happened on broker + + ResultInvalidConfiguration, /// Invalid configuration + + ResultTimeout, /// Operation timed out + ResultLookupError, /// Broker lookup failed + ResultConnectError, /// Failed to connect to broker + ResultReadError, /// Failed to read from socket + + ResultAuthenticationError, /// Authentication failed on broker + ResultAuthorizationError, /// Client is not authorized to create producer/consumer + ResultErrorGettingAuthenticationData, /// Client cannot find authorization data + + ResultBrokerMetadataError, /// Broker failed in updating metadata + ResultBrokerPersistenceError, /// Broker failed to persist entry + ResultChecksumError, /// Corrupt message checksum failure + + ResultConsumerBusy, /// Exclusive consumer is already connected + ResultNotConnected, /// Producer/Consumer is not currently connected to broker + ResultAlreadyClosed, /// Producer/Consumer is already closed and not accepting any operation + + ResultInvalidMessage, /// Error in publishing an already used message + + ResultConsumerNotInitialized, /// Consumer is not initialized + ResultProducerNotInitialized, /// Producer is not initialized + + ResultInvalidTopicName, /// Invalid topic name + ResultInvalidUrl, /// Client Initialized with Invalid Broker Url (VIP Url passed to Client Constructor) + ResultServiceUnitNotReady, /// Service Unit unloaded between client did lookup and producer/consumer got created + ResultOperationNotSupported, + ResultProducerBlockedQuotaExceededError, /// Producer is blocked + ResultProducerBlockedQuotaExceededException, /// Producer is getting exception + ResultProducerQueueIsFull, /// Producer queue is full + + ResultMessageTooBig /// Trying to send a messages exceeding the max size +}; + +// Return string representation of result code +const char* strResult(Result result); + +} + +std::ostream& operator<<(std::ostream& s, pulsar::Result result); + +#pragma GCC visibility pop + +#endif /* ERROR_HPP_ */ diff --git a/pulsar-client-cpp/lib/Auth.cc b/pulsar-client-cpp/lib/Auth.cc new file mode 100644 index 0000000000000..a9f99313dbde4 --- /dev/null +++ b/pulsar-client-cpp/lib/Auth.cc @@ -0,0 +1,106 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +// Built-in authentications +#include "auth/AuthTls.h" + +DECLARE_LOG_OBJECT() + +namespace pulsar { + +Authentication::Authentication() { +} + +Authentication::~Authentication() { +} + +class AuthDisabled : public Authentication { + public: + AuthDisabled() + : Authentication() { + } + + static AuthenticationPtr create() { + return boost::make_shared(); + } + + const std::string getAuthMethodName() const { + return "none"; + } + + Result getAuthData(std::string&) const { + return ResultOk; + } +}; + +AuthenticationPtr Auth::Disabled() { + return AuthDisabled::create(); +} + +AuthenticationPtr Auth::create(const std::string& dynamicLibPath) { + return Auth::create(dynamicLibPath, ""); +} + +boost::mutex mutex; +std::vector Auth::loadedLibrariesHandles_; +bool Auth::isShutdownHookRegistered_ = false; + +void Auth::release_handles() { + boost::lock_guard lock(mutex); + for (std::vector::iterator ite = Auth::loadedLibrariesHandles_.begin(); ite != Auth::loadedLibrariesHandles_.end(); + ite++) { + dlclose(*ite); + } + loadedLibrariesHandles_.clear(); +} + +AuthenticationPtr Auth::create(const std::string& dynamicLibPath, const std::string& params) { + { + boost::lock_guard lock(mutex); + if (!Auth::isShutdownHookRegistered_) { + atexit(release_handles); + Auth::isShutdownHookRegistered_ = true; + } + } + Authentication *auth = NULL; + void *handle = dlopen(dynamicLibPath.c_str(), RTLD_LAZY); + if (handle != NULL) { + { + boost::lock_guard lock(mutex); + loadedLibrariesHandles_.push_back(handle); + } + Authentication *(*createAuthentication)(const std::string); + *(void **) (&createAuthentication) = dlsym(handle, "create"); + if (createAuthentication != NULL) { + auth = createAuthentication(params); + } + } + return boost::shared_ptr(auth); +} + +} diff --git a/pulsar-client-cpp/lib/Backoff.cc b/pulsar-client-cpp/lib/Backoff.cc new file mode 100644 index 0000000000000..20fbcb632a37d --- /dev/null +++ b/pulsar-client-cpp/lib/Backoff.cc @@ -0,0 +1,38 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "Backoff.h" +#include + +namespace pulsar { + +Backoff::Backoff(const TimeDuration& initial, const TimeDuration& max) + : initial_(initial), + max_(max), + next_(initial) { +} + +TimeDuration Backoff::next() { + TimeDuration current = next_; + next_ = std::min(next_ * 2, max_); + return current; +} + +void Backoff::reset() { + next_ = initial_; +} + +} //pulsar - namespace end diff --git a/pulsar-client-cpp/lib/Backoff.h b/pulsar-client-cpp/lib/Backoff.h new file mode 100644 index 0000000000000..acacfcb30aa24 --- /dev/null +++ b/pulsar-client-cpp/lib/Backoff.h @@ -0,0 +1,41 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef _PULSAR_BACKOFF_HEADER_ +#define _PULSAR_BACKOFF_HEADER_ +#include + +#pragma GCC visibility push(default) + +namespace pulsar { + +typedef boost::posix_time::time_duration TimeDuration; + +class Backoff { + public: + Backoff(const TimeDuration& intial, const TimeDuration& max); + TimeDuration next(); + void reset(); + private: + TimeDuration initial_; + TimeDuration max_; + TimeDuration next_; +}; +} + +#pragma GCC visibility pop + +#endif //_PULSAR_BACKOFF_HEADER_ diff --git a/pulsar-client-cpp/lib/BatchAcknowledgementTracker.cc b/pulsar-client-cpp/lib/BatchAcknowledgementTracker.cc new file mode 100644 index 0000000000000..efec2b7403789 --- /dev/null +++ b/pulsar-client-cpp/lib/BatchAcknowledgementTracker.cc @@ -0,0 +1,154 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "BatchAcknowledgementTracker.h" + +namespace pulsar { +DECLARE_LOG_OBJECT() + +BatchAcknowledgementTracker::BatchAcknowledgementTracker(const std::string topic, const std::string subscription, + const long consumerId) + : greatestCumulativeAckSent_(BatchMessageId()) { + std::stringstream consumerStrStream; + consumerStrStream << "BatchAcknowledgementTracker for [" << topic << ", " << subscription + << ", " << consumerId << "] "; + name_ = consumerStrStream.str(); + LOG_DEBUG(name_ << "Constructed BatchAcknowledgementTracker"); +} + +void BatchAcknowledgementTracker::receivedMessage(const Message& message) { + // ignore message if it is not a batch message + if (!message.impl_->metadata.has_num_messages_in_batch()) { + return; + } + Lock lock(mutex_); + BatchMessageId msgID = message.impl_->messageId; + + // ignore message if it is less than the last cumulative ack sent or messageID is already being tracked + TrackerMap::iterator pos = trackerMap_.find(msgID); + if (msgID < greatestCumulativeAckSent_ || pos != trackerMap_.end() + || std::find(sendList_.begin(), sendList_.end(), msgID) != sendList_.end()) { + return; + } + LOG_DEBUG("Initializing the trackerMap_ with Message ID = " << msgID); + + // Since dynamic_set (this version) doesn't have all() function, initializing all bits with 1 and then reseting them to 0 and using any() + trackerMap_.insert(pos, TrackerPair(msgID, boost::dynamic_bitset<>(message.impl_->metadata.num_messages_in_batch()).set())); +} + +void BatchAcknowledgementTracker::deleteAckedMessage(const BatchMessageId& messageId, + proto::CommandAck_AckType ackType) { + // Not a batch message and a individual ack + if (messageId.batchIndex_ == -1 && ackType == proto::CommandAck_AckType_Individual) { + return; + } + + Lock lock(mutex_); + if (ackType == proto::CommandAck_AckType_Cumulative) { + // delete from trackerMap and sendList all messageIDs less than or equal to this one + // equal to - since getGreatestCumulativeAckReady already gives us the exact message id to be acked + + TrackerMap::iterator it = trackerMap_.begin(); + TrackerMapRemoveCriteria criteria(messageId); + while (it != trackerMap_.end()) { + if (criteria(*it)) { + trackerMap_.erase(it++); + } else { + ++it; + } + } + + // std::remove shifts all to be deleted items to the end of the vector and returns an iterator to the first + // instance of item, then we erase all elements from this iterator to the end of the list + sendList_.erase( + std::remove_if(sendList_.begin(), sendList_.end(), SendRemoveCriteria(messageId)), + sendList_.end()); + + if (greatestCumulativeAckSent_ < messageId) { + greatestCumulativeAckSent_ = messageId; + LOG_DEBUG( + *this << " The greatestCumulativeAckSent_ is now " << greatestCumulativeAckSent_); + } + } else { + // Error - if it is a batch message and found in trackerMap_ + if (trackerMap_.find(messageId) != trackerMap_.end()) { + LOG_ERROR( + *this << " - This should not happened - Message should have been removed from trakerMap_ and moved to sendList_ " << messageId); + } + + sendList_.erase(std::remove(sendList_.begin(), sendList_.end(), messageId), + sendList_.end()); + } +} + +bool BatchAcknowledgementTracker::isBatchReady(const BatchMessageId& msgID, const proto::CommandAck_AckType ackType) { + Lock lock(mutex_); + TrackerMap::iterator pos = trackerMap_.find(msgID); + if (std::find(sendList_.begin(), sendList_.end(), msgID) != sendList_.end() + || pos == trackerMap_.end()) { + LOG_DEBUG( + "Batch is ready since message present in sendList_ or not present in trackerMap_ [message ID = " << msgID << "]"); + return true; + } + + int batchIndex = msgID.batchIndex_; + assert(batchIndex < pos->second.size()); + pos->second.set(batchIndex, false); + + if (ackType == proto::CommandAck_AckType_Cumulative) { + for (int i = 0; i < batchIndex; i++) { + pos->second.set(i, false); + } + } + + if (pos->second.any()) { + return false; + } + sendList_.push_back(msgID); + trackerMap_.erase(pos); + LOG_DEBUG( + "Batch is ready since message all bits are reset in trackerMap_ [message ID = " << msgID << "]"); + return true; +} + +// returns +// - a batch message id < messageId +// - same messageId if it is the last message in the batch +const BatchMessageId BatchAcknowledgementTracker::getGreatestCumulativeAckReady( + const BatchMessageId& messageId) { + Lock lock(mutex_); + BatchMessageId messageReadyForCumulativeAck = BatchMessageId(); + TrackerMap::iterator pos = trackerMap_.find(messageId); + + // element not found + if (pos == trackerMap_.end()) { + return BatchMessageId(); + } + + + if (pos->second.size() - 1 != messageId.batchIndex_) { + // Can't cumulatively ack this batch message + if (pos == trackerMap_.begin()) { + // This was the first message hence we can't decrement the iterator + return BatchMessageId(); + } + pos--; + } + + return pos->first; +} + +} diff --git a/pulsar-client-cpp/lib/BatchAcknowledgementTracker.h b/pulsar-client-cpp/lib/BatchAcknowledgementTracker.h new file mode 100644 index 0000000000000..b8033fa7fbb4f --- /dev/null +++ b/pulsar-client-cpp/lib/BatchAcknowledgementTracker.h @@ -0,0 +1,105 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_BATCHACKNOWLEDGEMENTTRACKER_H_ +#define LIB_BATCHACKNOWLEDGEMENTTRACKER_H_ + +#include "pulsar/BatchMessageId.h" +#include "MessageImpl.h" +#include +#include +#include +#include +#include +#include "LogUtils.h" +#include +#include +namespace pulsar{ + +class ConsumerImpl; + +class BatchAcknowledgementTracker { + private: + typedef boost::unique_lock Lock; + typedef std::pair > TrackerPair; + typedef std::map > TrackerMap; + boost::mutex mutex_; + + TrackerMap trackerMap_; + + // SendList is used to reduce the time required to go over the dynamic_bitset and check if the entire batch is acked. + // It is useful in cases where the entire batch is acked but cnx is broken. In this case when any of the batch index + // is acked again, we just check the sendList to verify that the batch is acked w/o iterating over the dynamic_bitset. + std::vector sendList_; + + // we don't need to track MessageId < greatestCumulativeAckReceived + BatchMessageId greatestCumulativeAckSent_; + std::string name_; + + public: + BatchAcknowledgementTracker(const std::string topic, const std::string subscription, const long consumerId); + + bool isBatchReady(const BatchMessageId& msgID, const proto::CommandAck_AckType ackType); + const BatchMessageId getGreatestCumulativeAckReady(const BatchMessageId& messageId); + + void deleteAckedMessage(const BatchMessageId& messageId, proto::CommandAck_AckType ackType); + void receivedMessage(const Message& message); + + + inline friend std::ostream& operator<<(std::ostream& os, const BatchAcknowledgementTracker& batchAcknowledgementTracker); + + // Used for Cumulative acks only + struct SendRemoveCriteria { + private: + const BatchMessageId& messageId_; + + public: + SendRemoveCriteria(const BatchMessageId& messageId) + : messageId_(messageId) {} + + bool operator()(const BatchMessageId &element) const { + return (element <= messageId_); + } + }; + + // Used for Cumulative acks only + struct TrackerMapRemoveCriteria { + private: + const BatchMessageId& messageId_; + + public: + TrackerMapRemoveCriteria(const BatchMessageId& messageId) + : messageId_(messageId) {} + + bool operator()(std::pair > &element) const { + return (element.first <= messageId_); + } + }; + +}; + +std::ostream& operator<<(std::ostream& os, + const BatchAcknowledgementTracker& batchAcknowledgementTracker) { + os << "{ " << batchAcknowledgementTracker.name_ + << " [greatestCumulativeAckReceived_-" + << batchAcknowledgementTracker.greatestCumulativeAckSent_ << "] [trackerMap size = " + << batchAcknowledgementTracker.trackerMap_.size() << " ]}"; + return os; +} + +} + +#endif /* LIB_BATCHACKNOWLEDGEMENTTRACKER_H_ */ diff --git a/pulsar-client-cpp/lib/BatchMessageContainer.cc b/pulsar-client-cpp/lib/BatchMessageContainer.cc new file mode 100644 index 0000000000000..7fee02a8189f3 --- /dev/null +++ b/pulsar-client-cpp/lib/BatchMessageContainer.cc @@ -0,0 +1,145 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "BatchMessageContainer.h" + +namespace pulsar { + +static ObjectPool messagePool; +static ObjectPool messageContainerListPool; +DECLARE_LOG_OBJECT() + +BatchMessageContainer::BatchMessageContainer(ProducerImpl& producer) + : maxAllowedNumMessagesInBatch_(producer.conf_.getBatchingMaxMessages()), + maxAllowedMessageBatchSizeInBytes_(producer.conf_.getBatchingMaxAllowedSizeInBytes()), + topicName_(producer.topic_), + producerName_(producer.producerName_), + compressionType_(producer.conf_.getCompressionType()), + producer_(producer), + impl_(messagePool.create()), + timer_(producer.executor_->createDeadlineTimer()), + batchSizeInBytes_(0), + messagesContainerListPtr_(messageContainerListPool.create()), + averageBatchSize_(0), + numberOfBatchesSent_(0) { + messagesContainerListPtr_->reserve(1000); + LOG_INFO(*this << " BatchMessageContainer constructed"); +} + +void BatchMessageContainer::add(const Message& msg, SendCallback sendCallback, bool disableCheck) { + // disableCheck is needed to avoid recursion in case the batchSizeInKB < IndividualMessageSizeInKB + LOG_DEBUG(*this << " Called add function for [message = " << msg << "] [disableCheck = "<empty()) { + // First message to be added + startTimer(); + Commands::initBatchMessageMetadata(msg, impl_->metadata); + // TODO - add this to Commands.cc + impl_->metadata.set_producer_name(producerName_); + } + batchSizeInBytes_ += msg.impl_->payload.readableBytes(); + + LOG_DEBUG(*this << " Before serialization payload size in bytes = " <payload.readableBytes()); + Commands::serializeSingleMessageInBatchWithPayload(msg, impl_->payload, maxAllowedMessageBatchSizeInBytes_); + LOG_DEBUG(*this << " After serialization payload size in bytes = "<< impl_->payload.readableBytes()); + + messagesContainerListPtr_->push_back(MessageContainer(msg, sendCallback)); + + LOG_DEBUG(*this << " Number of messages in Batch = " << messagesContainerListPtr_->size()); + LOG_DEBUG(*this << " Batch Payload Size In Bytes = " << batchSizeInBytes_); + if (isFull()) { + LOG_DEBUG(*this << " Batch is full."); + sendMessage(); + } +} + +void BatchMessageContainer::startTimer() { + const unsigned long& publishDelayInMs = producer_.conf_.getBatchingMaxPublishDelayMs(); + LOG_DEBUG(*this << " Timer started with expiry after " << publishDelayInMs); + timer_->expires_from_now(boost::posix_time::milliseconds(publishDelayInMs)); + timer_->async_wait( + boost::bind(&pulsar::ProducerImpl::batchMessageTimeoutHandler, &producer_, + boost::asio::placeholders::error)); +} + +void BatchMessageContainer::sendMessage() { + // Call this function after acquiring the ProducerImpl lock + LOG_DEBUG(*this << "Sending the batch message container"); + if (isEmpty()) { + LOG_DEBUG(*this << " Batch is empty - returning."); + return; + } + impl_->metadata.set_num_messages_in_batch(messagesContainerListPtr_->size()); + compressPayLoad(); + + Message msg; + msg.impl_ = impl_; + + // bind keeps a copy of the parameters + SendCallback callback = boost::bind(&BatchMessageContainer::batchMessageCallBack, _1, messagesContainerListPtr_); + + producer_.sendMessage(msg, callback); + clear(); +} + +void BatchMessageContainer::compressPayLoad() { + + if (compressionType_ != CompressionNone) { + impl_->metadata.set_compression( + CompressionCodecProvider::convertType(compressionType_)); + impl_->metadata.set_uncompressed_size(impl_->payload.readableBytes()); + } + impl_->payload = CompressionCodecProvider::getCodec(compressionType_).encode(impl_->payload); +} + +SharedBuffer BatchMessageContainer::getBatchedPayload() { + return impl_->payload; +} + +void BatchMessageContainer::clear() { + LOG_DEBUG(*this << " BatchMessageContainer::clear() called"); + timer_->cancel(); + averageBatchSize_ = (messagesContainerListPtr_->size() + (averageBatchSize_ * numberOfBatchesSent_))/++numberOfBatchesSent_; + messagesContainerListPtr_ = messageContainerListPool.create(); + // Try to optimize this + messagesContainerListPtr_->reserve(10000); + impl_ = messagePool.create(); + batchSizeInBytes_ = 0; +} + +void BatchMessageContainer::batchMessageCallBack(Result r, MessageContainerListPtr messagesContainerListPtr) { + if (!messagesContainerListPtr) { + return; + } + LOG_DEBUG("BatchMessageContainer::batchMessageCallBack called with [Result = " << r << "] [numOfMessages = " << messagesContainerListPtr->size() << "]"); + for(MessageContainerList::iterator iter = messagesContainerListPtr->begin(); iter != messagesContainerListPtr->end(); iter++) { + // callback(result, message) + iter->sendCallback_(r, iter->message_); + } +} + +BatchMessageContainer::~BatchMessageContainer() { + timer_->cancel(); + LOG_DEBUG(*this << " BatchMessageContainer Object destructed"); + LOG_INFO("[numberOfBatchesSent = " << numberOfBatchesSent_ + << "] [averageBatchSize = " << averageBatchSize_ << "]"); +} +} diff --git a/pulsar-client-cpp/lib/BatchMessageContainer.h b/pulsar-client-cpp/lib/BatchMessageContainer.h new file mode 100644 index 0000000000000..19996328870cc --- /dev/null +++ b/pulsar-client-cpp/lib/BatchMessageContainer.h @@ -0,0 +1,140 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +/* + * \class BatchMessageContainer + * + * \brief This class is a container for holding individual messages being published until they are batched and sent to broker. + * + * \note This class is not thread safe. + */ + +#ifndef LIB_BATCHMESSAGECONTAINER_H_ +#define LIB_BATCHMESSAGECONTAINER_H_ +#include +#include +#include +#include +#include "MessageImpl.h" +#include "CompressionCodec.h" +#include "Commands.h" +#include "LogUtils.h" +#include "ObjectPool.h" +#include +#include "ExecutorService.h" +#include +#include "ProducerImpl.h" + +namespace pulsar { + +class BatchMessageContainer { + public: + + struct MessageContainer { + MessageContainer(Message message, SendCallback sendCallback) + : message_(message), + sendCallback_(sendCallback) { + } + Message message_; + SendCallback sendCallback_; + }; + typedef std::vector MessageContainerList; + typedef boost::shared_ptr MessageContainerListPtr; + + BatchMessageContainer(ProducerImpl& producer); + + ~BatchMessageContainer(); + + void add(const Message& msg, SendCallback sendCallback, bool disableCheck = false); + + SharedBuffer getBatchedPayload(); + + void clear(); + + static void batchMessageCallBack(Result r, MessageContainerListPtr messages); + + friend inline std::ostream& operator<<(std::ostream& os, const BatchMessageContainer& batchMessageContainer); + friend class ProducerImpl; + + private: + const CompressionType compressionType_; + + const unsigned int maxAllowedNumMessagesInBatch_; + const unsigned long maxAllowedMessageBatchSizeInBytes_; + unsigned long batchSizeInBytes_; + + /// Topic Name is used for creating descriptors in log messages + const std::string topicName_; + + /// Producer Name is used for creating descriptors in log messages + std::string producerName_; + + Message::MessageImplPtr impl_; + + // This copy (to vector) is needed since OpSendMsg no long holds the individual message and w/o a container + // the impl_ Shared Pointer will delete the data. + MessageContainerListPtr messagesContainerListPtr_; + + ProducerImpl& producer_; + + DeadlineTimerPtr timer_; + + + unsigned long numberOfBatchesSent_; + + double averageBatchSize_; + + void compressPayLoad(); + + inline bool isEmpty() const; + + inline bool isFull() const; + + inline bool hasSpaceInBatch(const Message& msg) const; + + void startTimer(); + + void sendMessage(); +}; + +bool BatchMessageContainer::hasSpaceInBatch(const Message& msg) const { + return (msg.impl_->payload.readableBytes() + this->batchSizeInBytes_ + <= this->maxAllowedMessageBatchSizeInBytes_) + && (this->messagesContainerListPtr_->size() < this->maxAllowedNumMessagesInBatch_); +} + +bool BatchMessageContainer::isEmpty() const { + return this->messagesContainerListPtr_->empty(); +} + +bool BatchMessageContainer::isFull() const { + return (this->batchSizeInBytes_ >= this->maxAllowedMessageBatchSizeInBytes_ + || this->messagesContainerListPtr_->size() >= this->maxAllowedNumMessagesInBatch_); +} + +std::ostream& operator<<(std::ostream& os, const BatchMessageContainer& b) { + os << "{ BatchContainer [size = " << b.messagesContainerListPtr_->size() << "] [batchSizeInBytes_ = " + << b.batchSizeInBytes_ << "] [maxAllowedMessageBatchSizeInBytes_ = " + << b.maxAllowedMessageBatchSizeInBytes_ << "] [maxAllowedNumMessagesInBatch_ = " + << b.maxAllowedNumMessagesInBatch_ << "] [topicName = " << b.topicName_ + << "] [producerName_ = " << b.producerName_ << "] [batchSizeInBytes_ = " + << b.batchSizeInBytes_ << "] [numberOfBatchesSent = " << b.numberOfBatchesSent_ + << "] [averageBatchSize = " << b.averageBatchSize_ << "]}"; + return os; +} + +} +#endif /* LIB_BATCHMESSAGECONTAINER_H_ */ diff --git a/pulsar-client-cpp/lib/BinaryProtoLookupService.cc b/pulsar-client-cpp/lib/BinaryProtoLookupService.cc new file mode 100644 index 0000000000000..4885d69c34d85 --- /dev/null +++ b/pulsar-client-cpp/lib/BinaryProtoLookupService.cc @@ -0,0 +1,146 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "DestinationName.h" +#include "BinaryProtoLookupService.h" +#include "LogUtils.h" +#include "SharedBuffer.h" + +#include +#include +#include "ConnectionPool.h" + +#include + +DECLARE_LOG_OBJECT() + +namespace pulsar { + + /* + * @param lookupUrl service url to do lookup + * Constructor + */ + BinaryProtoLookupService::BinaryProtoLookupService(ConnectionPool& cnxPool, const std::string& lookupUrl) + : + cnxPool_(cnxPool), + serviceUrl_(lookupUrl), + mutex_(), + requestIdGenerator_(0) {} + + /* + * @param destination_name topic name to get broker for + * + * Looks up the owner broker for the given destination name + */ + Future BinaryProtoLookupService::lookupAsync(const std::string& destinationName) { + DestinationNamePtr dn = DestinationName::get(destinationName); + if (!dn) { + LOG_ERROR("Unable to parse destination - " << destinationName); + LookupDataResultPromisePtr promise = boost::make_shared(); + promise->setFailed(ResultInvalidTopicName); + return promise->getFuture(); + } + std::string lookupName = dn->toString(); + LookupDataResultPromisePtr promise = boost::make_shared(); + Future future = cnxPool_.getConnectionAsync(serviceUrl_); + future.addListener(boost::bind(&BinaryProtoLookupService::sendTopicLookupRequest, this, lookupName, false, _1, _2, promise)); + return promise->getFuture(); + } + + /* + * @param destination_name topic to get number of partitions. + * + */ + Future BinaryProtoLookupService::getPartitionMetadataAsync(const DestinationNamePtr& dn) { + LookupDataResultPromisePtr promise = boost::make_shared(); + if (!dn) { + promise->setFailed(ResultInvalidTopicName); + return promise->getFuture(); + } + std::string lookupName = dn->toString(); + Future future = cnxPool_.getConnectionAsync(serviceUrl_); + future.addListener(boost::bind(&BinaryProtoLookupService::sendPartitionMetadataLookupRequest, this, lookupName, _1, _2, promise)); + return promise->getFuture(); + } + + + void BinaryProtoLookupService::sendTopicLookupRequest(const std::string& destinationName, bool authoritative, Result result, const ClientConnectionWeakPtr& clientCnx, LookupDataResultPromisePtr promise) { + if (result != ResultOk) { + promise->setFailed(ResultConnectError); + return; + } + LookupDataResultPromisePtr lookupPromise = boost::make_shared(); + ClientConnectionPtr conn = clientCnx.lock(); + uint64_t requestId = newRequestId(); + conn->newTopicLookup(destinationName, authoritative, requestId, lookupPromise); + lookupPromise->getFuture().addListener(boost::bind(&BinaryProtoLookupService::handleLookup, this, destinationName, _1, _2, clientCnx, promise)); + } + + void BinaryProtoLookupService::handleLookup(const std::string& destinationName, + Result result, LookupDataResultPtr data, const ClientConnectionWeakPtr& clientCnx, + LookupDataResultPromisePtr promise) { + if (data) { + if(data ->isRedirect()) { + LOG_DEBUG("Lookup request is for " << destinationName << " redirected to " << data->getBrokerUrl()); + Future future = cnxPool_.getConnectionAsync(data->getBrokerUrl()); + future.addListener(boost::bind(&BinaryProtoLookupService::sendTopicLookupRequest, this, destinationName, data->isAuthoritative(), _1, _2, promise)); + } else { + LOG_DEBUG("Lookup response for " << destinationName << ", lookup-broker-url " << data->getBrokerUrl()); + promise->setValue(data); + } + } else { + LOG_DEBUG("Lookup failed for " << destinationName << ", result " << result); + promise->setFailed(result); + } + } + + void BinaryProtoLookupService::sendPartitionMetadataLookupRequest(const std::string& destinationName, Result result, const ClientConnectionWeakPtr& clientCnx, LookupDataResultPromisePtr promise) { + if (result != ResultOk) { + promise->setFailed(ResultConnectError); + Future future = promise->getFuture(); + return; + } + LookupDataResultPromisePtr lookupPromise = boost::make_shared(); + ClientConnectionPtr conn = clientCnx.lock(); + uint64_t requestId = newRequestId(); + conn->newPartitionedMetadataLookup(destinationName, requestId, lookupPromise); + lookupPromise->getFuture().addListener(boost::bind(&BinaryProtoLookupService::handleLookup, this, destinationName, _1, _2, clientCnx, promise)); + } + + void BinaryProtoLookupService::handlePartitionMetadataLookup(const std::string& destinationName, + Result result, LookupDataResultPtr data, const ClientConnectionWeakPtr& clientCnx, + LookupDataResultPromisePtr promise) { + if (data) { + if(data->isRedirect()) { + LOG_DEBUG("Lookup request is for " << destinationName << " redirected to " << data->getBrokerUrl()); + Future future = cnxPool_.getConnectionAsync(data->getBrokerUrl()); + future.addListener(boost::bind(&BinaryProtoLookupService::sendPartitionMetadataLookupRequest, this, destinationName, _1, _2, promise)); + } else { + LOG_DEBUG("Lookup response for " << destinationName << ", lookup-broker-url " << data->getBrokerUrl()); + promise->setValue(data); + } + } else { + LOG_DEBUG("Lookup failed for " << destinationName << ", result " << result); + promise->setFailed(result); + } + } + + uint64_t BinaryProtoLookupService::newRequestId() { + Lock lock(mutex_); + return ++requestIdGenerator_; + } + +} diff --git a/pulsar-client-cpp/lib/BinaryProtoLookupService.h b/pulsar-client-cpp/lib/BinaryProtoLookupService.h new file mode 100644 index 0000000000000..1d719fcf9bbee --- /dev/null +++ b/pulsar-client-cpp/lib/BinaryProtoLookupService.h @@ -0,0 +1,78 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef _PULSAR_BINARY_LOOKUP_SERVICE_HEADER_ +#define _PULSAR_BINARY_LOOKUP_SERVICE_HEADER_ + +#include + +#include +#include +#include +#include "ConnectionPool.h" +#include "DestinationName.h" +#include "Future.h" +#include "LookupDataResult.h" +#include "Backoff.h" + +#pragma GCC visibility push(default) + +namespace pulsar { +class LookupDataResult; + +class BinaryProtoLookupService { + public: + /* + * constructor + */ + BinaryProtoLookupService(ConnectionPool& cnxPool, const std::string& serviceUrl); + + Future lookupAsync(const std::string& destinationName); + + Future getPartitionMetadataAsync(const DestinationNamePtr& dn); + + private: + + boost::mutex mutex_; + uint64_t requestIdGenerator_; + + std::string serviceUrl_; + ConnectionPool& cnxPool_; + + void sendTopicLookupRequest(const std::string& destinationName, bool authoritative, Result result, + const ClientConnectionWeakPtr& clientCnx, LookupDataResultPromisePtr promise); + + void handleLookup(const std::string& destinationName, Result result, LookupDataResultPtr data, + const ClientConnectionWeakPtr& clientCnx, LookupDataResultPromisePtr promise); + + + void sendPartitionMetadataLookupRequest(const std::string& destinationName, Result result, + const ClientConnectionWeakPtr& clientCnx, + LookupDataResultPromisePtr promise); + + void handlePartitionMetadataLookup(const std::string& destinationName, Result result, LookupDataResultPtr data, + const ClientConnectionWeakPtr& clientCnx, LookupDataResultPromisePtr promise); + + + uint64_t newRequestId(); + +}; + +} + +#pragma GCC visibility pop + +#endif //_PULSAR_BINARY_LOOKUP_SERVICE_HEADER_ diff --git a/pulsar-client-cpp/lib/BlockingQueue.h b/pulsar-client-cpp/lib/BlockingQueue.h new file mode 100644 index 0000000000000..2af38866c203a --- /dev/null +++ b/pulsar-client-cpp/lib/BlockingQueue.h @@ -0,0 +1,330 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_BLOCKINGQUEUE_H_ +#define LIB_BLOCKINGQUEUE_H_ + +#include +#include +#include + +/** + * Following structs are defined for holding a predicate in wait() call on condition variables. + * This is done in order to avoid spurious wake up problem. + * Details: https://www.justsoftwaresolutions.co.uk/threading/condition-variable-spurious-wakes.html + */ +template +struct QueueNotEmpty { + const Container& queue_; + QueueNotEmpty(const Container& queue) + : queue_(queue) { + + } + bool operator()() const { + return !queue_.isEmptyNoMutex(); + } +}; + +template +struct QueueNotFull { + const Container& queue_; + QueueNotFull(const Container& queue) + : queue_(queue) { + + } + bool operator()() const { + return !queue_.isFullNoMutex(); + } +}; + +template +class BlockingQueue { + public: + typedef typename boost::circular_buffer Container; + typedef typename Container::iterator iterator; + typedef typename Container::const_iterator const_iterator; + + class ReservedSpot { + public: + ReservedSpot() + : queue_(), + released_(true) { + } + + ReservedSpot(BlockingQueue& queue) + : queue_(&queue), + released_(false) { + } + + ~ReservedSpot() { + release(); + } + + void release() { + if (!released_) { + queue_->releaseReservedSpot(); + released_ = true; + } + } + + private: + BlockingQueue* queue_; + bool released_; + + friend class BlockingQueue ; + }; + + BlockingQueue(size_t maxSize) + : maxSize_(maxSize), + mutex_(), + queue_(maxSize), + reservedSpots_(0) { + } + + bool tryReserve(size_t noOfSpots) { + assert(noOfSpots <= maxSize_); + Lock lock(mutex_); + if(noOfSpots <= maxSize_ - (reservedSpots_ + queue_.size())) { + reservedSpots_ += noOfSpots; + return true; + } + return false; + } + + void reserve(size_t noOfSpots) { + assert(noOfSpots <= maxSize_); + Lock lock(mutex_); + while(noOfSpots--) { + queueFullCondition.wait(lock, QueueNotFull >(*this)); + reservedSpots_++; + } + } + + void release(size_t noOfSpots) { + Lock lock(mutex_); + assert(noOfSpots <= reservedSpots_); + bool wasFull = isFullNoMutex(); + reservedSpots_ -= noOfSpots; + lock.unlock(); + + if (wasFull) { + // Notify that one spot is now available + queueFullCondition.notify_all(); + } + } + + ReservedSpot reserve() { + Lock lock(mutex_); + // If the queue is full, wait for space to be available + queueFullCondition.wait(lock, QueueNotFull >(*this)); + reservedSpots_++; + return ReservedSpot(*this); + } + + void push(const T& value, bool wasReserved = false) { + Lock lock(mutex_); + if (wasReserved) { + reservedSpots_--; + } + // If the queue is full, wait for space to be available + queueFullCondition.wait(lock, QueueNotFull >(*this)); + bool wasEmpty = queue_.empty(); + queue_.push_back(value); + lock.unlock(); + if (wasEmpty) { + // Notify that an element is pushed + queueEmptyCondition.notify_one(); + } + } + + void push(const T& value, ReservedSpot& spot) { + Lock lock(mutex_); + + // Since the value already had a spot reserved in the queue, we need to + // discount it + assert(reservedSpots_ > 0); + reservedSpots_--; + spot.released_ = true; + + bool wasEmpty = queue_.empty(); + queue_.push_back(value); + lock.unlock(); + + if (wasEmpty) { + // Notify that an element is pushed + queueEmptyCondition.notify_one(); + } + } + + bool tryPush(const T& value) { + Lock lock(mutex_); + + // Need to consider queue_.size() + reserved spot + if (isFullNoMutex()) { + return false; + } + + bool wasEmpty = queue_.empty(); + queue_.push_back(value); + lock.unlock(); + + if (wasEmpty) { + // Notify that an element is pushed + queueEmptyCondition.notify_one(); + } + + return true; + } + + void pop() { + Lock lock(mutex_); + // If the queue is empty, wait until an element is available to be popped + queueEmptyCondition.wait(lock, QueueNotEmpty >(*this)); + + bool wasFull = isFullNoMutex(); + queue_.pop_front(); + lock.unlock(); + + if (wasFull) { + // Notify that an element is popped + queueFullCondition.notify_one(); + } + } + + void pop(T& value) { + Lock lock(mutex_); + // If the queue is empty, wait until an element is available to be popped + queueEmptyCondition.wait(lock, QueueNotEmpty >(*this)); + value = queue_.front(); + + bool wasFull = isFullNoMutex(); + queue_.pop_front(); + lock.unlock(); + + if (wasFull) { + // Notify that an element is popped + queueFullCondition.notify_one(); + } + } + + bool pop(T& value, const boost::posix_time::time_duration& timeout) { + Lock lock(mutex_); + if (!queueEmptyCondition.timed_wait(lock, timeout, + QueueNotEmpty >(*this))) { + return false; + } + + bool wasFull = isFullNoMutex(); + value = queue_.front(); + queue_.pop_front(); + lock.unlock(); + + if (wasFull) { + // Notify that an element is popped + queueFullCondition.notify_all(); + } + + return true; + } + + // Check the 1st element of the queue + bool peek(T& value) { + Lock lock(mutex_); + if (queue_.empty()) { + return false; + } + + value = queue_.front(); + return true; + } + + // Remove all elements from the queue + void clear() { + Lock lock(mutex_); + queue_.clear(); + queueFullCondition.notify_all(); + } + + size_t size() const { + Lock lock(mutex_); + return queue_.size(); + } + + size_t maxSize() const { + return maxSize_; + } + + bool empty() const { + Lock lock(mutex_); + return isEmptyNoMutex(); + } + + bool full() const { + Lock lock(mutex_); + return isFullNoMutex(); + } + + const_iterator begin() const { + return queue_.begin(); + } + + const_iterator end() const { + return queue_.end(); + } + + iterator begin() { + return queue_.begin(); + } + + iterator end() { + return queue_.end(); + } + + private: + void releaseReservedSpot() { + Lock lock(mutex_); + bool wasFull = isFullNoMutex(); + --reservedSpots_; + lock.unlock(); + + if (wasFull) { + // Notify that one spot is now available + queueFullCondition.notify_one(); + } + } + + bool isEmptyNoMutex() const { + return queue_.empty(); + } + + bool isFullNoMutex() const { + return (queue_.size() + reservedSpots_) == maxSize_; + } + + const size_t maxSize_; + mutable boost::mutex mutex_; + boost::condition_variable queueFullCondition; + boost::condition_variable queueEmptyCondition; + Container queue_; + int reservedSpots_; + + typedef boost::unique_lock Lock; + friend class QueueReservedSpot; + friend struct QueueNotEmpty > ; + friend struct QueueNotFull > ; +}; + +#endif /* LIB_BLOCKINGQUEUE_H_ */ diff --git a/pulsar-client-cpp/lib/CMakeLists.txt b/pulsar-client-cpp/lib/CMakeLists.txt new file mode 100644 index 0000000000000..10940fb6ddb5b --- /dev/null +++ b/pulsar-client-cpp/lib/CMakeLists.txt @@ -0,0 +1,31 @@ +# +# Copyright 2016 Yahoo Inc. +# +# Licensed 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. +# + +file(GLOB PULSAR_SOURCES *.cc lz4/*.c checksum/*.cc) + +execute_process(COMMAND /bin/cat ../pom.xml COMMAND /bin/grep -Po "[^<]+" COMMAND /bin/sed "s/.*>//g" COMMAND /usr/bin/head -1 COMMAND /usr/bin/tr -d '\\\n' OUTPUT_VARIABLE PV) +set (CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -msse4.2 -mpclmul -D_PULSAR_VERSION_=\\\"${PV}\\\"") + +add_library(pulsarStatic STATIC ${PULSAR_SOURCES}) +add_library(pulsarShared SHARED ${PULSAR_SOURCES}) + +set_target_properties(pulsarStatic PROPERTIES OUTPUT_NAME pulsar VERSION ${PV}) +set_target_properties(pulsarShared PROPERTIES OUTPUT_NAME pulsar VERSION ${PV}) + +target_link_libraries(pulsarStatic ${COMMON_LIBS}) +target_link_libraries(pulsarShared ${COMMON_LIBS}) + +add_subdirectory(auth) diff --git a/pulsar-client-cpp/lib/Client.cc b/pulsar-client-cpp/lib/Client.cc new file mode 100644 index 0000000000000..6eb60e2bb7abd --- /dev/null +++ b/pulsar-client-cpp/lib/Client.cc @@ -0,0 +1,190 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include +#include + +#include +#include + +#include "ClientImpl.h" +#include "Utils.h" +#include "ExecutorService.h" +#include "LogUtils.h" + +DECLARE_LOG_OBJECT() + +namespace pulsar { + +struct ClientConfiguration::Impl { + AuthenticationPtr authData; + int ioThreads; + int operationTimeoutSeconds; + int messageListenerThreads; + std::string logConfFilePath; + Impl() : authData(Auth::Disabled()), + ioThreads(1), + operationTimeoutSeconds(30), + messageListenerThreads(1), + logConfFilePath() {} +}; + +ClientConfiguration::ClientConfiguration() + : impl_(boost::make_shared()) { +} + +ClientConfiguration::~ClientConfiguration() { +} + +ClientConfiguration::ClientConfiguration(const ClientConfiguration& x) + : impl_(x.impl_) { +} + +ClientConfiguration& ClientConfiguration::operator=(const ClientConfiguration& x) { + impl_ = x.impl_; + return *this; +} + +ClientConfiguration& ClientConfiguration::setAuthentication(const AuthenticationPtr& authentication) { + impl_->authData = authentication; + return *this; +} + +const Authentication& ClientConfiguration::getAuthentication() const { + return *impl_->authData; +} + +const AuthenticationPtr& ClientConfiguration::getAuthenticationPtr() const { + return impl_->authData; +} + +ClientConfiguration& ClientConfiguration::setOperationTimeoutSeconds(int timeout) { + impl_->operationTimeoutSeconds = timeout; + return *this; +} + +int ClientConfiguration::getOperationTimeoutSeconds() const { + return impl_->operationTimeoutSeconds; +} + +ClientConfiguration& ClientConfiguration::setIOThreads(int threads) { + impl_->ioThreads = threads; + return *this; +} + +int ClientConfiguration::getIOThreads() const { + return impl_->ioThreads; +} + +ClientConfiguration& ClientConfiguration::setMessageListenerThreads(int threads) { + impl_->messageListenerThreads = threads; + return *this; +} + +int ClientConfiguration::getMessageListenerThreads() const { + return impl_->messageListenerThreads; +} + +ClientConfiguration& ClientConfiguration::setLogConfFilePath(const std::string& logConfFilePath) { + impl_->logConfFilePath = logConfFilePath; + return *this; +} + +const std::string& ClientConfiguration::getLogConfFilePath() const { + return impl_->logConfFilePath; +} + +///////////////////////////////////////////////////////////////// + +Client::Client(const std::string& serviceUrl) + : impl_(boost::make_shared(serviceUrl, ClientConfiguration(), true)) { +} + +Client::Client(const std::string& serviceUrl, const ClientConfiguration& clientConfiguration) + : impl_(boost::make_shared(serviceUrl, clientConfiguration, true)) { +} + +Client::Client(const std::string& serviceUrl, const ClientConfiguration& clientConfiguration, + bool poolConnections) + : impl_(boost::make_shared(serviceUrl, clientConfiguration, poolConnections)) { +} + +Result Client::createProducer(const std::string& topic, Producer& producer) { + return createProducer(topic, ProducerConfiguration(), producer); +} + +Result Client::createProducer(const std::string& topic, const ProducerConfiguration& conf, + Producer& producer) { + Promise promise; + createProducerAsync(topic, conf, WaitForCallbackValue(promise)); + Future future = promise.getFuture(); + + return future.get(producer); +} + +void Client::createProducerAsync(const std::string& topic, CreateProducerCallback callback) { + createProducerAsync(topic, ProducerConfiguration(), callback); +} + +void Client::createProducerAsync(const std::string& topic, ProducerConfiguration conf, + CreateProducerCallback callback) { + impl_->createProducerAsync(topic, conf, callback); +} + +Result Client::subscribe(const std::string& topic, const std::string& consumerName, + Consumer& consumer) { + return subscribe(topic, consumerName, ConsumerConfiguration(), consumer); +} + +Result Client::subscribe(const std::string& topic, const std::string& consumerName, + const ConsumerConfiguration& conf, Consumer& consumer) { + Promise promise; + subscribeAsync(topic, consumerName, conf, WaitForCallbackValue(promise)); + Future future = promise.getFuture(); + + return future.get(consumer); +} + +void Client::subscribeAsync(const std::string& topic, const std::string& consumerName, + SubscribeCallback callback) { + subscribeAsync(topic, consumerName, ConsumerConfiguration(), callback); +} + +void Client::subscribeAsync(const std::string& topic, const std::string& consumerName, + const ConsumerConfiguration& conf, SubscribeCallback callback) { + LOG_DEBUG("Topic is :" << topic); + impl_->subscribeAsync(topic, consumerName, conf, callback); +} + +Result Client::close() { + Promise promise; + closeAsync(WaitForCallback(promise)); + + Result result; + promise.getFuture().get(result); + return result; +} + +void Client::closeAsync(CloseCallback callback) { + impl_->closeAsync(callback); +} + +void Client::shutdown() { + impl_->shutdown(); +} + +} diff --git a/pulsar-client-cpp/lib/ClientConnection.cc b/pulsar-client-cpp/lib/ClientConnection.cc new file mode 100644 index 0000000000000..53e5d51fe1f92 --- /dev/null +++ b/pulsar-client-cpp/lib/ClientConnection.cc @@ -0,0 +1,1001 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "ClientConnection.h" + +#include "PulsarApi.pb.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "ExecutorService.h" +#include "Commands.h" +#include "LogUtils.h" +#include "Url.h" + +#include + +#include + +#include "ProducerImpl.h" +#include "ConsumerImpl.h" +#include "checksum/ChecksumProvider.h" + +DECLARE_LOG_OBJECT() + +using namespace pulsar::proto; +using namespace boost::asio::ip; + +namespace pulsar { + +static const uint32_t DefaultBufferSize = 64 * 1024; + +static const int KeepAliveIntervalInSeconds = 30; + +// Convert error codes from protobuf to client API Result +static Result getResult(ServerError serverError) { + switch (serverError) { + case UnknownError: + return ResultUnknownError; + + case MetadataError: + return ResultBrokerMetadataError; + + case ChecksumError: + return ResultChecksumError; + + case PersistenceError: + return ResultBrokerPersistenceError; + + case AuthenticationError: + return ResultAuthenticationError; + + case AuthorizationError: + return ResultAuthorizationError; + + case ConsumerBusy: + return ResultConsumerBusy; + + case ServiceNotReady: + return ResultServiceUnitNotReady; + + case ProducerBlockedQuotaExceededError: + return ResultProducerBlockedQuotaExceededError; + + case ProducerBlockedQuotaExceededException: + return ResultProducerBlockedQuotaExceededException; + } + // NOTE : Do not add default case in the switch above. In future if we get new cases for + // ServerError and miss them in the switch above we would like to get notified. Adding + // return here to make the compiler happy. + return ResultUnknownError; +} + +ClientConnection::ClientConnection(const std::string& endpoint, ExecutorServicePtr executor, + const ClientConfiguration& clientConfiguration, const AuthenticationPtr& authentication) + : state_(Pending), + operationsTimeout_(seconds(clientConfiguration.getOperationTimeoutSeconds())), + authentication_(authentication), + serverProtocolVersion_(ProtocolVersion_MIN), + executor_(executor), + resolver_(executor->createTcpResolver()), + socket_(executor->createSocket()), + address_(endpoint), + cnxString_("[ -> " + endpoint + "] "), + error_(boost::system::error_code()), + incomingBuffer_(SharedBuffer::allocate(DefaultBufferSize)), + incomingCmd_(), + pendingWriteBuffers_(), + pendingWriteOperations_(0), + outgoingBuffer_(SharedBuffer::allocate(DefaultBufferSize)), + outgoingCmd_(), + havePendingPingRequest_(false), + keepAliveTimer_() { +} + +ClientConnection::~ClientConnection() { + LOG_INFO(cnxString_ << "Destroyed connection"); +} + +void ClientConnection::handlePulsarConnected(const CommandConnected& cmdConnected) { + if (!cmdConnected.has_server_version()) { + LOG_ERROR(cnxString_ << "Server version is not set"); + close(); + return; + } + + state_ = Ready; + serverProtocolVersion_ = cmdConnected.protocol_version(); + connectPromise_.setValue(shared_from_this()); + + if (serverProtocolVersion_ >= v1) { + // Only send keep-alive probes if the broker supports it + keepAliveTimer_ = executor_->createDeadlineTimer(); + keepAliveTimer_->expires_from_now(boost::posix_time::seconds(KeepAliveIntervalInSeconds)); + keepAliveTimer_->async_wait( + boost::bind(&ClientConnection::handleKeepAliveTimeout, shared_from_this())); + } +} + +/// The number of unacknowledged probes to send before considering the connection dead and notifying the application layer +typedef boost::asio::detail::socket_option::integer tcp_keep_alive_count; + +/// The interval between subsequential keepalive probes, regardless of what the connection has exchanged in the meantime +typedef boost::asio::detail::socket_option::integer tcp_keep_alive_interval; + +/// The interval between the last data packet sent (simple ACKs are not considered data) and the first keepalive +/// probe; after the connection is marked to need keepalive, this counter is not used any further +#ifdef __APPLE__ + typedef boost::asio::detail::socket_option::integer tcp_keep_alive_idle; +#else + typedef boost::asio::detail::socket_option::integer tcp_keep_alive_idle; +#endif + +/* + * TCP Connect handler + * + * if async_connect without any error, connected_ would be set to true + * at this point the connection is deemed valid to be used by clients of this class + */ +void ClientConnection::handleTcpConnected(const boost::system::error_code& err, + tcp::resolver::iterator endpointIterator) { + if (!err) { + std::stringstream cnxStringStream; + cnxStringStream << "[" << socket_->local_endpoint() << " -> " << socket_->remote_endpoint() << "] "; + cnxString_ = cnxStringStream.str(); + + LOG_INFO(cnxString_ << "Connected to broker"); + state_ = TcpConnected; + socket_->set_option(tcp::no_delay(true)); + + socket_->set_option(tcp::socket::keep_alive(true)); + + // Start TCP keep-alive probes after connection has been idle after 1 minute. Ideally this + // should never happen, given that we're sending our own keep-alive probes (within the TCP + // connection) every 30 seconds + socket_->set_option(tcp_keep_alive_idle(1 * 60)); + + // Send up to 10 probes before declaring the connection broken + socket_->set_option(tcp_keep_alive_count(10)); + + // Interval between probes: 6 seconds + socket_->set_option(tcp_keep_alive_interval(6)); + + SharedBuffer buffer = Commands::newConnect(authentication_); + // Send CONNECT command to broker + boost::asio::async_write( + *socket_, + buffer.const_asio_buffer(), + boost::bind(&ClientConnection::handleSentPulsarConnect, shared_from_this(), + boost::asio::placeholders::error, buffer)); + } else if (endpointIterator != tcp::resolver::iterator()) { + // The connection failed. Try the next endpoint in the list. + socket_->close(); + tcp::endpoint endpoint = *endpointIterator; + socket_->async_connect( + endpoint, + boost::bind(&ClientConnection::handleTcpConnected, shared_from_this(), + boost::asio::placeholders::error, ++endpointIterator)); + } else { + LOG_ERROR(cnxString_ << "Failed to establish connection: " << err.message()); + close(); + return; + + } + +} + +void ClientConnection::handleSentPulsarConnect(const boost::system::error_code& err, + const SharedBuffer& buffer) { + if (err) { + LOG_ERROR(cnxString_ << "Failed to establish connection: " << err.message()); + close(); + return; + } + +// Schedule the reading of CONNECTED command from broker + readNextCommand(); +} + +/* + * Async method to establish TCP connection with broker + * + * tcpConnectCompletionHandler is notified when the result of this call is available. + * + */ +void ClientConnection::tcpConnectAsync() { + boost::system::error_code err; + Url service_url; + if (!Url::parse(address_, service_url)) { + LOG_ERROR(cnxString_ << "Invalid Url, unable to parse: " << err << " " << err.message()); + close(); + return; + } + + if (service_url.protocol() != "pulsar" && service_url.protocol() != "pulsar+ssl") { + LOG_ERROR(cnxString_ << "Invalid Url protocol '" << service_url.protocol() << "'. Valid values are 'pulsar' and 'pulsar+ssl'"); + close(); + return; + } + + LOG_DEBUG(cnxString_ << "Connecting to " << service_url.host() << ":" << service_url.port()); + tcp::resolver::query query(service_url.host(), + boost::lexical_cast(service_url.port())); + resolver_->async_resolve( + query, + boost::bind(&ClientConnection::handleResolve, shared_from_this(), + boost::asio::placeholders::error, boost::asio::placeholders::iterator)); +} + +void ClientConnection::handleResolve(const boost::system::error_code& err, + tcp::resolver::iterator endpointIterator) { + if (err) { + LOG_ERROR(cnxString_ << "Resolve error: " << err << " : " << err.message()); + close(); + return; + } + + if (endpointIterator != tcp::resolver::iterator()) { + LOG_DEBUG(cnxString_ << "Resolved hostname " << endpointIterator->host_name() // + << " to " << endpointIterator->endpoint()); + socket_->async_connect( + *endpointIterator++, + boost::bind(&ClientConnection::handleTcpConnected, shared_from_this(), + boost::asio::placeholders::error, endpointIterator)); + } else { + LOG_WARN(cnxString_ << "No IP address found"); + close(); + return; + } +} + +void ClientConnection::readNextCommand() { + const static uint32_t minReadSize = sizeof(uint32_t); + socket_->async_receive( + incomingBuffer_.asio_buffer(), + customAllocReadHandler( + boost::bind(&ClientConnection::handleRead, shared_from_this(), _1, _2, + minReadSize))); +} + +void ClientConnection::handleRead(const boost::system::error_code& err, size_t bytesTransferred, + uint32_t minReadSize) { + // Update buffer write idx with new data + incomingBuffer_.bytesWritten(bytesTransferred); + + if (err || bytesTransferred == 0) { + close(); + } else if (bytesTransferred < minReadSize) { + // Read the remaining part, use a slice of buffer to write on the next + // region + SharedBuffer buffer = incomingBuffer_.slice(bytesTransferred); + socket_->async_receive( + buffer.asio_buffer(), + customAllocReadHandler( + boost::bind(&ClientConnection::handleRead, shared_from_this(), _1, _2, + minReadSize - bytesTransferred))); + } else { + processIncomingBuffer(); + } +} + +void ClientConnection::processIncomingBuffer() { + // Process all the available frames from the incoming buffer + while (incomingBuffer_.readableBytes() >= sizeof(uint32_t)) { + + // Extract message frames from incoming buffer + // At this point we have at least 4 bytes in the buffer + uint32_t frameSize = incomingBuffer_.readUnsignedInt(); + + if (frameSize > incomingBuffer_.readableBytes()) { + // We don't have the entire frame yet + const uint32_t bytesToReceive = frameSize - incomingBuffer_.readableBytes(); + + // Rollback the reading of frameSize (when the frame will be complete, + // we'll read it again + incomingBuffer_.rollback(sizeof(uint32_t)); + + if (bytesToReceive <= incomingBuffer_.writableBytes()) { + // The rest of the frame still fits in the current buffer + socket_->async_receive( + incomingBuffer_.asio_buffer(), + customAllocReadHandler( + boost::bind(&ClientConnection::handleRead, shared_from_this(), _1, + _2, bytesToReceive))); + return; + } else { + // Need to allocate a buffer big enough for the frame + uint32_t newBufferSize = std::max(DefaultBufferSize, + frameSize + sizeof(uint32_t)); + incomingBuffer_ = SharedBuffer::copyFrom(incomingBuffer_, newBufferSize); + + socket_->async_receive( + incomingBuffer_.asio_buffer(), + customAllocReadHandler( + boost::bind(&ClientConnection::handleRead, shared_from_this(), _1, + _2, bytesToReceive))); + return; + } + } + + // At this point, we have at least one complete frame available in the buffer + uint32_t cmdSize = incomingBuffer_.readUnsignedInt(); + if (!incomingCmd_.ParseFromArray(incomingBuffer_.data(), cmdSize)) { + LOG_ERROR(cnxString_ << "Error parsing protocol buffer command"); + close(); + return; + } + + incomingBuffer_.consume(cmdSize); + + if (incomingCmd_.type() == BaseCommand::MESSAGE) { + // Parse message metadata and extract payload + MessageMetadata msgMetadata; + + //read checksum + bool isChecksumValid = verifyChecksum(incomingBuffer_, incomingCmd_); + + uint32_t metadataSize = incomingBuffer_.readUnsignedInt(); + if (!msgMetadata.ParseFromArray(incomingBuffer_.data(), metadataSize)) { + LOG_ERROR(cnxString_ << "[consumer id " << incomingCmd_.message().consumer_id() // + << ", message ledger id " << incomingCmd_.message().message_id().ledgerid() // + << ", entry id " << incomingCmd_.message().message_id().entryid() << "] Error parsing message metadata"); + close(); + return; + } + + incomingBuffer_.consume(metadataSize); + + uint32_t payloadSize = frameSize - (cmdSize + 4) - (metadataSize + 4); + SharedBuffer payload = SharedBuffer::copy(incomingBuffer_.data(), payloadSize); + incomingBuffer_.consume(payloadSize); + handleIncomingMessage(incomingCmd_.message(), isChecksumValid, msgMetadata, payload); + } else { + handleIncomingCommand(); + } + } + + if (incomingBuffer_.readableBytes() > 0) { + // We still have 1 to 3 bytes from the next frame + assert(incomingBuffer_.readableBytes() < sizeof(uint32_t)); + + // Restart with a new buffer and copy the the few bytes at the beginning + incomingBuffer_ = SharedBuffer::copyFrom(incomingBuffer_, DefaultBufferSize); + + // At least we need to read 4 bytes to have the complete frame size + uint32_t minReadSize = sizeof(uint32_t) - incomingBuffer_.readableBytes(); + + socket_->async_receive( + incomingBuffer_.asio_buffer(), + customAllocReadHandler( + boost::bind(&ClientConnection::handleRead, shared_from_this(), _1, _2, + minReadSize))); + return; + } + + // We have read everything we had in the buffer + // Rollback the indexes to reuse the same buffer + incomingBuffer_.reset(); + + readNextCommand(); +} + +bool ClientConnection::verifyChecksum(SharedBuffer& incomingBuffer_, proto::BaseCommand& incomingCmd_) { + int readerIndex = incomingBuffer_.readerIndex(); + bool isChecksumValid = true; + if (incomingBuffer_.readUnsignedShort() == Commands::magicCrc32c) { + uint32_t storedChecksum = incomingBuffer_.readUnsignedInt(); + // compute metadata-payload checksum + int metadataPayloadSize = incomingBuffer_.readableBytes(); + uint32_t computedChecksum = computeChecksum(0, incomingBuffer_.data(), metadataPayloadSize); + // verify checksum + isChecksumValid = (storedChecksum == computedChecksum); + + if (!isChecksumValid) { + LOG_ERROR("[consumer id " << incomingCmd_.message().consumer_id() // + << ", message ledger id " << incomingCmd_.message().message_id().ledgerid()// + << ", entry id " << incomingCmd_.message().message_id().entryid()// + << "stored-checksum" << storedChecksum << "computedChecksum" << computedChecksum// + << "] Checksum verification failed"); + } + } else { + incomingBuffer_.setReaderIndex(readerIndex); + } + return isChecksumValid; +} + +void ClientConnection::handleIncomingMessage(const proto::CommandMessage& msg, bool isChecksumValid, + proto::MessageMetadata& msgMetadata, + SharedBuffer& payload) { + LOG_DEBUG(cnxString_ << "Received a message from the server for consumer: " << msg.consumer_id()); + + Lock lock(mutex_); + ConsumersMap::iterator it = consumers_.find(msg.consumer_id()); + if (it != consumers_.end()) { + ConsumerImplPtr consumer = it->second.lock(); + + if (consumer) { + // Unlock the mutex before notifying the consumer of the + // new received message + lock.unlock(); + consumer->messageReceived(shared_from_this(), msg, isChecksumValid, msgMetadata, payload); + } else { + consumers_.erase(msg.consumer_id()); + LOG_DEBUG( + cnxString_ << "Ignoring incoming message for already destroyed consumer " << msg.consumer_id()); + } + } else { + LOG_DEBUG(cnxString_ << "Got invalid consumer Id in " // + << msg.consumer_id() << " -- msg: "<< msgMetadata.sequence_id()); + } +} + +void ClientConnection::handleIncomingCommand() { + LOG_DEBUG( + cnxString_ << "Handling incoming command: " << Commands::messageType(incomingCmd_.type())); + + switch (state_) { + case Pending: { + LOG_ERROR(cnxString_ << "Connection is not ready yet"); + break; + } + + case TcpConnected: { + // Handle Pulsar Connected + if (incomingCmd_.type() != BaseCommand::CONNECTED) { + // Wrong cmd + close(); + } else { + handlePulsarConnected(incomingCmd_.connected()); + } + break; + } + + case Disconnected: { + LOG_ERROR(cnxString_ << "Connection already disconnected"); + break; + } + + case Ready: { + // Handle normal commands + switch (incomingCmd_.type()) { + case BaseCommand::SEND_RECEIPT: { + const CommandSendReceipt& sendReceipt = incomingCmd_.send_receipt(); + int producerId = sendReceipt.producer_id(); + uint64_t sequenceId = sendReceipt.sequence_id(); + + LOG_DEBUG( + cnxString_ << "Got receipt for producer: " << producerId << " -- msg: "<< sequenceId); + + Lock lock(mutex_); + ProducersMap::iterator it = producers_.find(producerId); + if (it != producers_.end()) { + ProducerImplPtr producer = it->second.lock(); + lock.unlock(); + + if (producer) { + if (!producer->ackReceived(sequenceId)) { + // If the producer fails to process the ack, we need to close the connection to give it a chance to recover from there + close(); + } + } + } else { + LOG_ERROR(cnxString_ << "Got invalid producer Id in SendReceipt: " // + << producerId << " -- msg: "<< sequenceId); + } + + break; + } + + case BaseCommand::SEND_ERROR: { + const CommandSendError& error = incomingCmd_.send_error(); + LOG_WARN(cnxString_ << "Received send error from server: " << error.message()); + if (ChecksumError == error.error()) { + long producerId = error.producer_id(); + long sequenceId = error.sequence_id(); + Lock lock(mutex_); + ProducersMap::iterator it = producers_.find(producerId); + if (it != producers_.end()) { + ProducerImplPtr producer = it->second.lock(); + lock.unlock(); + + if (producer) { + if (!producer->removeCorruptMessage(sequenceId)) { + // If the producer fails to remove corrupt msg, we need to close the connection to give it a chance to recover from there + close(); + } + } + } + } else { + close(); + } + break; + } + + case BaseCommand::SUCCESS: { + const CommandSuccess& success = incomingCmd_.success(); + LOG_DEBUG( + cnxString_ << "Received success response from server. req_id: " << success.request_id()); + + Lock lock(mutex_); + PendingRequestsMap::iterator it = pendingRequests_.find(success.request_id()); + if (it != pendingRequests_.end()) { + PendingRequestData requestData = it->second; + pendingRequests_.erase(it); + lock.unlock(); + + requestData.promise.setValue(""); + requestData.timer->cancel(); + } + break; + } + + case BaseCommand::PARTITIONED_METADATA_RESPONSE: { + const CommandPartitionedTopicMetadataResponse& partitionMetadataResponse = + incomingCmd_.partitionmetadataresponse(); + LOG_DEBUG( + cnxString_ << "Received partition-metadata response from server. req_id: " << partitionMetadataResponse.request_id()); + + Lock lock(mutex_); + PendingLookupRequestsMap::iterator it = pendingLookupRequests_.find( + partitionMetadataResponse.request_id()); + if (it != pendingLookupRequests_.end()) { + LookupDataResultPromisePtr lookupDataPromise = it->second; + pendingLookupRequests_.erase(it); + lock.unlock(); + + if (!partitionMetadataResponse.has_response() + || (partitionMetadataResponse.response() + == CommandPartitionedTopicMetadataResponse::Failed)) { + if (partitionMetadataResponse.has_error()) { + LOG_ERROR( + cnxString_ << "Failed partition-metadata lookup req_id: " << partitionMetadataResponse.request_id() << " error: " << partitionMetadataResponse.error()); + } else { + LOG_ERROR( + cnxString_ << "Failed partition-metadata lookup req_id: " << partitionMetadataResponse.request_id() << " with empty response: "); + } + lookupDataPromise->setFailed(ResultConnectError); + } else { + LookupDataResultPtr lookupResultPtr = boost::make_shared< + LookupDataResult>(); + lookupResultPtr->setPartitions(partitionMetadataResponse.partitions()); + lookupDataPromise->setValue(lookupResultPtr); + } + + } else { + LOG_WARN( + "Received unknown request id from server: " << partitionMetadataResponse.request_id()); + } + break; + } + + case BaseCommand::LOOKUP_RESPONSE: { + const CommandLookupTopicResponse& lookupTopicResponse = incomingCmd_.lookuptopicresponse(); + LOG_DEBUG( + cnxString_ << "Received lookup response from server. req_id: " << lookupTopicResponse.request_id()); + + Lock lock(mutex_); + PendingLookupRequestsMap::iterator it = pendingLookupRequests_.find( + lookupTopicResponse.request_id()); + if (it != pendingLookupRequests_.end()) { + LookupDataResultPromisePtr lookupDataPromise = it->second; + pendingLookupRequests_.erase(it); + lock.unlock(); + + if (!lookupTopicResponse.has_response() + || (lookupTopicResponse.response() + == CommandLookupTopicResponse::Failed)) { + if (lookupTopicResponse.has_error()) { + LOG_ERROR( + cnxString_ << "Failed lookup req_id: " << lookupTopicResponse.request_id() << " error: " << lookupTopicResponse.error()); + } else { + LOG_ERROR( + cnxString_ << "Failed lookup req_id: " << lookupTopicResponse.request_id() << " with empty response: "); + } + lookupDataPromise -> setFailed(ResultConnectError); + } else { + LOG_DEBUG( + cnxString_ << "Received lookup response from server. req_id: " << lookupTopicResponse.request_id() // + << " -- broker-url: " << lookupTopicResponse.brokerserviceurl() << " -- broker-tls-url: "// + << lookupTopicResponse.brokerserviceurltls() << " authoritative: " << lookupTopicResponse.authoritative()// + << " redirect: " << lookupTopicResponse.response()); + LookupDataResultPtr lookupResultPtr = + boost::make_shared(); + lookupResultPtr->setBrokerUrl(lookupTopicResponse.brokerserviceurl()); + lookupResultPtr->setBrokerUrlSsl( + lookupTopicResponse.brokerserviceurltls()); + lookupResultPtr->setAuthoritative(lookupTopicResponse.authoritative()); + lookupResultPtr->setRedirect( + lookupTopicResponse.response() + == CommandLookupTopicResponse::Redirect); + lookupDataPromise->setValue(lookupResultPtr); + } + + } else { + LOG_WARN( + "Received unknown request id from server: " << lookupTopicResponse.request_id()); + } + break; + } + + + case BaseCommand::PRODUCER_SUCCESS: { + const CommandProducerSuccess& producerSuccess = incomingCmd_.producer_success(); + LOG_DEBUG( + cnxString_ << "Received success producer response from server. req_id: " << producerSuccess.request_id() // + << " -- producer name: " << producerSuccess.producer_name()); + + Lock lock(mutex_); + PendingRequestsMap::iterator it = pendingRequests_.find( + producerSuccess.request_id()); + if (it != pendingRequests_.end()) { + PendingRequestData requestData = it->second; + pendingRequests_.erase(it); + lock.unlock(); + + requestData.promise.setValue(producerSuccess.producer_name()); + requestData.timer->cancel(); + } + break; + } + + case BaseCommand::ERROR: { + const CommandError& error = incomingCmd_.error(); + Result result = getResult(error.error()); + LOG_WARN( + cnxString_ << "Received error response from server: " << result << " -- req_id: "<< error.request_id()); + + Lock lock(mutex_); + PendingRequestsMap::iterator it = pendingRequests_.find(error.request_id()); + if (it != pendingRequests_.end()) { + PendingRequestData requestData = it->second; + pendingRequests_.erase(it); + lock.unlock(); + + requestData.promise.setFailed(getResult(error.error())); + requestData.timer->cancel(); + } else { + lock.unlock(); + } + break; + } + + case BaseCommand::CLOSE_PRODUCER: { + const CommandCloseProducer& closeProducer = incomingCmd_.close_producer(); + int producerId = closeProducer.producer_id(); + + LOG_DEBUG("Broker notification of Closed producer: " << producerId); + + Lock lock(mutex_); + ProducersMap::iterator it = producers_.find(producerId); + if (it != producers_.end()) { + ProducerImplPtr producer = it->second.lock(); + lock.unlock(); + + if (producer) { + producer->disconnectProducer(); + } + } else { + LOG_ERROR( + cnxString_ << "Got invalid producer Id in closeProducer command: "<< producerId); + } + + break; + } + + case BaseCommand::CLOSE_CONSUMER: { + const CommandCloseConsumer& closeconsumer = incomingCmd_.close_consumer(); + int consumerId = closeconsumer.consumer_id(); + + LOG_DEBUG("Broker notification of Closed consumer: " << consumerId); + + Lock lock(mutex_); + ConsumersMap::iterator it = consumers_.find(consumerId); + if (it != consumers_.end()) { + ConsumerImplPtr consumer = it->second.lock(); + lock.unlock(); + + if (consumer) { + consumer->disconnectConsumer(); + } + } else { + LOG_ERROR( + cnxString_ << "Got invalid consumer Id in closeConsumer command: "<< consumerId); + } + + break; + } + + case BaseCommand::PING: { + // Respond to ping request + LOG_DEBUG(cnxString_ << "Replying to ping command"); + sendCommand(Commands::newPong()); + break; + } + + case BaseCommand::PONG: { + LOG_DEBUG(cnxString_ << "Received response to ping message"); + havePendingPingRequest_ = false; + break; + } + + default: { + LOG_WARN(cnxString_ << "Received invalid message from server"); + close(); + break; + } + } + } + } +} + +void ClientConnection::newTopicLookup(const std::string& destinationName, bool authoritative, + const uint64_t requestId, + LookupDataResultPromisePtr promise) { + newLookup(Commands::newLookup(outgoingCmd_, destinationName, authoritative, requestId), + requestId, promise); +} + +void ClientConnection::newPartitionedMetadataLookup(const std::string& destinationName, + const uint64_t requestId, + LookupDataResultPromisePtr promise) { + newLookup(Commands::newPartitionMetadataRequest(outgoingCmd_, destinationName, requestId), requestId, + promise); +} + +void ClientConnection::newLookup(const SharedBuffer& cmd, const uint64_t requestId, + LookupDataResultPromisePtr promise) { + Lock lock(mutex_); + boost::shared_ptr lookupDataResult; + lookupDataResult = boost::make_shared(); + if (isClosed()) { + lock.unlock(); + promise->setFailed(ResultNotConnected); + } + pendingLookupRequests_.insert(std::make_pair(requestId, promise)); + lock.unlock(); + sendCommand(cmd); +} + +void ClientConnection::sendCommand(const SharedBuffer& cmd) { + Lock lock(mutex_); + + if (pendingWriteOperations_++ == 0) { + + // Write immediately to socket + boost::asio::async_write( + *socket_, + cmd.const_asio_buffer(), + customAllocWriteHandler( + boost::bind(&ClientConnection::handleSend, shared_from_this(), _1, cmd))); + } else { + // Queue to send later + pendingWriteBuffers_.push_back(cmd); + } +} + +void ClientConnection::sendMessage(const OpSendMsg& opSend) { + Lock lock(mutex_); + + if (pendingWriteOperations_++ == 0) { + + PairSharedBuffer buffer = Commands::newSend(outgoingBuffer_, outgoingCmd_, + opSend.producerId_, opSend.sequenceId_, + getChecksumType(), opSend.msg_); + + // Write immediately to socket + boost::asio::async_write( + *socket_, + buffer, + customAllocWriteHandler( + boost::bind(&ClientConnection::handleSendPair, shared_from_this(), _1))); + } else { + // Queue to send later + pendingWriteBuffers_.push_back(opSend); + } +} + +void ClientConnection::handleSend(const boost::system::error_code& err, const SharedBuffer&) { + if (err) { + LOG_WARN(cnxString_ << "Could not send message on connection: " << err << " " << err.message()); + close(); + } else { + sendPendingCommands(); + } +} + +void ClientConnection::handleSendPair(const boost::system::error_code& err) { + if (err) { + LOG_WARN(cnxString_ << "Could not send pair message on connection: " << err << " " << err.message()); + close(); + } else { + sendPendingCommands(); + } +} + +void ClientConnection::sendPendingCommands() { + Lock lock(mutex_); + + if (--pendingWriteOperations_ > 0) { + assert(!pendingWriteBuffers_.empty()); + boost::any any = pendingWriteBuffers_.front(); + pendingWriteBuffers_.pop_front(); + + if (any.type() == typeid(SharedBuffer)) { + SharedBuffer buffer = boost::any_cast(any); + boost::asio::async_write( + *socket_, + buffer.const_asio_buffer(), + customAllocWriteHandler( + boost::bind(&ClientConnection::handleSend, shared_from_this(), _1, + buffer))); + } else { + assert(any.type() == typeid(OpSendMsg)); + + const OpSendMsg& op = boost::any_cast(any); + PairSharedBuffer buffer = Commands::newSend(outgoingBuffer_, outgoingCmd_, + op.producerId_, op.sequenceId_, + getChecksumType(), op.msg_); + + boost::asio::async_write( + *socket_, + buffer, + customAllocWriteHandler( + boost::bind(&ClientConnection::handleSendPair, shared_from_this(), + _1))); + } + } else { + // No more pending writes + outgoingBuffer_.reset(); + } +} + +Future ClientConnection::sendRequestWithId(SharedBuffer cmd, int requestId) { + Lock lock(mutex_); + + if (isClosed()) { + lock.unlock(); + Promise promise; + promise.setFailed(ResultNotConnected); + return promise.getFuture(); + } + + PendingRequestData requestData; + requestData.timer = executor_->createDeadlineTimer(); + requestData.timer->expires_from_now(operationsTimeout_); + requestData.timer->async_wait( + boost::bind(&ClientConnection::handleRequestTimeout, shared_from_this(), _1, + requestData)); + + pendingRequests_.insert(std::make_pair(requestId, requestData)); + lock.unlock(); + + sendCommand(cmd); + return requestData.promise.getFuture(); +} + +void ClientConnection::handleRequestTimeout(const boost::system::error_code& ec, + PendingRequestData pendingRequestData) { + if (!ec) { + pendingRequestData.promise.setFailed(ResultTimeout); + } +} + +void ClientConnection::handleKeepAliveTimeout() { + if (isClosed()) { + return; + } + + if (havePendingPingRequest_) { + LOG_WARN(cnxString_ << "Forcing connection to close after keep-alive timeout"); + close(); + } else { + // Send keep alive probe to peer + LOG_DEBUG(cnxString_ << "Sending ping message"); + havePendingPingRequest_ = true; + sendCommand(Commands::newPing()); + + keepAliveTimer_->expires_from_now(boost::posix_time::seconds(KeepAliveIntervalInSeconds)); + keepAliveTimer_->async_wait( + boost::bind(&ClientConnection::handleKeepAliveTimeout, shared_from_this())); + } +} + +void ClientConnection::close() { + Lock lock(mutex_); + state_ = Disconnected; + boost::system::error_code err; + socket_->close(err); + lock.unlock(); + + LOG_INFO(cnxString_ << "Connection closed"); + + if (keepAliveTimer_) { + keepAliveTimer_->cancel(); + } + + for (ProducersMap::iterator it = producers_.begin(); it != producers_.end(); ++it ) { + HandlerBase::handleDisconnection(ResultConnectError, shared_from_this(), it->second); + } + + for (ConsumersMap::iterator it = consumers_.begin(); it != consumers_.end(); ++it ) { + HandlerBase::handleDisconnection(ResultConnectError, shared_from_this(), it->second); + } + + connectPromise_.setFailed(ResultConnectError); + + // Fail all pending operations on the connection + for (PendingRequestsMap::iterator it = pendingRequests_.begin(); it != pendingRequests_.end(); ++it) { + it->second.promise.setFailed(ResultConnectError); + } + + // Fail all pending lookup-requests on the connection + for (PendingLookupRequestsMap::iterator it = pendingLookupRequests_.begin(); it != pendingLookupRequests_.end(); ++it) { + it->second->setFailed(ResultConnectError); + } +} + +bool ClientConnection::isClosed() const { + return state_ == Disconnected; +} + +Future ClientConnection::getConnectFuture() { + return connectPromise_.getFuture(); +} + +void ClientConnection::registerProducer(int producerId, ProducerImplPtr producer) { + Lock lock(mutex_); + producers_.insert(std::make_pair(producerId, producer)); +} + +void ClientConnection::registerConsumer(int consumerId, ConsumerImplPtr consumer) { + Lock lock(mutex_); + consumers_.insert(std::make_pair(consumerId, consumer)); +} + +void ClientConnection::removeProducer(int producerId) { + Lock lock(mutex_); + producers_.erase(producerId); +} + +void ClientConnection::removeConsumer(int consumerId) { + Lock lock(mutex_); + consumers_.erase(consumerId); +} + +const std::string& ClientConnection::brokerAddress() const { + return address_; +} + +const std::string& ClientConnection::cnxString() const { + return cnxString_; +} + +int ClientConnection::getServerProtocolVersion() const { + return serverProtocolVersion_; +} + +Commands::ChecksumType ClientConnection::getChecksumType() const { + return getServerProtocolVersion() >= proto::v6 ? + Commands::Crc32c : Commands::None; +} + +} diff --git a/pulsar-client-cpp/lib/ClientConnection.h b/pulsar-client-cpp/lib/ClientConnection.h new file mode 100644 index 0000000000000..593c47787027c --- /dev/null +++ b/pulsar-client-cpp/lib/ClientConnection.h @@ -0,0 +1,252 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef _PULSAR_CLIENT_CONNECTION_HEADER_ +#define _PULSAR_CLIENT_CONNECTION_HEADER_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ExecutorService.h" +#include "Future.h" +#include "PulsarApi.pb.h" +#include +#include "SharedBuffer.h" +#include "Backoff.h" +#include "Commands.h" +#include "LookupDataResult.h" +#include "UtilAllocator.h" +#include + +using namespace pulsar; + +namespace pulsar { + +class PulsarFriend; + +class ExecutorService; + +class ClientConnection; +typedef boost::shared_ptr ClientConnectionPtr; +typedef boost::weak_ptr ClientConnectionWeakPtr; + +class ProducerImpl; +typedef boost::shared_ptr ProducerImplPtr; +typedef boost::weak_ptr ProducerImplWeakPtr; + +class ConsumerImpl; +typedef boost::shared_ptr ConsumerImplPtr; +typedef boost::weak_ptr ConsumerImplWeakPtr; + +class LookupDataResult; + +struct OpSendMsg; + +class ClientConnection : public boost::enable_shared_from_this { + enum State { + Pending, + TcpConnected, + Ready, + Disconnected + }; + + public: + typedef boost::shared_ptr SocketPtr; + typedef boost::shared_ptr ConnectionPtr; + typedef boost::function ConnectionListener; + typedef std::vector::iterator ListenerIterator; + + /* + * endpoint - url of the service, for ex. pulsar://bm92.corp.yahoo.com:8880 + * connected - set when tcp connection is established + * + */ + ClientConnection(const std::string& endpoint, ExecutorServicePtr executor, + const ClientConfiguration& clientConfiguration, const AuthenticationPtr& authentication); + ~ClientConnection(); + + /* + * starts tcp connect_async + * @return future which is not yet set + */ + void tcpConnectAsync(); + + void close(); + + bool isClosed() const; + + Future getConnectFuture(); + + Future getCloseFuture(); + + void newTopicLookup(const std::string& destinationName, bool authoritative, const uint64_t requestId, + LookupDataResultPromisePtr promise); + + void newPartitionedMetadataLookup(const std::string& destinationName, const uint64_t requestId, + LookupDataResultPromisePtr promise); + + void sendCommand(const SharedBuffer& cmd); + void sendMessage(const OpSendMsg& opSend); + + void registerProducer(int producerId, ProducerImplPtr producer); + void registerConsumer(int consumerId, ConsumerImplPtr consumer); + + void removeProducer(int producerId); + void removeConsumer(int consumerId); + + /** + * Send a request with a specific Id over the connection. The future will be + * triggered when the response for this request is received + */ + Future sendRequestWithId(SharedBuffer cmd, int requestId); + + const std::string& brokerAddress() const; + + const std::string& cnxString() const; + + int getServerProtocolVersion() const; + + Commands::ChecksumType getChecksumType() const; + + private: + + struct PendingRequestData { + Promise promise; + DeadlineTimerPtr timer; + }; + + /* + * handler for connectAsync + * creates a ConnectionPtr which has a valid ClientConnection object + * although not usable at this point, since this is just tcp connection + * Pulsar - Connect/Connected has yet to happen + */ + void handleTcpConnected(const boost::system::error_code& err, + boost::asio::ip::tcp::resolver::iterator endpointIterator); + + void handleSentPulsarConnect(const boost::system::error_code& err, const SharedBuffer& buffer); + + void readNextCommand(); + + void handleRead(const boost::system::error_code& err, size_t bytesTransferred, uint32_t minReadSize); + + void processIncomingBuffer(); + bool verifyChecksum(SharedBuffer& incomingBuffer_, proto::BaseCommand& incomingCmd_); + + void handleIncomingCommand(); + void handleIncomingMessage(const proto::CommandMessage& msg, bool isChecksumValid, + proto::MessageMetadata& msgMetadata, SharedBuffer& payload); + + void handlePulsarConnected(const proto::CommandConnected& cmdConnected); + + void handleResolve(const boost::system::error_code& err, + boost::asio::ip::tcp::resolver::iterator endpointIterator); + + void handleSend(const boost::system::error_code& err, const SharedBuffer& cmd); + void handleSendPair(const boost::system::error_code& err); + void sendPendingCommands(); + void newLookup(const SharedBuffer& cmd, const uint64_t requestId, + LookupDataResultPromisePtr promise); + + + void handleRequestTimeout(const boost::system::error_code& ec, PendingRequestData pendingRequestData); + + void handleKeepAliveTimeout(); + + template + inline AllocHandler customAllocReadHandler(Handler h) { + return AllocHandler(readHandlerAllocator_, h); + } + + template + inline AllocHandler customAllocWriteHandler(Handler h) { + return AllocHandler(writeHandlerAllocator_, h); + } + + State state_; + TimeDuration operationsTimeout_; + AuthenticationPtr authentication_; + int serverProtocolVersion_; + + ExecutorServicePtr executor_; + + TcpResolverPtr resolver_; + + /* + * tcp connection socket to the pulsar broker + */ + SocketPtr socket_; + /* + * stores address of the service, for ex. pulsar://pulsar.corp.yahoo.com:8880 + */ + const std::string address_; + + // Represent both endpoint of the tcp connection. eg: [client:1234 -> server:6650] + std::string cnxString_; + + /* + * indicates if async connection establishment failed + */ + boost::system::error_code error_; + + SharedBuffer incomingBuffer_; + proto::BaseCommand incomingCmd_; + + Promise connectPromise_; + + typedef std::map PendingRequestsMap; + PendingRequestsMap pendingRequests_; + + typedef std::map PendingLookupRequestsMap; + PendingLookupRequestsMap pendingLookupRequests_; + + typedef std::map ProducersMap; + ProducersMap producers_; + + typedef std::map ConsumersMap; + ConsumersMap consumers_; + + boost::mutex mutex_; + typedef boost::unique_lock Lock; + + // Pending buffers to write on the socket + std::deque pendingWriteBuffers_; + int pendingWriteOperations_; + + SharedBuffer outgoingBuffer_; + proto::BaseCommand outgoingCmd_; + + HandlerAllocator readHandlerAllocator_; + HandlerAllocator writeHandlerAllocator_; + + // Signals whether we're waiting for a response from broker + bool havePendingPingRequest_; + DeadlineTimerPtr keepAliveTimer_; + + friend class PulsarFriend; +}; + +} + +#endif//_PULSAR_CLIENT_CONNECTION_HEADER_ diff --git a/pulsar-client-cpp/lib/ClientImpl.cc b/pulsar-client-cpp/lib/ClientImpl.cc new file mode 100644 index 0000000000000..ebd7cba2312fc --- /dev/null +++ b/pulsar-client-cpp/lib/ClientImpl.cc @@ -0,0 +1,358 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "ClientImpl.h" + +#include "LogUtils.h" +#include "ConsumerImpl.h" +#include "ProducerImpl.h" +#include "DestinationName.h" +#include "PartitionedProducerImpl.h" +#include "PartitionedConsumerImpl.h" +#include +#include +#include +#include +#include "boost/date_time/posix_time/posix_time.hpp" + +DECLARE_LOG_OBJECT() + +namespace pulsar { + + static const char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + + const std::string generateRandomName() { + unsigned char hash[SHA_DIGEST_LENGTH]; // == 20; + boost::posix_time::ptime t(boost::posix_time::microsec_clock::universal_time()); + long nanoSeconds = t.time_of_day().total_nanoseconds(); + std::stringstream ss; + ss << nanoSeconds; + SHA1(reinterpret_cast(ss.str().c_str()), ss.str().length(), hash); + + const int nameLength = 6; + std::stringstream hexHash; + for (int i = 0; i < nameLength / 2; i++) { + hexHash << hexDigits[(hash[i] & 0xF0) >> 4]; + hexHash << hexDigits[hash[i] & 0x0F]; + } + + return hexHash.str(); + } + typedef boost::unique_lock Lock; + + ClientImpl::ClientImpl(const std::string& serviceUrl, + const ClientConfiguration& clientConfiguration, bool poolConnections) + : mutex_(), + state_(Open), + serviceUrl_(serviceUrl), + clientConfiguration_(clientConfiguration), + ioExecutorProvider_(boost::make_shared(clientConfiguration.getIOThreads())), + listenerExecutorProvider_(boost::make_shared(clientConfiguration.getMessageListenerThreads())), + partitionListenerExecutorProvider_(boost::make_shared(clientConfiguration.getMessageListenerThreads())), + pool_(clientConfiguration, ioExecutorProvider_, clientConfiguration.getAuthenticationPtr(), poolConnections), + lookup_(pool_, serviceUrl), + producerIdGenerator_(0), + consumerIdGenerator_(0), + requestIdGenerator_(0) { + LogUtils::init(clientConfiguration.getLogConfFilePath()); + } + + ClientImpl::~ClientImpl() { + shutdown(); + } + + const ClientConfiguration& ClientImpl::conf() const { + return clientConfiguration_; + } + + ExecutorServiceProviderPtr ClientImpl::getIOExecutorProvider() { + return ioExecutorProvider_; + } + + ExecutorServiceProviderPtr ClientImpl::getListenerExecutorProvider() { + return listenerExecutorProvider_; + } + + ExecutorServiceProviderPtr ClientImpl::getPartitionListenerExecutorProvider() { + return partitionListenerExecutorProvider_; + } + void ClientImpl::createProducerAsync(const std::string& topic, + ProducerConfiguration conf, + CreateProducerCallback callback) { + DestinationNamePtr dn; + { + Lock lock(mutex_); + if (state_ != Open) { + lock.unlock(); + callback(ResultAlreadyClosed, Producer()); + return; + } else if (!(dn = DestinationName::get(topic))) { + lock.unlock(); + callback(ResultInvalidTopicName, Producer()); + return; + } + } + lookup_.getPartitionMetadataAsync(dn).addListener(boost::bind(&ClientImpl::handleCreateProducer, + shared_from_this(), _1, _2, dn, conf, callback)); + } + + void ClientImpl::handleCreateProducer(const Result result, + const LookupDataResultPtr partitionMetadata, + DestinationNamePtr dn, + ProducerConfiguration conf, + CreateProducerCallback callback) { + if (!result) { + ProducerImplBasePtr producer; + if (partitionMetadata->getPartitions() > 1) { + producer = boost::make_shared(shared_from_this(), + dn, partitionMetadata->getPartitions(), conf); + } else { + producer = boost::make_shared(shared_from_this(), dn->toString(), conf); + } + producer->getProducerCreatedFuture().addListener(boost::bind(&ClientImpl::handleProducerCreated, + shared_from_this(), _1, _2, callback, + producer)); + Lock lock(mutex_); + producers_.push_back(producer); + lock.unlock(); + producer->start(); + } else { + LOG_ERROR("Error Checking/Getting Partition Metadata while creating producer on " << dn->toString() << " -- " << result ); + callback (result, Producer()); + } + + } + + void ClientImpl::handleProducerCreated(Result result, ProducerImplBaseWeakPtr producerBaseWeakPtr, + CreateProducerCallback callback, ProducerImplBasePtr producer) { + callback(result, Producer(producer)); + } + + void ClientImpl::subscribeAsync(const std::string& topic, const std::string& consumerName, + const ConsumerConfiguration& conf, SubscribeCallback callback) { + DestinationNamePtr dn; + { + Lock lock(mutex_); + if (state_ != Open) { + lock.unlock(); + callback(ResultAlreadyClosed, Consumer()); + return; + } else if (!(dn = DestinationName::get(topic))) { + lock.unlock(); + callback(ResultInvalidTopicName, Consumer()); + return; + } + } + + lookup_.getPartitionMetadataAsync(dn).addListener(boost::bind(&ClientImpl::handleSubscribe, + shared_from_this(), _1, _2, dn, consumerName, conf, callback)); + } + + void ClientImpl::handleSubscribe(const Result result, + const LookupDataResultPtr partitionMetadata, + DestinationNamePtr dn, + const std::string& consumerName, + ConsumerConfiguration conf, + SubscribeCallback callback) { + if (!result) { + // generate random name if not supplied by the customer. + if(conf.getConsumerName().empty()) { + conf.setConsumerName(generateRandomName()); + } + ConsumerImplBasePtr consumer; + if (partitionMetadata->getPartitions() > 1) { + if (conf.getReceiverQueueSize() == 0) { + LOG_ERROR("Can't use partitioned topic if the queue size is 0."); + callback (ResultInvalidConfiguration, Consumer()); + return; + } + consumer = boost::make_shared(shared_from_this(), + consumerName, + dn, + partitionMetadata->getPartitions(), + conf); + } else { + consumer = boost::make_shared(shared_from_this(), dn->toString(), + consumerName, conf); + } + consumer->getConsumerCreatedFuture().addListener(boost::bind(&ClientImpl::handleConsumerCreated, + shared_from_this(), _1, _2, callback, + consumer)); + Lock lock(mutex_); + consumers_.push_back(consumer); + lock.unlock(); + consumer->start(); + } else { + LOG_ERROR("Error Checking/Getting Partition Metadata while Subscribing- " << result ); + callback (result, Consumer()); + } + + } + + void ClientImpl::handleConsumerCreated(Result result, + ConsumerImplBaseWeakPtr consumerImplBaseWeakPtr, + SubscribeCallback callback, + ConsumerImplBasePtr consumer) { + callback(result, Consumer(consumer)); + } + + Future ClientImpl::getConnection(const std::string& topic) { + Promise promise; + lookup_.lookupAsync(topic).addListener(boost::bind(&ClientImpl::handleLookup, this, _1, _2, promise)); + return promise.getFuture(); + } + + void ClientImpl::handleLookup(Result result, LookupDataResultPtr data, + Promise promise) { + if (data) { + LOG_DEBUG("Getting connection to broker: " << data->getBrokerUrl()); + Future future = pool_.getConnectionAsync( + data->getBrokerUrl()); + future.addListener(boost::bind(&ClientImpl::handleNewConnection, this, _1, _2, promise)); + } else { + promise.setFailed(result); + } + } + + void ClientImpl::handleNewConnection(Result result, const ClientConnectionWeakPtr& conn, + Promise promise) { + if (result == ResultOk) { + promise.setValue(conn); + } else { + promise.setFailed(ResultConnectError); + } + } + + void ClientImpl::closeAsync(CloseCallback callback) { + Lock lock(mutex_); + ProducersList producers(producers_); + ConsumersList consumers(consumers_); + + if (state_ != Open && callback) { + lock.unlock(); + callback(ResultAlreadyClosed); + return; + } + // Set the state to Closing so that no producers could get added + state_ = Closing; + lock.unlock(); + + LOG_DEBUG("Closing Pulsar client"); + SharedInt numberOfOpenHandlers = boost::make_shared(producers.size() + consumers.size()); + + for (ProducersList::iterator it = producers.begin(); it != producers.end(); ++it) { + ProducerImplBasePtr producer = it->lock(); + if (producer && !producer->isClosed()) { + producer->closeAsync( + boost::bind(&ClientImpl::handleClose, shared_from_this(), _1, numberOfOpenHandlers, + callback)); + } else { + // Since the connection is already closed + (*numberOfOpenHandlers)--; + } + } + + for (ConsumersList::iterator it = consumers.begin(); it != consumers.end(); ++it) { + ConsumerImplBasePtr consumer = it->lock(); + if (consumer && !consumer->isClosed()) { + consumer->closeAsync( + boost::bind(&ClientImpl::handleClose, shared_from_this(), _1, numberOfOpenHandlers, + callback)); + } else { + // Since the connection is already closed + (*numberOfOpenHandlers)--; + } + } + + if (*numberOfOpenHandlers == 0 && callback) { + callback(ResultOk); + } + } + + void ClientImpl::handleClose(Result result, SharedInt numberOfOpenHandlers, ResultCallback callback) { + static bool errorClosing = false; + static Result failResult = ResultOk; + if (result != ResultOk) { + errorClosing = true; + failResult = result; + } + if(*numberOfOpenHandlers > 0) { + --(*numberOfOpenHandlers); + } + if (*numberOfOpenHandlers == 0) { + + Lock lock(mutex_); + state_ = Closed; + lock.unlock(); + if (errorClosing) { + LOG_DEBUG("Problem in closing client, could not close one or more consumers or producers"); + if (callback) { + callback(failResult); + } + } + + LOG_DEBUG("Shutting down producers and consumers for client"); + shutdown(); + if (callback) { + callback(ResultOk); + } + } + } + + void ClientImpl::shutdown() { + Lock lock(mutex_); + ProducersList producers; + ConsumersList consumers; + + producers.swap(producers_); + consumers.swap(consumers_); + lock.unlock(); + + for (ProducersList::iterator it = producers.begin(); it != producers.end(); ++it) { + ProducerImplBasePtr producer = it->lock(); + if (producer) { + producer->shutdown(); + } + } + + for (ConsumersList::iterator it = consumers.begin(); it != consumers.end(); ++it) { + ConsumerImplBasePtr consumer = it->lock(); + if (consumer) { + consumer->shutdown(); + } + } + + ioExecutorProvider_->close(); + listenerExecutorProvider_->close(); + partitionListenerExecutorProvider_->close(); + } + + uint64_t ClientImpl::newProducerId() { + Lock lock(mutex_); + return producerIdGenerator_++; + } + + uint64_t ClientImpl::newConsumerId() { + Lock lock(mutex_); + return consumerIdGenerator_++; + } + + uint64_t ClientImpl::newRequestId() { + Lock lock(mutex_); + return requestIdGenerator_++; + } + +} /* namespace pulsar */ diff --git a/pulsar-client-cpp/lib/ClientImpl.h b/pulsar-client-cpp/lib/ClientImpl.h new file mode 100644 index 0000000000000..1eb5ffdd19393 --- /dev/null +++ b/pulsar-client-cpp/lib/ClientImpl.h @@ -0,0 +1,131 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_CLIENTIMPL_H_ +#define LIB_CLIENTIMPL_H_ + +#include +#include "ExecutorService.h" +#include "BinaryProtoLookupService.h" +#include "ConnectionPool.h" +#include "LookupDataResult.h" +#include "DestinationName.h" +#include +#include +#include "ProducerImplBase.h" +#include "ConsumerImplBase.h" + +#include + +namespace pulsar { + +class ClientImpl; +class PulsarFriend; +typedef boost::shared_ptr ClientImplPtr; +typedef boost::weak_ptr ClientImplWeakPtr; + +class ClientImpl : public boost::enable_shared_from_this { + public: + ClientImpl(const std::string& serviceUrl, const ClientConfiguration& clientConfiguration, + bool poolConnections); + ~ClientImpl(); + + void createProducerAsync(const std::string& topic, ProducerConfiguration conf, + CreateProducerCallback callback); + + void subscribeAsync(const std::string& topic, const std::string& consumerName, + const ConsumerConfiguration& conf, SubscribeCallback callback); + + Future getConnection(const std::string& topic); + void handleLookup(Result result, LookupDataResultPtr data, + Promise promise); + void handleNewConnection(Result result, const ClientConnectionWeakPtr& conn, + Promise promise); + + void closeAsync(CloseCallback callback); + void shutdown(); + + uint64_t newProducerId(); + uint64_t newConsumerId(); + uint64_t newRequestId(); + + const ClientConfiguration& conf() const; + ExecutorServiceProviderPtr getIOExecutorProvider(); + ExecutorServiceProviderPtr getListenerExecutorProvider(); + ExecutorServiceProviderPtr getPartitionListenerExecutorProvider(); + friend class PulsarFriend; + + private: + + void handleCreateProducer(const Result result, + const LookupDataResultPtr partitionMetadata, + DestinationNamePtr dn, + ProducerConfiguration conf, + CreateProducerCallback callback); + + void handleSubscribe(const Result result, + const LookupDataResultPtr partitionMetadata, + DestinationNamePtr dn, + const std::string& consumerName, + ConsumerConfiguration conf, + SubscribeCallback callback); + + void handleProducerCreated(Result result, ProducerImplBaseWeakPtr producerWeakPtr, + CreateProducerCallback callback, ProducerImplBasePtr producer); + void handleConsumerCreated(Result result, ConsumerImplBaseWeakPtr consumerWeakPtr, + SubscribeCallback callback, ConsumerImplBasePtr consumer); + + typedef boost::shared_ptr SharedInt; + + void handleClose(Result result, SharedInt remaining, ResultCallback callback); + + enum State { + Open, + Closing, + Closed + }; + + boost::mutex mutex_; + + State state_; + std::string serviceUrl_; + ClientConfiguration clientConfiguration_; + + ExecutorServiceProviderPtr ioExecutorProvider_; + ExecutorServiceProviderPtr listenerExecutorProvider_; + ExecutorServiceProviderPtr partitionListenerExecutorProvider_; + + BinaryProtoLookupService lookup_; + ConnectionPool pool_; + + uint64_t producerIdGenerator_; + uint64_t consumerIdGenerator_; + uint64_t requestIdGenerator_; + + typedef std::vector ProducersList; + ProducersList producers_; + + typedef std::vector ConsumersList; + ConsumersList consumers_; + + friend class Client; +}; + +typedef boost::shared_ptr ClientImplPtr; + +} /* namespace pulsar */ + +#endif /* LIB_CLIENTIMPL_H_ */ diff --git a/pulsar-client-cpp/lib/Commands.cc b/pulsar-client-cpp/lib/Commands.cc new file mode 100644 index 0000000000000..26ee67f62ba66 --- /dev/null +++ b/pulsar-client-cpp/lib/Commands.cc @@ -0,0 +1,401 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "Commands.h" +#include "MessageImpl.h" +#include "Version.h" +#include "pulsar/MessageBuilder.h" +#include "LogUtils.h" +#include "checksum/ChecksumProvider.h" +#include +namespace pulsar { + +using namespace pulsar::proto; + +DECLARE_LOG_OBJECT(); + +SharedBuffer Commands::writeMessageWithSize(const BaseCommand& cmd) { + size_t cmdSize = cmd.ByteSize(); + size_t frameSize = 4 + cmdSize; + size_t bufferSize = 4 + frameSize; + + SharedBuffer buffer = SharedBuffer::allocate(bufferSize); + + buffer.writeUnsignedInt(frameSize); + buffer.writeUnsignedInt(cmdSize); + cmd.SerializeToArray(buffer.mutableData(), cmdSize); + buffer.bytesWritten(cmdSize); + return buffer; +} + +SharedBuffer Commands::newPartitionMetadataRequest(BaseCommand& cmd, const std::string& topic, uint64_t requestId) { + cmd.set_type(BaseCommand::PARTITIONED_METADATA); + CommandPartitionedTopicMetadata* partitionMetadata = cmd.mutable_partitionmetadata(); + partitionMetadata->set_topic(topic); + partitionMetadata->set_request_id(requestId); + return writeMessageWithSize(cmd); +} + +SharedBuffer Commands::newLookup(BaseCommand& cmd, const std::string& topic, const bool authoritative, + uint64_t requestId) { + cmd.set_type(BaseCommand::LOOKUP); + CommandLookupTopic* lookup = cmd.mutable_lookuptopic(); + lookup->set_topic(topic); + lookup->set_authoritative(authoritative); + lookup->set_request_id(requestId); + return writeMessageWithSize(cmd); +} + +PairSharedBuffer Commands::newSend(SharedBuffer& headers, BaseCommand& cmd, + uint64_t producerId, uint64_t sequenceId, ChecksumType checksumType, const Message& msg) { + const proto::MessageMetadata& metadata = msg.impl_->metadata; + SharedBuffer& payload = msg.impl_->payload; + + cmd.set_type(BaseCommand::SEND); + CommandSend* send = cmd.mutable_send(); + send->set_producer_id(producerId); + send->set_sequence_id(sequenceId); + + // / Wire format + // [TOTAL_SIZE] [CMD_SIZE][CMD] [MAGIC_NUMBER][CHECKSUM] [METADATA_SIZE][METADATA] [PAYLOAD] + + int cmdSize = cmd.ByteSize(); + int msgMetadataSize = metadata.ByteSize(); + int payloadSize = payload.readableBytes(); + + int magicAndChecksumLength = + (Crc32c == (checksumType)) ? (2 + 4 /* magic + checksumLength*/) : 0; + bool includeChecksum = magicAndChecksumLength > 0; + int headerContentSize = 4 + cmdSize + magicAndChecksumLength + 4 + msgMetadataSize; // cmdLength + cmdSize + magicLength + + // checksumSize + msgMetadataLength + msgMetadataSize + int totalSize = headerContentSize + payloadSize; + int headersSize = 4 + headerContentSize; // totalSize + headerLength + int checksumReaderIndex = -1; + + headers.reset(); + assert(headers.writableBytes() >= headersSize); + headers.writeUnsignedInt(totalSize); // External frame + + // Write cmd + headers.writeUnsignedInt(cmdSize); + cmd.SerializeToArray(headers.mutableData(), cmdSize); + headers.bytesWritten(cmdSize); + + // Create checksum placeholder + if (includeChecksum) { + headers.writeUnsignedShort(magicCrc32c); + checksumReaderIndex = headers.writerIndex(); + headers.skipBytes(checksumSize); //skip 4 bytes of checksum + } + + // Write metadata + headers.writeUnsignedInt(msgMetadataSize); + metadata.SerializeToArray(headers.mutableData(), msgMetadataSize); + headers.bytesWritten(msgMetadataSize); + + PairSharedBuffer composite; + composite.set(0, headers); + composite.set(1, payload); + + // Write checksum at created checksum-placeholder + if (includeChecksum) { + int writeIndex = headers.writerIndex(); + int metadataStartIndex = checksumReaderIndex + checksumSize; + uint32_t metadataChecksum = computeChecksum( + 0, headers.data() + metadataStartIndex, (writeIndex - metadataStartIndex)); + uint32_t computedChecksum = computeChecksum(metadataChecksum, payload.data(), + payload.writerIndex()); + // set computed checksum + headers.setWriterIndex(checksumReaderIndex); + headers.writeUnsignedInt(computedChecksum); + headers.setWriterIndex(writeIndex); + } + + return composite; +} + +SharedBuffer Commands::newConnect(const AuthenticationPtr& authentication) { + BaseCommand cmd; + cmd.set_type(BaseCommand::CONNECT); + CommandConnect* connect = cmd.mutable_connect(); + connect->set_client_version(_PULSAR_VERSION_); + connect->set_auth_method_name(authentication->getAuthMethodName()); + connect->set_protocol_version(ProtocolVersion_MAX); + std::string authDataContent; + if (authentication->getAuthData(authDataContent) == ResultOk) { + connect->set_auth_data(authDataContent); + } + return writeMessageWithSize(cmd); +} + +SharedBuffer Commands::newSubscribe(const std::string& topic, const std::string&subscription, + uint64_t consumerId, uint64_t requestId, + CommandSubscribe_SubType subType, const std::string& consumerName) { + BaseCommand cmd; + cmd.set_type(BaseCommand::SUBSCRIBE); + CommandSubscribe* subscribe = cmd.mutable_subscribe(); + subscribe->set_topic(topic); + subscribe->set_subscription(subscription); + subscribe->set_subtype(subType); + subscribe->set_consumer_id(consumerId); + subscribe->set_request_id(requestId); + subscribe->set_consumer_name(consumerName); + + return writeMessageWithSize(cmd); +} + +SharedBuffer Commands::newUnsubscribe(uint64_t consumerId, uint64_t requestId) { + BaseCommand cmd; + cmd.set_type(BaseCommand::UNSUBSCRIBE); + CommandUnsubscribe* unsubscribe = cmd.mutable_unsubscribe(); + unsubscribe->set_consumer_id(consumerId); + unsubscribe->set_request_id(requestId); + + return writeMessageWithSize(cmd); +} + +SharedBuffer Commands::newProducer(const std::string& topic, uint64_t producerId, + const std::string& producerName, uint64_t requestId) { + BaseCommand cmd; + cmd.set_type(BaseCommand::PRODUCER); + CommandProducer* producer = cmd.mutable_producer(); + producer->set_topic(topic); + producer->set_producer_id(producerId); + producer->set_request_id(requestId); + + if (!producerName.empty()) { + producer->set_producer_name(producerName); + } + + return writeMessageWithSize(cmd); +} + +SharedBuffer Commands::newAck(uint64_t consumerId, const MessageIdData& messageId, + CommandAck_AckType ackType, + int validationError) { + BaseCommand cmd; + cmd.set_type(BaseCommand::ACK); + CommandAck* ack = cmd.mutable_ack(); + ack->set_consumer_id(consumerId); + ack->set_ack_type(ackType); + if (CommandAck_AckType_IsValid(validationError)) { + ack->set_validation_error((CommandAck_ValidationError) validationError); + } + *(ack->mutable_message_id()) = messageId; + return writeMessageWithSize(cmd); +} + +SharedBuffer Commands::newFlow(uint64_t consumerId, uint32_t messagePermits) { + BaseCommand cmd; + cmd.set_type(BaseCommand::FLOW); + CommandFlow* flow = cmd.mutable_flow(); + flow->set_consumer_id(consumerId); + flow->set_messagepermits(messagePermits); + return writeMessageWithSize(cmd); +} + +SharedBuffer Commands::newCloseProducer(uint64_t producerId, uint64_t requestId) { + BaseCommand cmd; + cmd.set_type(BaseCommand::CLOSE_PRODUCER); + CommandCloseProducer* close = cmd.mutable_close_producer(); + close->set_producer_id(producerId); + close->set_request_id(requestId); + return writeMessageWithSize(cmd); +} + +SharedBuffer Commands::newCloseConsumer(uint64_t consumerId, uint64_t requestId) { + BaseCommand cmd; + cmd.set_type(BaseCommand::CLOSE_CONSUMER); + CommandCloseConsumer* close = cmd.mutable_close_consumer(); + close->set_consumer_id(consumerId); + close->set_request_id(requestId); + return writeMessageWithSize(cmd); +} + +SharedBuffer Commands::newPing() { + BaseCommand cmd; + cmd.set_type(BaseCommand::PING); + cmd.mutable_ping(); + return writeMessageWithSize(cmd); +} + +SharedBuffer Commands::newPong() { + BaseCommand cmd; + cmd.set_type(BaseCommand::PONG); + cmd.mutable_pong(); + return writeMessageWithSize(cmd); +} + +SharedBuffer Commands::newRedeliverUnacknowledgedMessages(uint64_t consumerId) { + BaseCommand cmd; + cmd.set_type(BaseCommand::REDELIVER_UNACKNOWLEDGED_MESSAGES); + CommandRedeliverUnacknowledgedMessages* command = cmd.mutable_redeliverunacknowledgedmessages(); + command->set_consumer_id(consumerId); + return writeMessageWithSize(cmd); +} + +std::string Commands::messageType(BaseCommand_Type type) { + switch (type) { + case BaseCommand::CONNECT: + return "CONNECT"; + break; + case BaseCommand::CONNECTED: + return "CONNECTED"; + break; + case BaseCommand::SUBSCRIBE: + return "SUBSCRIBE"; + break; + case BaseCommand::PRODUCER: + return "PRODUCER"; + break; + case BaseCommand::SEND: + return "SEND"; + break; + case BaseCommand::SEND_RECEIPT: + return "SEND_RECEIPT"; + break; + case BaseCommand::SEND_ERROR: + return "SEND_ERROR"; + break; + case BaseCommand::MESSAGE: + return "MESSAGE"; + break; + case BaseCommand::ACK: + return "ACK"; + break; + case BaseCommand::FLOW: + return "FLOW"; + break; + case BaseCommand::UNSUBSCRIBE: + return "UNSUBSCRIBE"; + break; + case BaseCommand::SUCCESS: + return "SUCCESS"; + break; + case BaseCommand::ERROR: + return "ERROR"; + break; + case BaseCommand::CLOSE_PRODUCER: + return "CLOSE_PRODUCER"; + break; + case BaseCommand::CLOSE_CONSUMER: + return "CLOSE_CONSUMER"; + break; + case BaseCommand::PRODUCER_SUCCESS: + return "PRODUCER_SUCCESS"; + break; + case BaseCommand::PING: + return "PING"; + break; + case BaseCommand::PONG: + return "PONG"; + break; + case BaseCommand::PARTITIONED_METADATA: + return "PARTITIONED_METADATA"; + break; + case BaseCommand::PARTITIONED_METADATA_RESPONSE: + return "PARTITIONED_METADATA_RESPONSE"; + break; + case BaseCommand::REDELIVER_UNACKNOWLEDGED_MESSAGES: + return "REDELIVER_UNACKNOWLEDGED_MESSAGES"; + break; + case BaseCommand::LOOKUP: + return "LOOKUP"; + break; + case BaseCommand::LOOKUP_RESPONSE: + return "LOOKUP_RESPONSE"; + break; + }; +} + +void Commands::initBatchMessageMetadata(const Message &msg, pulsar::proto::MessageMetadata &batchMetadata) +{ + if (msg.impl_->metadata.has_publish_time()) { + batchMetadata.set_publish_time(msg.impl_->metadata.publish_time()); + } + + if (msg.impl_->metadata.has_sequence_id()) { + batchMetadata.set_sequence_id(msg.impl_->metadata.sequence_id()); + } + + if (msg.impl_->metadata.has_replicated_from()) { + batchMetadata.set_replicated_from(msg.impl_->metadata.replicated_from()); + } +} + +void Commands::serializeSingleMessageInBatchWithPayload(const Message &msg, + SharedBuffer& batchPayLoad, const unsigned long& maxMessageSizeInBytes) { + SingleMessageMetadata metadata; + if (msg.impl_->hasPartitionKey()) { + metadata.set_partition_key(msg.impl_->getPartitionKey()); + } + + for (MessageBuilder::StringMap::const_iterator it = msg.impl_->properties().begin(); + it != msg.impl_->properties().end(); it++) { + proto::KeyValue *keyValue = proto::KeyValue().New(); + keyValue->set_key(it->first); + keyValue->set_value(it->second); + metadata.mutable_properties()->AddAllocated(keyValue); + } + + // Format of batch message + // Each Message = [METADATA_SIZE][METADATA] [PAYLOAD] + + int payloadSize = msg.impl_->payload.readableBytes(); + metadata.set_payload_size(payloadSize); + + int msgMetadataSize = metadata.ByteSize(); + + unsigned long requiredSpace = sizeof(uint32_t) + msgMetadataSize + payloadSize; + if (batchPayLoad.writableBytes() <= sizeof(uint32_t) + msgMetadataSize + payloadSize) { + LOG_DEBUG("remaining size of batchPayLoad buffer [" << batchPayLoad.writableBytes() << "] can't accomodate new payload [" << requiredSpace << "] - expanding the batchPayload buffer"); + SharedBuffer buffer = SharedBuffer::allocate(batchPayLoad.readableBytes() + std::max(requiredSpace, maxMessageSizeInBytes)); + // Adding batch created so far + buffer.write(batchPayLoad.data(), batchPayLoad.readableBytes()); + batchPayLoad = buffer; + } + // Adding the new message + batchPayLoad.writeUnsignedInt(msgMetadataSize); + metadata.SerializeToArray(batchPayLoad.mutableData(), msgMetadataSize); + batchPayLoad.bytesWritten(msgMetadataSize); + batchPayLoad.write(msg.impl_->payload.data(), payloadSize); +} + +Message Commands::deSerializeSingleMessageInBatch(Message& batchedMessage) { + SharedBuffer& uncompressedPayload = batchedMessage.impl_->payload; + + // Format of batch message + // Each Message = [METADATA_SIZE][METADATA] [PAYLOAD] + + const int& singleMetaSize = uncompressedPayload.readUnsignedInt(); + SingleMessageMetadata metadata; + metadata.ParseFromArray(uncompressedPayload.data(), singleMetaSize); + uncompressedPayload.consume(singleMetaSize); + + const int& payloadSize = metadata.payload_size(); + + // Get a slice of size payloadSize from offset readIndex_ + SharedBuffer payload = uncompressedPayload.slice(0, payloadSize); + uncompressedPayload.consume(payloadSize); + + Message singleMessage(batchedMessage.impl_->messageId, batchedMessage.impl_->metadata, payload, + metadata); + singleMessage.impl_->cnx_ = batchedMessage.impl_->cnx_; + + return singleMessage; +} +} +/* namespace pulsar */ diff --git a/pulsar-client-cpp/lib/Commands.h b/pulsar-client-cpp/lib/Commands.h new file mode 100644 index 0000000000000..bab7f59b3bfac --- /dev/null +++ b/pulsar-client-cpp/lib/Commands.h @@ -0,0 +1,103 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_COMMANDS_H_ +#define LIB_COMMANDS_H_ + +#include +#include + +#include "PulsarApi.pb.h" +#include "SharedBuffer.h" + +using namespace pulsar; + +namespace pulsar { + +typedef boost::shared_ptr MessageMetadataPtr; + +/** + * Construct buffers ready to send for Pulsar client commands. + * + * Buffer are already including the 4 byte size at the beginning + */ +class Commands { + public: + + enum ChecksumType { + Crc32c, + None + }; + enum WireFormatConstant { + MaxMessageSize = (5 * 1024 * 1024 - (10 * 1024)), + MaxFrameSize = (5 * 1024 * 1024) + }; + + const static uint16_t magicCrc32c = 0x0e01; + const static int checksumSize = 4; + + static SharedBuffer newConnect(const AuthenticationPtr& authentication); + + static SharedBuffer newPartitionMetadataRequest(proto::BaseCommand& cmd, const std::string& topic, uint64_t requestId); + + static SharedBuffer newLookup(proto::BaseCommand& cmd, const std::string& topic, const bool authoritative, + uint64_t requestId); + + static PairSharedBuffer newSend(SharedBuffer& headers, proto::BaseCommand& cmd, + uint64_t producerId, uint64_t sequenceId, ChecksumType checksumType, const Message& msg); + + static SharedBuffer newSubscribe(const std::string& topic, const std::string&subscription, + uint64_t consumerId, uint64_t requestId, + proto::CommandSubscribe_SubType subType, + const std::string& consumerName); + + static SharedBuffer newUnsubscribe(uint64_t consumerId, uint64_t requestId); + + static SharedBuffer newProducer(const std::string& topic, uint64_t producerId, + const std::string& producerName, uint64_t requestId); + + static SharedBuffer newAck(uint64_t consumerId, const proto::MessageIdData& messageId, + proto::CommandAck_AckType ackType, int validationError); + + static SharedBuffer newFlow(uint64_t consumerId, uint32_t messagePermits); + + static SharedBuffer newCloseProducer(uint64_t producerId, uint64_t requestId); + + static SharedBuffer newCloseConsumer(uint64_t consumerId, uint64_t requestId); + + static SharedBuffer newPing(); + static SharedBuffer newPong(); + + static SharedBuffer newRedeliverUnacknowledgedMessages(uint64_t consumerId); + + static std::string messageType(proto::BaseCommand::Type type); + + static void initBatchMessageMetadata(const Message &msg, pulsar::proto::MessageMetadata &batchMetadata); + + static void serializeSingleMessageInBatchWithPayload(const Message &msg, SharedBuffer& batchPayLoad, const unsigned long& maxMessageSizeInBytes); + + static Message deSerializeSingleMessageInBatch(Message& batchedMessage); + + private: + Commands(); + + static SharedBuffer writeMessageWithSize(const proto::BaseCommand& cmd); + +}; + +} /* namespace pulsar */ + +#endif /* LIB_COMMANDS_H_ */ diff --git a/pulsar-client-cpp/lib/CompressionCodec.cc b/pulsar-client-cpp/lib/CompressionCodec.cc new file mode 100644 index 0000000000000..51174303d01c0 --- /dev/null +++ b/pulsar-client-cpp/lib/CompressionCodec.cc @@ -0,0 +1,73 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "CompressionCodec.h" +#include "CompressionCodecLZ4.h" +#include "CompressionCodecZLib.h" + +#include + +using namespace pulsar; +namespace pulsar { + +CompressionCodecNone CompressionCodecProvider::compressionCodecNone_; +CompressionCodecLZ4 CompressionCodecProvider::compressionCodecLZ4_; +CompressionCodecZLib CompressionCodecProvider::compressionCodecZLib_; + +CompressionCodec& CompressionCodecProvider::getCodec(CompressionType compressionType) { + switch (compressionType) { + case CompressionLZ4: + return compressionCodecLZ4_; + case CompressionZLib: + return compressionCodecZLib_; + default: + return compressionCodecNone_; + } +} + +CompressionType CompressionCodecProvider::convertType(proto::CompressionType type) { + switch (type) { + case proto::NONE: + return CompressionNone; + case proto::LZ4: + return CompressionLZ4; + case proto::ZLIB: + return CompressionZLib; + } +} + +proto::CompressionType CompressionCodecProvider::convertType(CompressionType type) { + switch (type) { + case CompressionNone: + return proto::NONE; + case CompressionLZ4: + return proto::LZ4; + case CompressionZLib: + return proto::ZLIB; + } +} + +SharedBuffer CompressionCodecNone::encode(const SharedBuffer& raw) { + return raw; +} + +bool CompressionCodecNone::decode(const SharedBuffer& encoded, uint32_t uncompressedSize, + SharedBuffer& decoded) { + decoded = encoded; + return true; +} + +} diff --git a/pulsar-client-cpp/lib/CompressionCodec.h b/pulsar-client-cpp/lib/CompressionCodec.h new file mode 100644 index 0000000000000..df10c97012b57 --- /dev/null +++ b/pulsar-client-cpp/lib/CompressionCodec.h @@ -0,0 +1,89 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_COMPRESSIONCODEC_H_ +#define LIB_COMPRESSIONCODEC_H_ + +#include + +#include + +#include "SharedBuffer.h" +#include "PulsarApi.pb.h" + +#include + +using namespace pulsar; +namespace pulsar { + +class CompressionCodec; +class CompressionCodecNone; +class CompressionCodecLZ4; +class CompressionCodecZLib; + +class CompressionCodecProvider { + public: + static CompressionType convertType(proto::CompressionType type); + static proto::CompressionType convertType(CompressionType type); + + static CompressionCodec& getCodec(CompressionType compressionType); + private: + static CompressionCodecNone compressionCodecNone_; + static CompressionCodecLZ4 compressionCodecLZ4_; + static CompressionCodecZLib compressionCodecZLib_; +}; + +class CompressionCodec { + public: + virtual ~CompressionCodec() { + } + + /** + * Compress a buffer + * + * @param raw + * a buffer with the uncompressed content. The reader/writer indexes will not be modified + * @return a buffer with the compressed content. + */ + virtual SharedBuffer encode(const SharedBuffer& raw) = 0; + + /** + * Decompress a buffer. + * + * The buffer needs to have been compressed with the matching Encoder. + * + * @param encoded + * the compressed content + * @param uncompressedSize + * the size of the original content + * @param decoded + * were the result will be passed + * @return true if the buffer was decompressed, false otherwise + */ + virtual bool decode(const SharedBuffer& encoded, uint32_t uncompressedSize, + SharedBuffer& decoded) = 0; +}; + +class CompressionCodecNone : public CompressionCodec { + public: + SharedBuffer encode(const SharedBuffer& raw); + + bool decode(const SharedBuffer& encoded, uint32_t uncompressedSize, SharedBuffer& decoded); +}; + +} + +#endif /* LIB_COMPRESSIONCODEC_H_ */ diff --git a/pulsar-client-cpp/lib/CompressionCodecLZ4.cc b/pulsar-client-cpp/lib/CompressionCodecLZ4.cc new file mode 100644 index 0000000000000..7fbc3fd729329 --- /dev/null +++ b/pulsar-client-cpp/lib/CompressionCodecLZ4.cc @@ -0,0 +1,52 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "CompressionCodecLZ4.h" + +#include "lz4/lz4.h" +#include + +namespace pulsar { + +SharedBuffer CompressionCodecLZ4::encode(const SharedBuffer& raw) { + // Get the max size of the compressed data and allocate a buffer to hold it + int maxCompressedSize = LZ4_compressBound(raw.readableBytes()); + SharedBuffer compressed = SharedBuffer::allocate(maxCompressedSize); + + int compressedSize = LZ4_compress_default(raw.data(), compressed.mutableData(), + raw.readableBytes(), maxCompressedSize); + assert(compressedSize > 0); + compressed.bytesWritten(compressedSize); + + return compressed; +} + +bool CompressionCodecLZ4::decode(const SharedBuffer& encoded, uint32_t uncompressedSize, + SharedBuffer& decoded) { + SharedBuffer decompressed = SharedBuffer::allocate(uncompressedSize); + + int result = LZ4_decompress_fast(encoded.data(), decompressed.mutableData(), uncompressedSize); + if (result > 0) { + decompressed.bytesWritten(uncompressedSize); + decoded = decompressed; + return true; + } else { + // Decompression failed + return false; + } +} + +} diff --git a/pulsar-client-cpp/lib/CompressionCodecLZ4.h b/pulsar-client-cpp/lib/CompressionCodecLZ4.h new file mode 100644 index 0000000000000..9fd2aaf66fe40 --- /dev/null +++ b/pulsar-client-cpp/lib/CompressionCodecLZ4.h @@ -0,0 +1,32 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_COMPRESSIONCODECLZ4_H_ +#define LIB_COMPRESSIONCODECLZ4_H_ + +#include "CompressionCodec.h" + +namespace pulsar { + +class CompressionCodecLZ4 : public CompressionCodec { + public: + SharedBuffer encode(const SharedBuffer& raw); + + bool decode(const SharedBuffer& encoded, uint32_t uncompressedSize, SharedBuffer& decoded); +}; + +} +#endif /* LIB_COMPRESSIONCODECLZ4_H_ */ diff --git a/pulsar-client-cpp/lib/CompressionCodecZLib.cc b/pulsar-client-cpp/lib/CompressionCodecZLib.cc new file mode 100644 index 0000000000000..649bd7245f892 --- /dev/null +++ b/pulsar-client-cpp/lib/CompressionCodecZLib.cc @@ -0,0 +1,62 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "CompressionCodecZLib.h" + +#include +#include +#include +#include +#include "LogUtils.h" + +DECLARE_LOG_OBJECT() + +namespace pulsar { + +SharedBuffer CompressionCodecZLib::encode(const SharedBuffer& raw) { + // Get the max size of the compressed data and allocate a buffer to hold it + int maxCompressedSize = compressBound(raw.readableBytes()); + SharedBuffer compressed = SharedBuffer::allocate(maxCompressedSize); + + unsigned long bytesWritten = maxCompressedSize; + int res = compress((Bytef*) compressed.mutableData(), &bytesWritten, (const Bytef*) raw.data(), + raw.readableBytes()); + if (res != Z_OK) { + LOG_ERROR("Failed to compress buffer. res=" << res); + abort(); + } + + compressed.bytesWritten(bytesWritten); + return compressed; +} + +bool CompressionCodecZLib::decode(const SharedBuffer& encoded, uint32_t uncompressedSize, + SharedBuffer& decoded) { + SharedBuffer decompressed = SharedBuffer::allocate(uncompressedSize); + + unsigned long bytesUncompressed = uncompressedSize; + int res = uncompress((Bytef*) decompressed.mutableData(), &bytesUncompressed, (Bytef*) encoded.data(), encoded.readableBytes()); + + decompressed.bytesWritten(bytesUncompressed); + if (res == Z_OK) { + decoded = decompressed; + return true; + } else { + return false; + } +} + +} diff --git a/pulsar-client-cpp/lib/CompressionCodecZLib.h b/pulsar-client-cpp/lib/CompressionCodecZLib.h new file mode 100644 index 0000000000000..eeb78a0cf682e --- /dev/null +++ b/pulsar-client-cpp/lib/CompressionCodecZLib.h @@ -0,0 +1,35 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_COMPRESSIONCODECZLIB_H_ +#define LIB_COMPRESSIONCODECZLIB_H_ + +#include "CompressionCodec.h" +#include +#include + +namespace pulsar { + +class CompressionCodecZLib : public CompressionCodec { + public: + SharedBuffer encode(const SharedBuffer& raw); + + bool decode(const SharedBuffer& encoded, uint32_t uncompressedSize, SharedBuffer& decoded); +}; + +} + +#endif /* LIB_COMPRESSIONCODECZLIB_H_ */ diff --git a/pulsar-client-cpp/lib/ConnectionPool.cc b/pulsar-client-cpp/lib/ConnectionPool.cc new file mode 100644 index 0000000000000..1fd07d0fb57b2 --- /dev/null +++ b/pulsar-client-cpp/lib/ConnectionPool.cc @@ -0,0 +1,73 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "ConnectionPool.h" + +#include "LogUtils.h" + +DECLARE_LOG_OBJECT() + +namespace pulsar { + +ConnectionPool::ConnectionPool(const ClientConfiguration& conf, + ExecutorServiceProviderPtr executorProvider, + const AuthenticationPtr& authentication, bool poolConnections) + : clientConfiguration_(conf), + executorProvider_(executorProvider), + authentication_(authentication), + pool_(), + poolConnections_(poolConnections), + mutex_() { +} + +Future ConnectionPool::getConnectionAsync( + const std::string& endpoint) { + boost::unique_lock lock(mutex_); + + if (poolConnections_) { + PoolMap::iterator cnxIt = pool_.find(endpoint); + if (cnxIt != pool_.end()) { + ClientConnectionPtr cnx = cnxIt->second.lock(); + + if (cnx && !cnx->isClosed()) { + // Found a valid or pending connection in the pool + LOG_DEBUG("Got connection from pool for " << endpoint << " use_count: " // + << (cnx.use_count() - 1) << " @ " << cnx.get()); + return cnx->getConnectFuture(); + } else { + // Deleting stale connection + LOG_INFO("Deleting stale connection from pool for " << endpoint << " use_count: " + << (cnx.use_count() - 1) << " @ " << cnx.get()); + pool_.erase(endpoint); + } + } + } + + // No valid or pending connection found in the pool, creating a new one + ClientConnectionPtr cnx(new ClientConnection(endpoint, executorProvider_->get(), clientConfiguration_, authentication_)); + + LOG_INFO("Created connection for " << endpoint); + + Future future = cnx->getConnectFuture(); + pool_.insert(std::make_pair(endpoint, cnx)); + + lock.unlock(); + + cnx->tcpConnectAsync(); + return future; +} + +} diff --git a/pulsar-client-cpp/lib/ConnectionPool.h b/pulsar-client-cpp/lib/ConnectionPool.h new file mode 100644 index 0000000000000..b24c8b10e4c28 --- /dev/null +++ b/pulsar-client-cpp/lib/ConnectionPool.h @@ -0,0 +1,53 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef _PULSAR_CONNECTION_POOL_HEADER_ +#define _PULSAR_CONNECTION_POOL_HEADER_ + +#include + +#include "ClientConnection.h" + +#include +#include +#include + +namespace pulsar { + +class ExecutorService; + +class ConnectionPool { + public: + ConnectionPool(const ClientConfiguration& conf, ExecutorServiceProviderPtr executorProvider, + const AuthenticationPtr& authentication, bool poolConnections = true); + + Future getConnectionAsync(const std::string& endpoint); + + private: + ClientConfiguration clientConfiguration_; + ExecutorServiceProviderPtr executorProvider_; + AuthenticationPtr authentication_; + typedef std::map PoolMap; + PoolMap pool_; + bool poolConnections_; + boost::mutex mutex_; + + friend class ConnectionPoolTest; +}; + +} + +#endif //_PULSAR_CONNECTION_POOL_HEADER_ diff --git a/pulsar-client-cpp/lib/Consumer.cc b/pulsar-client-cpp/lib/Consumer.cc new file mode 100644 index 0000000000000..41e163a682476 --- /dev/null +++ b/pulsar-client-cpp/lib/Consumer.cc @@ -0,0 +1,262 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include +#include "ConsumerImpl.h" +#include "Utils.h" + +namespace pulsar { + +const std::string EMPTY_STRING; + +struct ConsumerConfiguration::Impl { + long unAckedMessagesTimeoutMs; + ConsumerType consumerType; + MessageListener messageListener; + bool hasMessageListener; + int receiverQueueSize; + std::string consumerName; + Impl() + : unAckedMessagesTimeoutMs(0), + consumerType(ConsumerExclusive), + messageListener(), + hasMessageListener(false), + receiverQueueSize(1000) { + } +}; + +ConsumerConfiguration::ConsumerConfiguration() + : impl_(boost::make_shared()) { +} + +ConsumerConfiguration::~ConsumerConfiguration() { +} + +ConsumerConfiguration::ConsumerConfiguration(const ConsumerConfiguration& x) + : impl_(x.impl_) { +} + +ConsumerConfiguration& ConsumerConfiguration::operator=(const ConsumerConfiguration& x) { + impl_ = x.impl_; + return *this; +} + +ConsumerConfiguration& ConsumerConfiguration::setConsumerType(ConsumerType consumerType) { + impl_->consumerType = consumerType; + return *this; +} + +ConsumerType ConsumerConfiguration::getConsumerType() const { + return impl_->consumerType; +} + +ConsumerConfiguration& ConsumerConfiguration::setMessageListener(MessageListener messageListener) { + impl_->messageListener = messageListener; + impl_->hasMessageListener = true; + return *this; +} + +MessageListener ConsumerConfiguration::getMessageListener() const { + return impl_->messageListener; +} + +bool ConsumerConfiguration::hasMessageListener() const { + return impl_->hasMessageListener; +} + +void ConsumerConfiguration::setReceiverQueueSize(int size) { + impl_->receiverQueueSize = size; +} + +int ConsumerConfiguration::getReceiverQueueSize() const { + return impl_->receiverQueueSize; +} + +const std::string& ConsumerConfiguration::getConsumerName() const { + return impl_->consumerName; +} + +void ConsumerConfiguration::setConsumerName(const std::string& consumerName) { + impl_->consumerName = consumerName; +} + +long ConsumerConfiguration::getUnAckedMessagesTimeoutMs() const { + return impl_->unAckedMessagesTimeoutMs; +} + +void ConsumerConfiguration::setUnAckedMessagesTimeoutMs(const uint64_t milliSeconds) { + if (milliSeconds < 10000) { + throw "Consumer Config Exception: Unacknowledged message timeout should be greater than 10 seconds."; + } + impl_->unAckedMessagesTimeoutMs = milliSeconds; +} +////////////////////////////////////////////////////// + +Consumer::Consumer() + : impl_() { +} + +Consumer::Consumer(ConsumerImplBasePtr impl) + : impl_(impl) { +} + +const std::string& Consumer::getTopic() const { + return impl_ != NULL ? impl_->getTopic() : EMPTY_STRING; +} + +const std::string& Consumer::getSubscriptionName() const { + return impl_ != NULL ? impl_->getSubscriptionName() : EMPTY_STRING; +} + +Result Consumer::unsubscribe() { + if (!impl_) { + return ResultConsumerNotInitialized; + } + Promise promise; + impl_->unsubscribeAsync(WaitForCallback(promise)); + Result result; + promise.getFuture().get(result); + return result; +} + +void Consumer::unsubscribeAsync(ResultCallback callback) { + if (!impl_) { + callback(ResultConsumerNotInitialized); + return; + } + + impl_->unsubscribeAsync(callback); +} + +Result Consumer::receive(Message& msg) { + if (!impl_) { + return ResultConsumerNotInitialized; + } + + return impl_->receive(msg); +} + +Result Consumer::receive(Message& msg, int timeoutMs) { + if (!impl_) { + return ResultConsumerNotInitialized; + } + + return impl_->receive(msg, timeoutMs); +} + +Result Consumer::acknowledge(const Message& message) { + return acknowledge(message.getMessageId()); +} + +Result Consumer::acknowledge(const MessageId& messageId) { + if (!impl_) { + return ResultConsumerNotInitialized; + } + Promise promise; + impl_->acknowledgeAsync(messageId, WaitForCallback(promise)); + Result result; + promise.getFuture().get(result); + return result; +} + +void Consumer::acknowledgeAsync(const Message& message, ResultCallback callback) { + if (!impl_) { + callback(ResultConsumerNotInitialized); + return; + } + + impl_->acknowledgeAsync(message.getMessageId(), callback); +} + +void Consumer::acknowledgeAsync(const MessageId& messageId, ResultCallback callback) { + if (!impl_) { + callback(ResultConsumerNotInitialized); + return; + } + + impl_->acknowledgeAsync(messageId, callback); +} + +Result Consumer::acknowledgeCumulative(const Message& message) { + return acknowledgeCumulative(message.getMessageId()); +} + +Result Consumer::acknowledgeCumulative(const MessageId& messageId) { + if (!impl_) { + return ResultConsumerNotInitialized; + } + + Promise promise; + impl_->acknowledgeCumulativeAsync(messageId, WaitForCallback(promise)); + Result result; + promise.getFuture().get(result); + return result; +} + +void Consumer::acknowledgeCumulativeAsync(const Message& message, ResultCallback callback) { + acknowledgeCumulativeAsync(message.getMessageId(), callback); +} + +void Consumer::acknowledgeCumulativeAsync(const MessageId& messageId, ResultCallback callback) { + if (!impl_) { + callback(ResultConsumerNotInitialized); + return; + } + + impl_->acknowledgeCumulativeAsync(messageId, callback); +} + +Result Consumer::close() { + Promise promise; + closeAsync(WaitForCallback(promise)); + + Result result; + promise.getFuture().get(result); + return result; +} + +void Consumer::closeAsync(ResultCallback callback) { + if (!impl_) { + callback(ResultConsumerNotInitialized); + return; + } + + impl_->closeAsync(callback); +} + +Result Consumer::pauseMessageListener() { + if (!impl_) { + return ResultConsumerNotInitialized; + } + + return impl_->pauseMessageListener(); +} + +Result Consumer::resumeMessageListener() { + if (!impl_) { + return ResultConsumerNotInitialized; + } + + return impl_->resumeMessageListener(); +} + +void Consumer::redeliverUnacknowledgedMessages() { + if (impl_) { + impl_->redeliverUnacknowledgedMessages(); + } +} +} diff --git a/pulsar-client-cpp/lib/ConsumerImpl.cc b/pulsar-client-cpp/lib/ConsumerImpl.cc new file mode 100644 index 0000000000000..f481248c5633f --- /dev/null +++ b/pulsar-client-cpp/lib/ConsumerImpl.cc @@ -0,0 +1,689 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "ConsumerImpl.h" +#include "MessageImpl.h" +#include "Commands.h" +#include "LogUtils.h" +#include +#include "pulsar/Result.h" +#include "pulsar/MessageId.h" +#include "Utils.h" +#include +#include "DestinationName.h" +#include + +using namespace pulsar; +namespace pulsar { + +DECLARE_LOG_OBJECT() + +ConsumerImpl::ConsumerImpl(const ClientImplPtr client, const std::string& topic, + const std::string& subscription, const ConsumerConfiguration& conf, + const ExecutorServicePtr listenerExecutor /* = NULL by default */, + const ConsumerTopicType consumerTopicType /* = NonPartitioned by default */ ) + : HandlerBase(client, topic), + waitingForZeroQueueSizeMessage(false), + config_(conf), + subscription_(subscription), + originalSubscriptionName_(subscription), + messageListener_(config_.getMessageListener()), + consumerTopicType_(consumerTopicType), + // This is the initial capacity of the queue + incomingMessages_(std::max(config_.getReceiverQueueSize(), 1)), + availablePermits_(conf.getReceiverQueueSize()), + consumerId_(client->newConsumerId()), + consumerName_(config_.getConsumerName()), + partitionIndex_(-1), + consumerCreatedPromise_(), + messageListenerRunning_(true), + batchAcknowledgementTracker_(topic_, subscription, (long)consumerId_) { + std::stringstream consumerStrStream; + consumerStrStream << "[" << topic_ << ", " << subscription_ << ", " << consumerId_ << "] "; + consumerStr_ = consumerStrStream.str(); + if (conf.getUnAckedMessagesTimeoutMs() != 0) { + unAckedMessageTrackerPtr_.reset(new UnAckedMessageTrackerEnabled(conf.getUnAckedMessagesTimeoutMs(), client, *this)); + } else { + unAckedMessageTrackerPtr_.reset(new UnAckedMessageTrackerDisabled()); + } + if (listenerExecutor) { + listenerExecutor_ = listenerExecutor; + } else { + listenerExecutor_ = client->getListenerExecutorProvider()->get(); + } +} + +ConsumerImpl::~ConsumerImpl() { + LOG_DEBUG(getName() << "~ConsumerImpl"); + incomingMessages_.clear(); + if (state_ == Ready) { + LOG_WARN(getName() << "Destroyed consumer which was not properly closed"); + closeAsync(ResultCallback()); + } +} + +void ConsumerImpl::setPartitionIndex(int partitionIndex) { + partitionIndex_ = partitionIndex; +} + +int ConsumerImpl::getPartitionIndex() { + return partitionIndex_; +} + +uint64_t ConsumerImpl::getConsumerId() { + return consumerId_; +} + +Future ConsumerImpl::getConsumerCreatedFuture() { + return consumerCreatedPromise_.getFuture(); +} + +const std::string& ConsumerImpl::getSubscriptionName() const { + return originalSubscriptionName_; +} + +const std::string& ConsumerImpl::getTopic() const { + return topic_; +} + +void ConsumerImpl::start() { + grabCnx(); +} + +void ConsumerImpl::connectionOpened(const ClientConnectionPtr& cnx) { + Lock lock(mutex_); + if (state_ == Closed) { + lock.unlock(); + LOG_DEBUG(getName() << "connectionOpened : Consumer is already closed"); + return; + } + lock.unlock(); + + ClientImplPtr client = client_.lock(); + int requestId = client->newRequestId(); + SharedBuffer cmd = Commands::newSubscribe(topic_, subscription_, consumerId_, requestId, + getSubType(), consumerName_); + cnx->sendRequestWithId(cmd, requestId).addListener( + boost::bind(&ConsumerImpl::handleCreateConsumer, shared_from_this(), cnx, _1)); +} + +void ConsumerImpl::connectionFailed(Result result) { + // Keep a reference to ensure object is kept alive + ConsumerImplPtr ptr = shared_from_this(); + + if (consumerCreatedPromise_.setFailed(result)) { + Lock lock(mutex_); + state_ = Failed; + } +} + +void ConsumerImpl::receiveMessages(const ClientConnectionPtr& cnx, unsigned int count) { + SharedBuffer cmd = Commands::newFlow(consumerId_, count); + cnx->sendCommand(cmd); +} + +void ConsumerImpl::handleCreateConsumer(const ClientConnectionPtr& cnx, Result result) { + static bool firstTime = true; + if (result == ResultOk) { + if (firstTime) { + firstTime = false; + } + LOG_INFO(getName() << "Created consumer on broker " << cnx->cnxString()); + connection_ = cnx; + { + Lock lock(mutex_); + incomingMessages_.clear(); + cnx->registerConsumer(consumerId_, shared_from_this()); + state_ = Ready; + backoff_.reset(); + // Complicated logic since we don't have a isLocked() function for mutex + if (waitingForZeroQueueSizeMessage) { + receiveMessages(cnx, 1); + } + availablePermits_ = 0; + } + + + LOG_DEBUG(getName() << "Send initial flow permits: " << config_.getReceiverQueueSize()); + if ((consumerTopicType_ == NonPartitioned || !firstTime) + && config_.getReceiverQueueSize() != 0) { + receiveMessages(cnx, config_.getReceiverQueueSize()); + } + consumerCreatedPromise_.setValue(shared_from_this()); + } else { + if (result == ResultTimeout) { + // Creating the consumer has timed out. We need to ensure the broker closes the consumer + // in case it was indeed created, otherwise it might prevent new subscribe operation, + // since we are not closing the connection + int requestId = client_.lock()->newRequestId(); + cnx->sendRequestWithId(Commands::newCloseConsumer(consumerId_, requestId), + requestId); + } + + if (consumerCreatedPromise_.isComplete()) { + // Consumer had already been initially created, we need to retry connecting in any case + LOG_WARN( + getName() << "Failed to reconnect consumer: " << strResult(result)); + scheduleReconnection(shared_from_this()); + } else { + // Consumer was not yet created, retry to connect to broker if it's possible + if (isRetriableError(result) && (creationTimestamp_ + operationTimeut_ < now())) { + LOG_WARN( + getName() << "Temporary error in creating consumer : " << strResult(result)); + scheduleReconnection(shared_from_this()); + } else { + LOG_ERROR(getName() << "Failed to create consumer: " << strResult(result)); + consumerCreatedPromise_.setFailed(result); + state_ = Failed; + } + } + } +} + +void ConsumerImpl::unsubscribeAsync(ResultCallback callback) { + LOG_INFO(getName() << "Unsubscribing"); + + Lock lock(mutex_); + if (state_ != Ready) { + lock.unlock(); + callback(ResultAlreadyClosed); + LOG_ERROR( + getName() << "Can not unsubscribe a closed subscription, please call subscribe again and then call unsubscribe"); + return; + } + + ClientConnectionPtr cnx = getCnx().lock(); + if (cnx) { + LOG_DEBUG(getName() << "Unsubscribe request sent for consumer - " << consumerId_); + ClientImplPtr client = client_.lock(); + lock.unlock(); + int requestId = client->newRequestId(); + SharedBuffer cmd = Commands::newUnsubscribe(consumerId_, requestId); + cnx->sendRequestWithId(cmd, requestId).addListener( + boost::bind(&ConsumerImpl::handleUnsubscribe, shared_from_this(), _1, callback)); + } else { + Result result = ResultNotConnected; + lock.unlock(); + LOG_WARN(getName() << "Failed to unsubscribe: " << strResult(result)); + callback(result); + } +} + +void ConsumerImpl::handleUnsubscribe(Result result, ResultCallback callback) { + if (result == ResultOk) { + Lock lock(mutex_); + state_ = Closed; + LOG_INFO(getName() << "Unsubscribed successfully"); + } else { + LOG_WARN(getName() << "Failed to unsubscribe: " << strResult(result)); + } + callback(result); +} + +void ConsumerImpl::messageReceived(const ClientConnectionPtr& cnx, const proto::CommandMessage& msg, + bool& isChecksumValid, proto::MessageMetadata& metadata, + SharedBuffer& payload) { + LOG_DEBUG(getName() << "Received Message -- Size: " << payload.readableBytes()); + + if (!uncompressMessageIfNeeded(cnx, msg, metadata, payload)) { + // Message was discarded on decompression error + return; + } + + if (!isChecksumValid) { + // Message discarded for checksum error + discardCorruptedMessage(cnx, msg.message_id(), proto::CommandAck::ChecksumMismatch); + return; + } + + Message m(msg, metadata, payload); + m.impl_->messageId.partition_ = partitionIndex_; + m.impl_->cnx_ = cnx.get(); + + LOG_DEBUG(getName() << " metadata.num_messages_in_batch() = "<< metadata.num_messages_in_batch()); + LOG_DEBUG(getName() << " metadata.has_num_messages_in_batch() = "<< metadata.has_num_messages_in_batch()); + + unsigned int numOfMessageReceived = 1; + if (metadata.has_num_messages_in_batch()) { + Lock lock(mutex_); + numOfMessageReceived = receiveIndividualMessagesFromBatch(m); + } else { + // config_.getReceiverQueueSize() != 0 or waiting For ZeroQueueSize Message` + if (config_.getReceiverQueueSize() != 0) { + incomingMessages_.push(m); + } else { + Lock lock(mutex_); + if(waitingForZeroQueueSizeMessage) { + lock.unlock(); + incomingMessages_.push(m); + } + } + } + + if (messageListener_) { + Lock lock(messageListenerMutex_); + if (!messageListenerRunning_) { + return; + } + lock.unlock(); + // Trigger message listener callback in a separate thread + while(numOfMessageReceived--) { + listenerExecutor_->postWork( + boost::bind(&ConsumerImpl::internalListener, shared_from_this())); + } + } +} + +// Zero Queue size is not supported with Batch Messages +unsigned int ConsumerImpl::receiveIndividualMessagesFromBatch(Message& batchedMessage) { + unsigned int batchSize = batchedMessage.impl_->metadata.num_messages_in_batch(); + batchAcknowledgementTracker_.receivedMessage(batchedMessage); + LOG_DEBUG("Received Batch messages of size - " << batchSize); + for (int i=0; imessageId.batchIndex_ = i; + // This is a cheap copy since message contains only one shared pointer (impl_) + incomingMessages_.push(Commands::deSerializeSingleMessageInBatch(batchedMessage)); + } + return batchSize; +} + +bool ConsumerImpl::uncompressMessageIfNeeded(const ClientConnectionPtr& cnx, + const proto::CommandMessage& msg, + const proto::MessageMetadata& metadata, + SharedBuffer& payload) { + if (!metadata.has_compression()) { + return true; + } + + CompressionType compressionType = CompressionCodecProvider::convertType(metadata.compression()); + + uint32_t uncompressedSize = metadata.uncompressed_size(); + if (uncompressedSize > Commands::MaxMessageSize) { + // Uncompressed size is itself corrupted since it cannot be bigger than the MaxMessageSize + LOG_ERROR(getName() << "Got corrupted uncompressed message size " << uncompressedSize // + << " at " << msg.message_id().ledgerid() << ":" << msg.message_id().entryid()); + discardCorruptedMessage(cnx, msg.message_id(), + proto::CommandAck::UncompressedSizeCorruption); + return false; + } + + if (!CompressionCodecProvider::getCodec(compressionType).decode(payload, uncompressedSize, payload)) { + LOG_ERROR(getName() << "Failed to decompress message with " << uncompressedSize // + << " at " << msg.message_id().ledgerid() << ":" << msg.message_id().entryid()); + discardCorruptedMessage(cnx, msg.message_id(), proto::CommandAck::DecompressionError); + return false; + } + + return true; +} + +void ConsumerImpl::discardCorruptedMessage(const ClientConnectionPtr& cnx, + const proto::MessageIdData& messageId, + proto::CommandAck::ValidationError validationError) { + LOG_ERROR( + getName() << "Discarding corrupted message at " << messageId.ledgerid() << ":" << messageId.entryid()); + + SharedBuffer cmd = Commands::newAck(consumerId_, messageId, proto::CommandAck::Individual, validationError); + + cnx->sendCommand(cmd); + increaseAvailablePermits(cnx); +} + +void ConsumerImpl::internalListener() { + Lock lock(messageListenerMutex_); + if (!messageListenerRunning_) { + return; + } + lock.unlock(); + Message msg; + if (!incomingMessages_.pop(msg, boost::posix_time::milliseconds(0))) { + // This will only happen when the connection got reset and we cleared the queue + return; + } + try { + messageListener_(Consumer(shared_from_this()), msg); + } catch (const std::exception& e) { + LOG_ERROR(getName() << "Exception thrown from listener" << e.what()); + } + messageProcessed(msg); +} + +Result ConsumerImpl::fetchSingleMessageFromBroker(Message& msg) { + if (config_.getReceiverQueueSize() != 0) { + LOG_ERROR(getName() << " Can't use receiveForZeroQueueSize if the queue size is not 0"); + return ResultInvalidConfiguration; + } + + // Using RAII for locking + ClientConnectionPtr currentCnx = getCnx().lock(); + Lock lock(mutexForReceiveWithZeroQueueSize); + + // Just being cautious + if (incomingMessages_.size() != 0) { + LOG_ERROR( + getName() << "The incoming message queue should never be greater than 0 when Queue size is 0"); + incomingMessages_.clear(); + } + Lock localLock(mutex_); + waitingForZeroQueueSizeMessage = true; + localLock.unlock(); + + if (currentCnx) { + LOG_DEBUG(getName() << "Send more permits: " << 1); + receiveMessages(currentCnx, 1); + } + + while (true) { + incomingMessages_.pop(msg); + { + // Lock needed to prevent race between connectionOpened and the check "msg.impl_->cnx_ == currentCnx.get())" + Lock localLock(mutex_); + // if message received due to an old flow - discard it and wait for the message from the + // latest flow command + if (msg.impl_->cnx_ == currentCnx.get()) { + waitingForZeroQueueSizeMessage = false; + // Can't use break here else it may trigger a race with connection opened. + return ResultOk; + } + } + } + return ResultOk; +} + +Result ConsumerImpl::receive(Message& msg) { + { + Lock lock(mutex_); + if (state_ != Ready) { + return ResultAlreadyClosed; + } + } + if (messageListener_) { + LOG_ERROR(getName() << "Can not receive when a listener has been set"); + return ResultInvalidConfiguration; + } + + if (config_.getReceiverQueueSize() == 0) { + return fetchSingleMessageFromBroker(msg); + } + + incomingMessages_.pop(msg); + messageProcessed(msg); + unAckedMessageTrackerPtr_->add(msg.getMessageId()); + return ResultOk; +} + +Result ConsumerImpl::receive(Message& msg, int timeout) { + if (config_.getReceiverQueueSize() == 0) { + LOG_WARN(getName() << "Can't use this function if the queue size is 0"); + return ResultInvalidConfiguration; + } + + { + Lock lock(mutex_); + if (state_ != Ready) { + return ResultAlreadyClosed; + } + } + + if (messageListener_) { + LOG_ERROR(getName() << "Can not receive when a listener has been set"); + return ResultInvalidConfiguration; + } + + if (incomingMessages_.pop(msg, milliseconds(timeout))) { + messageProcessed(msg); + unAckedMessageTrackerPtr_->add(msg.getMessageId()); + return ResultOk; + } else { + return ResultTimeout; + } +} + +void ConsumerImpl::messageProcessed(Message& msg) { + Lock lock(mutex_); + ClientConnectionPtr currentCnx = getCnx().lock(); + if (currentCnx && msg.impl_->cnx_ != currentCnx.get()) { + LOG_DEBUG(getName() << "Not adding permit since connection is different."); + return; + } + + increaseAvailablePermits(currentCnx); +} + +void ConsumerImpl::increaseAvailablePermits(const ClientConnectionPtr& currentCnx) { + int additionalPermits = 0; + if (++availablePermits_ >= config_.getReceiverQueueSize() / 2) { + additionalPermits = availablePermits_; + availablePermits_ = 0; + } + if (additionalPermits > 0) { + if (currentCnx) { + LOG_DEBUG(getName() << "Send more permits: " << additionalPermits); + receiveMessages(currentCnx, additionalPermits); + } else { + LOG_DEBUG(getName() << "Connection is not ready, Unable to send flow Command"); + } + } +} + +inline proto::CommandSubscribe_SubType ConsumerImpl::getSubType() { + ConsumerType type = config_.getConsumerType(); + switch (type) { + case ConsumerExclusive: + return proto::CommandSubscribe_SubType_Exclusive; + + case ConsumerShared: + return proto::CommandSubscribe_SubType_Shared; + + case ConsumerFailover: + return proto::CommandSubscribe_SubType_Failover; + } +} + +void ConsumerImpl::acknowledgeAsync(const MessageId& msgId, ResultCallback callback) { + const BatchMessageId& batchMsgId = (const BatchMessageId&)msgId; + if(batchMsgId.batchIndex_ != -1 && !batchAcknowledgementTracker_.isBatchReady(batchMsgId, proto::CommandAck_AckType_Individual)) { + callback(ResultOk); + return; + } + doAcknowledge(batchMsgId, proto::CommandAck_AckType_Individual, callback); +} + +void ConsumerImpl::acknowledgeCumulativeAsync(const MessageId& mId, ResultCallback callback) { + const BatchMessageId& msgId = (const BatchMessageId&) mId; + if(msgId.batchIndex_ != -1 && !batchAcknowledgementTracker_.isBatchReady(msgId, proto::CommandAck_AckType_Cumulative)) { + BatchMessageId messageId = batchAcknowledgementTracker_.getGreatestCumulativeAckReady(msgId); + if(messageId == BatchMessageId()) { + // nothing to ack + callback(ResultOk); + } else { + doAcknowledge(messageId, proto::CommandAck_AckType_Cumulative, callback); + } + } else { + doAcknowledge(msgId, proto::CommandAck_AckType_Cumulative, callback); + } +} + +void ConsumerImpl::doAcknowledge(const BatchMessageId& messageId, proto::CommandAck_AckType ackType, + ResultCallback callback) { + + proto::MessageIdData messageIdData; + messageIdData.set_ledgerid(messageId.ledgerId_); + messageIdData.set_entryid(messageId.entryId_); + ClientConnectionPtr cnx = getCnx().lock(); + if (cnx) { + SharedBuffer cmd = Commands::newAck(consumerId_, messageIdData, ackType, -1); + cnx->sendCommand(cmd); + if (ackType == proto::CommandAck_AckType_Individual) { + unAckedMessageTrackerPtr_->remove(messageId); + } else { + unAckedMessageTrackerPtr_->removeMessagesTill(messageId); + } + batchAcknowledgementTracker_.deleteAckedMessage((BatchMessageId&)messageId, ackType); + callback(ResultOk); + LOG_DEBUG( + getName() << "ack request sent for message - [" << messageIdData.ledgerid() << "," << messageIdData.entryid() << "]"); + + } else { + LOG_DEBUG(getName() << "Connection is not ready, Acknowledge failed for message - [" // + << messageIdData.ledgerid() << "," << messageIdData.entryid() << "]"); + callback(ResultNotConnected); + } +} + +void ConsumerImpl::disconnectConsumer() { + LOG_DEBUG("Broker notification of Closed consumer: " << consumerId_); + connection_.reset(); + scheduleReconnection(shared_from_this()); +} + +void ConsumerImpl::closeAsync(ResultCallback callback) { + Lock lock(mutex_); + if (state_ != Ready) { + lock.unlock(); + if (!callback.empty()) { + callback(ResultAlreadyClosed); + } + return; + } + + ClientConnectionPtr cnx = getCnx().lock(); + if (!cnx) { + lock.unlock(); + // If connection is gone, also the consumer is closed on the broker side + if (!callback.empty()) { + callback(ResultOk); + } + return; + } + + + ClientImplPtr client = client_.lock(); + if (!client) { + lock.unlock(); + // Client was already destroyed + if (!callback.empty()) { + callback(ResultOk); + } + return; + } + + // Lock is no longer required + lock.unlock(); + int requestId = client->newRequestId(); + Future future = cnx->sendRequestWithId( + Commands::newCloseConsumer(consumerId_, requestId), requestId); + if (!callback.empty()) { + future.addListener( + boost::bind(&ConsumerImpl::handleClose, shared_from_this(), _1, callback)); + } + +} + +void ConsumerImpl::handleClose(Result result, ResultCallback callback) { + if (result == ResultOk) { + Lock lock(mutex_); + state_ = Closed; + lock.unlock(); + + ClientConnectionPtr cnx = getCnx().lock(); + if (cnx) { + cnx->removeConsumer(consumerId_); + } + + LOG_INFO(getName() << "Closed consumer " << consumerId_); + } else { + LOG_ERROR(getName() << "Failed to close consumer: " << result); + } + + callback(result); +} + + +const std::string& ConsumerImpl::getName() const { + return consumerStr_; +} + +void ConsumerImpl::shutdown() { + Lock lock(mutex_); + state_ = Closed; + lock.unlock(); + + consumerCreatedPromise_.setFailed(ResultAlreadyClosed); +} + +bool ConsumerImpl::isClosed() { + Lock lock(mutex_); + return state_ == Closed; +} + +bool ConsumerImpl::isOpen() { + Lock lock(mutex_); + return state_ == Ready; +} + +Result ConsumerImpl::pauseMessageListener() { + if (!messageListener_) { + return ResultInvalidConfiguration; + } + Lock lock(messageListenerMutex_); + messageListenerRunning_ = false; + return ResultOk; +} + +Result ConsumerImpl::resumeMessageListener() { + if (!messageListener_) { + return ResultInvalidConfiguration; + } + + Lock lock(messageListenerMutex_); + if (messageListenerRunning_) { + // Not paused + return ResultOk; + } + messageListenerRunning_ = true; + const size_t count = incomingMessages_.size(); + lock.unlock(); + + for (size_t i = 0; i < count; i++) { + // Trigger message listener callback in a separate thread + listenerExecutor_->postWork( + boost::bind(&ConsumerImpl::internalListener, shared_from_this())); + } + return ResultOk; +} + +void ConsumerImpl::redeliverUnacknowledgedMessages() { + ClientConnectionPtr cnx = getCnx().lock(); + if (cnx) { + if(cnx->getServerProtocolVersion() >= proto::v2) { + cnx->sendCommand(Commands::newRedeliverUnacknowledgedMessages(consumerId_)); + LOG_DEBUG( + "Sending RedeliverUnacknowledgedMessages command for Consumer - " << getConsumerId()); + } else { + LOG_DEBUG("Reconnecting the client to redeliver the messages for Consumer - " << getName()); + cnx->close(); + } + } else { + LOG_DEBUG("Connection not ready for Consumer - " << getConsumerId()); + } +} + +int ConsumerImpl::getNumOfPrefetchedMessages() const { + return incomingMessages_.size(); +} + +} /* namespace pulsar */ diff --git a/pulsar-client-cpp/lib/ConsumerImpl.h b/pulsar-client-cpp/lib/ConsumerImpl.h new file mode 100644 index 0000000000000..bbc0b4033f5a1 --- /dev/null +++ b/pulsar-client-cpp/lib/ConsumerImpl.h @@ -0,0 +1,141 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_CONSUMERIMPL_H_ +#define LIB_CONSUMERIMPL_H_ + +#include +#include "pulsar/BatchMessageId.h" +#include "pulsar/Result.h" +#include "UnboundedBlockingQueue.h" +#include "HandlerBase.h" +#include "boost/enable_shared_from_this.hpp" +#include "ClientConnection.h" +#include +#include "lib/UnAckedMessageTrackerEnabled.h" +#include "Commands.h" +#include "ExecutorService.h" +#include "ConsumerImplBase.h" +#include "lib/UnAckedMessageTrackerDisabled.h" + +#include "CompressionCodec.h" +#include +#include +#include "BatchAcknowledgementTracker.h" +#include + +using namespace pulsar; + +namespace pulsar { +class UnAckedMessageTracker; +class ExecutorService; +class ConsumerImpl; +class BatchAcknowledgementTracker; +typedef boost::shared_ptr ConsumerImplPtr; +typedef boost::weak_ptr ConsumerImplWeakPtr; + +enum ConsumerTopicType { + NonPartitioned, + Partitioned +}; + + class ConsumerImpl : public ConsumerImplBase, public HandlerBase, public boost::enable_shared_from_this { + + public: + ConsumerImpl(const ClientImplPtr client, const std::string& topic, + const std::string& subscription, const ConsumerConfiguration&, + const ExecutorServicePtr listenerExecutor = ExecutorServicePtr(), + const ConsumerTopicType consumerTopicType = NonPartitioned); + ~ConsumerImpl(); + void setPartitionIndex(int partitionIndex); + int getPartitionIndex(); + void receiveMessages(const ClientConnectionPtr& cnx, unsigned int count); + uint64_t getConsumerId(); + void messageReceived(const ClientConnectionPtr& cnx, const proto::CommandMessage& msg, + bool& isChecksumValid, proto::MessageMetadata& msgMetadata, + SharedBuffer& payload); + int incrementAndGetPermits(uint64_t cnxSequenceId); + void messageProcessed(Message& msg); + inline proto::CommandSubscribe_SubType getSubType(); + void unsubscribeAsync(ResultCallback callback); + void handleUnsubscribe(Result result, ResultCallback callback); + void doAcknowledge(const BatchMessageId& messageId, proto::CommandAck_AckType ackType, + ResultCallback callback); + virtual void disconnectConsumer(); + virtual Future getConsumerCreatedFuture(); + virtual const std::string& getSubscriptionName() const; + virtual const std::string& getTopic() const; + virtual Result receive(Message& msg); + virtual Result receive(Message& msg, int timeout); + Result fetchSingleMessageFromBroker(Message& msg); + virtual void acknowledgeAsync(const MessageId& msgId, ResultCallback callback); + virtual void acknowledgeCumulativeAsync(const MessageId& msgId, ResultCallback callback); + virtual void closeAsync(ResultCallback callback); + virtual void start(); + virtual void shutdown(); + virtual bool isClosed(); + virtual bool isOpen(); + virtual Result pauseMessageListener(); + virtual Result resumeMessageListener(); + virtual void redeliverUnacknowledgedMessages(); +protected: + void connectionOpened(const ClientConnectionPtr& cnx); + void connectionFailed(Result result); + void handleCreateConsumer(const ClientConnectionPtr& cnx, Result result); + + void internalListener(); + void handleClose(Result result, ResultCallback callback); + virtual HandlerBaseWeakPtr get_weak_from_this() { + return shared_from_this(); + } + virtual const std::string& getName() const; + virtual int getNumOfPrefetchedMessages() const ; + private: + bool waitingForZeroQueueSizeMessage; + bool uncompressMessageIfNeeded(const ClientConnectionPtr& cnx, const proto::CommandMessage& msg, + const proto::MessageMetadata& metadata, SharedBuffer& payload); + void discardCorruptedMessage(const ClientConnectionPtr& cnx, + const proto::MessageIdData& messageId, + proto::CommandAck::ValidationError validationError); + void increaseAvailablePermits(const ClientConnectionPtr& currentCnx); + void drainIncomingMessageQueue(size_t count); + unsigned int receiveIndividualMessagesFromBatch(Message &batchedMessage); + + boost::mutex mutexForReceiveWithZeroQueueSize; + const ConsumerConfiguration config_; + const std::string subscription_; + std::string originalSubscriptionName_; + MessageListener messageListener_; + ExecutorServicePtr listenerExecutor_; + ConsumerTopicType consumerTopicType_; + UnboundedBlockingQueue incomingMessages_; + int availablePermits_; + uint64_t consumerId_; + std::string consumerName_; + std::string consumerStr_; + short partitionIndex_; + Promise consumerCreatedPromise_; + bool messageListenerRunning_; + boost::mutex messageListenerMutex_; + CompressionCodecProvider compressionCodecProvider_; + UnAckedMessageTrackerScopedPtr unAckedMessageTrackerPtr_; + BatchAcknowledgementTracker batchAcknowledgementTracker_; + +}; + +} /* namespace pulsar */ + +#endif /* LIB_CONSUMERIMPL_H_ */ diff --git a/pulsar-client-cpp/lib/ConsumerImplBase.h b/pulsar-client-cpp/lib/ConsumerImplBase.h new file mode 100644 index 0000000000000..15ca683df8fc3 --- /dev/null +++ b/pulsar-client-cpp/lib/ConsumerImplBase.h @@ -0,0 +1,52 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef PULSAR_CONSUMER_IMPL_BASE_HEADER +#define PULSAR_CONSUMER_IMPL_BASE_HEADER +#include +#include + +namespace pulsar { +class ConsumerImplBase; + +typedef boost::weak_ptr ConsumerImplBaseWeakPtr; +typedef boost::shared_ptr ConsumerImplBasePtr; + +class ConsumerImplBase { +public: + virtual ~ConsumerImplBase(){ + } + virtual Future getConsumerCreatedFuture() = 0; + virtual const std::string& getSubscriptionName() const = 0; + virtual const std::string& getTopic() const = 0; + virtual Result receive(Message& msg) = 0; + virtual Result receive(Message& msg, int timeout) = 0; + virtual void unsubscribeAsync(ResultCallback callback) = 0; + virtual void acknowledgeAsync(const MessageId& msgId, ResultCallback callback) = 0; + virtual void acknowledgeCumulativeAsync(const MessageId& msgId, ResultCallback callback) = 0; + virtual void closeAsync(ResultCallback callback) = 0; + virtual void start() = 0; + virtual void shutdown() = 0; + virtual bool isClosed() = 0; + virtual bool isOpen() = 0; + virtual Result pauseMessageListener() = 0; + virtual Result resumeMessageListener() = 0; + virtual void redeliverUnacknowledgedMessages() = 0; + virtual const std::string& getName() const = 0; + virtual int getNumOfPrefetchedMessages() const = 0; +}; +} +#endif //PULSAR_CONSUMER_IMPL_BASE_HEADER diff --git a/pulsar-client-cpp/lib/DestinationName.cc b/pulsar-client-cpp/lib/DestinationName.cc new file mode 100644 index 0000000000000..e3eeb7d5ee463 --- /dev/null +++ b/pulsar-client-cpp/lib/DestinationName.cc @@ -0,0 +1,187 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "DestinationName.h" +#include "NamedEntity.h" +#include "LogUtils.h" +#include "PartitionedProducerImpl.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_LOG_OBJECT() +namespace pulsar { + + typedef boost::unique_lock Lock; + // static members + CURL* DestinationName::curl = NULL; + boost::mutex DestinationName::curlHandleMutex; + + CURL* DestinationName::getCurlHandle() { + if (curl == NULL) { + // this handle can not be shared across threads, so had to get here everytime + curl = curl_easy_init(); + } + return curl; + } + //******************************************************************** + DestinationName::DestinationName() { + } + + bool DestinationName::init(const std::string& destinationName) { + destination_ = destinationName; + if(destinationName.find("://") == std::string::npos){ + LOG_ERROR("Destination Name Invalid, domain not present - " << destinationName); + return false; + } + parse(destination_, domain_, property_, cluster_, namespacePortion_, localName_); + if(localName_.empty()) { + LOG_ERROR("Destination Name is not valid, topic name is empty - " << destination_); + return false; + } + namespaceName_ = NamespaceName::get(property_, cluster_, namespacePortion_); + return true; + } + void DestinationName::parse(const std::string& destinationName, + std::string& domain, + std::string& property, + std::string& cluster, + std::string& namespacePortion, + std::string& localName) { + std::string destinationNameCopy = destinationName; + boost::replace_first(destinationNameCopy, "://", "/"); + std::vector pathTokens; + boost::algorithm::split(pathTokens, destinationNameCopy, boost::algorithm::is_any_of("/")); + if (pathTokens.size() < 5) { + LOG_ERROR("Destination Name Invalid, does not have enough parts - " << destinationName); + return; + } + domain = pathTokens[0]; + property = pathTokens[1]; + cluster = pathTokens[2]; + namespacePortion = pathTokens[3]; + size_t slashIndex = -1; + //find four '/', whatever is left is topic local name + for(int i=0; i < 4; i++) { + slashIndex = destinationNameCopy.find('/', slashIndex + 1); + } + // get index to next char to '/' + slashIndex++; + localName = destinationNameCopy.substr( slashIndex, (destinationNameCopy.size() - slashIndex)); + } + std::string DestinationName::getEncodedName(const std::string& nameBeforeEncoding) { + Lock lock(curlHandleMutex); + std::string nameAfterEncoding; + if(getCurlHandle()) { + char *encodedName = curl_easy_escape(getCurlHandle(), nameBeforeEncoding.c_str(), nameBeforeEncoding.size()); + if(encodedName) { + nameAfterEncoding.assign(encodedName); + curl_free(encodedName); + } else { + LOG_ERROR("Unable to encode the name using curl_easy_escape, name - " << nameBeforeEncoding); + } + } else { + LOG_ERROR("Unable to get CURL handle to encode the name - " << nameBeforeEncoding); + } + return nameAfterEncoding; + } + + std::string DestinationName::getDomain() { + return domain_; + } + + std::string DestinationName::getProperty() { + return property_; + } + + std::string DestinationName::getCluster() { + return cluster_; + } + + std::string DestinationName::getNamespacePortion() { + return namespacePortion_; + } + + std::string DestinationName::getLocalName() { + return localName_; + } + + std::string DestinationName::getEncodedLocalName() { + return getEncodedName(localName_); + } + + bool DestinationName::operator ==(const DestinationName& other) { + return (this->destination_.compare(other.destination_) == 0); + } + + bool DestinationName::validateDestination() { + // check domain matches to "persistent", in future check "memory" when server is ready + if (domain_.compare("persistent") != 0) { + return false; + } + if (!property_.empty() && !cluster_.empty() && !namespacePortion_.empty() && !localName_.empty()) { + return NamedEntity::checkName(property_) && NamedEntity::checkName(cluster_) + && NamedEntity::checkName(namespacePortion_); + } else { + return false; + } + } + + boost::shared_ptr DestinationName::get(const std::string& destination) { + boost::shared_ptr ptr(new DestinationName()); + if (!ptr->init(destination)) { + LOG_ERROR("Destination Name Initialization failed"); + return boost::shared_ptr(); + } + if (ptr->validateDestination()) { + return ptr; + } else { + LOG_ERROR("Destination Name Validation Failed"); + return boost::shared_ptr(); + } + } + + //TODO - for now return empty string if there's any error in format, later think about better error handling + std::string DestinationName::getLookupName() { + std::stringstream ss; + std::string seperator("/"); + ss << domain_ << seperator << property_ << seperator << cluster_ << seperator + << namespacePortion_ << seperator << getEncodedLocalName(); + return ss.str(); + } + + std::string DestinationName::toString() { + std::stringstream ss; + std::string seperator("/"); + ss << domain_ << "://" << property_ << seperator << cluster_ << seperator + << namespacePortion_ << seperator << localName_; + return ss.str(); + } + + const std::string DestinationName::getTopicPartitionName(unsigned int partition) { + std::stringstream topicPartitionName; + // make this topic name as well + topicPartitionName << toString()<< PartitionedProducerImpl::PARTITION_NAME_SUFFIX << partition ; + return topicPartitionName.str(); + } +} //namespace pulsar diff --git a/pulsar-client-cpp/lib/DestinationName.h b/pulsar-client-cpp/lib/DestinationName.h new file mode 100644 index 0000000000000..154e94166ff7a --- /dev/null +++ b/pulsar-client-cpp/lib/DestinationName.h @@ -0,0 +1,74 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef _PULSAR_DESTINATION_NAME_HEADER_ +#define _PULSAR_DESTINATION_NAME_HEADER_ + +#include "NamespaceName.h" +#include "ServiceUnitId.h" + +#include +#include +#include +#include + +#pragma GCC visibility push(default) + +namespace pulsar { + class DestinationName : public ServiceUnitId { + private: + std::string destination_; + std::string domain_; + std::string property_; + std::string cluster_; + std::string namespacePortion_; + std::string localName_; + boost::shared_ptr namespaceName_; + + public: + std::string getLookupName(); + std::string getDomain(); + std::string getProperty(); + std::string getCluster(); + std::string getNamespacePortion(); + std::string getLocalName(); + std::string getEncodedLocalName(); + std::string toString(); + static boost::shared_ptr get(const std::string& destination); + bool operator ==(const DestinationName& other); + static std::string getEncodedName(const std::string& nameBeforeEncoding); + const std::string getTopicPartitionName(unsigned int partition); + private: + static CURL* getCurlHandle(); + static CURL* curl; + static boost::mutex curlHandleMutex; + static void parse(const std::string& destinationName, + std::string& domain, + std::string& property, + std::string& cluster, + std::string& namespacePortion, + std::string& localName); + DestinationName(); + bool validateDestination(); + bool init(const std::string& destinationName); + }; + typedef boost::shared_ptr DestinationNamePtr; +} +// end of namespace pulsar + +#pragma GCC visibility pop + +#endif //_PULSAR_DESTINATION_NAME_HEADER_ diff --git a/pulsar-client-cpp/lib/ExecutorService.cc b/pulsar-client-cpp/lib/ExecutorService.cc new file mode 100644 index 0000000000000..958fa5e67c478 --- /dev/null +++ b/pulsar-client-cpp/lib/ExecutorService.cc @@ -0,0 +1,95 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "ExecutorService.h" + +#include +#include +#include +#include +#include + +namespace pulsar { + +ExecutorService::ExecutorService() + : io_service_(), + work_(new BackgroundWork(io_service_)), + worker_(boost::bind(&boost::asio::io_service::run, &io_service_)) { +} + +ExecutorService::~ExecutorService() { + close(); +} + +/* + * factory method of boost::asio::ip::tcp::socket associated with io_service_ instance + * @ returns shared_ptr to this socket + */ +SocketPtr ExecutorService::createSocket() { + return boost::make_shared(boost::ref(io_service_)); +} + +/* + * factory method of Resolver object associated with io_service_ instance + * @returns shraed_ptr to resolver object + */ +TcpResolverPtr ExecutorService::createTcpResolver() { + return boost::make_shared(boost::ref(io_service_)); +} + +DeadlineTimerPtr ExecutorService::createDeadlineTimer() { + return boost::make_shared(boost::ref(io_service_)); +} + +void ExecutorService::close() { + io_service_.stop(); + work_.reset(); + worker_.join(); +} + +void ExecutorService::postWork(boost::function task) { + io_service_.post(task); +} + +///////////////////// + +ExecutorServiceProvider::ExecutorServiceProvider(int nthreads) + : executors_(nthreads), + executorIdx_(0), + mutex_() { +} + +ExecutorServicePtr ExecutorServiceProvider::get() { + Lock lock(mutex_); + + int idx = executorIdx_++ % executors_.size(); + if (!executors_[idx]) { + executors_[idx] = boost::make_shared(); + } + + return executors_[idx]; +} + +void ExecutorServiceProvider::close() { + for (ExecutorList::iterator it = executors_.begin(); it != executors_.end(); ++it) { + if (*it != NULL) { + (*it)->close(); + } + it->reset(); + } +} + +} diff --git a/pulsar-client-cpp/lib/ExecutorService.h b/pulsar-client-cpp/lib/ExecutorService.h new file mode 100644 index 0000000000000..3bf7a62322949 --- /dev/null +++ b/pulsar-client-cpp/lib/ExecutorService.h @@ -0,0 +1,95 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef _PULSAR_EXECUTOR_SERVICE_HEADER_ +#define _PULSAR_EXECUTOR_SERVICE_HEADER_ + +#include +#include +#include +#include +#include + +#pragma GCC visibility push(default) + +namespace pulsar { +typedef boost::shared_ptr SocketPtr; +typedef boost::shared_ptr TcpResolverPtr; +typedef boost::shared_ptr DeadlineTimerPtr; +class ExecutorService : private boost::noncopyable { + + public: + ExecutorService(); + ~ExecutorService(); + + SocketPtr createSocket(); + TcpResolverPtr createTcpResolver(); + DeadlineTimerPtr createDeadlineTimer(); + void postWork(boost::function task); + void close(); + + private: + + /* + * only called once and within lock so no need to worry about thread-safety + */ + void startWorker(); + + /* + * io_service is our interface to os, io object schedule async ops on this object + */ + boost::asio::io_service io_service_; + + /* + * work will not let io_service.run() return even after it has finished work + * it will keep it running in the background so we don't have to take care of it + */ + typedef boost::asio::io_service::work BackgroundWork; + boost::scoped_ptr work_; + + /* + * worker thread which runs until work object is destroyed, it's running io_service::run in + * background invoking async handlers as they are finished and result is available from + * io_service + */ + boost::asio::detail::thread worker_; +}; + +typedef boost::shared_ptr ExecutorServicePtr; + +class ExecutorServiceProvider { + public: + explicit ExecutorServiceProvider(int nthreads); + + ExecutorServicePtr get(); + + void close(); + + private: + typedef std::vector ExecutorList; + ExecutorList executors_; + int executorIdx_; + boost::mutex mutex_; + typedef boost::unique_lock Lock; +}; + +typedef boost::shared_ptr ExecutorServiceProviderPtr; + +} + +#pragma GCC visibility pop + +#endif //_PULSAR_EXECUTOR_SERVICE_HEADER_ diff --git a/pulsar-client-cpp/lib/Future.h b/pulsar-client-cpp/lib/Future.h new file mode 100644 index 0000000000000..faba32bbb65be --- /dev/null +++ b/pulsar-client-cpp/lib/Future.h @@ -0,0 +1,165 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_FUTURE_H_ +#define LIB_FUTURE_H_ + +#include +#include +#include +#include +#include + +#include + +#pragma GCC visibility push(default) + +typedef boost::unique_lock Lock; + +namespace pulsar { + +template +struct InternalState { + boost::mutex mutex; + boost::condition_variable condition; + Result result; + Type value; + bool complete; + + std::list > listeners; +}; + +template +class Future { + public: + typedef boost::function ListenerCallback; + + Future& addListener(ListenerCallback callback) { + InternalState* state = state_.get(); + Lock lock(state->mutex); + + if (state->complete) { + lock.unlock(); + callback(state->result, state->value); + } else { + state->listeners.push_back(callback); + } + + return *this; + } + + Result get(Type& result) { + InternalState* state = state_.get(); + Lock lock(state->mutex); + + if (!state->complete) { + // Wait for result + while (!state->complete) { + state->condition.wait(lock); + } + } + + result = state->value; + return state->result; + } + + private: + typedef boost::shared_ptr > InternalStatePtr; + Future(InternalStatePtr state) + : state_(state) { + } + + boost::shared_ptr > state_; + + template + friend class Promise; +}; + +template +class Promise { + public: + Promise() + : state_(boost::make_shared >()) { + } + + bool setValue(const Type& value) { + InternalState* state = state_.get(); + Lock lock(state->mutex); + + if (state->complete) { + return false; + } + + state->value = value; + state->result = Result(); + state->complete = true; + + typename std::list::iterator it; + for (it = state->listeners.begin(); it != state->listeners.end(); ++it) { + ListenerCallback& callback = *it; + callback(state->result, state->value); + } + + state->listeners.clear(); + state->condition.notify_all(); + return true; + } + + bool setFailed(Result result) { + InternalState* state = state_.get(); + Lock lock(state->mutex); + + if (state->complete) { + return false; + } + + state->result = result; + state->complete = true; + + typename std::list::iterator it; + for (it = state->listeners.begin(); it != state->listeners.end(); ++it) { + ListenerCallback& callback = *it; + callback(state->result, state->value); + } + + state->listeners.clear(); + state->condition.notify_all(); + return true; + } + + bool isComplete() const { + InternalState* state = state_.get(); + Lock lock(state->mutex); + return state->complete; + } + + Future getFuture() const { + return Future(state_); + } + + private: + typedef boost::function ListenerCallback; + boost::shared_ptr > state_; +}; + +class Void { +}; + +} /* namespace pulsar */ + +#pragma GCC visibility pop + +#endif /* LIB_FUTURE_H_ */ diff --git a/pulsar-client-cpp/lib/HandlerBase.cc b/pulsar-client-cpp/lib/HandlerBase.cc new file mode 100644 index 0000000000000..bfeeeb5d56012 --- /dev/null +++ b/pulsar-client-cpp/lib/HandlerBase.cc @@ -0,0 +1,161 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "HandlerBase.h" +#include + +#include + +#include "LogUtils.h" + +DECLARE_LOG_OBJECT() + +namespace pulsar { + +HandlerBase::HandlerBase(const ClientImplPtr& client, const std::string& topic) + : client_(client), + topic_(topic), + connection_(), + mutex_(), + creationTimestamp_(now()), + operationTimeut_(seconds(client->conf().getOperationTimeoutSeconds())), + state_(Pending), + backoff_(milliseconds(100), seconds(60)), + timer_(client->getIOExecutorProvider()->get()->createDeadlineTimer()) { +} + +HandlerBase::~HandlerBase() { + timer_->cancel(); +} + +void HandlerBase::start() { + grabCnx(); +} + +void HandlerBase::grabCnx() { + if (connection_.lock()) { + LOG_INFO(getName() << "Ignoring reconnection request since we're already connected"); + return; + } + + LOG_INFO(getName() << "Getting connection from pool"); + ClientImplPtr client = client_.lock(); + Future future = client->getConnection(topic_); + future.addListener( + boost::bind(&HandlerBase::handleNewConnection, _1, _2, get_weak_from_this())); +} + +void HandlerBase::handleNewConnection(Result result, ClientConnectionWeakPtr connection, + HandlerBaseWeakPtr weakHandler) { + HandlerBasePtr handler = weakHandler.lock(); + if (!handler) { + LOG_DEBUG("HandlerBase Weak reference is not valid anymore"); + return; + } + if (result == ResultOk) { + ClientConnectionPtr conn = connection.lock(); + if (conn) { + LOG_DEBUG(handler->getName() << "Connected to broker: " << conn->cnxString()); + handler->connectionOpened(conn); + return; + } + // TODO - look deeper into why the connection is null while the result is ResultOk + LOG_INFO(handler->getName() << "ClientConnectionPtr is no longer valid"); + } + handler->connectionFailed(result); + scheduleReconnection(handler); +} + +void HandlerBase::handleDisconnection(Result result, ClientConnectionWeakPtr connection, + HandlerBaseWeakPtr weakHandler) { + HandlerBasePtr handler = weakHandler.lock(); + if (!handler) { + LOG_DEBUG("HandlerBase Weak reference is not valid anymore"); + return; + } + + Lock lock(handler->mutex_); + State state = handler->state_; + + ClientConnectionPtr currentConnection = handler->connection_.lock(); + if (currentConnection && connection.lock().get() != currentConnection.get()) { + LOG_WARN( + handler->getName() << "Ignoring connection closed since we are already attached to a newer connection"); + return; + } + + if (currentConnection) { + currentConnection.reset(); + } + + switch (state) { + case Pending: + case Ready: + scheduleReconnection(handler); + break; + + case Closing: + case Closed: + case Failed: + LOG_DEBUG(handler->getName() << + "Ignoring connection closed event since the handler is not used anymore"); + break; + } +} + +bool HandlerBase::isRetriableError(Result result) { + switch (result) { + case ResultServiceUnitNotReady: + return true; + default: + return false; + } +} + +void HandlerBase::scheduleReconnection(HandlerBasePtr handler) { + if (handler->state_ == Pending || handler->state_ == Ready) { + TimeDuration delay = handler->backoff_.next(); + + LOG_INFO( + handler->getName() << "Schedule reconnection in " << (delay.total_milliseconds() / 1000.0) << " s"); + handler->timer_->expires_from_now(delay); + //passing shared_ptr here since time_ will get destroyed, so tasks will be cancelled + //so we will not run into the case where grabCnx is invoked on out of scope handler + handler->timer_->async_wait(boost::bind(&HandlerBase::handleTimeout, _1, handler)); + } +} + +void HandlerBase::handleTimeout(const boost::system::error_code& ec, HandlerBasePtr handler) { + if (ec) { + LOG_DEBUG(handler->getName() << "Ignoring timer cancelled event, code[" << ec <<"]"); + return; + } else { + handler->grabCnx(); + } +} + +ptime now() { + return microsec_clock::universal_time(); +} + +int64_t currentTimeMillis() { + static ptime time_t_epoch(boost::gregorian::date(1970, 1, 1)); + + time_duration diff = now() - time_t_epoch; + return diff.total_milliseconds(); +} + +} diff --git a/pulsar-client-cpp/lib/HandlerBase.h b/pulsar-client-cpp/lib/HandlerBase.h new file mode 100644 index 0000000000000..357c69694ae75 --- /dev/null +++ b/pulsar-client-cpp/lib/HandlerBase.h @@ -0,0 +1,118 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef _PULSAR_HANDLER_BASE_HEADER_ +#define _PULSAR_HANDLER_BASE_HEADER_ +#include "Backoff.h" +#include "ClientImpl.h" +#include "ClientConnection.h" +#include +#include +#include +#include + +namespace pulsar { + +using namespace boost::posix_time; +using boost::posix_time::milliseconds; +using boost::posix_time::seconds; + +ptime now(); +int64_t currentTimeMillis(); + +class HandlerBase; +typedef boost::weak_ptr HandlerBaseWeakPtr; +typedef boost::shared_ptr HandlerBasePtr; + +class HandlerBase { + + public: + HandlerBase(const ClientImplPtr& client, const std::string& topic); + + virtual ~HandlerBase(); + + void start(); + + /* + * get method for derived class to access weak ptr to connection so that they + * have to check if they can get a shared_ptr out of it or not + */ + ClientConnectionWeakPtr getCnx() { + return connection_; + } + + protected: + /* + * tries reconnection and sets connection_ to valid object + */ + void grabCnx(); + + /* + * Schedule reconnection after backoff time + */ + static void scheduleReconnection(HandlerBasePtr handler); + + /* + * Should we retry in error that are transient + */ + bool isRetriableError(Result result); + /* + * connectionOpened will be implemented by derived class to receive notification + */ + + virtual void connectionOpened(const ClientConnectionPtr& connection) = 0; + + virtual void connectionFailed(Result result) = 0; + + virtual HandlerBaseWeakPtr get_weak_from_this() = 0; + + virtual const std::string& getName() const = 0; + + private: + static void handleNewConnection(Result result, ClientConnectionWeakPtr connection, + HandlerBaseWeakPtr wp); + static void handleDisconnection(Result result, ClientConnectionWeakPtr connection, + HandlerBaseWeakPtr wp); + + static void handleTimeout(const boost::system::error_code& ec, HandlerBasePtr handler); + + protected: + ClientImplWeakPtr client_; + const std::string topic_; + ClientConnectionWeakPtr connection_; + boost::mutex mutex_; + ptime creationTimestamp_; + + const TimeDuration operationTimeut_; + typedef boost::unique_lock Lock; + + enum State { + Pending, + Ready, + Closing, + Closed, + Failed + }; + + State state_; + Backoff backoff_; + + private: + DeadlineTimerPtr timer_; + friend class ClientConnection; +}; +} +#endif //_PULSAR_HANDLER_BASE_HEADER_ diff --git a/pulsar-client-cpp/lib/Latch.cc b/pulsar-client-cpp/lib/Latch.cc new file mode 100644 index 0000000000000..7f555185d35cd --- /dev/null +++ b/pulsar-client-cpp/lib/Latch.cc @@ -0,0 +1,68 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "Latch.h" + +#include + +namespace pulsar { + +struct CountIsZero { + const int& count_; + + CountIsZero(const int& count) + : count_(count) { + } + + bool operator()() const { + return count_ == 0; + } +}; + +Latch::Latch(int count) + : state_(boost::make_shared()) { + state_->count = count; +} + +void Latch::countdown() { + Lock lock(state_->mutex); + + state_->count--; + + if (state_->count == 0) { + state_->condition.notify_all(); + } +} + +int Latch::getCount() { + Lock lock(state_->mutex); + + return state_->count; + +} + +void Latch::wait() { + Lock lock(state_->mutex); + + state_->condition.wait(lock, CountIsZero(state_->count)); +} + +bool Latch::wait(const boost::posix_time::time_duration& timeout) { + Lock lock(state_->mutex); + return state_->condition.timed_wait(lock, timeout, CountIsZero(state_->count)); +} + +} /* namespace pulsar */ diff --git a/pulsar-client-cpp/lib/Latch.h b/pulsar-client-cpp/lib/Latch.h new file mode 100644 index 0000000000000..c2685f6b09cd5 --- /dev/null +++ b/pulsar-client-cpp/lib/Latch.h @@ -0,0 +1,55 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_LATCH_H_ +#define LIB_LATCH_H_ + +#include +#include +#include + +#pragma GCC visibility push(default) + +namespace pulsar { + +class Latch { + public: + Latch(int count); + + void countdown(); + + void wait(); + + bool wait(const boost::posix_time::time_duration& timeout); + + int getCount(); + + private: + struct InternalState { + boost::mutex mutex; + boost::condition_variable condition; + int count; + }; + + typedef boost::unique_lock Lock; + boost::shared_ptr state_; +}; +typedef boost::shared_ptr LatchPtr; +} /* namespace pulsar */ + +#pragma GCC visibility pop + +#endif /* LIB_LATCH_H_ */ diff --git a/pulsar-client-cpp/lib/LogUtils.cc b/pulsar-client-cpp/lib/LogUtils.cc new file mode 100644 index 0000000000000..dcee65d213253 --- /dev/null +++ b/pulsar-client-cpp/lib/LogUtils.cc @@ -0,0 +1,51 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "LogUtils.h" + +#include +#include +#include +#include +#include +#include + +using namespace log4cxx; + +void LogUtils::init(const std::string& logfilePath) { + try { + if (logfilePath.empty()) { + if (!LogManager::getLoggerRepository()->isConfigured()) { + LogManager::getLoggerRepository()->setConfigured(true); + LoggerPtr root = Logger::getRootLogger(); + static const LogString TTCC_CONVERSION_PATTERN( + LOG4CXX_STR("%d{HH:mm:ss.SSS} [%t] %-5p %l - %m%n")); + LayoutPtr layout(new PatternLayout(TTCC_CONVERSION_PATTERN)); + AppenderPtr appender(new ConsoleAppender(layout)); + root->setLevel(log4cxx::Level::getInfo()); + root->addAppender(appender); + } + } else { + log4cxx::PropertyConfigurator::configure(logfilePath); + } + } catch (const std::exception& e) { + std::cerr << "exception caught while configuring log4cpp via '" << logfilePath << "': " + << e.what() << std::endl; + } catch (...) { + std::cerr << "unknown exception while configuring log4cpp via '" << logfilePath << "'." + << std::endl; + } +} diff --git a/pulsar-client-cpp/lib/LogUtils.h b/pulsar-client-cpp/lib/LogUtils.h new file mode 100644 index 0000000000000..7fd47e62fdf79 --- /dev/null +++ b/pulsar-client-cpp/lib/LogUtils.h @@ -0,0 +1,70 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LOG_UTIL_H +#define LOG_UTIL_H + +#include +#include +#include + +#define DECLARE_LOG_OBJECT() \ + static log4cxx::LoggerPtr& logger() \ + { \ + static boost::thread_specific_ptr threadSpecificLogPtr; \ + log4cxx::LoggerPtr* ptr = threadSpecificLogPtr.get(); \ + if (!ptr) { \ + threadSpecificLogPtr.reset(new log4cxx::LoggerPtr(log4cxx::Logger::getLogger("pulsar." __FILE__)));\ + ptr = threadSpecificLogPtr.get(); \ + } \ + return *ptr; \ + } + +#define LOG_DEBUG(message) { \ + if (LOG4CXX_UNLIKELY(logger()->isDebugEnabled())) {\ + ::log4cxx::helpers::MessageBuffer oss_; \ + logger()->forcedLog(::log4cxx::Level::getDebug(), oss_.str(((std::ostream&)oss_) << message), LOG4CXX_LOCATION); }} + +#define LOG_INFO(message) { \ + if (logger()->isInfoEnabled()) {\ + ::log4cxx::helpers::MessageBuffer oss_; \ + logger()->forcedLog(::log4cxx::Level::getInfo(), oss_.str(((std::ostream&)oss_) << message), LOG4CXX_LOCATION); }} + +#define LOG_WARN(message) { \ + if (logger()->isWarnEnabled()) {\ + ::log4cxx::helpers::MessageBuffer oss_; \ + logger()->forcedLog(::log4cxx::Level::getWarn(), oss_.str(((std::ostream&)oss_) << message), LOG4CXX_LOCATION); }} + +#define LOG_ERROR(message) { \ + if (logger()->isErrorEnabled()) {\ + ::log4cxx::helpers::MessageBuffer oss_; \ + logger()->forcedLog(::log4cxx::Level::getError(), oss_.str(((std::ostream&)oss_) << message), LOG4CXX_LOCATION); }} + +#define LOG_FATAL(message) { \ + if (logger()->isFatalEnabled()) {\ + ::log4cxx::helpers::MessageBuffer oss_; \ + logger()->forcedLog(::log4cxx::Level::getFatal(), oss_.str(((std::ostream&)oss_) << message), LOG4CXX_LOCATION); }} + +#pragma GCC visibility push(default) + +class LogUtils { + public: + static void init(const std::string& logConfFilePath); +}; + +#pragma GCC visibility pop + +#endif diff --git a/pulsar-client-cpp/lib/LookupDataResult.h b/pulsar-client-cpp/lib/LookupDataResult.h new file mode 100644 index 0000000000000..855fa153e29a9 --- /dev/null +++ b/pulsar-client-cpp/lib/LookupDataResult.h @@ -0,0 +1,76 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef _PULSAR_LOOKUP_DATA_RESULT_HEADER_ +#define _PULSAR_LOOKUP_DATA_RESULT_HEADER_ +#include + +namespace pulsar { +class LookupDataResult; +typedef boost::shared_ptr LookupDataResultPtr; +typedef Promise LookupDataResultPromise; +typedef boost::shared_ptr LookupDataResultPromisePtr; + +class LookupDataResult { + public: + void setBrokerUrl(const std::string& brokerUrl) { + brokerUrl_ = brokerUrl; + } + void setBrokerUrlSsl(const std::string& brokerUrlSsl) { + brokerUrlSsl_ = brokerUrlSsl; + } + std::string getBrokerUrl() { + return brokerUrl_; + } + std::string getBrokerUrlSsl() { + return brokerUrlSsl_; + } + + bool isAuthoritative() const { + return authoritative; + } + + void setAuthoritative(bool authoritative) { + this->authoritative = authoritative; + } + + int getPartitions() const { + return partitions; + } + + void setPartitions(int partitions) { + this->partitions = partitions; + } + + bool isRedirect() const { + return redirect; + } + + void setRedirect(bool redirect) { + this->redirect = redirect; + } + + private: + std::string brokerUrl_; + std::string brokerUrlSsl_; + int partitions; + bool authoritative; + bool redirect; +}; + +} + +#endif // _PULSAR_LOOKUP_DATA_RESULT_HEADER_ diff --git a/pulsar-client-cpp/lib/Message.cc b/pulsar-client-cpp/lib/Message.cc new file mode 100644 index 0000000000000..34ffaa4775d91 --- /dev/null +++ b/pulsar-client-cpp/lib/Message.cc @@ -0,0 +1,157 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include + +#include +#include + +#include "PulsarApi.pb.h" + +#include "MessageImpl.h" +#include "SharedBuffer.h" + +#include + +using namespace pulsar; + +namespace pulsar { + +const static std::string emptyString; +const static MessageId invalidMessageId; + +const Message::StringMap& Message::getProperties() const { + return impl_->properties(); +} + +bool Message::hasProperty(const std::string& name) const { + const StringMap& m = impl_->properties(); + return m.find(name) != m.end(); +} + +const std::string& Message::getProperty(const std::string& name) const { + if (hasProperty(name)) { + const StringMap& m = impl_->properties(); + return m.at(name); + } else { + return emptyString; + } +} + +const void* Message::getData() const { + return impl_->payload.data(); +} + +std::size_t Message::getLength() const { + return impl_->payload.readableBytes(); +} + +std::string Message::getDataAsString() const { + return std::string((const char*) getData(), getLength()); +} + +Message::Message() + : impl_() { +} + +Message::Message(MessageImplPtr& impl) + : impl_(impl) { +} + +Message::Message(const proto::CommandMessage& msg, proto::MessageMetadata& metadata, + SharedBuffer& payload) + : impl_(boost::make_shared()) { + impl_->messageId = BatchMessageId(msg.message_id().ledgerid(), msg.message_id().entryid()); + impl_->metadata = metadata; + impl_->payload = payload; +} + +Message::Message(const BatchMessageId& messageID, proto::MessageMetadata& metadata, SharedBuffer& payload, proto::SingleMessageMetadata& singleMetadata) +: impl_(boost::make_shared()) { + impl_->messageId = messageID; + impl_->metadata = metadata; + impl_->payload = payload; + impl_->metadata.mutable_properties()->CopyFrom(singleMetadata.properties()); +} + +const MessageId& Message::getMessageId() const { + if (!impl_) { + return invalidMessageId; + } else { + return impl_->messageId; + } +} + +bool Message::hasPartitionKey() const{ + if(impl_) { + return impl_->hasPartitionKey(); + } + return false; +} + +const std::string& Message::getPartitionKey() const { + if (!impl_) { + return emptyString; + } + return impl_->getPartitionKey(); +} + +uint64_t Message::getPublishTimestamp() const { + return impl_ ? impl_->getPublishTimestamp() : 0ull; +} + +#pragma GCC visibility push(default) + +std::ostream& operator<<(std::ostream& s, const Message::StringMap& map) { + // Output at most 10 elements -- appropriate if used for logging. + s << '{'; + + Message::StringMap::const_iterator begin = map.begin(); + Message::StringMap::const_iterator end = map.end(); + for (int i = 0; begin != end && i < 10; ++i, ++begin) { + if (i > 0) { + s << ", "; + } + + s << "'" << begin->first << "':'" << begin->second << "'"; + } + + if (begin != end) { + s << " ..."; + } + + s << '}'; + return s; +} + +std::ostream& operator<<(std::ostream& s, const Message& msg) { + assert(msg.impl_.get()); + assert(msg.impl_->metadata.has_sequence_id()); + assert(msg.impl_->metadata.has_publish_time()); + s << "Message(prod=" << msg.impl_->metadata.producer_name() << ", seq=" + << msg.impl_->metadata.sequence_id() << ", publish_time=" + << msg.impl_->metadata.publish_time() << ", payload_size=" << msg.getLength() << ", msg_id=" + << msg.getMessageId() << ", props=" << msg.getProperties() << ')'; + if (! msg.impl_->metadata.has_producer_name()) { + s << "WARN: Message has no producer name set, this should only happen if batch messaging is enabled"; + } + return s; +} + +#pragma GCC visibility pop + +} diff --git a/pulsar-client-cpp/lib/MessageBuilder.cc b/pulsar-client-cpp/lib/MessageBuilder.cc new file mode 100644 index 0000000000000..182bef49d1113 --- /dev/null +++ b/pulsar-client-cpp/lib/MessageBuilder.cc @@ -0,0 +1,114 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include + +#include + +#include "MessageImpl.h" +#include "SharedBuffer.h" +#include "LogUtils.h" +#include "PulsarApi.pb.h" + +DECLARE_LOG_OBJECT() + +#include "ObjectPool.h" + +using namespace pulsar; + +namespace pulsar { + +ObjectPool messagePool; + +MessageBuilder::MessageBuilder() { + impl_ = messagePool.create(); +} + +MessageBuilder& MessageBuilder::create() { + impl_ = messagePool.create(); + return *this; +} + +Message MessageBuilder::build() { + return Message(impl_); +} + +void MessageBuilder::checkMetadata() { + if (!impl_.get()) { + LOG_FATAL("Cannot reuse the same message builder to build a message"); + abort(); + } +} + +MessageBuilder& MessageBuilder::setContent(const void* data, size_t size) { + checkMetadata(); + impl_->payload = SharedBuffer::copy((char *) data, size); + return *this; +} + +MessageBuilder& MessageBuilder::setAllocatedContent(void* data, size_t size) { + checkMetadata(); + impl_->payload = SharedBuffer::wrap((char *) data, size); + return *this; +} + +MessageBuilder& MessageBuilder::setContent(const std::string& data) { + checkMetadata(); + impl_->payload = SharedBuffer::copy((char *) data.c_str(), data.length()); + return *this; +} + +MessageBuilder& MessageBuilder::setProperty(const std::string& name, const std::string& value) { + checkMetadata(); + proto::KeyValue *keyValue = proto::KeyValue().New(); + keyValue->set_key(name); + keyValue->set_value(value); + impl_->metadata.mutable_properties()->AddAllocated(keyValue); + return *this; +} + +MessageBuilder& MessageBuilder::setProperties(const StringMap& properties) { + checkMetadata(); + for (StringMap::const_iterator it = properties.begin(); it != properties.end(); it++) { + setProperty(it->first, it->second); + } + return *this; +} + +MessageBuilder& MessageBuilder::setPartitionKey(const std::string& partitionKey) { + checkMetadata(); + impl_->metadata.set_partition_key(partitionKey); + return *this; +} + +MessageBuilder& MessageBuilder::setReplicationClusters(const std::vector& clusters) { + checkMetadata(); + google::protobuf::RepeatedPtrField r(clusters.begin(), clusters.end()); + r.Swap(impl_->metadata.mutable_replicate_to()); + return *this; +} + +MessageBuilder& MessageBuilder::disableReplication(bool flag) { + checkMetadata(); + google::protobuf::RepeatedPtrField r; + if (flag) { + r.AddAllocated(new std::string("__local__")); + } + r.Swap(impl_->metadata.mutable_replicate_to()); + return *this; +} + +} diff --git a/pulsar-client-cpp/lib/MessageId.cc b/pulsar-client-cpp/lib/MessageId.cc new file mode 100644 index 0000000000000..39227125b0a09 --- /dev/null +++ b/pulsar-client-cpp/lib/MessageId.cc @@ -0,0 +1,52 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include + +#include + +namespace pulsar { + +MessageId::MessageId() + : ledgerId_(-1), + entryId_(-1), + partition_(-1) { +} + +MessageId& MessageId::operator=(const MessageId& m) { + entryId_ = m.entryId_; + ledgerId_ = m.ledgerId_; + partition_ = m.partition_; + return *this; +} + +MessageId::MessageId(int64_t ledgerId, int64_t entryId) + : ledgerId_(ledgerId), + entryId_(entryId), + partition_(-1) { + // partition is set explicitly in consumerImpl when message is received + // consumer's partition is assigned to this partition +} + + +#pragma GCC visibility push(default) +std::ostream& operator<<(std::ostream& s, const pulsar::MessageId& messageId) { + s << '(' << messageId.ledgerId_ << ',' << messageId.entryId_ << ',' << messageId.partition_ << ')'; + return s; +} +#pragma GCC visibility pop + +} diff --git a/pulsar-client-cpp/lib/MessageImpl.cc b/pulsar-client-cpp/lib/MessageImpl.cc new file mode 100644 index 0000000000000..a3773651bfdd1 --- /dev/null +++ b/pulsar-client-cpp/lib/MessageImpl.cc @@ -0,0 +1,54 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "MessageImpl.h" + +namespace pulsar { + + MessageImpl::MessageImpl() + : metadata(), + payload(), + messageId(), + cnx_(0) { + } + + const Message::StringMap& MessageImpl::properties() { + if (properties_.size() == 0) { + for (int i = 0; i < metadata.properties_size(); i++) { + const std::string& key = metadata.properties(i).key(); + const std::string& value = metadata.properties(i).value(); + properties_.insert(std::make_pair(key, value)); + } + } + return properties_; + } + + const std::string& MessageImpl::getPartitionKey() const { + return metadata.partition_key(); + } + + bool MessageImpl::hasPartitionKey() const { + return metadata.has_partition_key(); + } + + uint64_t MessageImpl::getPublishTimestamp() const { + if (metadata.has_publish_time()) { + return metadata.publish_time(); + } else { + return 0ull; + } + } +} diff --git a/pulsar-client-cpp/lib/MessageImpl.h b/pulsar-client-cpp/lib/MessageImpl.h new file mode 100644 index 0000000000000..8b10e986b0f8c --- /dev/null +++ b/pulsar-client-cpp/lib/MessageImpl.h @@ -0,0 +1,55 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_MESSAGEIMPL_H_ +#define LIB_MESSAGEIMPL_H_ + +#include +#include +#include "pulsar/BatchMessageId.h" +#include "SharedBuffer.h" +#include "PulsarApi.pb.h" + +#include + +using namespace pulsar; +namespace pulsar { + +class ClientConnection; +class BatchMessageContainer; + +class MessageImpl { + public: + MessageImpl(); + + const Message::StringMap& properties(); + + proto::MessageMetadata metadata; + SharedBuffer payload; + BatchMessageId messageId; + ClientConnection* cnx_; + + const std::string& getPartitionKey() const; + bool hasPartitionKey() const; + + uint64_t getPublishTimestamp() const; + private: + Message::StringMap properties_; +}; + +} + +#endif /* LIB_MESSAGEIMPL_H_ */ diff --git a/pulsar-client-cpp/lib/NamedEntity.cc b/pulsar-client-cpp/lib/NamedEntity.cc new file mode 100644 index 0000000000000..e7e8a4e1d1cda --- /dev/null +++ b/pulsar-client-cpp/lib/NamedEntity.cc @@ -0,0 +1,23 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "NamedEntity.h" + +const boost::regex NamedEntity::pattern = boost::regex("^[-=:.\\w]*$"); + +bool NamedEntity::checkName(const std::string& name) { + return boost::regex_match(name, pattern) ? true : false; +} diff --git a/pulsar-client-cpp/lib/NamedEntity.h b/pulsar-client-cpp/lib/NamedEntity.h new file mode 100644 index 0000000000000..589a3a88c5798 --- /dev/null +++ b/pulsar-client-cpp/lib/NamedEntity.h @@ -0,0 +1,28 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef _PULSAR_NAMED_ENTITY_HEADER_ +#define _PULSAR_NAMED_ENTITY_HEADER_ + +#include + +class NamedEntity { + private: + static const boost::regex pattern; + public: + static bool checkName(const std::string& name); +}; +#endif diff --git a/pulsar-client-cpp/lib/NamespaceName.cc b/pulsar-client-cpp/lib/NamespaceName.cc new file mode 100644 index 0000000000000..82986a54325c0 --- /dev/null +++ b/pulsar-client-cpp/lib/NamespaceName.cc @@ -0,0 +1,80 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "NamespaceName.h" +#include "NamedEntity.h" +#include "LogUtils.h" + +#include +#include +#include +#include +#include + +DECLARE_LOG_OBJECT() + +boost::shared_ptr NamespaceName::get(const std::string& property, + const std::string& cluster, + const std::string& namespaceName) { + if (validateNamespace(property, cluster, namespaceName)) { + boost::shared_ptr ptr(new NamespaceName(property, cluster, namespaceName)); + return ptr; + } else { + LOG_DEBUG("Returning a null NamespaceName object"); + return boost::shared_ptr(); + } +} + +NamespaceName::NamespaceName(const std::string& property, const std::string& cluster, + const std::string& namespaceName) { + std::ostringstream oss; + oss << property << "/" << cluster << "/" << namespaceName; + this->namespace_ = oss.str(); + this->property_ = property; + this->cluster_ = cluster; + this->localName_ = namespaceName; +} + +bool NamespaceName::validateNamespace(const std::string& property, const std::string& cluster, + const std::string& namespaceName) { + if (!property.empty() && !cluster.empty() && !namespaceName.empty()) { + return NamedEntity::checkName(property) && NamedEntity::checkName(cluster) + && NamedEntity::checkName(namespaceName); + } else { + LOG_DEBUG("Empty parameters passed for validating namespace"); + return false; + } +} + +boost::shared_ptr NamespaceName::getNamespaceObject() { + return boost::shared_ptr(this); +} + +bool NamespaceName::operator ==(const NamespaceName& namespaceName) { + return this->namespace_.compare(namespaceName.namespace_) == 0; +} + +std::string NamespaceName::getProperty() { + return this->property_; +} + +std::string NamespaceName::getCluster() { + return this->cluster_; +} + +std::string NamespaceName::getLocalName() { + return this->localName_; +} diff --git a/pulsar-client-cpp/lib/NamespaceName.h b/pulsar-client-cpp/lib/NamespaceName.h new file mode 100644 index 0000000000000..7fa6c7ea0a57f --- /dev/null +++ b/pulsar-client-cpp/lib/NamespaceName.h @@ -0,0 +1,52 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef _PULSAR_NAMESPACE_NAME_HEADER_ +#define _PULSAR_NAMESPACE_NAME_HEADER_ + +#include "ServiceUnitId.h" + +#include +#include + + +#pragma GCC visibility push(default) + +class NamespaceName : public ServiceUnitId { + public: + boost::shared_ptr getNamespaceObject(); + std::string getProperty(); + std::string getCluster(); + std::string getLocalName(); + static boost::shared_ptr get(const std::string& property, + const std::string& cluster, + const std::string& namespaceName); + bool operator ==(const NamespaceName& namespaceName); + + private: + std::string namespace_; + std::string property_; + std::string cluster_; + std::string localName_; + static bool validateNamespace(const std::string& property, const std::string& cluster, + const std::string& namespace_); + NamespaceName(const std::string& property, const std::string& cluster, + const std::string& namespace_); +}; + +#pragma GCC visibility pop + +#endif diff --git a/pulsar-client-cpp/lib/ObjectPool.h b/pulsar-client-cpp/lib/ObjectPool.h new file mode 100644 index 0000000000000..6e478b19e44d9 --- /dev/null +++ b/pulsar-client-cpp/lib/ObjectPool.h @@ -0,0 +1,243 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_OBJECTPOOL_H_ +#define LIB_OBJECTPOOL_H_ + +#include +#include +#include +#include +#include +#include + +namespace pulsar { + +template +class Allocator { + public: + // Allocator must be stateless, so put everything in this static + class Impl { + public: + // cheap lock to acquire + static boost::mutex mutex_; + + // note: use std::forward_list<> when switching to C++11 mode + struct Node { + Node* next; + explicit Node(Node* n) : next(n) {} + }; + Node *head_; + int pushSize_; + + struct GlobalPool { + Node *node_; + int nodeCount_; + GlobalPool *next_; + explicit GlobalPool(GlobalPool* n) : next_(n) {} + }; + static struct GlobalPool *globalPool_; + static int globalNodeCount_; + + Impl(const Impl&); + void operator=(const Impl&); + + void* pop() { + if (!head_) { + // size = 0 + boost::lock_guard lock(mutex_); + + if (!globalPool_) { + return NULL; + } + + GlobalPool *poolEntry = globalPool_; + head_ = globalPool_->node_; + pushSize_ += globalPool_->nodeCount_; + globalNodeCount_ -= globalPool_->nodeCount_; + globalPool_ = globalPool_->next_; + delete poolEntry; + + } + void* result = head_; + if (result) { + head_ = head_->next; + pushSize_--; + } + return result; + } + + bool push(void* p) { + + // Once thread specific entries reaches 10% of max size, push them to GlobalPool + if (pushSize_ >= MaxSize*0.1) { + + bool deleteList = true; + { + // Move the entries to global pool + boost::lock_guard lock(mutex_); + + // If total node count reached max allowed cache limit, + // skip adding to global pool. + if ((globalNodeCount_ + pushSize_) <= MaxSize) { + + deleteList = false; + + globalPool_ = new GlobalPool(globalPool_); + globalPool_->node_ = head_; + globalPool_->nodeCount_ = pushSize_; + globalNodeCount_ += pushSize_; + } + + } + if (deleteList) { + pushSize_ = 0; + deleteLinkedList(head_); + } + head_ = new(p) Node(0); + pushSize_ = 1; + return true; + } + + head_ = new(p) Node(head_); + pushSize_++; + return true; + } + + static void deleteLinkedList(Node* head) { + Node* n = head; + while (n) { + void* p = n; + n = n->next; + ::operator delete(p); + } + } + public: + Impl() { + pushSize_ = 0; + head_ = 0; + } + + ~Impl() { + // No need for mutex for pop + deleteLinkedList(head_); + } + + void* allocate() { + void* result = pop(); + if (!result) { + result = ::operator new(std::max(sizeof(T), sizeof(Node))); + } + return result; + } + + void deallocate(void* p) { + if (!push(p)) { + ::operator delete(p); + } + } + }; + + static boost::thread_specific_ptr implPtr_; + typedef size_t size_type; + typedef T* pointer; + typedef const void* const_pointer; + + Allocator() { + } + + Allocator(const Allocator& /*other*/) { + } + + template + Allocator(const Allocator& /*other*/) { + } + + pointer allocate(size_type n, const void * /*hint*/ = 0) { + Impl *impl = implPtr_.get(); + if (!impl) { + implPtr_.reset(new Impl); + impl = implPtr_.get(); + } + void* p = (n == 1) + ? impl->allocate() + : operator new(n * sizeof(T)); + return static_cast(p); + } + + void deallocate(pointer ptr, size_type n) { + Impl *impl = implPtr_.get(); + if (!impl) { + implPtr_.reset(new Impl); + impl = implPtr_.get(); + } + if (n == 1) + impl->deallocate(ptr); + else + ::operator delete(ptr); + } + + template struct rebind { + typedef Allocator other; + }; +}; + +// typename Allocator::Impl is important else the compiler +// doesn't understand that it is a type +template +boost::thread_specific_ptr::Impl> Allocator::implPtr_; + +template +boost::mutex Allocator::Impl::mutex_; + +template +struct Allocator::Impl::GlobalPool *Allocator::Impl::globalPool_; + +template +int Allocator::Impl::globalNodeCount_; + +template +class ObjectPool { + typedef boost::shared_ptr TypeSharedPtr; + + Allocator allocator_; + + public: + ObjectPool() { + + } + + TypeSharedPtr create() { + return boost::allocate_shared(allocator_); + } + + ~ObjectPool() { + + struct Allocator::Impl::GlobalPool *poolEntry = Allocator::Impl::globalPool_; + while(poolEntry) { + Allocator::Impl::deleteLinkedList(poolEntry->node_); + struct Allocator::Impl::GlobalPool *delEntry = poolEntry; + poolEntry = poolEntry->next_; + ::operator delete(delEntry); + } + } + private: + ObjectPool(const ObjectPool&); + ObjectPool& operator=(const ObjectPool&); +}; + +} +#endif /* LIB_OBJECTPOOL_H_ */ diff --git a/pulsar-client-cpp/lib/PartitionedConsumerImpl.cc b/pulsar-client-cpp/lib/PartitionedConsumerImpl.cc new file mode 100644 index 0000000000000..7b54da730e988 --- /dev/null +++ b/pulsar-client-cpp/lib/PartitionedConsumerImpl.cc @@ -0,0 +1,383 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "PartitionedConsumerImpl.h" +#include "LogUtils.h" +#include +#include "pulsar/Result.h" +#include "MessageImpl.h" +#include "Utils.h" + +DECLARE_LOG_OBJECT() + +namespace pulsar { + + PartitionedConsumerImpl::PartitionedConsumerImpl(ClientImplPtr client, + const std::string& subscriptionName, + const DestinationNamePtr destinationName, + const unsigned int numPartitions, + const ConsumerConfiguration& conf) + : client_(client), + subscriptionName_(subscriptionName), + destinationName_(destinationName), + numPartitions_(numPartitions), + numConsumersCreated_(0), + conf_(conf), + state_(Pending), + unsubscribedSoFar_(0), + messages_(1000), + listenerExecutor_(client->getListenerExecutorProvider()->get()), + messageListener_(conf.getMessageListener()), + topic_(destinationName->toString()) + { + std::stringstream consumerStrStream; + consumerStrStream << "[Partitioned Consumer: " << topic_ << "," << subscriptionName << "," << numPartitions << "]"; + if(conf.getUnAckedMessagesTimeoutMs() != 0) { + unAckedMessageTrackerPtr_.reset(new UnAckedMessageTrackerEnabled(conf.getUnAckedMessagesTimeoutMs(), client, *this)); + } else { + unAckedMessageTrackerPtr_.reset(new UnAckedMessageTrackerDisabled()); + } + } + + PartitionedConsumerImpl::~PartitionedConsumerImpl() { + } + + Future PartitionedConsumerImpl::getConsumerCreatedFuture() { + return partitionedConsumerCreatedPromise_.getFuture(); + } + const std::string& PartitionedConsumerImpl::getSubscriptionName() const { + return subscriptionName_; + } + + const std::string& PartitionedConsumerImpl::getTopic() const { + return topic_; + } + + Result PartitionedConsumerImpl::receive(Message& msg) { + Lock lock(mutex_); + if (state_ != Ready) { + lock.unlock(); + return ResultAlreadyClosed; + } + + if (messageListener_) { + LOG_ERROR("Can not receive when a listener has been set"); + return ResultInvalidConfiguration; + } + + messages_.pop(msg); + unAckedMessageTrackerPtr_->add(msg.getMessageId()); + return ResultOk; + } + + Result PartitionedConsumerImpl::receive(Message& msg, int timeout) { + Lock lock(mutex_); + if (state_ != Ready) { + lock.unlock(); + return ResultAlreadyClosed; + } + + if (messageListener_) { + LOG_ERROR("Can not receive when a listener has been set"); + return ResultInvalidConfiguration; + } + + if (messages_.pop(msg, milliseconds(timeout))) { + unAckedMessageTrackerPtr_->add(msg.getMessageId()); + return ResultOk; + } else { + return ResultTimeout; + } + } + + void PartitionedConsumerImpl::unsubscribeAsync(ResultCallback callback) { + LOG_INFO("[" << destinationName_->toString() << "," << subscriptionName_ << "] Unsubscribing"); + // change state to Closing, so that no Ready state operation is permitted during unsubscribe + setState(Closing); + // do not accept un subscribe until we have subscribe to all of the partitions of a topic + // it's a logical single topic so it should behave like a single topic, even if it's sharded + Lock lock(mutex_); + if (state_ != Ready) { + lock.unlock(); + unsigned int index = 0; + for (ConsumerList::const_iterator consumer = consumers_.begin(); consumer != consumers_.end(); consumer++) { + LOG_DEBUG("Unsubcribing Consumer - " << index << " for Subscription - " + << subscriptionName_ << " for Topic - " << destinationName_->toString()); + (*consumer)->unsubscribeAsync(boost::bind(&PartitionedConsumerImpl::handleUnsubscribeAsync, + shared_from_this(), + _1, index++, callback)); + } + } + } + + void PartitionedConsumerImpl::handleUnsubscribeAsync(Result result, + unsigned int consumerIndex, + ResultCallback callback) { + + Lock lock(mutex_); + if (state_ == Failed) { + lock.unlock(); + // we have already informed the client that unsubcribe has failed so, ignore this callbacks + // or do we still go ahead and check how many could we close successfully? + LOG_DEBUG("handleUnsubscribeAsync callback received in Failed State for consumerIndex - " + << consumerIndex << "with Result - " << result << " for Subscription - " + << subscriptionName_ << " for Topic - " << destinationName_->toString()); + return; + } + lock.unlock(); + if (result != ResultOk) { + setState(Failed); + LOG_ERROR("Error Closing one of the parition consumers, consumerIndex - " << consumerIndex); + callback(ResultUnknownError); + return; + } + assert (unsubscribedSoFar_ <= numPartitions_); + assert (consumerIndex <= numPartitions_); + // this means we have successfully closed this partition consumer and no unsubscribe has failed so far + LOG_INFO("Successfully Unsubscribed Consumer - " << consumerIndex << " for Subscription - " + << subscriptionName_ << " for Topic - " << destinationName_->toString()); + unsubscribedSoFar_++; + if (unsubscribedSoFar_ == numPartitions_) { + LOG_DEBUG("Unsubscribed all of the partition consumer for subscription - " << subscriptionName_); + setState(Closed); + callback(ResultOk); + return; + } + } + + void PartitionedConsumerImpl::acknowledgeAsync(const MessageId& msgId, ResultCallback callback){ + int partition = msgId.partition_; + assert (partition < numPartitions_ && partition >= 0 && consumers_.size() > partition); + unAckedMessageTrackerPtr_->remove(msgId); + consumers_[partition]->acknowledgeAsync(msgId, callback); + } + + void PartitionedConsumerImpl::acknowledgeCumulativeAsync(const MessageId& msgId, ResultCallback callback){ + callback(ResultOperationNotSupported); + } + + void PartitionedConsumerImpl::start(){ + ExecutorServicePtr internalListenerExecutor = client_->getPartitionListenerExecutorProvider()->get(); + boost::shared_ptr consumer; + ConsumerConfiguration config; + // all the partitioned-consumer belonging to one partitioned topic should have same name + config.setConsumerName(conf_.getConsumerName()); + config.setConsumerType(conf_.getConsumerType()); + config.setMessageListener(boost::bind(&PartitionedConsumerImpl::messageReceived, shared_from_this(), _1, _2)); + // create consumer on each partition + for (unsigned int i = 0; i < numPartitions_; i++ ) { + std::string topicPartitionName = destinationName_->getTopicPartitionName(i); + std::stringstream partitionSubName; + partitionSubName << subscriptionName_ << i; + consumer = boost::make_shared(client_, topicPartitionName, + partitionSubName.str(), config, + internalListenerExecutor, Partitioned); + consumer->getConsumerCreatedFuture().addListener(boost::bind(&PartitionedConsumerImpl::handleSinglePartitionConsumerCreated, + shared_from_this(), _1, _2, i)); + consumer->setPartitionIndex(i); + consumers_.push_back(consumer); + + LOG_DEBUG("Creating Consumer for single Partition - " << topicPartitionName << "SubName - " << partitionSubName.str()); + } + for (ConsumerList::const_iterator consumer = consumers_.begin(); consumer != consumers_.end(); consumer++) { + (*consumer)->start(); + } + + } + + void PartitionedConsumerImpl::handleSinglePartitionConsumerCreated(Result result, + ConsumerImplBaseWeakPtr consumerImplBaseWeakPtr, + unsigned int partitionIndex) { + ResultCallback nullCallbackForCleanup = NULL; + Lock lock(mutex_); + if (state_ == Failed) { + // one of the consumer creation failed, and we are cleaning up + return; + } + assert (numConsumersCreated_ < numPartitions_); + + if (result != ResultOk) { + state_ = Failed; + lock.unlock(); + partitionedConsumerCreatedPromise_.setFailed(result); + // unsubscribed all of the successfully subscribed partitioned consumers + closeAsync(nullCallbackForCleanup); + LOG_DEBUG("Unable to create Consumer for partition - " << partitionIndex << " Error - " << result); + return; + } + + assert(partitionIndex < numPartitions_ && partitionIndex >= 0); + numConsumersCreated_++; + if(numConsumersCreated_ == numPartitions_) { + LOG_INFO("Successfully Subscribed to Partitioned Topic - " + << destinationName_->toString() << " with - " << numPartitions_ << " Partitions."); + state_ = Ready; + lock.unlock(); + receiveMessages(); + partitionedConsumerCreatedPromise_.setValue(shared_from_this()); + return; + } + + } + + void PartitionedConsumerImpl::handleSinglePartitionConsumerClose (Result result, unsigned int partitionIndex, CloseCallback callback) { + Lock lock(mutex_); + if (state_ == Failed) { + // we should have already notified the client by callback + return; + } + if (result != ResultOk) { + state_ = Failed; + LOG_ERROR("Closing the consumer failed for partition - " << partitionIndex); + lock.unlock(); + partitionedConsumerCreatedPromise_.setFailed(result); + if (!callback.empty()) { + callback(result); + } + return; + } + assert (partitionIndex < numPartitions_ && partitionIndex >= 0); + if(numConsumersCreated_ > 0) { + numConsumersCreated_--; + } + // closed all successfully + if(!numConsumersCreated_) { + state_ = Closed; + lock.unlock(); + // set the producerCreatedPromise to failure + partitionedConsumerCreatedPromise_.setFailed(ResultUnknownError); + if (!callback.empty()) { + callback(result); + } + return; + } + } + void PartitionedConsumerImpl::closeAsync(ResultCallback callback) { + if (consumers_.empty()) { + notifyResult(callback); + return; + } + setState(Closed); + int consumerIndex = 0; + unsigned int consumerAlreadyClosed = 0; + // close successfully subscribed consumers + for (ConsumerList::const_iterator i = consumers_.begin(); i != consumers_.end(); i++) { + ConsumerImplPtr consumer = *i; + if(!consumer->isClosed()) { + consumer->closeAsync(boost::bind(&PartitionedConsumerImpl::handleSinglePartitionConsumerClose, + shared_from_this(), _1, consumerIndex, callback)); + } else { + if(++consumerAlreadyClosed == consumers_.size()) { + //everything is closed already. so we are good. + notifyResult(callback); + return; + } + } + } + } + + void PartitionedConsumerImpl::notifyResult(CloseCallback closeCallback) { + if(closeCallback) { + // this means client invoked the closeAsync with a valid callback + setState(Closed); + closeCallback(ResultOk); + } else { + // consumer create failed, closeAsync called to cleanup the successfully created producers + setState(Failed); + partitionedConsumerCreatedPromise_.setFailed(ResultUnknownError); + } + } + + void PartitionedConsumerImpl::setState(const PartitionedConsumerState state) { + Lock lock(mutex_); + state_ = state; + lock.unlock(); + } + + void PartitionedConsumerImpl::shutdown(){} + + bool PartitionedConsumerImpl::isClosed(){ + return state_ == Closed; + } + + bool PartitionedConsumerImpl::isOpen() { + Lock lock(mutex_); + return state_ == Ready; + } + + void PartitionedConsumerImpl::messageReceived(Consumer consumer, const Message& msg) { + LOG_DEBUG("Received Message from one of the partition - " << msg.impl_->messageId.partition_); + messages_.push(msg); + if (messageListener_) { + listenerExecutor_->postWork(boost::bind(&PartitionedConsumerImpl::internalListener, shared_from_this(), consumer)); + } + } + + void PartitionedConsumerImpl::internalListener(Consumer consumer) { + Message m; + messages_.pop(m); + try { + messageListener_(Consumer(shared_from_this()), m); + } catch (const std::exception& e) { + LOG_ERROR("Exception thrown from listener of Partitioned Consumer" << e.what()); + } + } + + void PartitionedConsumerImpl::receiveMessages() { + for (ConsumerList::const_iterator i = consumers_.begin(); i != consumers_.end(); i++) { + ConsumerImplPtr consumer = *i; + consumer->receiveMessages(consumer->getCnx().lock(), conf_.getReceiverQueueSize()); + LOG_DEBUG("Sending FLOW command for consumer - " << consumer->getConsumerId()); + } + } + + + Result PartitionedConsumerImpl::pauseMessageListener() { + if (!messageListener_) { + return ResultInvalidConfiguration; + } + for (ConsumerList::const_iterator i = consumers_.begin(); i != consumers_.end(); i++) { + (*i)->pauseMessageListener(); + } + return ResultOk; + } + + Result PartitionedConsumerImpl::resumeMessageListener() { + if (!messageListener_) { + return ResultInvalidConfiguration; + } + for (ConsumerList::const_iterator i = consumers_.begin(); i != consumers_.end(); i++) { + (*i)->resumeMessageListener(); + } + return ResultOk; + } + + void PartitionedConsumerImpl::redeliverUnacknowledgedMessages() { + LOG_DEBUG("Sending RedeliverUnacknowledgedMessages command for partitioned consumer."); + for (ConsumerList::const_iterator i = consumers_.begin(); i != consumers_.end(); i++) { + (*i)->redeliverUnacknowledgedMessages(); + } + } + + const std::string& PartitionedConsumerImpl::getName() const { + return partitionStr_; + } + + int PartitionedConsumerImpl::getNumOfPrefetchedMessages() const { + return messages_.size(); + } + +} diff --git a/pulsar-client-cpp/lib/PartitionedConsumerImpl.h b/pulsar-client-cpp/lib/PartitionedConsumerImpl.h new file mode 100644 index 0000000000000..ff6fc4563ba0a --- /dev/null +++ b/pulsar-client-cpp/lib/PartitionedConsumerImpl.h @@ -0,0 +1,100 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef PULSAR_PARTITIONED_CONSUMER_HEADER +#define PULSAR_PARTITIONED_CONSUMER_HEADER +#include "ConsumerImpl.h" +#include "ClientImpl.h" +#include "DestinationName.h" +#include +#include +#include +#include "boost/enable_shared_from_this.hpp" +#include "ConsumerImplBase.h" +#include "lib/UnAckedMessageTrackerDisabled.h" +namespace pulsar { + class PartitionedConsumerImpl; + class PartitionedConsumerImpl: public ConsumerImplBase, public boost::enable_shared_from_this { + public: + enum PartitionedConsumerState { + Pending, + Ready, + Closing, + Closed, + Failed + }; + PartitionedConsumerImpl(ClientImplPtr client, + const std::string& subscriptionName, + const DestinationNamePtr destinationName, + const unsigned int numPartitions, + const ConsumerConfiguration& conf); + virtual ~PartitionedConsumerImpl (); + virtual Future getConsumerCreatedFuture(); + virtual const std::string& getSubscriptionName() const; + virtual const std::string& getTopic() const; + virtual Result receive(Message& msg); + virtual Result receive(Message& msg, int timeout); + virtual void unsubscribeAsync(ResultCallback callback); + virtual void acknowledgeAsync(const MessageId& msgId, ResultCallback callback); + virtual void acknowledgeCumulativeAsync(const MessageId& msgId, ResultCallback callback); + virtual void closeAsync(ResultCallback callback); + virtual void start(); + virtual void shutdown(); + virtual bool isClosed(); + virtual bool isOpen(); + virtual Result pauseMessageListener(); + virtual Result resumeMessageListener(); + virtual void redeliverUnacknowledgedMessages(); + virtual const std::string& getName() const; + virtual int getNumOfPrefetchedMessages() const ; + private: + const ClientImplPtr client_; + const std::string subscriptionName_; + const DestinationNamePtr destinationName_; + unsigned int numPartitions_; + unsigned int numConsumersCreated_; + const ConsumerConfiguration conf_; + typedef std::vector ConsumerList; + ConsumerList consumers_; + boost::mutex mutex_; + PartitionedConsumerState state_; + unsigned int unsubscribedSoFar_; + BlockingQueue messages_; + ExecutorServicePtr listenerExecutor_; + MessageListener messageListener_; + const std::string topic_; + const std::string name_; + const std::string partitionStr_; + /* methods */ + void setState(PartitionedConsumerState state); + void handleUnsubscribeAsync(Result result, + unsigned int consumerIndex, + ResultCallback callback); + void handleSinglePartitionConsumerCreated(Result result, + ConsumerImplBaseWeakPtr consumerImplBaseWeakPtr, + unsigned int partitionIndex); + void handleSinglePartitionConsumerClose(Result result, unsigned int partitionIndex, CloseCallback callback); + void notifyResult(CloseCallback closeCallback); + void messageReceived(Consumer consumer, const Message& msg); + void internalListener(Consumer consumer); + void receiveMessages(); + Promise partitionedConsumerCreatedPromise_; + UnAckedMessageTrackerScopedPtr unAckedMessageTrackerPtr_; + }; + typedef boost::weak_ptr PartitionedConsumerImplWeakPtr; + typedef boost::shared_ptr PartitionedConsumerImplPtr; +} +#endif //PULSAR_PARTITIONED_CONSUMER_HEADER diff --git a/pulsar-client-cpp/lib/PartitionedProducerImpl.cc b/pulsar-client-cpp/lib/PartitionedProducerImpl.cc new file mode 100644 index 0000000000000..d1fd106518066 --- /dev/null +++ b/pulsar-client-cpp/lib/PartitionedProducerImpl.cc @@ -0,0 +1,214 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "PartitionedProducerImpl.h" +#include "LogUtils.h" +#include +#include +#include "RoundRobinMessageRouter.h" +#include "SinglePartitionMessageRouter.h" +#include "DestinationName.h" +#include "MessageImpl.h" + +DECLARE_LOG_OBJECT() + +namespace pulsar { + + const std::string PartitionedProducerImpl::PARTITION_NAME_SUFFIX = "-partition-"; + + PartitionedProducerImpl::PartitionedProducerImpl(ClientImplPtr client, + const DestinationNamePtr destinationName, + const unsigned int numPartitions, + const ProducerConfiguration& config):client_(client), + destinationName_(destinationName), + topic_(destinationName_->toString()), + numPartitions_(numPartitions), + conf_(config), + state_(Pending) + { + numProducersCreated_ = 0; + cleanup_ = false; + if(config.getPartitionsRoutingMode() == ProducerConfiguration::RoundRobinDistribution) { + routerPolicy_ = boost::make_shared(numPartitions); + } else if (config.getPartitionsRoutingMode() == ProducerConfiguration::UseSinglePartition) { + routerPolicy_ = boost::make_shared(numPartitions); + } else { + routerPolicy_ = config.getMessageRouterPtr(); + } + } + + PartitionedProducerImpl::~PartitionedProducerImpl() { + } + //override + const std::string& PartitionedProducerImpl::getTopic() const { + return topic_; + } + + //override + void PartitionedProducerImpl::start() { + boost::shared_ptr producer; + // create producer per partition + for (unsigned int i = 0; i < numPartitions_; i++) { + std::string topicPartitionName = destinationName_->getTopicPartitionName(i); + producer = boost::make_shared(client_, topicPartitionName, conf_); + producer->getProducerCreatedFuture().addListener(boost::bind(&PartitionedProducerImpl::handleSinglePartitionProducerCreated, + shared_from_this(), _1, _2, i)); + producers_.push_back(producer); + LOG_DEBUG("Creating Producer for single Partition - " << topicPartitionName); + } + + for (ProducerList::const_iterator prod = producers_.begin(); prod != producers_.end(); prod++) { + (*prod)->start(); + } + } + + + void PartitionedProducerImpl::handleSinglePartitionProducerCreated(Result result, + ProducerImplBaseWeakPtr producerWeakPtr, + unsigned int partitionIndex) { + // to indicate, we are doing cleanup using closeAsync after producer create + // has failed and the invocation of closeAsync is not from client + CloseCallback closeCallback = NULL; + Lock lock(mutex_); + if (state_ == Failed) { + // Ignore, we have already informed client that producer creation failed + return; + } + assert(numProducersCreated_ <= numPartitions_); + if (result != ResultOk) { + state_ = Failed; + lock.unlock(); + closeAsync(closeCallback); + partitionedProducerCreatedPromise_.setFailed(result); + LOG_DEBUG("Unable to create Producer for partition - " << partitionIndex << " Error - " << result); + return; + } + + assert(partitionIndex <= numPartitions_); + numProducersCreated_++; + if(numProducersCreated_ == numPartitions_) { + lock.unlock(); + partitionedProducerCreatedPromise_.setValue(shared_from_this()); + } + } + + //override + void PartitionedProducerImpl::sendAsync(const Message& msg, SendCallback callback) { + //get partition for this message from router policy + short partition = (short)(routerPolicy_->getPartition(msg)); + if (partition >= numPartitions_ || partition >= producers_.size()) { + LOG_ERROR("Got Invalid Partition for message from Router Policy, Partition - " << partition); + //change me: abort or notify failure in callback? + // change to appropriate error if callback + callback(ResultUnknownError, msg); + return; + } + //find a producer for that partition, index should start from 0 + ProducerImplPtr& producer = producers_[partition]; + msg.impl_->messageId.partition_ = partition; + //send message on that partition + producer->sendAsync(msg, callback); + } + + //override + void PartitionedProducerImpl::shutdown() { + setState(Closed); + } + + void PartitionedProducerImpl::setState(const PartitionedProducerState state) { + Lock lock(mutex_); + state_ = state; + lock.unlock(); + } + + /* + * if createProducerCallback is set, it means the closeAsync is called from CreateProducer API which failed to create + * one or many producers for partitions. So, we have to notify with ERROR on createProducerFailure + */ + void PartitionedProducerImpl::closeAsync(CloseCallback closeCallback) { + int producerIndex = 0; + unsigned int producerAlreadyClosed = 0; + + for (ProducerList::const_iterator i = producers_.begin(); i != producers_.end(); i++) { + ProducerImplPtr prod = *i; + if(!prod->isClosed()) { + prod->closeAsync(boost::bind(&PartitionedProducerImpl::handleSinglePartitionProducerClose, + shared_from_this(), _1, producerIndex, closeCallback)); + } else { + producerAlreadyClosed++; + } + } + + /* + * No need to set state since:- + * a. If closeAsync before creation then state == Closed, since producers_.size() = producerAlreadyClosed = 0 + * b. If closeAsync called after all sub partitioned producer connected - handleSinglePartitionProducerClose handles the closing + * c. If closeAsync called due to failure in creating just one sub producer then state is set by handleSinglePartitionProducerCreated + */ + if (producerAlreadyClosed == producers_.size() && closeCallback) { + setState(Closed); + closeCallback(ResultOk); + } + } + + void PartitionedProducerImpl::handleSinglePartitionProducerClose(Result result, + const unsigned int partitionIndex, + CloseCallback callback) { + Lock lock(mutex_); + if (state_ == Failed) { + // we should have already notified the client by callback + return; + } + if (result != ResultOk) { + state_ = Failed; + lock.unlock(); + LOG_ERROR("Closing the producer failed for partition - " << partitionIndex); + if (callback) { + callback(result); + } + return; + } + assert (partitionIndex < numPartitions_); + if(numProducersCreated_ > 0) { + numProducersCreated_--; + } + // closed all successfully + if(!numProducersCreated_) { + state_ = Closed; + lock.unlock(); + // set the producerCreatedPromise to failure, if client called + // closeAsync and it's not failure to create producer, the promise + // is set second time here, first time it was successful. So check + // if there's any adverse effect of setting it again. It should not + // be but must check. MUSTCHECK changeme + partitionedProducerCreatedPromise_.setFailed(ResultUnknownError); + if (callback) { + callback(result); + } + return; + } + } + + //override + Future PartitionedProducerImpl::getProducerCreatedFuture() { + return partitionedProducerCreatedPromise_.getFuture(); + } + + //override + bool PartitionedProducerImpl::isClosed() { + return state_ == Closed; + } +} diff --git a/pulsar-client-cpp/lib/PartitionedProducerImpl.h b/pulsar-client-cpp/lib/PartitionedProducerImpl.h new file mode 100644 index 0000000000000..c3d995b42b5f2 --- /dev/null +++ b/pulsar-client-cpp/lib/PartitionedProducerImpl.h @@ -0,0 +1,111 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "ProducerImpl.h" +#include "ClientImpl.h" +#include "DestinationName.h" +#include +#include +#include +#include + +namespace pulsar { + + class PartitionedProducerImpl: public ProducerImplBase, public boost::enable_shared_from_this { + + public: + enum PartitionedProducerState { + Pending, + Ready, + Closing, + Closed, + Failed + }; + const static std::string PARTITION_NAME_SUFFIX; + + typedef boost::unique_lock Lock; + + PartitionedProducerImpl(ClientImplPtr ptr, + const DestinationNamePtr destinationName, + const unsigned int numPartitions, + const ProducerConfiguration& config); + virtual ~PartitionedProducerImpl(); + + virtual void sendAsync(const Message& msg, SendCallback callback); + + /* + * closes all active producers, it can be called explicitly from client as well as createProducer + * when it fails to create one of the producers and we want to fail createProducer + */ + virtual void closeAsync(CloseCallback closeCallback); + + virtual void start(); + + virtual void shutdown(); + + virtual bool isClosed(); + + virtual const std::string& getTopic() const; + + virtual Future getProducerCreatedFuture(); + + void handleSinglePartitionProducerCreated(Result result, + ProducerImplBaseWeakPtr producerBaseWeakPtr, + const unsigned int partitionIndex); + + void handleSinglePartitionProducerClose(Result result, + const unsigned int partitionIndex, + CloseCallback callback); + + void notifyResult(CloseCallback closeCallback); + + void setState(PartitionedProducerState state); + + friend class PulsarFriend; + + private: + const ClientImplPtr client_; + + const DestinationNamePtr destinationName_; + const std::string topic_; + + const unsigned int numPartitions_; + + unsigned int numProducersCreated_; + + /* + * set when one or more Single Partition Creation fails, close will cleanup and fail the create callbackxo + */ + bool cleanup_; + + const ProducerConfiguration conf_; + + typedef std::vector ProducerList; + + ProducerList producers_; + + MessageRoutingPolicyPtr routerPolicy_; + + // mutex_ is used to share state_, and numProducersCreated_ + boost::mutex mutex_; + + PartitionedProducerState state_; + + // only set this promise to value, when producers on all partitions are created. + Promise partitionedProducerCreatedPromise_; + }; + +} //ends namespace Pulsar diff --git a/pulsar-client-cpp/lib/Producer.cc b/pulsar-client-cpp/lib/Producer.cc new file mode 100644 index 0000000000000..a390c7760e130 --- /dev/null +++ b/pulsar-client-cpp/lib/Producer.cc @@ -0,0 +1,208 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include "SharedBuffer.h" +#include + +#include "Utils.h" +#include "ProducerImpl.h" + +namespace pulsar { + +const std::string EMPTY_STRING; + +struct ProducerConfiguration::Impl { + int sendTimeoutMs; + CompressionType compressionType; + int maxPendingMessages; + PartitionsRoutingMode routingMode; + MessageRoutingPolicyPtr messageRouter; + bool blockIfQueueFull; + bool batchingEnabled; + unsigned int batchingMaxMessages; + unsigned long batchingMaxAllowedSizeInBytes; + unsigned long batchingMaxPublishDelayMs; + Impl() + : sendTimeoutMs(30000), + compressionType(CompressionNone), + maxPendingMessages(1000), + routingMode(ProducerConfiguration::UseSinglePartition), + blockIfQueueFull(true), + batchingEnabled(false), + batchingMaxMessages(1000), + batchingMaxAllowedSizeInBytes(128 * 1024), // 128 KB + batchingMaxPublishDelayMs(3000) { // 3 seconds + } +}; + +ProducerConfiguration::ProducerConfiguration() + : impl_(boost::make_shared()) { +} + +ProducerConfiguration::~ProducerConfiguration() { +} + +ProducerConfiguration::ProducerConfiguration(const ProducerConfiguration& x) + : impl_(x.impl_) { +} + +ProducerConfiguration& ProducerConfiguration::operator=(const ProducerConfiguration& x) { + impl_ = x.impl_; + return *this; +} + +ProducerConfiguration& ProducerConfiguration::setSendTimeout(int sendTimeoutMs) { + impl_->sendTimeoutMs = sendTimeoutMs; + return *this; +} + +int ProducerConfiguration::getSendTimeout() const { + return impl_->sendTimeoutMs; +} + +ProducerConfiguration& ProducerConfiguration::setCompressionType(CompressionType compressionType) { + impl_->compressionType = compressionType; + return *this; +} + +CompressionType ProducerConfiguration::getCompressionType() const { + return impl_->compressionType; +} + +ProducerConfiguration& ProducerConfiguration::setMaxPendingMessages(int maxPendingMessages) { + assert(maxPendingMessages > 0); + impl_->maxPendingMessages = maxPendingMessages; + return *this; +} + +int ProducerConfiguration::getMaxPendingMessages() const { + return impl_->maxPendingMessages; +} + +ProducerConfiguration& ProducerConfiguration::setPartitionsRoutingMode(const PartitionsRoutingMode& mode) { + impl_->routingMode = mode; + return *this; +} + +ProducerConfiguration::PartitionsRoutingMode ProducerConfiguration::getPartitionsRoutingMode() const { + return impl_->routingMode; +} + +ProducerConfiguration& ProducerConfiguration::setMessageRouter(const MessageRoutingPolicyPtr& router) { + impl_->routingMode = ProducerConfiguration::CustomPartition; + impl_->messageRouter = router; + return *this; +} + +const MessageRoutingPolicyPtr& ProducerConfiguration::getMessageRouterPtr() const { + return impl_->messageRouter; +} + +ProducerConfiguration& ProducerConfiguration::setBlockIfQueueFull(bool flag) { + impl_->blockIfQueueFull = flag; + return *this; +} + +bool ProducerConfiguration::getBlockIfQueueFull() const { + return impl_->blockIfQueueFull; +} + +ProducerConfiguration& ProducerConfiguration::setBatchingEnabled(const bool& batchingEnabled) { + impl_->batchingEnabled = batchingEnabled; + return *this; +} +const bool& ProducerConfiguration::getBatchingEnabled() const { + return impl_->batchingEnabled; +} + +ProducerConfiguration& ProducerConfiguration::setBatchingMaxMessages(const unsigned int& batchingMaxMessages) { + assert(batchingMaxMessages > 1); + impl_->batchingMaxMessages = batchingMaxMessages; + return *this; +} + +const unsigned int& ProducerConfiguration::getBatchingMaxMessages() const { + return impl_->batchingMaxMessages ; +} + +ProducerConfiguration& ProducerConfiguration::setBatchingMaxAllowedSizeInBytes(const unsigned long& batchingMaxAllowedSizeInBytes) { + impl_->batchingMaxAllowedSizeInBytes = batchingMaxAllowedSizeInBytes; + return *this; +} +const unsigned long& ProducerConfiguration::getBatchingMaxAllowedSizeInBytes() const { + return impl_->batchingMaxAllowedSizeInBytes; +} + +ProducerConfiguration& ProducerConfiguration::setBatchingMaxPublishDelayMs(const unsigned long& batchingMaxPublishDelayMs) { + impl_->batchingMaxPublishDelayMs = batchingMaxPublishDelayMs; + return *this; +} + +const unsigned long& ProducerConfiguration::getBatchingMaxPublishDelayMs() const{ + return impl_->batchingMaxPublishDelayMs; +} +//////////////////////////////////////////////////////////////////////////////// + +Producer::Producer() + : impl_() { +} + +Producer::Producer(ProducerImplBasePtr impl) + : impl_(impl) { +} + +const std::string& Producer::getTopic() const { + return impl_ != NULL ? impl_->getTopic() : EMPTY_STRING; +} + +Result Producer::send(const Message& msg) { + Promise promise; + sendAsync(msg, WaitForCallbackValue(promise)); + + Message m; + Result result = promise.getFuture().get(m); + return result; +} + +void Producer::sendAsync(const Message& msg, SendCallback callback) { + if (!impl_) { + callback(ResultProducerNotInitialized, msg); + return; + } + + impl_->sendAsync(msg, callback); +} + +Result Producer::close() { + Promise promise; + closeAsync(WaitForCallback(promise)); + + Result result; + promise.getFuture().get(result); + return result; +} + +void Producer::closeAsync(CloseCallback callback) { + if (!impl_) { + callback(ResultProducerNotInitialized); + return; + } + + impl_->closeAsync(callback); +} + +} diff --git a/pulsar-client-cpp/lib/ProducerImpl.cc b/pulsar-client-cpp/lib/ProducerImpl.cc new file mode 100644 index 0000000000000..3225dee3daf29 --- /dev/null +++ b/pulsar-client-cpp/lib/ProducerImpl.cc @@ -0,0 +1,570 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "ProducerImpl.h" +#include "LogUtils.h" +#include "MessageImpl.h" +#include "PulsarApi.pb.h" +#include "Commands.h" +#include "DestinationName.h" +#include "BatchMessageContainer.h" +#include +#include + +using namespace pulsar; +namespace pulsar { +DECLARE_LOG_OBJECT() + +OpSendMsg ::OpSendMsg() + : msg_(), + sendCallback_(), + producerId_(), + sequenceId_(), + timeout_() { +} + +OpSendMsg::OpSendMsg(uint64_t producerId, uint64_t sequenceId, const Message& msg, + const SendCallback& sendCallback, const ProducerConfiguration& conf) + : msg_(msg), + sendCallback_(sendCallback), + producerId_(producerId), + sequenceId_(sequenceId), + timeout_(now() + milliseconds(conf.getSendTimeout())) { +} + +ProducerImpl::ProducerImpl(ClientImplPtr client, const std::string& topic, + const ProducerConfiguration& producerConfiguration) + : HandlerBase(client, topic), + conf_(producerConfiguration), + executor_(client->getIOExecutorProvider()->get()), + pendingMessagesQueue_(conf_.getMaxPendingMessages()), + producerStr_("[" + topic_ + ", " + producerName_ + "] "), + producerId_(client->newProducerId()), + msgSequenceGenerator_(0), + sendTimer_() { + LOG_DEBUG( + "ProducerName - " << producerName_ << " Created producer on topic " << topic_ << " id: " << producerId_); + // boost::ref is used to drop the constantness constraint of make_shared + if(conf_.getBatchingEnabled()) { + batchMessageContainer = boost::make_shared(boost::ref(*this)); + } + numOfMsgPublished = 0; + numOfSendAsyncCalls = 0; + numOfMsgAckSuccessfully = 0; +} + +ProducerImpl::~ProducerImpl() { + LOG_DEBUG(getName() << "~ProducerImpl"); + closeAsync(ResultCallback()); + printStats(); +} + +const std::string& ProducerImpl::getTopic() const { + return topic_; +} + +void ProducerImpl::connectionOpened(const ClientConnectionPtr& cnx) { + Lock lock(mutex_); + if (state_ == Closed) { + lock.unlock(); + LOG_DEBUG(getName() << "connectionOpened : Producer is already closed"); + return; + } + lock.unlock(); + + ClientImplPtr client = client_.lock(); + int requestId = client->newRequestId(); + + SharedBuffer cmd = Commands::newProducer(topic_, producerId_, producerName_, requestId); + cnx->sendRequestWithId(cmd, requestId).addListener( + boost::bind(&ProducerImpl::handleCreateProducer, shared_from_this(), cnx, _1, _2)); +} + +void ProducerImpl::connectionFailed(Result result) { + // Keep a reference to ensure object is kept alive + ProducerImplPtr ptr = shared_from_this(); + + if (producerCreatedPromise_.setFailed(result)) { + Lock lock(mutex_); + state_ = Failed; + } +} + +void ProducerImpl::handleCreateProducer(const ClientConnectionPtr& cnx, Result result, + const std::string& producerName) { + LOG_DEBUG(getName() << "ProducerImpl::handleCreateProducer res: " << strResult(result)); + + if (result == ResultOk) { + // We are now reconnected to broker and clear to send messages. Re-send all pending messages and + // set the cnx pointer so that new messages will be sent immediately + LOG_INFO(getName() << "Created producer on broker " << cnx->cnxString()); + + Lock lock(mutex_); + cnx->registerProducer(producerId_, shared_from_this()); + producerName_ = producerName; + producerStr_ = "[" + topic_ + ", " + producerName_ + "] "; + if (batchMessageContainer) { + batchMessageContainer->producerName_ = producerName_; + } + resendMessages(cnx); + connection_ = cnx; + state_ = Ready; + backoff_.reset(); + lock.unlock(); + + // Initialize the sendTimer only once per producer and only when producer timeout is + // configured. Set the timeout as configured value and asynchronously wait for the + // timeout to happen. + if (!sendTimer_ && conf_.getSendTimeout() > 0) { + sendTimer_ = executor_->createDeadlineTimer(); + sendTimer_->expires_from_now(milliseconds(conf_.getSendTimeout())); + sendTimer_->async_wait( + boost::bind(&ProducerImpl::handleSendTimeout, shared_from_this(), _1)); + } + + producerCreatedPromise_.setValue(shared_from_this()); + + } else { + // Producer creation failed + if (result == ResultTimeout) { + // 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 closing the connection + int requestId = client_.lock()->newRequestId(); + cnx->sendRequestWithId(Commands::newCloseProducer(producerId_, requestId), requestId); + } + + if (producerCreatedPromise_.isComplete()) { + if (result == ResultProducerBlockedQuotaExceededException) { + LOG_WARN(getName() << "Backlog is exceeded on topic. Sending exception to producer"); + failPendingMessages(ResultProducerBlockedQuotaExceededException); + } else if (result == ResultProducerBlockedQuotaExceededError) { + LOG_WARN( + getName() << "Producer is blocked on creation because backlog is exceeded on topic"); + } + + // Producer had already been initially created, we need to retry connecting in any case + LOG_WARN(getName() << "Failed to reconnect producer: " << strResult(result)); + scheduleReconnection(shared_from_this()); + } else { + // Producer was not yet created, retry to connect to broker if it's possible + if (isRetriableError(result) && (creationTimestamp_ + operationTimeut_ < now())) { + LOG_WARN(getName() << "Temporary error in creating producer: " << strResult(result)); + scheduleReconnection(shared_from_this()); + } else { + LOG_ERROR(getName() << "Failed to create producer: " << strResult(result)); + producerCreatedPromise_.setFailed(result); + Lock lock(mutex_); + state_ = Failed; + } + } + } +} + +void ProducerImpl::failPendingMessages(Result result) { + std::vector messagesToFail; + Lock lock(mutex_); + messagesToFail.reserve(pendingMessagesQueue_.size()); + LOG_DEBUG(getName() << "# messages in pending queue : " << pendingMessagesQueue_.size()); + + // Iterate over a copy of the pending messages queue, to trigger the future completion + // without holding producer mutex. + for (MessageQueue::const_iterator it = pendingMessagesQueue_.begin(); + it != pendingMessagesQueue_.end(); it++) { + messagesToFail.push_back(*it); + } + + BatchMessageContainer::MessageContainerListPtr messageContainerListPtr; + if (batchMessageContainer) { + messageContainerListPtr = batchMessageContainer->messagesContainerListPtr_; + batchMessageContainer->clear(); + } + pendingMessagesQueue_.clear(); + lock.unlock(); + for (std::vector::const_iterator it = messagesToFail.begin(); + it != messagesToFail.end(); it++) { + it->sendCallback_(result, it->msg_); + } + + // this function can handle null pointer + BatchMessageContainer::batchMessageCallBack(ResultTimeout, messageContainerListPtr); +} + +void ProducerImpl::resendMessages(ClientConnectionPtr cnx) { + if (pendingMessagesQueue_.empty()) { + return; + } + + LOG_DEBUG(getName() << "Re-Sending " << pendingMessagesQueue_.size() << " messages to server"); + + for (MessageQueue::const_iterator it = pendingMessagesQueue_.begin(); + it != pendingMessagesQueue_.end(); ++it) { + LOG_DEBUG(getName() << "Re-Sending " << it->sequenceId_); + cnx->sendMessage(*it); + } +} + +void ProducerImpl::setMessageMetadata(const Message &msg, const uint64_t& sequenceId, const uint32_t& uncompressedSize) { + // Call this function after acquiring the mutex_ + proto::MessageMetadata& msgMetadata = msg.impl_->metadata; + if (! batchMessageContainer) { + msgMetadata.set_producer_name(producerName_); + } + msgMetadata.set_publish_time(currentTimeMillis()); + msgMetadata.set_sequence_id(sequenceId); + if (conf_.getCompressionType() != CompressionNone) { + msgMetadata.set_compression( + CompressionCodecProvider::convertType(conf_.getCompressionType())); + msgMetadata.set_uncompressed_size(uncompressedSize); + } +} + +void ProducerImpl::sendAsync(const Message& msg, SendCallback callback) { + if (msg.getLength() > Commands::MaxMessageSize) { + callback(ResultMessageTooBig, msg); + return; + } + + // Reserve a spot in the messages queue before acquiring the ProducerImpl + // mutex. When the queue is full, this call will block until a spot is + // available. + if (conf_.getBlockIfQueueFull()) { + pendingMessagesQueue_.reserve(1); + } + + // Compress the payload if required + SharedBuffer& payload = msg.impl_->payload; + + uint32_t uncompressedSize = payload.readableBytes(); + + if (! batchMessageContainer) { + // If batching is enabled we compress all the payloads together before sending the batch + payload = CompressionCodecProvider::getCodec(conf_.getCompressionType()).encode(payload); + } + + Lock lock(mutex_); + numOfSendAsyncCalls++; + if (state_ != Ready) { + lock.unlock(); + if (conf_.getBlockIfQueueFull()) { + pendingMessagesQueue_.release(1); + } + callback(ResultAlreadyClosed, msg); + return; + } + + if (msg.impl_->metadata.has_producer_name()) { + // Message had already been sent before + lock.unlock(); + if (conf_.getBlockIfQueueFull()) { + pendingMessagesQueue_.release(1); + } + callback(ResultInvalidMessage, msg); + return; + } + + setMessageMetadata(msg, msgSequenceGenerator_++, uncompressedSize); + + // reserving a spot and going forward - not blocking + if (!conf_.getBlockIfQueueFull() && !pendingMessagesQueue_.tryReserve(1)) { + LOG_DEBUG(getName() << " - Producer Queue is full"); + // If queue is full sending the batch immediately, no point waiting till batchMessageimeout + if (batchMessageContainer) { + LOG_DEBUG(getName() << " - sending batch message immediately"); + batchMessageContainer->sendMessage(); + } + lock.unlock(); + callback(ResultProducerQueueIsFull, msg); + return; + } + + // If we reach this point then you have a reserved spot on the queue + + if (batchMessageContainer) { // Batching is enabled + batchMessageContainer->add(msg, callback); + return; + } + sendMessage(msg, callback); +} + +// Precondition - +// a. we have a reserved spot on the queue +// b. call this function after acquiring the ProducerImpl mutex_ +void ProducerImpl::sendMessage(const Message& msg, SendCallback callback) { + const uint64_t& sequenceId = msg.impl_->metadata.sequence_id(); + LOG_DEBUG( + getName() << "Sending msg: " << sequenceId << " -- queue_size: " << pendingMessagesQueue_.size()); + + OpSendMsg op(producerId_, sequenceId, msg, callback, conf_); + + LOG_DEBUG("Inserting data to pendingMessagesQueue_"); + pendingMessagesQueue_.push(op, true); + numOfMsgPublished++; + LOG_DEBUG("Completed Inserting data to pendingMessagesQueue_"); + + ClientConnectionPtr cnx = getCnx().lock(); + if (cnx) { + // If we do have a connection, the message is sent immediately, otherwise + // we'll try again once a new connection is established + LOG_DEBUG(getName() << "Sending msg immediately - seq: " << sequenceId); + cnx->sendMessage(op); + } else { + LOG_DEBUG(getName() << "Connection is not ready - seq: " << sequenceId); + } +} + +void ProducerImpl::batchMessageTimeoutHandler(const boost::system::error_code& ec) { + if (ec) { + LOG_DEBUG(getName() << " Ignoring timer cancelled event, code[" << ec <<"]"); + return; + } + LOG_DEBUG(getName() << " - Batch Message Timer expired"); + Lock lock(mutex_); + batchMessageContainer->sendMessage(); +} + +void ProducerImpl::printStats() { + if (batchMessageContainer) { + LOG_INFO("Producer - " << producerStr_ << ", [numOfMsgPublished = " << numOfMsgPublished + << "] [numOfMsgAckSuccessfully = " << numOfMsgAckSuccessfully + << "] [numOfSendAsyncCalls =" << numOfSendAsyncCalls << "] [batchMessageContainer = " + << *batchMessageContainer << "]"); + } else { + LOG_INFO("Producer - " << producerStr_ << ", [numOfMsgPublished = " << numOfMsgPublished + << "] [numOfMsgAckSuccessfully = " << numOfMsgAckSuccessfully + << "] [numOfSendAsyncCalls =" << numOfSendAsyncCalls << "] [batching = off]"); + } +} + +void ProducerImpl::closeAsync(CloseCallback callback) { + Lock lock(mutex_); + + if (state_ != Ready) { + lock.unlock(); + if (!callback.empty()) { + callback(ResultAlreadyClosed); + } + return; + } + LOG_DEBUG(getName() << "Closing producer"); + state_ = Closing; + + ClientConnectionPtr cnx = getCnx().lock(); + if (!cnx) { + lock.unlock(); + if (!callback.empty()) { + callback(ResultOk); + } + return; + } + + // Detach the producer from the connection to avoid sending any other + // message from the producer + connection_.reset(); + lock.unlock(); + + ClientImplPtr client = client_.lock(); + if (!client) { + // Client was already destroyed + if (!callback.empty()) { + callback(ResultOk); + } + return; + } + int requestId = client->newRequestId(); + Future future = cnx->sendRequestWithId( + Commands::newCloseProducer(producerId_, requestId), requestId); + if (!callback.empty()) { + future.addListener( + boost::bind(&ProducerImpl::handleClose, shared_from_this(), _1, callback)); + } +} + +void ProducerImpl::handleClose(Result result, ResultCallback callback) { + if (result == ResultOk) { + Lock lock(mutex_); + state_ = Closed; + LOG_INFO(getName() << "Closed producer"); + ClientConnectionPtr cnx = getCnx().lock(); + if (cnx) { + cnx->removeProducer(producerId_); + } + } else { + LOG_ERROR(getName() << "Failed to close producer: " << strResult(result)); + } + + callback(result); +} + +Future ProducerImpl::getProducerCreatedFuture() { + return producerCreatedPromise_.getFuture(); +} + +uint64_t ProducerImpl::getProducerId() const { + return producerId_; +} + +void ProducerImpl::handleSendTimeout(const boost::system::error_code& err) { + if (err == boost::asio::error::operation_aborted) { + LOG_DEBUG(getName() << "Timer cancelled: " << err.message()); + return; + } else if (err) { + LOG_ERROR(getName() << "Timer error: " << err.message()); + return; + } + + OpSendMsg msg; + if (!pendingMessagesQueue_.peek(msg)) { + // If there are no pending messages, reset the timeout to the configured value. + sendTimer_->expires_from_now(milliseconds(conf_.getSendTimeout())); + LOG_DEBUG(getName() << "Producer timeout triggered on empty pending message queue"); + } else { + // If there is at least one message, calculate the diff between the message timeout and + // the current time. + time_duration diff = msg.timeout_ - now(); + if (diff.total_milliseconds() <= 0) { + // The diff is less than or equal to zero, meaning that the message has been expired. + LOG_DEBUG(getName() << "Timer expired. Calling timeout callbacks."); + failPendingMessages(ResultTimeout); + // Since the pending queue is cleared now, set timer to expire after configured value. + sendTimer_->expires_from_now(milliseconds(conf_.getSendTimeout())); + } else { + // The diff is greater than zero, set the timeout to the diff value + LOG_DEBUG(getName() << "Timer hasn't expired yet, setting new timeout " << diff); + sendTimer_->expires_from_now(diff); + } + } + + // Asynchronously wait for the timeout to trigger + sendTimer_->async_wait(boost::bind(&ProducerImpl::handleSendTimeout, shared_from_this(), _1)); +} + +bool ProducerImpl::removeCorruptMessage(uint64_t sequenceId) { + + OpSendMsg op; + Lock lock(mutex_); + bool havePendingAck = pendingMessagesQueue_.peek(op); + if (!havePendingAck) { + LOG_DEBUG(getName() << " -- SequenceId - " << sequenceId << "]" // + << "Got send failure for expired message, ignoring it."); + return true; + } + uint64_t expectedSequenceId = op.sequenceId_; + if (sequenceId > expectedSequenceId) { + LOG_WARN(getName() << "Got ack failure for msg " << sequenceId // + << " expecting: " << expectedSequenceId << " queue size="// + << pendingMessagesQueue_.size() << " producer: " << producerId_); + return false; + } else if (sequenceId < expectedSequenceId) { + LOG_DEBUG(getName() << "Corrupt message is already timed out. Ignoring msg " << sequenceId); + return true; + } else { + LOG_DEBUG(getName() << "Remove corrupt message from queue " << sequenceId); + pendingMessagesQueue_.pop(); + numOfMsgAckSuccessfully++; + if (op.msg_.impl_->metadata.has_num_messages_in_batch()) { + // batch message - need to release more spots + // -1 since the pushing batch message into the queue already released a spot + pendingMessagesQueue_.release(op.msg_.impl_->metadata.num_messages_in_batch() - 1); + } + lock.unlock(); + if (op.sendCallback_) { + // to protect from client callback exception + try { + op.sendCallback_(ResultChecksumError, op.msg_); + } catch (const std::exception& e) { + LOG_ERROR(getName() << "Exception thrown from callback " << e.what()); + } + } + return true; + } + +} + +bool ProducerImpl::ackReceived(uint64_t sequenceId) { + OpSendMsg op; + Lock lock(mutex_); + bool havePendingAck = pendingMessagesQueue_.peek(op); + if (!havePendingAck) { + LOG_DEBUG(getName() << " -- SequenceId - " << sequenceId << "]" // + << "Got an SEND_ACK for expired message, ignoring it."); + return true; + } + uint64_t expectedSequenceId = op.sequenceId_; + if (sequenceId > expectedSequenceId) { + LOG_WARN(getName() << "Got ack for msg " << sequenceId // + << " expecting: " << expectedSequenceId << " queue size="// + << pendingMessagesQueue_.size() << " producer: " << producerId_); + return false; + } else if (sequenceId < expectedSequenceId) { + // Ignoring the ack since it's referring to a message that has already timed out. + LOG_DEBUG(getName() << "Got ack for timed out msg " << sequenceId // + << " last-seq: " << expectedSequenceId << " producer: " << producerId_); + return true; + } else { + // Message was persisted correctly + LOG_DEBUG(getName() << "Received ack for msg " << sequenceId); + pendingMessagesQueue_.pop(); + numOfMsgAckSuccessfully++; + if (op.msg_.impl_->metadata.has_num_messages_in_batch()) { + // batch message - need to release more spots + // -1 since the pushing batch message into the queue already released a spot + pendingMessagesQueue_.release(op.msg_.impl_->metadata.num_messages_in_batch() - 1); + } + lock.unlock(); + if (op.sendCallback_) { + try { + op.sendCallback_(ResultOk, op.msg_); + } catch (const std::exception& e) { + LOG_ERROR(getName() << "Exception thrown from callback " << e.what()); + } + } + return true; + } +} + +void ProducerImpl::disconnectProducer() { + LOG_DEBUG("Broker notification of Closed producer: " << producerId_); + connection_.reset(); + scheduleReconnection(shared_from_this()); + +} + +const std::string& ProducerImpl::getName() const{ + return producerStr_; +} + +void ProducerImpl::start() { + HandlerBase::start(); +} +void ProducerImpl::shutdown() { + Lock lock(mutex_); + state_ = Closed; + sendTimer_.reset(); + producerCreatedPromise_.setFailed(ResultAlreadyClosed); +} + +bool ProducerImplCmp::operator()(const ProducerImplPtr &a, const ProducerImplPtr &b) const { + return a->getProducerId() < b->getProducerId(); +} + +bool ProducerImpl::isClosed() { + Lock lock(mutex_); + return state_ == Closed; +} + +} +/* namespace pulsar */ diff --git a/pulsar-client-cpp/lib/ProducerImpl.h b/pulsar-client-cpp/lib/ProducerImpl.h new file mode 100644 index 0000000000000..cfc1883b6e982 --- /dev/null +++ b/pulsar-client-cpp/lib/ProducerImpl.h @@ -0,0 +1,149 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_PRODUCERIMPL_H_ +#define LIB_PRODUCERIMPL_H_ + +#include +#include + + + +#include "ClientImpl.h" +#include "BlockingQueue.h" +#include "HandlerBase.h" +#include "SharedBuffer.h" +#include "CompressionCodec.h" + +using namespace pulsar; + +namespace pulsar { + +class BatchMessageContainer; + +typedef boost::shared_ptr BatchMessageContainerPtr; + +class PulsarFriend; + +struct OpSendMsg { + Message msg_; + SendCallback sendCallback_; + uint64_t producerId_; + uint64_t sequenceId_; + boost::posix_time::ptime timeout_; + + OpSendMsg(); + OpSendMsg(uint64_t producerId, uint64_t sequenceId, const Message& msg, + const SendCallback& sendCallback, const ProducerConfiguration& conf); +}; + +class ProducerImpl : public HandlerBase, public boost::enable_shared_from_this, public ProducerImplBase { + public: + + ProducerImpl(ClientImplPtr client, const std::string& topic, + const ProducerConfiguration& producerConfiguration); + ~ProducerImpl(); + + virtual const std::string& getTopic() const; + + virtual void sendAsync(const Message& msg, SendCallback callback); + + virtual void closeAsync(CloseCallback callback); + + virtual Future getProducerCreatedFuture(); + + bool removeCorruptMessage(uint64_t sequenceId); + + bool ackReceived(uint64_t sequenceId); + + virtual void disconnectProducer(); + + uint64_t getProducerId() const; + + virtual void start(); + + virtual void shutdown(); + + bool isClosed(); + + protected: + + typedef BlockingQueue MessageQueue; + + void setMessageMetadata(const Message &msg, const uint64_t& sequenceId, const uint32_t& uncompressedSize); + + void sendMessage(const Message& msg, SendCallback callback); + + void batchMessageTimeoutHandler(const boost::system::error_code& ec); + + friend class PulsarFriend; + + friend class BatchMessageContainer; + + virtual void connectionOpened(const ClientConnectionPtr& connection); + virtual void connectionFailed(Result result); + + virtual HandlerBaseWeakPtr get_weak_from_this() { + return shared_from_this(); + } + + const std::string& getName() const; + + private: + void printStats(); + + void handleCreateProducer(const ClientConnectionPtr& cnx, Result result, + const std::string& producerName); + + void handleClose(Result result, ResultCallback callback); + + void resendMessages(ClientConnectionPtr cnx); + + typedef boost::unique_lock Lock; + + ProducerConfiguration conf_; + + ExecutorServicePtr executor_; + + MessageQueue pendingMessagesQueue_; + + std::string producerName_; + std::string producerStr_; + uint64_t producerId_; + uint64_t msgSequenceGenerator_; + proto::BaseCommand cmd_; + BatchMessageContainerPtr batchMessageContainer; + + typedef boost::shared_ptr TimerPtr; + TimerPtr sendTimer_; + void handleSendTimeout(const boost::system::error_code& err); + + Promise producerCreatedPromise_; + + void failPendingMessages(Result result); + + unsigned long numOfMsgPublished; + unsigned long numOfSendAsyncCalls; + unsigned long numOfMsgAckSuccessfully; +}; + +struct ProducerImplCmp { + bool operator()(const ProducerImplPtr &a, const ProducerImplPtr &b) const; +}; + +} /* namespace pulsar */ + +#endif /* LIB_PRODUCERIMPL_H_ */ diff --git a/pulsar-client-cpp/lib/ProducerImplBase.h b/pulsar-client-cpp/lib/ProducerImplBase.h new file mode 100644 index 0000000000000..7521620fc252e --- /dev/null +++ b/pulsar-client-cpp/lib/ProducerImplBase.h @@ -0,0 +1,42 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef PULSAR_PRODUCER_IMPL_BASE_HEADER +#define PULSAR_PRODUCER_IMPL_BASE_HEADER +#include +#include + +namespace pulsar { +class ProducerImplBase; + +typedef boost::weak_ptr ProducerImplBaseWeakPtr; +typedef boost::shared_ptr ProducerImplBasePtr; + +class ProducerImplBase { +public: + virtual ~ProducerImplBase(){ + } + + virtual void sendAsync(const Message& msg, SendCallback callback) = 0; + virtual void closeAsync(CloseCallback callback) = 0; + virtual void start() = 0; + virtual void shutdown() = 0; + virtual bool isClosed() = 0; + virtual const std::string& getTopic() const = 0; + virtual Future getProducerCreatedFuture() = 0; +}; +} +#endif //PULSAR_PRODUCER_IMPL_BASE_HEADER diff --git a/pulsar-client-cpp/lib/PulsarApi.pb.cc b/pulsar-client-cpp/lib/PulsarApi.pb.cc new file mode 100644 index 0000000000000..b415698764435 --- /dev/null +++ b/pulsar-client-cpp/lib/PulsarApi.pb.cc @@ -0,0 +1,9223 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: PulsarApi.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "PulsarApi.pb.h" + +#include + +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace pulsar { +namespace proto { + +void protobuf_ShutdownFile_PulsarApi_2eproto() { + delete MessageIdData::default_instance_; + delete KeyValue::default_instance_; + delete MessageMetadata::default_instance_; + delete SingleMessageMetadata::default_instance_; + delete CommandConnect::default_instance_; + delete CommandConnected::default_instance_; + delete CommandSubscribe::default_instance_; + delete CommandPartitionedTopicMetadata::default_instance_; + delete CommandPartitionedTopicMetadataResponse::default_instance_; + delete CommandLookupTopic::default_instance_; + delete CommandLookupTopicResponse::default_instance_; + delete CommandProducer::default_instance_; + delete CommandSend::default_instance_; + delete CommandSendReceipt::default_instance_; + delete CommandSendError::default_instance_; + delete CommandMessage::default_instance_; + delete CommandAck::default_instance_; + delete CommandFlow::default_instance_; + delete CommandUnsubscribe::default_instance_; + delete CommandCloseProducer::default_instance_; + delete CommandCloseConsumer::default_instance_; + delete CommandRedeliverUnacknowledgedMessages::default_instance_; + delete CommandSuccess::default_instance_; + delete CommandProducerSuccess::default_instance_; + delete CommandError::default_instance_; + delete CommandPing::default_instance_; + delete CommandPong::default_instance_; + delete BaseCommand::default_instance_; +} + +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER +void protobuf_AddDesc_PulsarApi_2eproto_impl() { + GOOGLE_PROTOBUF_VERIFY_VERSION; + +#else +void protobuf_AddDesc_PulsarApi_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + +#endif + MessageIdData::default_instance_ = new MessageIdData(); + KeyValue::default_instance_ = new KeyValue(); + MessageMetadata::default_instance_ = new MessageMetadata(); + SingleMessageMetadata::default_instance_ = new SingleMessageMetadata(); + CommandConnect::default_instance_ = new CommandConnect(); + CommandConnected::default_instance_ = new CommandConnected(); + CommandSubscribe::default_instance_ = new CommandSubscribe(); + CommandPartitionedTopicMetadata::default_instance_ = new CommandPartitionedTopicMetadata(); + CommandPartitionedTopicMetadataResponse::default_instance_ = new CommandPartitionedTopicMetadataResponse(); + CommandLookupTopic::default_instance_ = new CommandLookupTopic(); + CommandLookupTopicResponse::default_instance_ = new CommandLookupTopicResponse(); + CommandProducer::default_instance_ = new CommandProducer(); + CommandSend::default_instance_ = new CommandSend(); + CommandSendReceipt::default_instance_ = new CommandSendReceipt(); + CommandSendError::default_instance_ = new CommandSendError(); + CommandMessage::default_instance_ = new CommandMessage(); + CommandAck::default_instance_ = new CommandAck(); + CommandFlow::default_instance_ = new CommandFlow(); + CommandUnsubscribe::default_instance_ = new CommandUnsubscribe(); + CommandCloseProducer::default_instance_ = new CommandCloseProducer(); + CommandCloseConsumer::default_instance_ = new CommandCloseConsumer(); + CommandRedeliverUnacknowledgedMessages::default_instance_ = new CommandRedeliverUnacknowledgedMessages(); + CommandSuccess::default_instance_ = new CommandSuccess(); + CommandProducerSuccess::default_instance_ = new CommandProducerSuccess(); + CommandError::default_instance_ = new CommandError(); + CommandPing::default_instance_ = new CommandPing(); + CommandPong::default_instance_ = new CommandPong(); + BaseCommand::default_instance_ = new BaseCommand(); + MessageIdData::default_instance_->InitAsDefaultInstance(); + KeyValue::default_instance_->InitAsDefaultInstance(); + MessageMetadata::default_instance_->InitAsDefaultInstance(); + SingleMessageMetadata::default_instance_->InitAsDefaultInstance(); + CommandConnect::default_instance_->InitAsDefaultInstance(); + CommandConnected::default_instance_->InitAsDefaultInstance(); + CommandSubscribe::default_instance_->InitAsDefaultInstance(); + CommandPartitionedTopicMetadata::default_instance_->InitAsDefaultInstance(); + CommandPartitionedTopicMetadataResponse::default_instance_->InitAsDefaultInstance(); + CommandLookupTopic::default_instance_->InitAsDefaultInstance(); + CommandLookupTopicResponse::default_instance_->InitAsDefaultInstance(); + CommandProducer::default_instance_->InitAsDefaultInstance(); + CommandSend::default_instance_->InitAsDefaultInstance(); + CommandSendReceipt::default_instance_->InitAsDefaultInstance(); + CommandSendError::default_instance_->InitAsDefaultInstance(); + CommandMessage::default_instance_->InitAsDefaultInstance(); + CommandAck::default_instance_->InitAsDefaultInstance(); + CommandFlow::default_instance_->InitAsDefaultInstance(); + CommandUnsubscribe::default_instance_->InitAsDefaultInstance(); + CommandCloseProducer::default_instance_->InitAsDefaultInstance(); + CommandCloseConsumer::default_instance_->InitAsDefaultInstance(); + CommandRedeliverUnacknowledgedMessages::default_instance_->InitAsDefaultInstance(); + CommandSuccess::default_instance_->InitAsDefaultInstance(); + CommandProducerSuccess::default_instance_->InitAsDefaultInstance(); + CommandError::default_instance_->InitAsDefaultInstance(); + CommandPing::default_instance_->InitAsDefaultInstance(); + CommandPong::default_instance_->InitAsDefaultInstance(); + BaseCommand::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_PulsarApi_2eproto); +} + +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AddDesc_PulsarApi_2eproto_once_); +void protobuf_AddDesc_PulsarApi_2eproto() { + ::google::protobuf::GoogleOnceInit(&protobuf_AddDesc_PulsarApi_2eproto_once_, + &protobuf_AddDesc_PulsarApi_2eproto_impl); +} +#else +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_PulsarApi_2eproto { + StaticDescriptorInitializer_PulsarApi_2eproto() { + protobuf_AddDesc_PulsarApi_2eproto(); + } +} static_descriptor_initializer_PulsarApi_2eproto_; +#endif +bool CompressionType_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + return true; + default: + return false; + } +} + +bool ServerError_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + return true; + default: + return false; + } +} + +bool AuthMethod_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + return true; + default: + return false; + } +} + +bool ProtocolVersion_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + return true; + default: + return false; + } +} + + +// =================================================================== + +#ifndef _MSC_VER +const int MessageIdData::kLedgerIdFieldNumber; +const int MessageIdData::kEntryIdFieldNumber; +const int MessageIdData::kPartitionFieldNumber; +const int MessageIdData::kBatchIndexFieldNumber; +#endif // !_MSC_VER + +MessageIdData::MessageIdData() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.MessageIdData) +} + +void MessageIdData::InitAsDefaultInstance() { +} + +MessageIdData::MessageIdData(const MessageIdData& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.MessageIdData) +} + +void MessageIdData::SharedCtor() { + _cached_size_ = 0; + ledgerid_ = GOOGLE_ULONGLONG(0); + entryid_ = GOOGLE_ULONGLONG(0); + partition_ = -1; + batch_index_ = -1; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +MessageIdData::~MessageIdData() { + // @@protoc_insertion_point(destructor:pulsar.proto.MessageIdData) + SharedDtor(); +} + +void MessageIdData::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void MessageIdData::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const MessageIdData& MessageIdData::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +MessageIdData* MessageIdData::default_instance_ = NULL; + +MessageIdData* MessageIdData::New() const { + return new MessageIdData; +} + +void MessageIdData::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 15) { + ZR_(ledgerid_, entryid_); + partition_ = -1; + batch_index_ = -1; + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool MessageIdData::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.MessageIdData) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 ledgerId = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &ledgerid_))); + set_has_ledgerid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_entryId; + break; + } + + // required uint64 entryId = 2; + case 2: { + if (tag == 16) { + parse_entryId: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &entryid_))); + set_has_entryid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_partition; + break; + } + + // optional int32 partition = 3 [default = -1]; + case 3: { + if (tag == 24) { + parse_partition: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &partition_))); + set_has_partition(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_batch_index; + break; + } + + // optional int32 batch_index = 4 [default = -1]; + case 4: { + if (tag == 32) { + parse_batch_index: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &batch_index_))); + set_has_batch_index(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.MessageIdData) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.MessageIdData) + return false; +#undef DO_ +} + +void MessageIdData::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.MessageIdData) + // required uint64 ledgerId = 1; + if (has_ledgerid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->ledgerid(), output); + } + + // required uint64 entryId = 2; + if (has_entryid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->entryid(), output); + } + + // optional int32 partition = 3 [default = -1]; + if (has_partition()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->partition(), output); + } + + // optional int32 batch_index = 4 [default = -1]; + if (has_batch_index()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->batch_index(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.MessageIdData) +} + +int MessageIdData::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint64 ledgerId = 1; + if (has_ledgerid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->ledgerid()); + } + + // required uint64 entryId = 2; + if (has_entryid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->entryid()); + } + + // optional int32 partition = 3 [default = -1]; + if (has_partition()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->partition()); + } + + // optional int32 batch_index = 4 [default = -1]; + if (has_batch_index()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->batch_index()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void MessageIdData::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void MessageIdData::MergeFrom(const MessageIdData& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_ledgerid()) { + set_ledgerid(from.ledgerid()); + } + if (from.has_entryid()) { + set_entryid(from.entryid()); + } + if (from.has_partition()) { + set_partition(from.partition()); + } + if (from.has_batch_index()) { + set_batch_index(from.batch_index()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void MessageIdData::CopyFrom(const MessageIdData& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool MessageIdData::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void MessageIdData::Swap(MessageIdData* other) { + if (other != this) { + std::swap(ledgerid_, other->ledgerid_); + std::swap(entryid_, other->entryid_); + std::swap(partition_, other->partition_); + std::swap(batch_index_, other->batch_index_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string MessageIdData::GetTypeName() const { + return "pulsar.proto.MessageIdData"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int KeyValue::kKeyFieldNumber; +const int KeyValue::kValueFieldNumber; +#endif // !_MSC_VER + +KeyValue::KeyValue() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.KeyValue) +} + +void KeyValue::InitAsDefaultInstance() { +} + +KeyValue::KeyValue(const KeyValue& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.KeyValue) +} + +void KeyValue::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +KeyValue::~KeyValue() { + // @@protoc_insertion_point(destructor:pulsar.proto.KeyValue) + SharedDtor(); +} + +void KeyValue::SharedDtor() { + if (key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete key_; + } + if (value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete value_; + } + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void KeyValue::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const KeyValue& KeyValue::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +KeyValue* KeyValue::default_instance_ = NULL; + +KeyValue* KeyValue::New() const { + return new KeyValue; +} + +void KeyValue::Clear() { + if (_has_bits_[0 / 32] & 3) { + if (has_key()) { + if (key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + key_->clear(); + } + } + if (has_value()) { + if (value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + value_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool KeyValue::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.KeyValue) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string key = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_key())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_value; + break; + } + + // required string value = 2; + case 2: { + if (tag == 18) { + parse_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_value())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.KeyValue) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.KeyValue) + return false; +#undef DO_ +} + +void KeyValue::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.KeyValue) + // required string key = 1; + if (has_key()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->key(), output); + } + + // required string value = 2; + if (has_value()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 2, this->value(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.KeyValue) +} + +int KeyValue::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string key = 1; + if (has_key()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->key()); + } + + // required string value = 2; + if (has_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->value()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void KeyValue::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void KeyValue::MergeFrom(const KeyValue& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_key()) { + set_key(from.key()); + } + if (from.has_value()) { + set_value(from.value()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void KeyValue::CopyFrom(const KeyValue& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool KeyValue::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void KeyValue::Swap(KeyValue* other) { + if (other != this) { + std::swap(key_, other->key_); + std::swap(value_, other->value_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string KeyValue::GetTypeName() const { + return "pulsar.proto.KeyValue"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int MessageMetadata::kProducerNameFieldNumber; +const int MessageMetadata::kSequenceIdFieldNumber; +const int MessageMetadata::kPublishTimeFieldNumber; +const int MessageMetadata::kPropertiesFieldNumber; +const int MessageMetadata::kReplicatedFromFieldNumber; +const int MessageMetadata::kPartitionKeyFieldNumber; +const int MessageMetadata::kReplicateToFieldNumber; +const int MessageMetadata::kCompressionFieldNumber; +const int MessageMetadata::kUncompressedSizeFieldNumber; +const int MessageMetadata::kNumMessagesInBatchFieldNumber; +#endif // !_MSC_VER + +MessageMetadata::MessageMetadata() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.MessageMetadata) +} + +void MessageMetadata::InitAsDefaultInstance() { +} + +MessageMetadata::MessageMetadata(const MessageMetadata& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.MessageMetadata) +} + +void MessageMetadata::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + producer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + sequence_id_ = GOOGLE_ULONGLONG(0); + publish_time_ = GOOGLE_ULONGLONG(0); + replicated_from_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + partition_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + compression_ = 0; + uncompressed_size_ = 0u; + num_messages_in_batch_ = 1; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +MessageMetadata::~MessageMetadata() { + // @@protoc_insertion_point(destructor:pulsar.proto.MessageMetadata) + SharedDtor(); +} + +void MessageMetadata::SharedDtor() { + if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete producer_name_; + } + if (replicated_from_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete replicated_from_; + } + if (partition_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete partition_key_; + } + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void MessageMetadata::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const MessageMetadata& MessageMetadata::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +MessageMetadata* MessageMetadata::default_instance_ = NULL; + +MessageMetadata* MessageMetadata::New() const { + return new MessageMetadata; +} + +void MessageMetadata::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 183) { + ZR_(sequence_id_, publish_time_); + if (has_producer_name()) { + if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_->clear(); + } + } + if (has_replicated_from()) { + if (replicated_from_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + replicated_from_->clear(); + } + } + if (has_partition_key()) { + if (partition_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + partition_key_->clear(); + } + } + compression_ = 0; + } + if (_has_bits_[8 / 32] & 768) { + uncompressed_size_ = 0u; + num_messages_in_batch_ = 1; + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + properties_.Clear(); + replicate_to_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool MessageMetadata::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.MessageMetadata) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string producer_name = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_producer_name())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_sequence_id; + break; + } + + // required uint64 sequence_id = 2; + case 2: { + if (tag == 16) { + parse_sequence_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &sequence_id_))); + set_has_sequence_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_publish_time; + break; + } + + // required uint64 publish_time = 3; + case 3: { + if (tag == 24) { + parse_publish_time: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &publish_time_))); + set_has_publish_time(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(34)) goto parse_properties; + break; + } + + // repeated .pulsar.proto.KeyValue properties = 4; + case 4: { + if (tag == 34) { + parse_properties: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_properties())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(34)) goto parse_properties; + if (input->ExpectTag(42)) goto parse_replicated_from; + break; + } + + // optional string replicated_from = 5; + case 5: { + if (tag == 42) { + parse_replicated_from: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_replicated_from())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(50)) goto parse_partition_key; + break; + } + + // optional string partition_key = 6; + case 6: { + if (tag == 50) { + parse_partition_key: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_partition_key())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(58)) goto parse_replicate_to; + break; + } + + // repeated string replicate_to = 7; + case 7: { + if (tag == 58) { + parse_replicate_to: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_replicate_to())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(58)) goto parse_replicate_to; + if (input->ExpectTag(64)) goto parse_compression; + break; + } + + // optional .pulsar.proto.CompressionType compression = 8 [default = NONE]; + case 8: { + if (tag == 64) { + parse_compression: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::pulsar::proto::CompressionType_IsValid(value)) { + set_compression(static_cast< ::pulsar::proto::CompressionType >(value)); + } else { + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(72)) goto parse_uncompressed_size; + break; + } + + // optional uint32 uncompressed_size = 9 [default = 0]; + case 9: { + if (tag == 72) { + parse_uncompressed_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &uncompressed_size_))); + set_has_uncompressed_size(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(88)) goto parse_num_messages_in_batch; + break; + } + + // optional int32 num_messages_in_batch = 11 [default = 1]; + case 11: { + if (tag == 88) { + parse_num_messages_in_batch: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &num_messages_in_batch_))); + set_has_num_messages_in_batch(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.MessageMetadata) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.MessageMetadata) + return false; +#undef DO_ +} + +void MessageMetadata::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.MessageMetadata) + // required string producer_name = 1; + if (has_producer_name()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->producer_name(), output); + } + + // required uint64 sequence_id = 2; + if (has_sequence_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->sequence_id(), output); + } + + // required uint64 publish_time = 3; + if (has_publish_time()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->publish_time(), output); + } + + // repeated .pulsar.proto.KeyValue properties = 4; + for (int i = 0; i < this->properties_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 4, this->properties(i), output); + } + + // optional string replicated_from = 5; + if (has_replicated_from()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 5, this->replicated_from(), output); + } + + // optional string partition_key = 6; + if (has_partition_key()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 6, this->partition_key(), output); + } + + // repeated string replicate_to = 7; + for (int i = 0; i < this->replicate_to_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteString( + 7, this->replicate_to(i), output); + } + + // optional .pulsar.proto.CompressionType compression = 8 [default = NONE]; + if (has_compression()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 8, this->compression(), output); + } + + // optional uint32 uncompressed_size = 9 [default = 0]; + if (has_uncompressed_size()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(9, this->uncompressed_size(), output); + } + + // optional int32 num_messages_in_batch = 11 [default = 1]; + if (has_num_messages_in_batch()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(11, this->num_messages_in_batch(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.MessageMetadata) +} + +int MessageMetadata::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string producer_name = 1; + if (has_producer_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->producer_name()); + } + + // required uint64 sequence_id = 2; + if (has_sequence_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->sequence_id()); + } + + // required uint64 publish_time = 3; + if (has_publish_time()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->publish_time()); + } + + // optional string replicated_from = 5; + if (has_replicated_from()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->replicated_from()); + } + + // optional string partition_key = 6; + if (has_partition_key()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->partition_key()); + } + + // optional .pulsar.proto.CompressionType compression = 8 [default = NONE]; + if (has_compression()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->compression()); + } + + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + // optional uint32 uncompressed_size = 9 [default = 0]; + if (has_uncompressed_size()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->uncompressed_size()); + } + + // optional int32 num_messages_in_batch = 11 [default = 1]; + if (has_num_messages_in_batch()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->num_messages_in_batch()); + } + + } + // repeated .pulsar.proto.KeyValue properties = 4; + total_size += 1 * this->properties_size(); + for (int i = 0; i < this->properties_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->properties(i)); + } + + // repeated string replicate_to = 7; + total_size += 1 * this->replicate_to_size(); + for (int i = 0; i < this->replicate_to_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->replicate_to(i)); + } + + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void MessageMetadata::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void MessageMetadata::MergeFrom(const MessageMetadata& from) { + GOOGLE_CHECK_NE(&from, this); + properties_.MergeFrom(from.properties_); + replicate_to_.MergeFrom(from.replicate_to_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_producer_name()) { + set_producer_name(from.producer_name()); + } + if (from.has_sequence_id()) { + set_sequence_id(from.sequence_id()); + } + if (from.has_publish_time()) { + set_publish_time(from.publish_time()); + } + if (from.has_replicated_from()) { + set_replicated_from(from.replicated_from()); + } + if (from.has_partition_key()) { + set_partition_key(from.partition_key()); + } + if (from.has_compression()) { + set_compression(from.compression()); + } + } + if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) { + if (from.has_uncompressed_size()) { + set_uncompressed_size(from.uncompressed_size()); + } + if (from.has_num_messages_in_batch()) { + set_num_messages_in_batch(from.num_messages_in_batch()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void MessageMetadata::CopyFrom(const MessageMetadata& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool MessageMetadata::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + if (!::google::protobuf::internal::AllAreInitialized(this->properties())) return false; + return true; +} + +void MessageMetadata::Swap(MessageMetadata* other) { + if (other != this) { + std::swap(producer_name_, other->producer_name_); + std::swap(sequence_id_, other->sequence_id_); + std::swap(publish_time_, other->publish_time_); + properties_.Swap(&other->properties_); + std::swap(replicated_from_, other->replicated_from_); + std::swap(partition_key_, other->partition_key_); + replicate_to_.Swap(&other->replicate_to_); + std::swap(compression_, other->compression_); + std::swap(uncompressed_size_, other->uncompressed_size_); + std::swap(num_messages_in_batch_, other->num_messages_in_batch_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string MessageMetadata::GetTypeName() const { + return "pulsar.proto.MessageMetadata"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int SingleMessageMetadata::kPropertiesFieldNumber; +const int SingleMessageMetadata::kPartitionKeyFieldNumber; +const int SingleMessageMetadata::kPayloadSizeFieldNumber; +#endif // !_MSC_VER + +SingleMessageMetadata::SingleMessageMetadata() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.SingleMessageMetadata) +} + +void SingleMessageMetadata::InitAsDefaultInstance() { +} + +SingleMessageMetadata::SingleMessageMetadata(const SingleMessageMetadata& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.SingleMessageMetadata) +} + +void SingleMessageMetadata::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + partition_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + payload_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +SingleMessageMetadata::~SingleMessageMetadata() { + // @@protoc_insertion_point(destructor:pulsar.proto.SingleMessageMetadata) + SharedDtor(); +} + +void SingleMessageMetadata::SharedDtor() { + if (partition_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete partition_key_; + } + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void SingleMessageMetadata::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const SingleMessageMetadata& SingleMessageMetadata::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +SingleMessageMetadata* SingleMessageMetadata::default_instance_ = NULL; + +SingleMessageMetadata* SingleMessageMetadata::New() const { + return new SingleMessageMetadata; +} + +void SingleMessageMetadata::Clear() { + if (_has_bits_[0 / 32] & 6) { + if (has_partition_key()) { + if (partition_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + partition_key_->clear(); + } + } + payload_size_ = 0; + } + properties_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool SingleMessageMetadata::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.SingleMessageMetadata) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .pulsar.proto.KeyValue properties = 1; + case 1: { + if (tag == 10) { + parse_properties: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_properties())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(10)) goto parse_properties; + if (input->ExpectTag(18)) goto parse_partition_key; + break; + } + + // optional string partition_key = 2; + case 2: { + if (tag == 18) { + parse_partition_key: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_partition_key())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_payload_size; + break; + } + + // required int32 payload_size = 3; + case 3: { + if (tag == 24) { + parse_payload_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &payload_size_))); + set_has_payload_size(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.SingleMessageMetadata) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.SingleMessageMetadata) + return false; +#undef DO_ +} + +void SingleMessageMetadata::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.SingleMessageMetadata) + // repeated .pulsar.proto.KeyValue properties = 1; + for (int i = 0; i < this->properties_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 1, this->properties(i), output); + } + + // optional string partition_key = 2; + if (has_partition_key()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 2, this->partition_key(), output); + } + + // required int32 payload_size = 3; + if (has_payload_size()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->payload_size(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.SingleMessageMetadata) +} + +int SingleMessageMetadata::ByteSize() const { + int total_size = 0; + + if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) { + // optional string partition_key = 2; + if (has_partition_key()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->partition_key()); + } + + // required int32 payload_size = 3; + if (has_payload_size()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->payload_size()); + } + + } + // repeated .pulsar.proto.KeyValue properties = 1; + total_size += 1 * this->properties_size(); + for (int i = 0; i < this->properties_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->properties(i)); + } + + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void SingleMessageMetadata::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void SingleMessageMetadata::MergeFrom(const SingleMessageMetadata& from) { + GOOGLE_CHECK_NE(&from, this); + properties_.MergeFrom(from.properties_); + if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) { + if (from.has_partition_key()) { + set_partition_key(from.partition_key()); + } + if (from.has_payload_size()) { + set_payload_size(from.payload_size()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void SingleMessageMetadata::CopyFrom(const SingleMessageMetadata& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool SingleMessageMetadata::IsInitialized() const { + if ((_has_bits_[0] & 0x00000004) != 0x00000004) return false; + + if (!::google::protobuf::internal::AllAreInitialized(this->properties())) return false; + return true; +} + +void SingleMessageMetadata::Swap(SingleMessageMetadata* other) { + if (other != this) { + properties_.Swap(&other->properties_); + std::swap(partition_key_, other->partition_key_); + std::swap(payload_size_, other->payload_size_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string SingleMessageMetadata::GetTypeName() const { + return "pulsar.proto.SingleMessageMetadata"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CommandConnect::kClientVersionFieldNumber; +const int CommandConnect::kAuthMethodFieldNumber; +const int CommandConnect::kAuthMethodNameFieldNumber; +const int CommandConnect::kAuthDataFieldNumber; +const int CommandConnect::kProtocolVersionFieldNumber; +#endif // !_MSC_VER + +CommandConnect::CommandConnect() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandConnect) +} + +void CommandConnect::InitAsDefaultInstance() { +} + +CommandConnect::CommandConnect(const CommandConnect& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandConnect) +} + +void CommandConnect::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + client_version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + auth_method_ = 0; + auth_method_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + auth_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + protocol_version_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandConnect::~CommandConnect() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandConnect) + SharedDtor(); +} + +void CommandConnect::SharedDtor() { + if (client_version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete client_version_; + } + if (auth_method_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete auth_method_name_; + } + if (auth_data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete auth_data_; + } + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandConnect::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandConnect& CommandConnect::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandConnect* CommandConnect::default_instance_ = NULL; + +CommandConnect* CommandConnect::New() const { + return new CommandConnect; +} + +void CommandConnect::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 31) { + ZR_(auth_method_, protocol_version_); + if (has_client_version()) { + if (client_version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + client_version_->clear(); + } + } + if (has_auth_method_name()) { + if (auth_method_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + auth_method_name_->clear(); + } + } + if (has_auth_data()) { + if (auth_data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + auth_data_->clear(); + } + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandConnect::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandConnect) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string client_version = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_client_version())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_auth_method; + break; + } + + // optional .pulsar.proto.AuthMethod auth_method = 2; + case 2: { + if (tag == 16) { + parse_auth_method: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::pulsar::proto::AuthMethod_IsValid(value)) { + set_auth_method(static_cast< ::pulsar::proto::AuthMethod >(value)); + } else { + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_auth_data; + break; + } + + // optional bytes auth_data = 3; + case 3: { + if (tag == 26) { + parse_auth_data: + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_auth_data())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_protocol_version; + break; + } + + // optional int32 protocol_version = 4 [default = 0]; + case 4: { + if (tag == 32) { + parse_protocol_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &protocol_version_))); + set_has_protocol_version(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(42)) goto parse_auth_method_name; + break; + } + + // optional string auth_method_name = 5; + case 5: { + if (tag == 42) { + parse_auth_method_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_auth_method_name())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandConnect) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandConnect) + return false; +#undef DO_ +} + +void CommandConnect::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandConnect) + // required string client_version = 1; + if (has_client_version()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->client_version(), output); + } + + // optional .pulsar.proto.AuthMethod auth_method = 2; + if (has_auth_method()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 2, this->auth_method(), output); + } + + // optional bytes auth_data = 3; + if (has_auth_data()) { + ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased( + 3, this->auth_data(), output); + } + + // optional int32 protocol_version = 4 [default = 0]; + if (has_protocol_version()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->protocol_version(), output); + } + + // optional string auth_method_name = 5; + if (has_auth_method_name()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 5, this->auth_method_name(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandConnect) +} + +int CommandConnect::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string client_version = 1; + if (has_client_version()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->client_version()); + } + + // optional .pulsar.proto.AuthMethod auth_method = 2; + if (has_auth_method()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->auth_method()); + } + + // optional string auth_method_name = 5; + if (has_auth_method_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->auth_method_name()); + } + + // optional bytes auth_data = 3; + if (has_auth_data()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->auth_data()); + } + + // optional int32 protocol_version = 4 [default = 0]; + if (has_protocol_version()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->protocol_version()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandConnect::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandConnect::MergeFrom(const CommandConnect& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_client_version()) { + set_client_version(from.client_version()); + } + if (from.has_auth_method()) { + set_auth_method(from.auth_method()); + } + if (from.has_auth_method_name()) { + set_auth_method_name(from.auth_method_name()); + } + if (from.has_auth_data()) { + set_auth_data(from.auth_data()); + } + if (from.has_protocol_version()) { + set_protocol_version(from.protocol_version()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandConnect::CopyFrom(const CommandConnect& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandConnect::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void CommandConnect::Swap(CommandConnect* other) { + if (other != this) { + std::swap(client_version_, other->client_version_); + std::swap(auth_method_, other->auth_method_); + std::swap(auth_method_name_, other->auth_method_name_); + std::swap(auth_data_, other->auth_data_); + std::swap(protocol_version_, other->protocol_version_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandConnect::GetTypeName() const { + return "pulsar.proto.CommandConnect"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CommandConnected::kServerVersionFieldNumber; +const int CommandConnected::kProtocolVersionFieldNumber; +#endif // !_MSC_VER + +CommandConnected::CommandConnected() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandConnected) +} + +void CommandConnected::InitAsDefaultInstance() { +} + +CommandConnected::CommandConnected(const CommandConnected& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandConnected) +} + +void CommandConnected::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + server_version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + protocol_version_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandConnected::~CommandConnected() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandConnected) + SharedDtor(); +} + +void CommandConnected::SharedDtor() { + if (server_version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete server_version_; + } + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandConnected::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandConnected& CommandConnected::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandConnected* CommandConnected::default_instance_ = NULL; + +CommandConnected* CommandConnected::New() const { + return new CommandConnected; +} + +void CommandConnected::Clear() { + if (_has_bits_[0 / 32] & 3) { + if (has_server_version()) { + if (server_version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + server_version_->clear(); + } + } + protocol_version_ = 0; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandConnected::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandConnected) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string server_version = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_server_version())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_protocol_version; + break; + } + + // optional int32 protocol_version = 2 [default = 0]; + case 2: { + if (tag == 16) { + parse_protocol_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &protocol_version_))); + set_has_protocol_version(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandConnected) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandConnected) + return false; +#undef DO_ +} + +void CommandConnected::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandConnected) + // required string server_version = 1; + if (has_server_version()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->server_version(), output); + } + + // optional int32 protocol_version = 2 [default = 0]; + if (has_protocol_version()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->protocol_version(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandConnected) +} + +int CommandConnected::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string server_version = 1; + if (has_server_version()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->server_version()); + } + + // optional int32 protocol_version = 2 [default = 0]; + if (has_protocol_version()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->protocol_version()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandConnected::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandConnected::MergeFrom(const CommandConnected& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_server_version()) { + set_server_version(from.server_version()); + } + if (from.has_protocol_version()) { + set_protocol_version(from.protocol_version()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandConnected::CopyFrom(const CommandConnected& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandConnected::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void CommandConnected::Swap(CommandConnected* other) { + if (other != this) { + std::swap(server_version_, other->server_version_); + std::swap(protocol_version_, other->protocol_version_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandConnected::GetTypeName() const { + return "pulsar.proto.CommandConnected"; +} + + +// =================================================================== + +bool CommandSubscribe_SubType_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const CommandSubscribe_SubType CommandSubscribe::Exclusive; +const CommandSubscribe_SubType CommandSubscribe::Shared; +const CommandSubscribe_SubType CommandSubscribe::Failover; +const CommandSubscribe_SubType CommandSubscribe::SubType_MIN; +const CommandSubscribe_SubType CommandSubscribe::SubType_MAX; +const int CommandSubscribe::SubType_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int CommandSubscribe::kTopicFieldNumber; +const int CommandSubscribe::kSubscriptionFieldNumber; +const int CommandSubscribe::kSubTypeFieldNumber; +const int CommandSubscribe::kConsumerIdFieldNumber; +const int CommandSubscribe::kRequestIdFieldNumber; +const int CommandSubscribe::kConsumerNameFieldNumber; +#endif // !_MSC_VER + +CommandSubscribe::CommandSubscribe() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandSubscribe) +} + +void CommandSubscribe::InitAsDefaultInstance() { +} + +CommandSubscribe::CommandSubscribe(const CommandSubscribe& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandSubscribe) +} + +void CommandSubscribe::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + subscription_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + subtype_ = 0; + consumer_id_ = GOOGLE_ULONGLONG(0); + request_id_ = GOOGLE_ULONGLONG(0); + consumer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandSubscribe::~CommandSubscribe() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandSubscribe) + SharedDtor(); +} + +void CommandSubscribe::SharedDtor() { + if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete topic_; + } + if (subscription_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete subscription_; + } + if (consumer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete consumer_name_; + } + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandSubscribe::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandSubscribe& CommandSubscribe::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandSubscribe* CommandSubscribe::default_instance_ = NULL; + +CommandSubscribe* CommandSubscribe::New() const { + return new CommandSubscribe; +} + +void CommandSubscribe::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 63) { + ZR_(consumer_id_, request_id_); + if (has_topic()) { + if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_->clear(); + } + } + if (has_subscription()) { + if (subscription_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + subscription_->clear(); + } + } + subtype_ = 0; + if (has_consumer_name()) { + if (consumer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + consumer_name_->clear(); + } + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandSubscribe::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandSubscribe) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string topic = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_topic())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_subscription; + break; + } + + // required string subscription = 2; + case 2: { + if (tag == 18) { + parse_subscription: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_subscription())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_subType; + break; + } + + // required .pulsar.proto.CommandSubscribe.SubType subType = 3; + case 3: { + if (tag == 24) { + parse_subType: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::pulsar::proto::CommandSubscribe_SubType_IsValid(value)) { + set_subtype(static_cast< ::pulsar::proto::CommandSubscribe_SubType >(value)); + } else { + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_consumer_id; + break; + } + + // required uint64 consumer_id = 4; + case 4: { + if (tag == 32) { + parse_consumer_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &consumer_id_))); + set_has_consumer_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(40)) goto parse_request_id; + break; + } + + // required uint64 request_id = 5; + case 5: { + if (tag == 40) { + parse_request_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &request_id_))); + set_has_request_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(50)) goto parse_consumer_name; + break; + } + + // optional string consumer_name = 6; + case 6: { + if (tag == 50) { + parse_consumer_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_consumer_name())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandSubscribe) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandSubscribe) + return false; +#undef DO_ +} + +void CommandSubscribe::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandSubscribe) + // required string topic = 1; + if (has_topic()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->topic(), output); + } + + // required string subscription = 2; + if (has_subscription()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 2, this->subscription(), output); + } + + // required .pulsar.proto.CommandSubscribe.SubType subType = 3; + if (has_subtype()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 3, this->subtype(), output); + } + + // required uint64 consumer_id = 4; + if (has_consumer_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->consumer_id(), output); + } + + // required uint64 request_id = 5; + if (has_request_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(5, this->request_id(), output); + } + + // optional string consumer_name = 6; + if (has_consumer_name()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 6, this->consumer_name(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandSubscribe) +} + +int CommandSubscribe::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string topic = 1; + if (has_topic()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->topic()); + } + + // required string subscription = 2; + if (has_subscription()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->subscription()); + } + + // required .pulsar.proto.CommandSubscribe.SubType subType = 3; + if (has_subtype()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->subtype()); + } + + // required uint64 consumer_id = 4; + if (has_consumer_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->consumer_id()); + } + + // required uint64 request_id = 5; + if (has_request_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->request_id()); + } + + // optional string consumer_name = 6; + if (has_consumer_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->consumer_name()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandSubscribe::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandSubscribe::MergeFrom(const CommandSubscribe& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_topic()) { + set_topic(from.topic()); + } + if (from.has_subscription()) { + set_subscription(from.subscription()); + } + if (from.has_subtype()) { + set_subtype(from.subtype()); + } + if (from.has_consumer_id()) { + set_consumer_id(from.consumer_id()); + } + if (from.has_request_id()) { + set_request_id(from.request_id()); + } + if (from.has_consumer_name()) { + set_consumer_name(from.consumer_name()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandSubscribe::CopyFrom(const CommandSubscribe& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandSubscribe::IsInitialized() const { + if ((_has_bits_[0] & 0x0000001f) != 0x0000001f) return false; + + return true; +} + +void CommandSubscribe::Swap(CommandSubscribe* other) { + if (other != this) { + std::swap(topic_, other->topic_); + std::swap(subscription_, other->subscription_); + std::swap(subtype_, other->subtype_); + std::swap(consumer_id_, other->consumer_id_); + std::swap(request_id_, other->request_id_); + std::swap(consumer_name_, other->consumer_name_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandSubscribe::GetTypeName() const { + return "pulsar.proto.CommandSubscribe"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CommandPartitionedTopicMetadata::kTopicFieldNumber; +const int CommandPartitionedTopicMetadata::kRequestIdFieldNumber; +#endif // !_MSC_VER + +CommandPartitionedTopicMetadata::CommandPartitionedTopicMetadata() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandPartitionedTopicMetadata) +} + +void CommandPartitionedTopicMetadata::InitAsDefaultInstance() { +} + +CommandPartitionedTopicMetadata::CommandPartitionedTopicMetadata(const CommandPartitionedTopicMetadata& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandPartitionedTopicMetadata) +} + +void CommandPartitionedTopicMetadata::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + request_id_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandPartitionedTopicMetadata::~CommandPartitionedTopicMetadata() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandPartitionedTopicMetadata) + SharedDtor(); +} + +void CommandPartitionedTopicMetadata::SharedDtor() { + if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete topic_; + } + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandPartitionedTopicMetadata::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandPartitionedTopicMetadata& CommandPartitionedTopicMetadata::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandPartitionedTopicMetadata* CommandPartitionedTopicMetadata::default_instance_ = NULL; + +CommandPartitionedTopicMetadata* CommandPartitionedTopicMetadata::New() const { + return new CommandPartitionedTopicMetadata; +} + +void CommandPartitionedTopicMetadata::Clear() { + if (_has_bits_[0 / 32] & 3) { + if (has_topic()) { + if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_->clear(); + } + } + request_id_ = GOOGLE_ULONGLONG(0); + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandPartitionedTopicMetadata::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandPartitionedTopicMetadata) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string topic = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_topic())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_request_id; + break; + } + + // required uint64 request_id = 2; + case 2: { + if (tag == 16) { + parse_request_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &request_id_))); + set_has_request_id(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandPartitionedTopicMetadata) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandPartitionedTopicMetadata) + return false; +#undef DO_ +} + +void CommandPartitionedTopicMetadata::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandPartitionedTopicMetadata) + // required string topic = 1; + if (has_topic()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->topic(), output); + } + + // required uint64 request_id = 2; + if (has_request_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->request_id(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandPartitionedTopicMetadata) +} + +int CommandPartitionedTopicMetadata::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string topic = 1; + if (has_topic()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->topic()); + } + + // required uint64 request_id = 2; + if (has_request_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->request_id()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandPartitionedTopicMetadata::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandPartitionedTopicMetadata::MergeFrom(const CommandPartitionedTopicMetadata& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_topic()) { + set_topic(from.topic()); + } + if (from.has_request_id()) { + set_request_id(from.request_id()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandPartitionedTopicMetadata::CopyFrom(const CommandPartitionedTopicMetadata& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandPartitionedTopicMetadata::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void CommandPartitionedTopicMetadata::Swap(CommandPartitionedTopicMetadata* other) { + if (other != this) { + std::swap(topic_, other->topic_); + std::swap(request_id_, other->request_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandPartitionedTopicMetadata::GetTypeName() const { + return "pulsar.proto.CommandPartitionedTopicMetadata"; +} + + +// =================================================================== + +bool CommandPartitionedTopicMetadataResponse_LookupType_IsValid(int value) { + switch(value) { + case 0: + case 1: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const CommandPartitionedTopicMetadataResponse_LookupType CommandPartitionedTopicMetadataResponse::Success; +const CommandPartitionedTopicMetadataResponse_LookupType CommandPartitionedTopicMetadataResponse::Failed; +const CommandPartitionedTopicMetadataResponse_LookupType CommandPartitionedTopicMetadataResponse::LookupType_MIN; +const CommandPartitionedTopicMetadataResponse_LookupType CommandPartitionedTopicMetadataResponse::LookupType_MAX; +const int CommandPartitionedTopicMetadataResponse::LookupType_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int CommandPartitionedTopicMetadataResponse::kPartitionsFieldNumber; +const int CommandPartitionedTopicMetadataResponse::kRequestIdFieldNumber; +const int CommandPartitionedTopicMetadataResponse::kResponseFieldNumber; +const int CommandPartitionedTopicMetadataResponse::kErrorFieldNumber; +const int CommandPartitionedTopicMetadataResponse::kMessageFieldNumber; +#endif // !_MSC_VER + +CommandPartitionedTopicMetadataResponse::CommandPartitionedTopicMetadataResponse() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandPartitionedTopicMetadataResponse) +} + +void CommandPartitionedTopicMetadataResponse::InitAsDefaultInstance() { +} + +CommandPartitionedTopicMetadataResponse::CommandPartitionedTopicMetadataResponse(const CommandPartitionedTopicMetadataResponse& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandPartitionedTopicMetadataResponse) +} + +void CommandPartitionedTopicMetadataResponse::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + partitions_ = 0u; + request_id_ = GOOGLE_ULONGLONG(0); + response_ = 0; + error_ = 0; + message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandPartitionedTopicMetadataResponse::~CommandPartitionedTopicMetadataResponse() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandPartitionedTopicMetadataResponse) + SharedDtor(); +} + +void CommandPartitionedTopicMetadataResponse::SharedDtor() { + if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete message_; + } + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandPartitionedTopicMetadataResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandPartitionedTopicMetadataResponse& CommandPartitionedTopicMetadataResponse::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandPartitionedTopicMetadataResponse* CommandPartitionedTopicMetadataResponse::default_instance_ = NULL; + +CommandPartitionedTopicMetadataResponse* CommandPartitionedTopicMetadataResponse::New() const { + return new CommandPartitionedTopicMetadataResponse; +} + +void CommandPartitionedTopicMetadataResponse::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 31) { + ZR_(request_id_, response_); + error_ = 0; + if (has_message()) { + if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_->clear(); + } + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandPartitionedTopicMetadataResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandPartitionedTopicMetadataResponse) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional uint32 partitions = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &partitions_))); + set_has_partitions(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_request_id; + break; + } + + // required uint64 request_id = 2; + case 2: { + if (tag == 16) { + parse_request_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &request_id_))); + set_has_request_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_response; + break; + } + + // optional .pulsar.proto.CommandPartitionedTopicMetadataResponse.LookupType response = 3; + case 3: { + if (tag == 24) { + parse_response: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::pulsar::proto::CommandPartitionedTopicMetadataResponse_LookupType_IsValid(value)) { + set_response(static_cast< ::pulsar::proto::CommandPartitionedTopicMetadataResponse_LookupType >(value)); + } else { + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_error; + break; + } + + // optional .pulsar.proto.ServerError error = 4; + case 4: { + if (tag == 32) { + parse_error: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::pulsar::proto::ServerError_IsValid(value)) { + set_error(static_cast< ::pulsar::proto::ServerError >(value)); + } else { + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(42)) goto parse_message; + break; + } + + // optional string message = 5; + case 5: { + if (tag == 42) { + parse_message: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_message())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandPartitionedTopicMetadataResponse) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandPartitionedTopicMetadataResponse) + return false; +#undef DO_ +} + +void CommandPartitionedTopicMetadataResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandPartitionedTopicMetadataResponse) + // optional uint32 partitions = 1; + if (has_partitions()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->partitions(), output); + } + + // required uint64 request_id = 2; + if (has_request_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->request_id(), output); + } + + // optional .pulsar.proto.CommandPartitionedTopicMetadataResponse.LookupType response = 3; + if (has_response()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 3, this->response(), output); + } + + // optional .pulsar.proto.ServerError error = 4; + if (has_error()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 4, this->error(), output); + } + + // optional string message = 5; + if (has_message()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 5, this->message(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandPartitionedTopicMetadataResponse) +} + +int CommandPartitionedTopicMetadataResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional uint32 partitions = 1; + if (has_partitions()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->partitions()); + } + + // required uint64 request_id = 2; + if (has_request_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->request_id()); + } + + // optional .pulsar.proto.CommandPartitionedTopicMetadataResponse.LookupType response = 3; + if (has_response()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->response()); + } + + // optional .pulsar.proto.ServerError error = 4; + if (has_error()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->error()); + } + + // optional string message = 5; + if (has_message()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->message()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandPartitionedTopicMetadataResponse::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandPartitionedTopicMetadataResponse::MergeFrom(const CommandPartitionedTopicMetadataResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_partitions()) { + set_partitions(from.partitions()); + } + if (from.has_request_id()) { + set_request_id(from.request_id()); + } + if (from.has_response()) { + set_response(from.response()); + } + if (from.has_error()) { + set_error(from.error()); + } + if (from.has_message()) { + set_message(from.message()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandPartitionedTopicMetadataResponse::CopyFrom(const CommandPartitionedTopicMetadataResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandPartitionedTopicMetadataResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000002) != 0x00000002) return false; + + return true; +} + +void CommandPartitionedTopicMetadataResponse::Swap(CommandPartitionedTopicMetadataResponse* other) { + if (other != this) { + std::swap(partitions_, other->partitions_); + std::swap(request_id_, other->request_id_); + std::swap(response_, other->response_); + std::swap(error_, other->error_); + std::swap(message_, other->message_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandPartitionedTopicMetadataResponse::GetTypeName() const { + return "pulsar.proto.CommandPartitionedTopicMetadataResponse"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CommandLookupTopic::kTopicFieldNumber; +const int CommandLookupTopic::kRequestIdFieldNumber; +const int CommandLookupTopic::kAuthoritativeFieldNumber; +#endif // !_MSC_VER + +CommandLookupTopic::CommandLookupTopic() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandLookupTopic) +} + +void CommandLookupTopic::InitAsDefaultInstance() { +} + +CommandLookupTopic::CommandLookupTopic(const CommandLookupTopic& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandLookupTopic) +} + +void CommandLookupTopic::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + request_id_ = GOOGLE_ULONGLONG(0); + authoritative_ = false; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandLookupTopic::~CommandLookupTopic() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandLookupTopic) + SharedDtor(); +} + +void CommandLookupTopic::SharedDtor() { + if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete topic_; + } + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandLookupTopic::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandLookupTopic& CommandLookupTopic::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandLookupTopic* CommandLookupTopic::default_instance_ = NULL; + +CommandLookupTopic* CommandLookupTopic::New() const { + return new CommandLookupTopic; +} + +void CommandLookupTopic::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 7) { + ZR_(request_id_, authoritative_); + if (has_topic()) { + if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_->clear(); + } + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandLookupTopic::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandLookupTopic) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string topic = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_topic())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_request_id; + break; + } + + // required uint64 request_id = 2; + case 2: { + if (tag == 16) { + parse_request_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &request_id_))); + set_has_request_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_authoritative; + break; + } + + // optional bool authoritative = 3 [default = false]; + case 3: { + if (tag == 24) { + parse_authoritative: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &authoritative_))); + set_has_authoritative(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandLookupTopic) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandLookupTopic) + return false; +#undef DO_ +} + +void CommandLookupTopic::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandLookupTopic) + // required string topic = 1; + if (has_topic()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->topic(), output); + } + + // required uint64 request_id = 2; + if (has_request_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->request_id(), output); + } + + // optional bool authoritative = 3 [default = false]; + if (has_authoritative()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->authoritative(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandLookupTopic) +} + +int CommandLookupTopic::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string topic = 1; + if (has_topic()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->topic()); + } + + // required uint64 request_id = 2; + if (has_request_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->request_id()); + } + + // optional bool authoritative = 3 [default = false]; + if (has_authoritative()) { + total_size += 1 + 1; + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandLookupTopic::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandLookupTopic::MergeFrom(const CommandLookupTopic& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_topic()) { + set_topic(from.topic()); + } + if (from.has_request_id()) { + set_request_id(from.request_id()); + } + if (from.has_authoritative()) { + set_authoritative(from.authoritative()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandLookupTopic::CopyFrom(const CommandLookupTopic& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandLookupTopic::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void CommandLookupTopic::Swap(CommandLookupTopic* other) { + if (other != this) { + std::swap(topic_, other->topic_); + std::swap(request_id_, other->request_id_); + std::swap(authoritative_, other->authoritative_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandLookupTopic::GetTypeName() const { + return "pulsar.proto.CommandLookupTopic"; +} + + +// =================================================================== + +bool CommandLookupTopicResponse_LookupType_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const CommandLookupTopicResponse_LookupType CommandLookupTopicResponse::Redirect; +const CommandLookupTopicResponse_LookupType CommandLookupTopicResponse::Connect; +const CommandLookupTopicResponse_LookupType CommandLookupTopicResponse::Failed; +const CommandLookupTopicResponse_LookupType CommandLookupTopicResponse::LookupType_MIN; +const CommandLookupTopicResponse_LookupType CommandLookupTopicResponse::LookupType_MAX; +const int CommandLookupTopicResponse::LookupType_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int CommandLookupTopicResponse::kBrokerServiceUrlFieldNumber; +const int CommandLookupTopicResponse::kBrokerServiceUrlTlsFieldNumber; +const int CommandLookupTopicResponse::kResponseFieldNumber; +const int CommandLookupTopicResponse::kRequestIdFieldNumber; +const int CommandLookupTopicResponse::kAuthoritativeFieldNumber; +const int CommandLookupTopicResponse::kErrorFieldNumber; +const int CommandLookupTopicResponse::kMessageFieldNumber; +#endif // !_MSC_VER + +CommandLookupTopicResponse::CommandLookupTopicResponse() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandLookupTopicResponse) +} + +void CommandLookupTopicResponse::InitAsDefaultInstance() { +} + +CommandLookupTopicResponse::CommandLookupTopicResponse(const CommandLookupTopicResponse& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandLookupTopicResponse) +} + +void CommandLookupTopicResponse::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + brokerserviceurl_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + brokerserviceurltls_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + response_ = 0; + request_id_ = GOOGLE_ULONGLONG(0); + authoritative_ = false; + error_ = 0; + message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandLookupTopicResponse::~CommandLookupTopicResponse() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandLookupTopicResponse) + SharedDtor(); +} + +void CommandLookupTopicResponse::SharedDtor() { + if (brokerserviceurl_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete brokerserviceurl_; + } + if (brokerserviceurltls_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete brokerserviceurltls_; + } + if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete message_; + } + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandLookupTopicResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandLookupTopicResponse& CommandLookupTopicResponse::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandLookupTopicResponse* CommandLookupTopicResponse::default_instance_ = NULL; + +CommandLookupTopicResponse* CommandLookupTopicResponse::New() const { + return new CommandLookupTopicResponse; +} + +void CommandLookupTopicResponse::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 127) { + ZR_(request_id_, authoritative_); + if (has_brokerserviceurl()) { + if (brokerserviceurl_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + brokerserviceurl_->clear(); + } + } + if (has_brokerserviceurltls()) { + if (brokerserviceurltls_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + brokerserviceurltls_->clear(); + } + } + error_ = 0; + if (has_message()) { + if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_->clear(); + } + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandLookupTopicResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandLookupTopicResponse) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string brokerServiceUrl = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_brokerserviceurl())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_brokerServiceUrlTls; + break; + } + + // optional string brokerServiceUrlTls = 2; + case 2: { + if (tag == 18) { + parse_brokerServiceUrlTls: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_brokerserviceurltls())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_response; + break; + } + + // optional .pulsar.proto.CommandLookupTopicResponse.LookupType response = 3; + case 3: { + if (tag == 24) { + parse_response: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::pulsar::proto::CommandLookupTopicResponse_LookupType_IsValid(value)) { + set_response(static_cast< ::pulsar::proto::CommandLookupTopicResponse_LookupType >(value)); + } else { + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_request_id; + break; + } + + // required uint64 request_id = 4; + case 4: { + if (tag == 32) { + parse_request_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &request_id_))); + set_has_request_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(40)) goto parse_authoritative; + break; + } + + // optional bool authoritative = 5 [default = false]; + case 5: { + if (tag == 40) { + parse_authoritative: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &authoritative_))); + set_has_authoritative(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(48)) goto parse_error; + break; + } + + // optional .pulsar.proto.ServerError error = 6; + case 6: { + if (tag == 48) { + parse_error: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::pulsar::proto::ServerError_IsValid(value)) { + set_error(static_cast< ::pulsar::proto::ServerError >(value)); + } else { + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(58)) goto parse_message; + break; + } + + // optional string message = 7; + case 7: { + if (tag == 58) { + parse_message: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_message())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandLookupTopicResponse) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandLookupTopicResponse) + return false; +#undef DO_ +} + +void CommandLookupTopicResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandLookupTopicResponse) + // optional string brokerServiceUrl = 1; + if (has_brokerserviceurl()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->brokerserviceurl(), output); + } + + // optional string brokerServiceUrlTls = 2; + if (has_brokerserviceurltls()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 2, this->brokerserviceurltls(), output); + } + + // optional .pulsar.proto.CommandLookupTopicResponse.LookupType response = 3; + if (has_response()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 3, this->response(), output); + } + + // required uint64 request_id = 4; + if (has_request_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->request_id(), output); + } + + // optional bool authoritative = 5 [default = false]; + if (has_authoritative()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->authoritative(), output); + } + + // optional .pulsar.proto.ServerError error = 6; + if (has_error()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 6, this->error(), output); + } + + // optional string message = 7; + if (has_message()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 7, this->message(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandLookupTopicResponse) +} + +int CommandLookupTopicResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string brokerServiceUrl = 1; + if (has_brokerserviceurl()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->brokerserviceurl()); + } + + // optional string brokerServiceUrlTls = 2; + if (has_brokerserviceurltls()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->brokerserviceurltls()); + } + + // optional .pulsar.proto.CommandLookupTopicResponse.LookupType response = 3; + if (has_response()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->response()); + } + + // required uint64 request_id = 4; + if (has_request_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->request_id()); + } + + // optional bool authoritative = 5 [default = false]; + if (has_authoritative()) { + total_size += 1 + 1; + } + + // optional .pulsar.proto.ServerError error = 6; + if (has_error()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->error()); + } + + // optional string message = 7; + if (has_message()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->message()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandLookupTopicResponse::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandLookupTopicResponse::MergeFrom(const CommandLookupTopicResponse& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_brokerserviceurl()) { + set_brokerserviceurl(from.brokerserviceurl()); + } + if (from.has_brokerserviceurltls()) { + set_brokerserviceurltls(from.brokerserviceurltls()); + } + if (from.has_response()) { + set_response(from.response()); + } + if (from.has_request_id()) { + set_request_id(from.request_id()); + } + if (from.has_authoritative()) { + set_authoritative(from.authoritative()); + } + if (from.has_error()) { + set_error(from.error()); + } + if (from.has_message()) { + set_message(from.message()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandLookupTopicResponse::CopyFrom(const CommandLookupTopicResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandLookupTopicResponse::IsInitialized() const { + if ((_has_bits_[0] & 0x00000008) != 0x00000008) return false; + + return true; +} + +void CommandLookupTopicResponse::Swap(CommandLookupTopicResponse* other) { + if (other != this) { + std::swap(brokerserviceurl_, other->brokerserviceurl_); + std::swap(brokerserviceurltls_, other->brokerserviceurltls_); + std::swap(response_, other->response_); + std::swap(request_id_, other->request_id_); + std::swap(authoritative_, other->authoritative_); + std::swap(error_, other->error_); + std::swap(message_, other->message_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandLookupTopicResponse::GetTypeName() const { + return "pulsar.proto.CommandLookupTopicResponse"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CommandProducer::kTopicFieldNumber; +const int CommandProducer::kProducerIdFieldNumber; +const int CommandProducer::kRequestIdFieldNumber; +const int CommandProducer::kProducerNameFieldNumber; +#endif // !_MSC_VER + +CommandProducer::CommandProducer() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandProducer) +} + +void CommandProducer::InitAsDefaultInstance() { +} + +CommandProducer::CommandProducer(const CommandProducer& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandProducer) +} + +void CommandProducer::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + producer_id_ = GOOGLE_ULONGLONG(0); + request_id_ = GOOGLE_ULONGLONG(0); + producer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandProducer::~CommandProducer() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandProducer) + SharedDtor(); +} + +void CommandProducer::SharedDtor() { + if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete topic_; + } + if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete producer_name_; + } + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandProducer::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandProducer& CommandProducer::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandProducer* CommandProducer::default_instance_ = NULL; + +CommandProducer* CommandProducer::New() const { + return new CommandProducer; +} + +void CommandProducer::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 15) { + ZR_(producer_id_, request_id_); + if (has_topic()) { + if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_->clear(); + } + } + if (has_producer_name()) { + if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_->clear(); + } + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandProducer::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandProducer) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string topic = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_topic())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_producer_id; + break; + } + + // required uint64 producer_id = 2; + case 2: { + if (tag == 16) { + parse_producer_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &producer_id_))); + set_has_producer_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_request_id; + break; + } + + // required uint64 request_id = 3; + case 3: { + if (tag == 24) { + parse_request_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &request_id_))); + set_has_request_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(34)) goto parse_producer_name; + break; + } + + // optional string producer_name = 4; + case 4: { + if (tag == 34) { + parse_producer_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_producer_name())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandProducer) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandProducer) + return false; +#undef DO_ +} + +void CommandProducer::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandProducer) + // required string topic = 1; + if (has_topic()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->topic(), output); + } + + // required uint64 producer_id = 2; + if (has_producer_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->producer_id(), output); + } + + // required uint64 request_id = 3; + if (has_request_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->request_id(), output); + } + + // optional string producer_name = 4; + if (has_producer_name()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 4, this->producer_name(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandProducer) +} + +int CommandProducer::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string topic = 1; + if (has_topic()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->topic()); + } + + // required uint64 producer_id = 2; + if (has_producer_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->producer_id()); + } + + // required uint64 request_id = 3; + if (has_request_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->request_id()); + } + + // optional string producer_name = 4; + if (has_producer_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->producer_name()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandProducer::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandProducer::MergeFrom(const CommandProducer& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_topic()) { + set_topic(from.topic()); + } + if (from.has_producer_id()) { + set_producer_id(from.producer_id()); + } + if (from.has_request_id()) { + set_request_id(from.request_id()); + } + if (from.has_producer_name()) { + set_producer_name(from.producer_name()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandProducer::CopyFrom(const CommandProducer& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandProducer::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void CommandProducer::Swap(CommandProducer* other) { + if (other != this) { + std::swap(topic_, other->topic_); + std::swap(producer_id_, other->producer_id_); + std::swap(request_id_, other->request_id_); + std::swap(producer_name_, other->producer_name_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandProducer::GetTypeName() const { + return "pulsar.proto.CommandProducer"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CommandSend::kProducerIdFieldNumber; +const int CommandSend::kSequenceIdFieldNumber; +const int CommandSend::kNumMessagesFieldNumber; +#endif // !_MSC_VER + +CommandSend::CommandSend() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandSend) +} + +void CommandSend::InitAsDefaultInstance() { +} + +CommandSend::CommandSend(const CommandSend& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandSend) +} + +void CommandSend::SharedCtor() { + _cached_size_ = 0; + producer_id_ = GOOGLE_ULONGLONG(0); + sequence_id_ = GOOGLE_ULONGLONG(0); + num_messages_ = 1; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandSend::~CommandSend() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandSend) + SharedDtor(); +} + +void CommandSend::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandSend::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandSend& CommandSend::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandSend* CommandSend::default_instance_ = NULL; + +CommandSend* CommandSend::New() const { + return new CommandSend; +} + +void CommandSend::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 7) { + ZR_(producer_id_, sequence_id_); + num_messages_ = 1; + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandSend::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandSend) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 producer_id = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &producer_id_))); + set_has_producer_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_sequence_id; + break; + } + + // required uint64 sequence_id = 2; + case 2: { + if (tag == 16) { + parse_sequence_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &sequence_id_))); + set_has_sequence_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_num_messages; + break; + } + + // optional int32 num_messages = 3 [default = 1]; + case 3: { + if (tag == 24) { + parse_num_messages: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &num_messages_))); + set_has_num_messages(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandSend) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandSend) + return false; +#undef DO_ +} + +void CommandSend::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandSend) + // required uint64 producer_id = 1; + if (has_producer_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->producer_id(), output); + } + + // required uint64 sequence_id = 2; + if (has_sequence_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->sequence_id(), output); + } + + // optional int32 num_messages = 3 [default = 1]; + if (has_num_messages()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->num_messages(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandSend) +} + +int CommandSend::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint64 producer_id = 1; + if (has_producer_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->producer_id()); + } + + // required uint64 sequence_id = 2; + if (has_sequence_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->sequence_id()); + } + + // optional int32 num_messages = 3 [default = 1]; + if (has_num_messages()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->num_messages()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandSend::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandSend::MergeFrom(const CommandSend& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_producer_id()) { + set_producer_id(from.producer_id()); + } + if (from.has_sequence_id()) { + set_sequence_id(from.sequence_id()); + } + if (from.has_num_messages()) { + set_num_messages(from.num_messages()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandSend::CopyFrom(const CommandSend& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandSend::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void CommandSend::Swap(CommandSend* other) { + if (other != this) { + std::swap(producer_id_, other->producer_id_); + std::swap(sequence_id_, other->sequence_id_); + std::swap(num_messages_, other->num_messages_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandSend::GetTypeName() const { + return "pulsar.proto.CommandSend"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CommandSendReceipt::kProducerIdFieldNumber; +const int CommandSendReceipt::kSequenceIdFieldNumber; +const int CommandSendReceipt::kMessageIdFieldNumber; +#endif // !_MSC_VER + +CommandSendReceipt::CommandSendReceipt() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandSendReceipt) +} + +void CommandSendReceipt::InitAsDefaultInstance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + message_id_ = const_cast< ::pulsar::proto::MessageIdData*>( + ::pulsar::proto::MessageIdData::internal_default_instance()); +#else + message_id_ = const_cast< ::pulsar::proto::MessageIdData*>(&::pulsar::proto::MessageIdData::default_instance()); +#endif +} + +CommandSendReceipt::CommandSendReceipt(const CommandSendReceipt& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandSendReceipt) +} + +void CommandSendReceipt::SharedCtor() { + _cached_size_ = 0; + producer_id_ = GOOGLE_ULONGLONG(0); + sequence_id_ = GOOGLE_ULONGLONG(0); + message_id_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandSendReceipt::~CommandSendReceipt() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandSendReceipt) + SharedDtor(); +} + +void CommandSendReceipt::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + delete message_id_; + } +} + +void CommandSendReceipt::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandSendReceipt& CommandSendReceipt::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandSendReceipt* CommandSendReceipt::default_instance_ = NULL; + +CommandSendReceipt* CommandSendReceipt::New() const { + return new CommandSendReceipt; +} + +void CommandSendReceipt::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 7) { + ZR_(producer_id_, sequence_id_); + if (has_message_id()) { + if (message_id_ != NULL) message_id_->::pulsar::proto::MessageIdData::Clear(); + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandSendReceipt::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandSendReceipt) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 producer_id = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &producer_id_))); + set_has_producer_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_sequence_id; + break; + } + + // required uint64 sequence_id = 2; + case 2: { + if (tag == 16) { + parse_sequence_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &sequence_id_))); + set_has_sequence_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_message_id; + break; + } + + // optional .pulsar.proto.MessageIdData message_id = 3; + case 3: { + if (tag == 26) { + parse_message_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_message_id())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandSendReceipt) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandSendReceipt) + return false; +#undef DO_ +} + +void CommandSendReceipt::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandSendReceipt) + // required uint64 producer_id = 1; + if (has_producer_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->producer_id(), output); + } + + // required uint64 sequence_id = 2; + if (has_sequence_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->sequence_id(), output); + } + + // optional .pulsar.proto.MessageIdData message_id = 3; + if (has_message_id()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 3, this->message_id(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandSendReceipt) +} + +int CommandSendReceipt::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint64 producer_id = 1; + if (has_producer_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->producer_id()); + } + + // required uint64 sequence_id = 2; + if (has_sequence_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->sequence_id()); + } + + // optional .pulsar.proto.MessageIdData message_id = 3; + if (has_message_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->message_id()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandSendReceipt::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandSendReceipt::MergeFrom(const CommandSendReceipt& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_producer_id()) { + set_producer_id(from.producer_id()); + } + if (from.has_sequence_id()) { + set_sequence_id(from.sequence_id()); + } + if (from.has_message_id()) { + mutable_message_id()->::pulsar::proto::MessageIdData::MergeFrom(from.message_id()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandSendReceipt::CopyFrom(const CommandSendReceipt& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandSendReceipt::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (has_message_id()) { + if (!this->message_id().IsInitialized()) return false; + } + return true; +} + +void CommandSendReceipt::Swap(CommandSendReceipt* other) { + if (other != this) { + std::swap(producer_id_, other->producer_id_); + std::swap(sequence_id_, other->sequence_id_); + std::swap(message_id_, other->message_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandSendReceipt::GetTypeName() const { + return "pulsar.proto.CommandSendReceipt"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CommandSendError::kProducerIdFieldNumber; +const int CommandSendError::kSequenceIdFieldNumber; +const int CommandSendError::kErrorFieldNumber; +const int CommandSendError::kMessageFieldNumber; +#endif // !_MSC_VER + +CommandSendError::CommandSendError() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandSendError) +} + +void CommandSendError::InitAsDefaultInstance() { +} + +CommandSendError::CommandSendError(const CommandSendError& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandSendError) +} + +void CommandSendError::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + producer_id_ = GOOGLE_ULONGLONG(0); + sequence_id_ = GOOGLE_ULONGLONG(0); + error_ = 0; + message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandSendError::~CommandSendError() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandSendError) + SharedDtor(); +} + +void CommandSendError::SharedDtor() { + if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete message_; + } + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandSendError::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandSendError& CommandSendError::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandSendError* CommandSendError::default_instance_ = NULL; + +CommandSendError* CommandSendError::New() const { + return new CommandSendError; +} + +void CommandSendError::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 15) { + ZR_(producer_id_, sequence_id_); + error_ = 0; + if (has_message()) { + if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_->clear(); + } + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandSendError::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandSendError) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 producer_id = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &producer_id_))); + set_has_producer_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_sequence_id; + break; + } + + // required uint64 sequence_id = 2; + case 2: { + if (tag == 16) { + parse_sequence_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &sequence_id_))); + set_has_sequence_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_error; + break; + } + + // required .pulsar.proto.ServerError error = 3; + case 3: { + if (tag == 24) { + parse_error: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::pulsar::proto::ServerError_IsValid(value)) { + set_error(static_cast< ::pulsar::proto::ServerError >(value)); + } else { + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(34)) goto parse_message; + break; + } + + // required string message = 4; + case 4: { + if (tag == 34) { + parse_message: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_message())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandSendError) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandSendError) + return false; +#undef DO_ +} + +void CommandSendError::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandSendError) + // required uint64 producer_id = 1; + if (has_producer_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->producer_id(), output); + } + + // required uint64 sequence_id = 2; + if (has_sequence_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->sequence_id(), output); + } + + // required .pulsar.proto.ServerError error = 3; + if (has_error()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 3, this->error(), output); + } + + // required string message = 4; + if (has_message()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 4, this->message(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandSendError) +} + +int CommandSendError::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint64 producer_id = 1; + if (has_producer_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->producer_id()); + } + + // required uint64 sequence_id = 2; + if (has_sequence_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->sequence_id()); + } + + // required .pulsar.proto.ServerError error = 3; + if (has_error()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->error()); + } + + // required string message = 4; + if (has_message()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->message()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandSendError::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandSendError::MergeFrom(const CommandSendError& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_producer_id()) { + set_producer_id(from.producer_id()); + } + if (from.has_sequence_id()) { + set_sequence_id(from.sequence_id()); + } + if (from.has_error()) { + set_error(from.error()); + } + if (from.has_message()) { + set_message(from.message()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandSendError::CopyFrom(const CommandSendError& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandSendError::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + return true; +} + +void CommandSendError::Swap(CommandSendError* other) { + if (other != this) { + std::swap(producer_id_, other->producer_id_); + std::swap(sequence_id_, other->sequence_id_); + std::swap(error_, other->error_); + std::swap(message_, other->message_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandSendError::GetTypeName() const { + return "pulsar.proto.CommandSendError"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CommandMessage::kConsumerIdFieldNumber; +const int CommandMessage::kMessageIdFieldNumber; +#endif // !_MSC_VER + +CommandMessage::CommandMessage() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandMessage) +} + +void CommandMessage::InitAsDefaultInstance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + message_id_ = const_cast< ::pulsar::proto::MessageIdData*>( + ::pulsar::proto::MessageIdData::internal_default_instance()); +#else + message_id_ = const_cast< ::pulsar::proto::MessageIdData*>(&::pulsar::proto::MessageIdData::default_instance()); +#endif +} + +CommandMessage::CommandMessage(const CommandMessage& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandMessage) +} + +void CommandMessage::SharedCtor() { + _cached_size_ = 0; + consumer_id_ = GOOGLE_ULONGLONG(0); + message_id_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandMessage::~CommandMessage() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandMessage) + SharedDtor(); +} + +void CommandMessage::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + delete message_id_; + } +} + +void CommandMessage::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandMessage& CommandMessage::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandMessage* CommandMessage::default_instance_ = NULL; + +CommandMessage* CommandMessage::New() const { + return new CommandMessage; +} + +void CommandMessage::Clear() { + if (_has_bits_[0 / 32] & 3) { + consumer_id_ = GOOGLE_ULONGLONG(0); + if (has_message_id()) { + if (message_id_ != NULL) message_id_->::pulsar::proto::MessageIdData::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandMessage::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandMessage) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 consumer_id = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &consumer_id_))); + set_has_consumer_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_message_id; + break; + } + + // required .pulsar.proto.MessageIdData message_id = 2; + case 2: { + if (tag == 18) { + parse_message_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_message_id())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandMessage) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandMessage) + return false; +#undef DO_ +} + +void CommandMessage::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandMessage) + // required uint64 consumer_id = 1; + if (has_consumer_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->consumer_id(), output); + } + + // required .pulsar.proto.MessageIdData message_id = 2; + if (has_message_id()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 2, this->message_id(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandMessage) +} + +int CommandMessage::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint64 consumer_id = 1; + if (has_consumer_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->consumer_id()); + } + + // required .pulsar.proto.MessageIdData message_id = 2; + if (has_message_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->message_id()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandMessage::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandMessage::MergeFrom(const CommandMessage& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_consumer_id()) { + set_consumer_id(from.consumer_id()); + } + if (from.has_message_id()) { + mutable_message_id()->::pulsar::proto::MessageIdData::MergeFrom(from.message_id()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandMessage::CopyFrom(const CommandMessage& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandMessage::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (has_message_id()) { + if (!this->message_id().IsInitialized()) return false; + } + return true; +} + +void CommandMessage::Swap(CommandMessage* other) { + if (other != this) { + std::swap(consumer_id_, other->consumer_id_); + std::swap(message_id_, other->message_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandMessage::GetTypeName() const { + return "pulsar.proto.CommandMessage"; +} + + +// =================================================================== + +bool CommandAck_AckType_IsValid(int value) { + switch(value) { + case 0: + case 1: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const CommandAck_AckType CommandAck::Individual; +const CommandAck_AckType CommandAck::Cumulative; +const CommandAck_AckType CommandAck::AckType_MIN; +const CommandAck_AckType CommandAck::AckType_MAX; +const int CommandAck::AckType_ARRAYSIZE; +#endif // _MSC_VER +bool CommandAck_ValidationError_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const CommandAck_ValidationError CommandAck::UncompressedSizeCorruption; +const CommandAck_ValidationError CommandAck::DecompressionError; +const CommandAck_ValidationError CommandAck::ChecksumMismatch; +const CommandAck_ValidationError CommandAck::BatchDeSerializeError; +const CommandAck_ValidationError CommandAck::ValidationError_MIN; +const CommandAck_ValidationError CommandAck::ValidationError_MAX; +const int CommandAck::ValidationError_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int CommandAck::kConsumerIdFieldNumber; +const int CommandAck::kAckTypeFieldNumber; +const int CommandAck::kMessageIdFieldNumber; +const int CommandAck::kValidationErrorFieldNumber; +#endif // !_MSC_VER + +CommandAck::CommandAck() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandAck) +} + +void CommandAck::InitAsDefaultInstance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + message_id_ = const_cast< ::pulsar::proto::MessageIdData*>( + ::pulsar::proto::MessageIdData::internal_default_instance()); +#else + message_id_ = const_cast< ::pulsar::proto::MessageIdData*>(&::pulsar::proto::MessageIdData::default_instance()); +#endif +} + +CommandAck::CommandAck(const CommandAck& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandAck) +} + +void CommandAck::SharedCtor() { + _cached_size_ = 0; + consumer_id_ = GOOGLE_ULONGLONG(0); + ack_type_ = 0; + message_id_ = NULL; + validation_error_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandAck::~CommandAck() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandAck) + SharedDtor(); +} + +void CommandAck::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + delete message_id_; + } +} + +void CommandAck::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandAck& CommandAck::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandAck* CommandAck::default_instance_ = NULL; + +CommandAck* CommandAck::New() const { + return new CommandAck; +} + +void CommandAck::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 15) { + ZR_(ack_type_, validation_error_); + consumer_id_ = GOOGLE_ULONGLONG(0); + if (has_message_id()) { + if (message_id_ != NULL) message_id_->::pulsar::proto::MessageIdData::Clear(); + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandAck::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandAck) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 consumer_id = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &consumer_id_))); + set_has_consumer_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_ack_type; + break; + } + + // required .pulsar.proto.CommandAck.AckType ack_type = 2; + case 2: { + if (tag == 16) { + parse_ack_type: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::pulsar::proto::CommandAck_AckType_IsValid(value)) { + set_ack_type(static_cast< ::pulsar::proto::CommandAck_AckType >(value)); + } else { + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_message_id; + break; + } + + // required .pulsar.proto.MessageIdData message_id = 3; + case 3: { + if (tag == 26) { + parse_message_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_message_id())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_validation_error; + break; + } + + // optional .pulsar.proto.CommandAck.ValidationError validation_error = 4; + case 4: { + if (tag == 32) { + parse_validation_error: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::pulsar::proto::CommandAck_ValidationError_IsValid(value)) { + set_validation_error(static_cast< ::pulsar::proto::CommandAck_ValidationError >(value)); + } else { + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); + } + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandAck) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandAck) + return false; +#undef DO_ +} + +void CommandAck::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandAck) + // required uint64 consumer_id = 1; + if (has_consumer_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->consumer_id(), output); + } + + // required .pulsar.proto.CommandAck.AckType ack_type = 2; + if (has_ack_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 2, this->ack_type(), output); + } + + // required .pulsar.proto.MessageIdData message_id = 3; + if (has_message_id()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 3, this->message_id(), output); + } + + // optional .pulsar.proto.CommandAck.ValidationError validation_error = 4; + if (has_validation_error()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 4, this->validation_error(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandAck) +} + +int CommandAck::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint64 consumer_id = 1; + if (has_consumer_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->consumer_id()); + } + + // required .pulsar.proto.CommandAck.AckType ack_type = 2; + if (has_ack_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->ack_type()); + } + + // required .pulsar.proto.MessageIdData message_id = 3; + if (has_message_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->message_id()); + } + + // optional .pulsar.proto.CommandAck.ValidationError validation_error = 4; + if (has_validation_error()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->validation_error()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandAck::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandAck::MergeFrom(const CommandAck& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_consumer_id()) { + set_consumer_id(from.consumer_id()); + } + if (from.has_ack_type()) { + set_ack_type(from.ack_type()); + } + if (from.has_message_id()) { + mutable_message_id()->::pulsar::proto::MessageIdData::MergeFrom(from.message_id()); + } + if (from.has_validation_error()) { + set_validation_error(from.validation_error()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandAck::CopyFrom(const CommandAck& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandAck::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + if (has_message_id()) { + if (!this->message_id().IsInitialized()) return false; + } + return true; +} + +void CommandAck::Swap(CommandAck* other) { + if (other != this) { + std::swap(consumer_id_, other->consumer_id_); + std::swap(ack_type_, other->ack_type_); + std::swap(message_id_, other->message_id_); + std::swap(validation_error_, other->validation_error_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandAck::GetTypeName() const { + return "pulsar.proto.CommandAck"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CommandFlow::kConsumerIdFieldNumber; +const int CommandFlow::kMessagePermitsFieldNumber; +#endif // !_MSC_VER + +CommandFlow::CommandFlow() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandFlow) +} + +void CommandFlow::InitAsDefaultInstance() { +} + +CommandFlow::CommandFlow(const CommandFlow& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandFlow) +} + +void CommandFlow::SharedCtor() { + _cached_size_ = 0; + consumer_id_ = GOOGLE_ULONGLONG(0); + messagepermits_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandFlow::~CommandFlow() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandFlow) + SharedDtor(); +} + +void CommandFlow::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandFlow::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandFlow& CommandFlow::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandFlow* CommandFlow::default_instance_ = NULL; + +CommandFlow* CommandFlow::New() const { + return new CommandFlow; +} + +void CommandFlow::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(consumer_id_, messagepermits_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandFlow::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandFlow) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 consumer_id = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &consumer_id_))); + set_has_consumer_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_messagePermits; + break; + } + + // required uint32 messagePermits = 2; + case 2: { + if (tag == 16) { + parse_messagePermits: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &messagepermits_))); + set_has_messagepermits(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandFlow) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandFlow) + return false; +#undef DO_ +} + +void CommandFlow::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandFlow) + // required uint64 consumer_id = 1; + if (has_consumer_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->consumer_id(), output); + } + + // required uint32 messagePermits = 2; + if (has_messagepermits()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->messagepermits(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandFlow) +} + +int CommandFlow::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint64 consumer_id = 1; + if (has_consumer_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->consumer_id()); + } + + // required uint32 messagePermits = 2; + if (has_messagepermits()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->messagepermits()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandFlow::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandFlow::MergeFrom(const CommandFlow& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_consumer_id()) { + set_consumer_id(from.consumer_id()); + } + if (from.has_messagepermits()) { + set_messagepermits(from.messagepermits()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandFlow::CopyFrom(const CommandFlow& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandFlow::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void CommandFlow::Swap(CommandFlow* other) { + if (other != this) { + std::swap(consumer_id_, other->consumer_id_); + std::swap(messagepermits_, other->messagepermits_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandFlow::GetTypeName() const { + return "pulsar.proto.CommandFlow"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CommandUnsubscribe::kConsumerIdFieldNumber; +const int CommandUnsubscribe::kRequestIdFieldNumber; +#endif // !_MSC_VER + +CommandUnsubscribe::CommandUnsubscribe() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandUnsubscribe) +} + +void CommandUnsubscribe::InitAsDefaultInstance() { +} + +CommandUnsubscribe::CommandUnsubscribe(const CommandUnsubscribe& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandUnsubscribe) +} + +void CommandUnsubscribe::SharedCtor() { + _cached_size_ = 0; + consumer_id_ = GOOGLE_ULONGLONG(0); + request_id_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandUnsubscribe::~CommandUnsubscribe() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandUnsubscribe) + SharedDtor(); +} + +void CommandUnsubscribe::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandUnsubscribe::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandUnsubscribe& CommandUnsubscribe::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandUnsubscribe* CommandUnsubscribe::default_instance_ = NULL; + +CommandUnsubscribe* CommandUnsubscribe::New() const { + return new CommandUnsubscribe; +} + +void CommandUnsubscribe::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(consumer_id_, request_id_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandUnsubscribe::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandUnsubscribe) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 consumer_id = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &consumer_id_))); + set_has_consumer_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_request_id; + break; + } + + // required uint64 request_id = 2; + case 2: { + if (tag == 16) { + parse_request_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &request_id_))); + set_has_request_id(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandUnsubscribe) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandUnsubscribe) + return false; +#undef DO_ +} + +void CommandUnsubscribe::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandUnsubscribe) + // required uint64 consumer_id = 1; + if (has_consumer_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->consumer_id(), output); + } + + // required uint64 request_id = 2; + if (has_request_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->request_id(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandUnsubscribe) +} + +int CommandUnsubscribe::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint64 consumer_id = 1; + if (has_consumer_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->consumer_id()); + } + + // required uint64 request_id = 2; + if (has_request_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->request_id()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandUnsubscribe::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandUnsubscribe::MergeFrom(const CommandUnsubscribe& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_consumer_id()) { + set_consumer_id(from.consumer_id()); + } + if (from.has_request_id()) { + set_request_id(from.request_id()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandUnsubscribe::CopyFrom(const CommandUnsubscribe& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandUnsubscribe::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void CommandUnsubscribe::Swap(CommandUnsubscribe* other) { + if (other != this) { + std::swap(consumer_id_, other->consumer_id_); + std::swap(request_id_, other->request_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandUnsubscribe::GetTypeName() const { + return "pulsar.proto.CommandUnsubscribe"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CommandCloseProducer::kProducerIdFieldNumber; +const int CommandCloseProducer::kRequestIdFieldNumber; +#endif // !_MSC_VER + +CommandCloseProducer::CommandCloseProducer() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandCloseProducer) +} + +void CommandCloseProducer::InitAsDefaultInstance() { +} + +CommandCloseProducer::CommandCloseProducer(const CommandCloseProducer& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandCloseProducer) +} + +void CommandCloseProducer::SharedCtor() { + _cached_size_ = 0; + producer_id_ = GOOGLE_ULONGLONG(0); + request_id_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandCloseProducer::~CommandCloseProducer() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandCloseProducer) + SharedDtor(); +} + +void CommandCloseProducer::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandCloseProducer::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandCloseProducer& CommandCloseProducer::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandCloseProducer* CommandCloseProducer::default_instance_ = NULL; + +CommandCloseProducer* CommandCloseProducer::New() const { + return new CommandCloseProducer; +} + +void CommandCloseProducer::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(producer_id_, request_id_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandCloseProducer::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandCloseProducer) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 producer_id = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &producer_id_))); + set_has_producer_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_request_id; + break; + } + + // required uint64 request_id = 2; + case 2: { + if (tag == 16) { + parse_request_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &request_id_))); + set_has_request_id(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandCloseProducer) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandCloseProducer) + return false; +#undef DO_ +} + +void CommandCloseProducer::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandCloseProducer) + // required uint64 producer_id = 1; + if (has_producer_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->producer_id(), output); + } + + // required uint64 request_id = 2; + if (has_request_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->request_id(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandCloseProducer) +} + +int CommandCloseProducer::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint64 producer_id = 1; + if (has_producer_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->producer_id()); + } + + // required uint64 request_id = 2; + if (has_request_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->request_id()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandCloseProducer::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandCloseProducer::MergeFrom(const CommandCloseProducer& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_producer_id()) { + set_producer_id(from.producer_id()); + } + if (from.has_request_id()) { + set_request_id(from.request_id()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandCloseProducer::CopyFrom(const CommandCloseProducer& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandCloseProducer::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void CommandCloseProducer::Swap(CommandCloseProducer* other) { + if (other != this) { + std::swap(producer_id_, other->producer_id_); + std::swap(request_id_, other->request_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandCloseProducer::GetTypeName() const { + return "pulsar.proto.CommandCloseProducer"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CommandCloseConsumer::kConsumerIdFieldNumber; +const int CommandCloseConsumer::kRequestIdFieldNumber; +#endif // !_MSC_VER + +CommandCloseConsumer::CommandCloseConsumer() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandCloseConsumer) +} + +void CommandCloseConsumer::InitAsDefaultInstance() { +} + +CommandCloseConsumer::CommandCloseConsumer(const CommandCloseConsumer& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandCloseConsumer) +} + +void CommandCloseConsumer::SharedCtor() { + _cached_size_ = 0; + consumer_id_ = GOOGLE_ULONGLONG(0); + request_id_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandCloseConsumer::~CommandCloseConsumer() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandCloseConsumer) + SharedDtor(); +} + +void CommandCloseConsumer::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandCloseConsumer::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandCloseConsumer& CommandCloseConsumer::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandCloseConsumer* CommandCloseConsumer::default_instance_ = NULL; + +CommandCloseConsumer* CommandCloseConsumer::New() const { + return new CommandCloseConsumer; +} + +void CommandCloseConsumer::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(consumer_id_, request_id_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandCloseConsumer::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandCloseConsumer) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 consumer_id = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &consumer_id_))); + set_has_consumer_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_request_id; + break; + } + + // required uint64 request_id = 2; + case 2: { + if (tag == 16) { + parse_request_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &request_id_))); + set_has_request_id(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandCloseConsumer) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandCloseConsumer) + return false; +#undef DO_ +} + +void CommandCloseConsumer::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandCloseConsumer) + // required uint64 consumer_id = 1; + if (has_consumer_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->consumer_id(), output); + } + + // required uint64 request_id = 2; + if (has_request_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->request_id(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandCloseConsumer) +} + +int CommandCloseConsumer::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint64 consumer_id = 1; + if (has_consumer_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->consumer_id()); + } + + // required uint64 request_id = 2; + if (has_request_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->request_id()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandCloseConsumer::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandCloseConsumer::MergeFrom(const CommandCloseConsumer& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_consumer_id()) { + set_consumer_id(from.consumer_id()); + } + if (from.has_request_id()) { + set_request_id(from.request_id()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandCloseConsumer::CopyFrom(const CommandCloseConsumer& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandCloseConsumer::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void CommandCloseConsumer::Swap(CommandCloseConsumer* other) { + if (other != this) { + std::swap(consumer_id_, other->consumer_id_); + std::swap(request_id_, other->request_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandCloseConsumer::GetTypeName() const { + return "pulsar.proto.CommandCloseConsumer"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CommandRedeliverUnacknowledgedMessages::kConsumerIdFieldNumber; +const int CommandRedeliverUnacknowledgedMessages::kMessageIdsFieldNumber; +#endif // !_MSC_VER + +CommandRedeliverUnacknowledgedMessages::CommandRedeliverUnacknowledgedMessages() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandRedeliverUnacknowledgedMessages) +} + +void CommandRedeliverUnacknowledgedMessages::InitAsDefaultInstance() { +} + +CommandRedeliverUnacknowledgedMessages::CommandRedeliverUnacknowledgedMessages(const CommandRedeliverUnacknowledgedMessages& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandRedeliverUnacknowledgedMessages) +} + +void CommandRedeliverUnacknowledgedMessages::SharedCtor() { + _cached_size_ = 0; + consumer_id_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandRedeliverUnacknowledgedMessages::~CommandRedeliverUnacknowledgedMessages() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandRedeliverUnacknowledgedMessages) + SharedDtor(); +} + +void CommandRedeliverUnacknowledgedMessages::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandRedeliverUnacknowledgedMessages::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandRedeliverUnacknowledgedMessages& CommandRedeliverUnacknowledgedMessages::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandRedeliverUnacknowledgedMessages* CommandRedeliverUnacknowledgedMessages::default_instance_ = NULL; + +CommandRedeliverUnacknowledgedMessages* CommandRedeliverUnacknowledgedMessages::New() const { + return new CommandRedeliverUnacknowledgedMessages; +} + +void CommandRedeliverUnacknowledgedMessages::Clear() { + consumer_id_ = GOOGLE_ULONGLONG(0); + message_ids_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandRedeliverUnacknowledgedMessages::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandRedeliverUnacknowledgedMessages) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 consumer_id = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &consumer_id_))); + set_has_consumer_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_message_ids; + break; + } + + // repeated .pulsar.proto.MessageIdData message_ids = 2; + case 2: { + if (tag == 18) { + parse_message_ids: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_message_ids())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_message_ids; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandRedeliverUnacknowledgedMessages) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandRedeliverUnacknowledgedMessages) + return false; +#undef DO_ +} + +void CommandRedeliverUnacknowledgedMessages::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandRedeliverUnacknowledgedMessages) + // required uint64 consumer_id = 1; + if (has_consumer_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->consumer_id(), output); + } + + // repeated .pulsar.proto.MessageIdData message_ids = 2; + for (int i = 0; i < this->message_ids_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 2, this->message_ids(i), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandRedeliverUnacknowledgedMessages) +} + +int CommandRedeliverUnacknowledgedMessages::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint64 consumer_id = 1; + if (has_consumer_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->consumer_id()); + } + + } + // repeated .pulsar.proto.MessageIdData message_ids = 2; + total_size += 1 * this->message_ids_size(); + for (int i = 0; i < this->message_ids_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->message_ids(i)); + } + + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandRedeliverUnacknowledgedMessages::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandRedeliverUnacknowledgedMessages::MergeFrom(const CommandRedeliverUnacknowledgedMessages& from) { + GOOGLE_CHECK_NE(&from, this); + message_ids_.MergeFrom(from.message_ids_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_consumer_id()) { + set_consumer_id(from.consumer_id()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandRedeliverUnacknowledgedMessages::CopyFrom(const CommandRedeliverUnacknowledgedMessages& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandRedeliverUnacknowledgedMessages::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (!::google::protobuf::internal::AllAreInitialized(this->message_ids())) return false; + return true; +} + +void CommandRedeliverUnacknowledgedMessages::Swap(CommandRedeliverUnacknowledgedMessages* other) { + if (other != this) { + std::swap(consumer_id_, other->consumer_id_); + message_ids_.Swap(&other->message_ids_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandRedeliverUnacknowledgedMessages::GetTypeName() const { + return "pulsar.proto.CommandRedeliverUnacknowledgedMessages"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CommandSuccess::kRequestIdFieldNumber; +#endif // !_MSC_VER + +CommandSuccess::CommandSuccess() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandSuccess) +} + +void CommandSuccess::InitAsDefaultInstance() { +} + +CommandSuccess::CommandSuccess(const CommandSuccess& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandSuccess) +} + +void CommandSuccess::SharedCtor() { + _cached_size_ = 0; + request_id_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandSuccess::~CommandSuccess() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandSuccess) + SharedDtor(); +} + +void CommandSuccess::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandSuccess::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandSuccess& CommandSuccess::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandSuccess* CommandSuccess::default_instance_ = NULL; + +CommandSuccess* CommandSuccess::New() const { + return new CommandSuccess; +} + +void CommandSuccess::Clear() { + request_id_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandSuccess::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandSuccess) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 request_id = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &request_id_))); + set_has_request_id(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandSuccess) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandSuccess) + return false; +#undef DO_ +} + +void CommandSuccess::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandSuccess) + // required uint64 request_id = 1; + if (has_request_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->request_id(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandSuccess) +} + +int CommandSuccess::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint64 request_id = 1; + if (has_request_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->request_id()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandSuccess::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandSuccess::MergeFrom(const CommandSuccess& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_request_id()) { + set_request_id(from.request_id()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandSuccess::CopyFrom(const CommandSuccess& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandSuccess::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void CommandSuccess::Swap(CommandSuccess* other) { + if (other != this) { + std::swap(request_id_, other->request_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandSuccess::GetTypeName() const { + return "pulsar.proto.CommandSuccess"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CommandProducerSuccess::kRequestIdFieldNumber; +const int CommandProducerSuccess::kProducerNameFieldNumber; +#endif // !_MSC_VER + +CommandProducerSuccess::CommandProducerSuccess() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandProducerSuccess) +} + +void CommandProducerSuccess::InitAsDefaultInstance() { +} + +CommandProducerSuccess::CommandProducerSuccess(const CommandProducerSuccess& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandProducerSuccess) +} + +void CommandProducerSuccess::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + request_id_ = GOOGLE_ULONGLONG(0); + producer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandProducerSuccess::~CommandProducerSuccess() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandProducerSuccess) + SharedDtor(); +} + +void CommandProducerSuccess::SharedDtor() { + if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete producer_name_; + } + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandProducerSuccess::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandProducerSuccess& CommandProducerSuccess::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandProducerSuccess* CommandProducerSuccess::default_instance_ = NULL; + +CommandProducerSuccess* CommandProducerSuccess::New() const { + return new CommandProducerSuccess; +} + +void CommandProducerSuccess::Clear() { + if (_has_bits_[0 / 32] & 3) { + request_id_ = GOOGLE_ULONGLONG(0); + if (has_producer_name()) { + if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandProducerSuccess::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandProducerSuccess) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 request_id = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &request_id_))); + set_has_request_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_producer_name; + break; + } + + // required string producer_name = 2; + case 2: { + if (tag == 18) { + parse_producer_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_producer_name())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandProducerSuccess) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandProducerSuccess) + return false; +#undef DO_ +} + +void CommandProducerSuccess::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandProducerSuccess) + // required uint64 request_id = 1; + if (has_request_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->request_id(), output); + } + + // required string producer_name = 2; + if (has_producer_name()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 2, this->producer_name(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandProducerSuccess) +} + +int CommandProducerSuccess::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint64 request_id = 1; + if (has_request_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->request_id()); + } + + // required string producer_name = 2; + if (has_producer_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->producer_name()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandProducerSuccess::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandProducerSuccess::MergeFrom(const CommandProducerSuccess& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_request_id()) { + set_request_id(from.request_id()); + } + if (from.has_producer_name()) { + set_producer_name(from.producer_name()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandProducerSuccess::CopyFrom(const CommandProducerSuccess& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandProducerSuccess::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void CommandProducerSuccess::Swap(CommandProducerSuccess* other) { + if (other != this) { + std::swap(request_id_, other->request_id_); + std::swap(producer_name_, other->producer_name_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandProducerSuccess::GetTypeName() const { + return "pulsar.proto.CommandProducerSuccess"; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int CommandError::kRequestIdFieldNumber; +const int CommandError::kErrorFieldNumber; +const int CommandError::kMessageFieldNumber; +#endif // !_MSC_VER + +CommandError::CommandError() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandError) +} + +void CommandError::InitAsDefaultInstance() { +} + +CommandError::CommandError(const CommandError& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandError) +} + +void CommandError::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + request_id_ = GOOGLE_ULONGLONG(0); + error_ = 0; + message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandError::~CommandError() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandError) + SharedDtor(); +} + +void CommandError::SharedDtor() { + if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete message_; + } + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandError::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandError& CommandError::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandError* CommandError::default_instance_ = NULL; + +CommandError* CommandError::New() const { + return new CommandError; +} + +void CommandError::Clear() { + if (_has_bits_[0 / 32] & 7) { + request_id_ = GOOGLE_ULONGLONG(0); + error_ = 0; + if (has_message()) { + if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandError::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandError) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 request_id = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &request_id_))); + set_has_request_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_error; + break; + } + + // required .pulsar.proto.ServerError error = 2; + case 2: { + if (tag == 16) { + parse_error: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::pulsar::proto::ServerError_IsValid(value)) { + set_error(static_cast< ::pulsar::proto::ServerError >(value)); + } else { + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_message; + break; + } + + // required string message = 3; + case 3: { + if (tag == 26) { + parse_message: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_message())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandError) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandError) + return false; +#undef DO_ +} + +void CommandError::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandError) + // required uint64 request_id = 1; + if (has_request_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->request_id(), output); + } + + // required .pulsar.proto.ServerError error = 2; + if (has_error()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 2, this->error(), output); + } + + // required string message = 3; + if (has_message()) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 3, this->message(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandError) +} + +int CommandError::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint64 request_id = 1; + if (has_request_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->request_id()); + } + + // required .pulsar.proto.ServerError error = 2; + if (has_error()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->error()); + } + + // required string message = 3; + if (has_message()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->message()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandError::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandError::MergeFrom(const CommandError& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_request_id()) { + set_request_id(from.request_id()); + } + if (from.has_error()) { + set_error(from.error()); + } + if (from.has_message()) { + set_message(from.message()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandError::CopyFrom(const CommandError& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandError::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void CommandError::Swap(CommandError* other) { + if (other != this) { + std::swap(request_id_, other->request_id_); + std::swap(error_, other->error_); + std::swap(message_, other->message_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandError::GetTypeName() const { + return "pulsar.proto.CommandError"; +} + + +// =================================================================== + +#ifndef _MSC_VER +#endif // !_MSC_VER + +CommandPing::CommandPing() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandPing) +} + +void CommandPing::InitAsDefaultInstance() { +} + +CommandPing::CommandPing(const CommandPing& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandPing) +} + +void CommandPing::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandPing::~CommandPing() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandPing) + SharedDtor(); +} + +void CommandPing::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandPing::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandPing& CommandPing::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandPing* CommandPing::default_instance_ = NULL; + +CommandPing* CommandPing::New() const { + return new CommandPing; +} + +void CommandPing::Clear() { + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandPing::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandPing) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandPing) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandPing) + return false; +#undef DO_ +} + +void CommandPing::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandPing) + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandPing) +} + +int CommandPing::ByteSize() const { + int total_size = 0; + + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandPing::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandPing::MergeFrom(const CommandPing& from) { + GOOGLE_CHECK_NE(&from, this); + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandPing::CopyFrom(const CommandPing& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandPing::IsInitialized() const { + + return true; +} + +void CommandPing::Swap(CommandPing* other) { + if (other != this) { + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandPing::GetTypeName() const { + return "pulsar.proto.CommandPing"; +} + + +// =================================================================== + +#ifndef _MSC_VER +#endif // !_MSC_VER + +CommandPong::CommandPong() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.CommandPong) +} + +void CommandPong::InitAsDefaultInstance() { +} + +CommandPong::CommandPong(const CommandPong& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.CommandPong) +} + +void CommandPong::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CommandPong::~CommandPong() { + // @@protoc_insertion_point(destructor:pulsar.proto.CommandPong) + SharedDtor(); +} + +void CommandPong::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void CommandPong::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const CommandPong& CommandPong::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +CommandPong* CommandPong::default_instance_ = NULL; + +CommandPong* CommandPong::New() const { + return new CommandPong; +} + +void CommandPong::Clear() { + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool CommandPong::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.CommandPong) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.CommandPong) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.CommandPong) + return false; +#undef DO_ +} + +void CommandPong::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.CommandPong) + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.CommandPong) +} + +int CommandPong::ByteSize() const { + int total_size = 0; + + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CommandPong::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void CommandPong::MergeFrom(const CommandPong& from) { + GOOGLE_CHECK_NE(&from, this); + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void CommandPong::CopyFrom(const CommandPong& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CommandPong::IsInitialized() const { + + return true; +} + +void CommandPong::Swap(CommandPong* other) { + if (other != this) { + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string CommandPong::GetTypeName() const { + return "pulsar.proto.CommandPong"; +} + + +// =================================================================== + +bool BaseCommand_Type_IsValid(int value) { + switch(value) { + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 23: + case 24: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const BaseCommand_Type BaseCommand::CONNECT; +const BaseCommand_Type BaseCommand::CONNECTED; +const BaseCommand_Type BaseCommand::SUBSCRIBE; +const BaseCommand_Type BaseCommand::PRODUCER; +const BaseCommand_Type BaseCommand::SEND; +const BaseCommand_Type BaseCommand::SEND_RECEIPT; +const BaseCommand_Type BaseCommand::SEND_ERROR; +const BaseCommand_Type BaseCommand::MESSAGE; +const BaseCommand_Type BaseCommand::ACK; +const BaseCommand_Type BaseCommand::FLOW; +const BaseCommand_Type BaseCommand::UNSUBSCRIBE; +const BaseCommand_Type BaseCommand::SUCCESS; +const BaseCommand_Type BaseCommand::ERROR; +const BaseCommand_Type BaseCommand::CLOSE_PRODUCER; +const BaseCommand_Type BaseCommand::CLOSE_CONSUMER; +const BaseCommand_Type BaseCommand::PRODUCER_SUCCESS; +const BaseCommand_Type BaseCommand::PING; +const BaseCommand_Type BaseCommand::PONG; +const BaseCommand_Type BaseCommand::REDELIVER_UNACKNOWLEDGED_MESSAGES; +const BaseCommand_Type BaseCommand::PARTITIONED_METADATA; +const BaseCommand_Type BaseCommand::PARTITIONED_METADATA_RESPONSE; +const BaseCommand_Type BaseCommand::LOOKUP; +const BaseCommand_Type BaseCommand::LOOKUP_RESPONSE; +const BaseCommand_Type BaseCommand::Type_MIN; +const BaseCommand_Type BaseCommand::Type_MAX; +const int BaseCommand::Type_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int BaseCommand::kTypeFieldNumber; +const int BaseCommand::kConnectFieldNumber; +const int BaseCommand::kConnectedFieldNumber; +const int BaseCommand::kSubscribeFieldNumber; +const int BaseCommand::kProducerFieldNumber; +const int BaseCommand::kSendFieldNumber; +const int BaseCommand::kSendReceiptFieldNumber; +const int BaseCommand::kSendErrorFieldNumber; +const int BaseCommand::kMessageFieldNumber; +const int BaseCommand::kAckFieldNumber; +const int BaseCommand::kFlowFieldNumber; +const int BaseCommand::kUnsubscribeFieldNumber; +const int BaseCommand::kSuccessFieldNumber; +const int BaseCommand::kErrorFieldNumber; +const int BaseCommand::kCloseProducerFieldNumber; +const int BaseCommand::kCloseConsumerFieldNumber; +const int BaseCommand::kProducerSuccessFieldNumber; +const int BaseCommand::kPingFieldNumber; +const int BaseCommand::kPongFieldNumber; +const int BaseCommand::kRedeliverUnacknowledgedMessagesFieldNumber; +const int BaseCommand::kPartitionMetadataFieldNumber; +const int BaseCommand::kPartitionMetadataResponseFieldNumber; +const int BaseCommand::kLookupTopicFieldNumber; +const int BaseCommand::kLookupTopicResponseFieldNumber; +#endif // !_MSC_VER + +BaseCommand::BaseCommand() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:pulsar.proto.BaseCommand) +} + +void BaseCommand::InitAsDefaultInstance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + connect_ = const_cast< ::pulsar::proto::CommandConnect*>( + ::pulsar::proto::CommandConnect::internal_default_instance()); +#else + connect_ = const_cast< ::pulsar::proto::CommandConnect*>(&::pulsar::proto::CommandConnect::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + connected_ = const_cast< ::pulsar::proto::CommandConnected*>( + ::pulsar::proto::CommandConnected::internal_default_instance()); +#else + connected_ = const_cast< ::pulsar::proto::CommandConnected*>(&::pulsar::proto::CommandConnected::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + subscribe_ = const_cast< ::pulsar::proto::CommandSubscribe*>( + ::pulsar::proto::CommandSubscribe::internal_default_instance()); +#else + subscribe_ = const_cast< ::pulsar::proto::CommandSubscribe*>(&::pulsar::proto::CommandSubscribe::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + producer_ = const_cast< ::pulsar::proto::CommandProducer*>( + ::pulsar::proto::CommandProducer::internal_default_instance()); +#else + producer_ = const_cast< ::pulsar::proto::CommandProducer*>(&::pulsar::proto::CommandProducer::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + send_ = const_cast< ::pulsar::proto::CommandSend*>( + ::pulsar::proto::CommandSend::internal_default_instance()); +#else + send_ = const_cast< ::pulsar::proto::CommandSend*>(&::pulsar::proto::CommandSend::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + send_receipt_ = const_cast< ::pulsar::proto::CommandSendReceipt*>( + ::pulsar::proto::CommandSendReceipt::internal_default_instance()); +#else + send_receipt_ = const_cast< ::pulsar::proto::CommandSendReceipt*>(&::pulsar::proto::CommandSendReceipt::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + send_error_ = const_cast< ::pulsar::proto::CommandSendError*>( + ::pulsar::proto::CommandSendError::internal_default_instance()); +#else + send_error_ = const_cast< ::pulsar::proto::CommandSendError*>(&::pulsar::proto::CommandSendError::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + message_ = const_cast< ::pulsar::proto::CommandMessage*>( + ::pulsar::proto::CommandMessage::internal_default_instance()); +#else + message_ = const_cast< ::pulsar::proto::CommandMessage*>(&::pulsar::proto::CommandMessage::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + ack_ = const_cast< ::pulsar::proto::CommandAck*>( + ::pulsar::proto::CommandAck::internal_default_instance()); +#else + ack_ = const_cast< ::pulsar::proto::CommandAck*>(&::pulsar::proto::CommandAck::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + flow_ = const_cast< ::pulsar::proto::CommandFlow*>( + ::pulsar::proto::CommandFlow::internal_default_instance()); +#else + flow_ = const_cast< ::pulsar::proto::CommandFlow*>(&::pulsar::proto::CommandFlow::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + unsubscribe_ = const_cast< ::pulsar::proto::CommandUnsubscribe*>( + ::pulsar::proto::CommandUnsubscribe::internal_default_instance()); +#else + unsubscribe_ = const_cast< ::pulsar::proto::CommandUnsubscribe*>(&::pulsar::proto::CommandUnsubscribe::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + success_ = const_cast< ::pulsar::proto::CommandSuccess*>( + ::pulsar::proto::CommandSuccess::internal_default_instance()); +#else + success_ = const_cast< ::pulsar::proto::CommandSuccess*>(&::pulsar::proto::CommandSuccess::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + error_ = const_cast< ::pulsar::proto::CommandError*>( + ::pulsar::proto::CommandError::internal_default_instance()); +#else + error_ = const_cast< ::pulsar::proto::CommandError*>(&::pulsar::proto::CommandError::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + close_producer_ = const_cast< ::pulsar::proto::CommandCloseProducer*>( + ::pulsar::proto::CommandCloseProducer::internal_default_instance()); +#else + close_producer_ = const_cast< ::pulsar::proto::CommandCloseProducer*>(&::pulsar::proto::CommandCloseProducer::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + close_consumer_ = const_cast< ::pulsar::proto::CommandCloseConsumer*>( + ::pulsar::proto::CommandCloseConsumer::internal_default_instance()); +#else + close_consumer_ = const_cast< ::pulsar::proto::CommandCloseConsumer*>(&::pulsar::proto::CommandCloseConsumer::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + producer_success_ = const_cast< ::pulsar::proto::CommandProducerSuccess*>( + ::pulsar::proto::CommandProducerSuccess::internal_default_instance()); +#else + producer_success_ = const_cast< ::pulsar::proto::CommandProducerSuccess*>(&::pulsar::proto::CommandProducerSuccess::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + ping_ = const_cast< ::pulsar::proto::CommandPing*>( + ::pulsar::proto::CommandPing::internal_default_instance()); +#else + ping_ = const_cast< ::pulsar::proto::CommandPing*>(&::pulsar::proto::CommandPing::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + pong_ = const_cast< ::pulsar::proto::CommandPong*>( + ::pulsar::proto::CommandPong::internal_default_instance()); +#else + pong_ = const_cast< ::pulsar::proto::CommandPong*>(&::pulsar::proto::CommandPong::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + redeliverunacknowledgedmessages_ = const_cast< ::pulsar::proto::CommandRedeliverUnacknowledgedMessages*>( + ::pulsar::proto::CommandRedeliverUnacknowledgedMessages::internal_default_instance()); +#else + redeliverunacknowledgedmessages_ = const_cast< ::pulsar::proto::CommandRedeliverUnacknowledgedMessages*>(&::pulsar::proto::CommandRedeliverUnacknowledgedMessages::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + partitionmetadata_ = const_cast< ::pulsar::proto::CommandPartitionedTopicMetadata*>( + ::pulsar::proto::CommandPartitionedTopicMetadata::internal_default_instance()); +#else + partitionmetadata_ = const_cast< ::pulsar::proto::CommandPartitionedTopicMetadata*>(&::pulsar::proto::CommandPartitionedTopicMetadata::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + partitionmetadataresponse_ = const_cast< ::pulsar::proto::CommandPartitionedTopicMetadataResponse*>( + ::pulsar::proto::CommandPartitionedTopicMetadataResponse::internal_default_instance()); +#else + partitionmetadataresponse_ = const_cast< ::pulsar::proto::CommandPartitionedTopicMetadataResponse*>(&::pulsar::proto::CommandPartitionedTopicMetadataResponse::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + lookuptopic_ = const_cast< ::pulsar::proto::CommandLookupTopic*>( + ::pulsar::proto::CommandLookupTopic::internal_default_instance()); +#else + lookuptopic_ = const_cast< ::pulsar::proto::CommandLookupTopic*>(&::pulsar::proto::CommandLookupTopic::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + lookuptopicresponse_ = const_cast< ::pulsar::proto::CommandLookupTopicResponse*>( + ::pulsar::proto::CommandLookupTopicResponse::internal_default_instance()); +#else + lookuptopicresponse_ = const_cast< ::pulsar::proto::CommandLookupTopicResponse*>(&::pulsar::proto::CommandLookupTopicResponse::default_instance()); +#endif +} + +BaseCommand::BaseCommand(const BaseCommand& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:pulsar.proto.BaseCommand) +} + +void BaseCommand::SharedCtor() { + _cached_size_ = 0; + type_ = 2; + connect_ = NULL; + connected_ = NULL; + subscribe_ = NULL; + producer_ = NULL; + send_ = NULL; + send_receipt_ = NULL; + send_error_ = NULL; + message_ = NULL; + ack_ = NULL; + flow_ = NULL; + unsubscribe_ = NULL; + success_ = NULL; + error_ = NULL; + close_producer_ = NULL; + close_consumer_ = NULL; + producer_success_ = NULL; + ping_ = NULL; + pong_ = NULL; + redeliverunacknowledgedmessages_ = NULL; + partitionmetadata_ = NULL; + partitionmetadataresponse_ = NULL; + lookuptopic_ = NULL; + lookuptopicresponse_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +BaseCommand::~BaseCommand() { + // @@protoc_insertion_point(destructor:pulsar.proto.BaseCommand) + SharedDtor(); +} + +void BaseCommand::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + delete connect_; + delete connected_; + delete subscribe_; + delete producer_; + delete send_; + delete send_receipt_; + delete send_error_; + delete message_; + delete ack_; + delete flow_; + delete unsubscribe_; + delete success_; + delete error_; + delete close_producer_; + delete close_consumer_; + delete producer_success_; + delete ping_; + delete pong_; + delete redeliverunacknowledgedmessages_; + delete partitionmetadata_; + delete partitionmetadataresponse_; + delete lookuptopic_; + delete lookuptopicresponse_; + } +} + +void BaseCommand::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const BaseCommand& BaseCommand::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_PulsarApi_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_PulsarApi_2eproto(); +#endif + return *default_instance_; +} + +BaseCommand* BaseCommand::default_instance_ = NULL; + +BaseCommand* BaseCommand::New() const { + return new BaseCommand; +} + +void BaseCommand::Clear() { + if (_has_bits_[0 / 32] & 255) { + type_ = 2; + if (has_connect()) { + if (connect_ != NULL) connect_->::pulsar::proto::CommandConnect::Clear(); + } + if (has_connected()) { + if (connected_ != NULL) connected_->::pulsar::proto::CommandConnected::Clear(); + } + if (has_subscribe()) { + if (subscribe_ != NULL) subscribe_->::pulsar::proto::CommandSubscribe::Clear(); + } + if (has_producer()) { + if (producer_ != NULL) producer_->::pulsar::proto::CommandProducer::Clear(); + } + if (has_send()) { + if (send_ != NULL) send_->::pulsar::proto::CommandSend::Clear(); + } + if (has_send_receipt()) { + if (send_receipt_ != NULL) send_receipt_->::pulsar::proto::CommandSendReceipt::Clear(); + } + if (has_send_error()) { + if (send_error_ != NULL) send_error_->::pulsar::proto::CommandSendError::Clear(); + } + } + if (_has_bits_[8 / 32] & 65280) { + if (has_message()) { + if (message_ != NULL) message_->::pulsar::proto::CommandMessage::Clear(); + } + if (has_ack()) { + if (ack_ != NULL) ack_->::pulsar::proto::CommandAck::Clear(); + } + if (has_flow()) { + if (flow_ != NULL) flow_->::pulsar::proto::CommandFlow::Clear(); + } + if (has_unsubscribe()) { + if (unsubscribe_ != NULL) unsubscribe_->::pulsar::proto::CommandUnsubscribe::Clear(); + } + if (has_success()) { + if (success_ != NULL) success_->::pulsar::proto::CommandSuccess::Clear(); + } + if (has_error()) { + if (error_ != NULL) error_->::pulsar::proto::CommandError::Clear(); + } + if (has_close_producer()) { + if (close_producer_ != NULL) close_producer_->::pulsar::proto::CommandCloseProducer::Clear(); + } + if (has_close_consumer()) { + if (close_consumer_ != NULL) close_consumer_->::pulsar::proto::CommandCloseConsumer::Clear(); + } + } + if (_has_bits_[16 / 32] & 16711680) { + if (has_producer_success()) { + if (producer_success_ != NULL) producer_success_->::pulsar::proto::CommandProducerSuccess::Clear(); + } + if (has_ping()) { + if (ping_ != NULL) ping_->::pulsar::proto::CommandPing::Clear(); + } + if (has_pong()) { + if (pong_ != NULL) pong_->::pulsar::proto::CommandPong::Clear(); + } + if (has_redeliverunacknowledgedmessages()) { + if (redeliverunacknowledgedmessages_ != NULL) redeliverunacknowledgedmessages_->::pulsar::proto::CommandRedeliverUnacknowledgedMessages::Clear(); + } + if (has_partitionmetadata()) { + if (partitionmetadata_ != NULL) partitionmetadata_->::pulsar::proto::CommandPartitionedTopicMetadata::Clear(); + } + if (has_partitionmetadataresponse()) { + if (partitionmetadataresponse_ != NULL) partitionmetadataresponse_->::pulsar::proto::CommandPartitionedTopicMetadataResponse::Clear(); + } + if (has_lookuptopic()) { + if (lookuptopic_ != NULL) lookuptopic_->::pulsar::proto::CommandLookupTopic::Clear(); + } + if (has_lookuptopicresponse()) { + if (lookuptopicresponse_ != NULL) lookuptopicresponse_->::pulsar::proto::CommandLookupTopicResponse::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool BaseCommand::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:pulsar.proto.BaseCommand) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .pulsar.proto.BaseCommand.Type type = 1; + case 1: { + if (tag == 8) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::pulsar::proto::BaseCommand_Type_IsValid(value)) { + set_type(static_cast< ::pulsar::proto::BaseCommand_Type >(value)); + } else { + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_connect; + break; + } + + // optional .pulsar.proto.CommandConnect connect = 2; + case 2: { + if (tag == 18) { + parse_connect: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_connect())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_connected; + break; + } + + // optional .pulsar.proto.CommandConnected connected = 3; + case 3: { + if (tag == 26) { + parse_connected: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_connected())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(34)) goto parse_subscribe; + break; + } + + // optional .pulsar.proto.CommandSubscribe subscribe = 4; + case 4: { + if (tag == 34) { + parse_subscribe: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_subscribe())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(42)) goto parse_producer; + break; + } + + // optional .pulsar.proto.CommandProducer producer = 5; + case 5: { + if (tag == 42) { + parse_producer: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_producer())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(50)) goto parse_send; + break; + } + + // optional .pulsar.proto.CommandSend send = 6; + case 6: { + if (tag == 50) { + parse_send: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_send())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(58)) goto parse_send_receipt; + break; + } + + // optional .pulsar.proto.CommandSendReceipt send_receipt = 7; + case 7: { + if (tag == 58) { + parse_send_receipt: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_send_receipt())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(66)) goto parse_send_error; + break; + } + + // optional .pulsar.proto.CommandSendError send_error = 8; + case 8: { + if (tag == 66) { + parse_send_error: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_send_error())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(74)) goto parse_message; + break; + } + + // optional .pulsar.proto.CommandMessage message = 9; + case 9: { + if (tag == 74) { + parse_message: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_message())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(82)) goto parse_ack; + break; + } + + // optional .pulsar.proto.CommandAck ack = 10; + case 10: { + if (tag == 82) { + parse_ack: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_ack())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(90)) goto parse_flow; + break; + } + + // optional .pulsar.proto.CommandFlow flow = 11; + case 11: { + if (tag == 90) { + parse_flow: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_flow())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(98)) goto parse_unsubscribe; + break; + } + + // optional .pulsar.proto.CommandUnsubscribe unsubscribe = 12; + case 12: { + if (tag == 98) { + parse_unsubscribe: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_unsubscribe())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(106)) goto parse_success; + break; + } + + // optional .pulsar.proto.CommandSuccess success = 13; + case 13: { + if (tag == 106) { + parse_success: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_success())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(114)) goto parse_error; + break; + } + + // optional .pulsar.proto.CommandError error = 14; + case 14: { + if (tag == 114) { + parse_error: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_error())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(122)) goto parse_close_producer; + break; + } + + // optional .pulsar.proto.CommandCloseProducer close_producer = 15; + case 15: { + if (tag == 122) { + parse_close_producer: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_close_producer())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(130)) goto parse_close_consumer; + break; + } + + // optional .pulsar.proto.CommandCloseConsumer close_consumer = 16; + case 16: { + if (tag == 130) { + parse_close_consumer: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_close_consumer())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(138)) goto parse_producer_success; + break; + } + + // optional .pulsar.proto.CommandProducerSuccess producer_success = 17; + case 17: { + if (tag == 138) { + parse_producer_success: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_producer_success())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(146)) goto parse_ping; + break; + } + + // optional .pulsar.proto.CommandPing ping = 18; + case 18: { + if (tag == 146) { + parse_ping: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_ping())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(154)) goto parse_pong; + break; + } + + // optional .pulsar.proto.CommandPong pong = 19; + case 19: { + if (tag == 154) { + parse_pong: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_pong())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(162)) goto parse_redeliverUnacknowledgedMessages; + break; + } + + // optional .pulsar.proto.CommandRedeliverUnacknowledgedMessages redeliverUnacknowledgedMessages = 20; + case 20: { + if (tag == 162) { + parse_redeliverUnacknowledgedMessages: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_redeliverunacknowledgedmessages())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(170)) goto parse_partitionMetadata; + break; + } + + // optional .pulsar.proto.CommandPartitionedTopicMetadata partitionMetadata = 21; + case 21: { + if (tag == 170) { + parse_partitionMetadata: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_partitionmetadata())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(178)) goto parse_partitionMetadataResponse; + break; + } + + // optional .pulsar.proto.CommandPartitionedTopicMetadataResponse partitionMetadataResponse = 22; + case 22: { + if (tag == 178) { + parse_partitionMetadataResponse: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_partitionmetadataresponse())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(186)) goto parse_lookupTopic; + break; + } + + // optional .pulsar.proto.CommandLookupTopic lookupTopic = 23; + case 23: { + if (tag == 186) { + parse_lookupTopic: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_lookuptopic())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(194)) goto parse_lookupTopicResponse; + break; + } + + // optional .pulsar.proto.CommandLookupTopicResponse lookupTopicResponse = 24; + case 24: { + if (tag == 194) { + parse_lookupTopicResponse: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_lookuptopicresponse())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:pulsar.proto.BaseCommand) + return true; +failure: + // @@protoc_insertion_point(parse_failure:pulsar.proto.BaseCommand) + return false; +#undef DO_ +} + +void BaseCommand::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:pulsar.proto.BaseCommand) + // required .pulsar.proto.BaseCommand.Type type = 1; + if (has_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->type(), output); + } + + // optional .pulsar.proto.CommandConnect connect = 2; + if (has_connect()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 2, this->connect(), output); + } + + // optional .pulsar.proto.CommandConnected connected = 3; + if (has_connected()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 3, this->connected(), output); + } + + // optional .pulsar.proto.CommandSubscribe subscribe = 4; + if (has_subscribe()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 4, this->subscribe(), output); + } + + // optional .pulsar.proto.CommandProducer producer = 5; + if (has_producer()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 5, this->producer(), output); + } + + // optional .pulsar.proto.CommandSend send = 6; + if (has_send()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 6, this->send(), output); + } + + // optional .pulsar.proto.CommandSendReceipt send_receipt = 7; + if (has_send_receipt()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 7, this->send_receipt(), output); + } + + // optional .pulsar.proto.CommandSendError send_error = 8; + if (has_send_error()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 8, this->send_error(), output); + } + + // optional .pulsar.proto.CommandMessage message = 9; + if (has_message()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 9, this->message(), output); + } + + // optional .pulsar.proto.CommandAck ack = 10; + if (has_ack()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 10, this->ack(), output); + } + + // optional .pulsar.proto.CommandFlow flow = 11; + if (has_flow()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 11, this->flow(), output); + } + + // optional .pulsar.proto.CommandUnsubscribe unsubscribe = 12; + if (has_unsubscribe()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 12, this->unsubscribe(), output); + } + + // optional .pulsar.proto.CommandSuccess success = 13; + if (has_success()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 13, this->success(), output); + } + + // optional .pulsar.proto.CommandError error = 14; + if (has_error()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 14, this->error(), output); + } + + // optional .pulsar.proto.CommandCloseProducer close_producer = 15; + if (has_close_producer()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 15, this->close_producer(), output); + } + + // optional .pulsar.proto.CommandCloseConsumer close_consumer = 16; + if (has_close_consumer()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 16, this->close_consumer(), output); + } + + // optional .pulsar.proto.CommandProducerSuccess producer_success = 17; + if (has_producer_success()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 17, this->producer_success(), output); + } + + // optional .pulsar.proto.CommandPing ping = 18; + if (has_ping()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 18, this->ping(), output); + } + + // optional .pulsar.proto.CommandPong pong = 19; + if (has_pong()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 19, this->pong(), output); + } + + // optional .pulsar.proto.CommandRedeliverUnacknowledgedMessages redeliverUnacknowledgedMessages = 20; + if (has_redeliverunacknowledgedmessages()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 20, this->redeliverunacknowledgedmessages(), output); + } + + // optional .pulsar.proto.CommandPartitionedTopicMetadata partitionMetadata = 21; + if (has_partitionmetadata()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 21, this->partitionmetadata(), output); + } + + // optional .pulsar.proto.CommandPartitionedTopicMetadataResponse partitionMetadataResponse = 22; + if (has_partitionmetadataresponse()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 22, this->partitionmetadataresponse(), output); + } + + // optional .pulsar.proto.CommandLookupTopic lookupTopic = 23; + if (has_lookuptopic()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 23, this->lookuptopic(), output); + } + + // optional .pulsar.proto.CommandLookupTopicResponse lookupTopicResponse = 24; + if (has_lookuptopicresponse()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 24, this->lookuptopicresponse(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:pulsar.proto.BaseCommand) +} + +int BaseCommand::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .pulsar.proto.BaseCommand.Type type = 1; + if (has_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->type()); + } + + // optional .pulsar.proto.CommandConnect connect = 2; + if (has_connect()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->connect()); + } + + // optional .pulsar.proto.CommandConnected connected = 3; + if (has_connected()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->connected()); + } + + // optional .pulsar.proto.CommandSubscribe subscribe = 4; + if (has_subscribe()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->subscribe()); + } + + // optional .pulsar.proto.CommandProducer producer = 5; + if (has_producer()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->producer()); + } + + // optional .pulsar.proto.CommandSend send = 6; + if (has_send()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->send()); + } + + // optional .pulsar.proto.CommandSendReceipt send_receipt = 7; + if (has_send_receipt()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->send_receipt()); + } + + // optional .pulsar.proto.CommandSendError send_error = 8; + if (has_send_error()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->send_error()); + } + + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + // optional .pulsar.proto.CommandMessage message = 9; + if (has_message()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->message()); + } + + // optional .pulsar.proto.CommandAck ack = 10; + if (has_ack()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->ack()); + } + + // optional .pulsar.proto.CommandFlow flow = 11; + if (has_flow()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->flow()); + } + + // optional .pulsar.proto.CommandUnsubscribe unsubscribe = 12; + if (has_unsubscribe()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->unsubscribe()); + } + + // optional .pulsar.proto.CommandSuccess success = 13; + if (has_success()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->success()); + } + + // optional .pulsar.proto.CommandError error = 14; + if (has_error()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->error()); + } + + // optional .pulsar.proto.CommandCloseProducer close_producer = 15; + if (has_close_producer()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->close_producer()); + } + + // optional .pulsar.proto.CommandCloseConsumer close_consumer = 16; + if (has_close_consumer()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->close_consumer()); + } + + } + if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) { + // optional .pulsar.proto.CommandProducerSuccess producer_success = 17; + if (has_producer_success()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->producer_success()); + } + + // optional .pulsar.proto.CommandPing ping = 18; + if (has_ping()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->ping()); + } + + // optional .pulsar.proto.CommandPong pong = 19; + if (has_pong()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->pong()); + } + + // optional .pulsar.proto.CommandRedeliverUnacknowledgedMessages redeliverUnacknowledgedMessages = 20; + if (has_redeliverunacknowledgedmessages()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->redeliverunacknowledgedmessages()); + } + + // optional .pulsar.proto.CommandPartitionedTopicMetadata partitionMetadata = 21; + if (has_partitionmetadata()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->partitionmetadata()); + } + + // optional .pulsar.proto.CommandPartitionedTopicMetadataResponse partitionMetadataResponse = 22; + if (has_partitionmetadataresponse()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->partitionmetadataresponse()); + } + + // optional .pulsar.proto.CommandLookupTopic lookupTopic = 23; + if (has_lookuptopic()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->lookuptopic()); + } + + // optional .pulsar.proto.CommandLookupTopicResponse lookupTopicResponse = 24; + if (has_lookuptopicresponse()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->lookuptopicresponse()); + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void BaseCommand::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void BaseCommand::MergeFrom(const BaseCommand& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_type()) { + set_type(from.type()); + } + if (from.has_connect()) { + mutable_connect()->::pulsar::proto::CommandConnect::MergeFrom(from.connect()); + } + if (from.has_connected()) { + mutable_connected()->::pulsar::proto::CommandConnected::MergeFrom(from.connected()); + } + if (from.has_subscribe()) { + mutable_subscribe()->::pulsar::proto::CommandSubscribe::MergeFrom(from.subscribe()); + } + if (from.has_producer()) { + mutable_producer()->::pulsar::proto::CommandProducer::MergeFrom(from.producer()); + } + if (from.has_send()) { + mutable_send()->::pulsar::proto::CommandSend::MergeFrom(from.send()); + } + if (from.has_send_receipt()) { + mutable_send_receipt()->::pulsar::proto::CommandSendReceipt::MergeFrom(from.send_receipt()); + } + if (from.has_send_error()) { + mutable_send_error()->::pulsar::proto::CommandSendError::MergeFrom(from.send_error()); + } + } + if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) { + if (from.has_message()) { + mutable_message()->::pulsar::proto::CommandMessage::MergeFrom(from.message()); + } + if (from.has_ack()) { + mutable_ack()->::pulsar::proto::CommandAck::MergeFrom(from.ack()); + } + if (from.has_flow()) { + mutable_flow()->::pulsar::proto::CommandFlow::MergeFrom(from.flow()); + } + if (from.has_unsubscribe()) { + mutable_unsubscribe()->::pulsar::proto::CommandUnsubscribe::MergeFrom(from.unsubscribe()); + } + if (from.has_success()) { + mutable_success()->::pulsar::proto::CommandSuccess::MergeFrom(from.success()); + } + if (from.has_error()) { + mutable_error()->::pulsar::proto::CommandError::MergeFrom(from.error()); + } + if (from.has_close_producer()) { + mutable_close_producer()->::pulsar::proto::CommandCloseProducer::MergeFrom(from.close_producer()); + } + if (from.has_close_consumer()) { + mutable_close_consumer()->::pulsar::proto::CommandCloseConsumer::MergeFrom(from.close_consumer()); + } + } + if (from._has_bits_[16 / 32] & (0xffu << (16 % 32))) { + if (from.has_producer_success()) { + mutable_producer_success()->::pulsar::proto::CommandProducerSuccess::MergeFrom(from.producer_success()); + } + if (from.has_ping()) { + mutable_ping()->::pulsar::proto::CommandPing::MergeFrom(from.ping()); + } + if (from.has_pong()) { + mutable_pong()->::pulsar::proto::CommandPong::MergeFrom(from.pong()); + } + if (from.has_redeliverunacknowledgedmessages()) { + mutable_redeliverunacknowledgedmessages()->::pulsar::proto::CommandRedeliverUnacknowledgedMessages::MergeFrom(from.redeliverunacknowledgedmessages()); + } + if (from.has_partitionmetadata()) { + mutable_partitionmetadata()->::pulsar::proto::CommandPartitionedTopicMetadata::MergeFrom(from.partitionmetadata()); + } + if (from.has_partitionmetadataresponse()) { + mutable_partitionmetadataresponse()->::pulsar::proto::CommandPartitionedTopicMetadataResponse::MergeFrom(from.partitionmetadataresponse()); + } + if (from.has_lookuptopic()) { + mutable_lookuptopic()->::pulsar::proto::CommandLookupTopic::MergeFrom(from.lookuptopic()); + } + if (from.has_lookuptopicresponse()) { + mutable_lookuptopicresponse()->::pulsar::proto::CommandLookupTopicResponse::MergeFrom(from.lookuptopicresponse()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void BaseCommand::CopyFrom(const BaseCommand& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool BaseCommand::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_connect()) { + if (!this->connect().IsInitialized()) return false; + } + if (has_connected()) { + if (!this->connected().IsInitialized()) return false; + } + if (has_subscribe()) { + if (!this->subscribe().IsInitialized()) return false; + } + if (has_producer()) { + if (!this->producer().IsInitialized()) return false; + } + if (has_send()) { + if (!this->send().IsInitialized()) return false; + } + if (has_send_receipt()) { + if (!this->send_receipt().IsInitialized()) return false; + } + if (has_send_error()) { + if (!this->send_error().IsInitialized()) return false; + } + if (has_message()) { + if (!this->message().IsInitialized()) return false; + } + if (has_ack()) { + if (!this->ack().IsInitialized()) return false; + } + if (has_flow()) { + if (!this->flow().IsInitialized()) return false; + } + if (has_unsubscribe()) { + if (!this->unsubscribe().IsInitialized()) return false; + } + if (has_success()) { + if (!this->success().IsInitialized()) return false; + } + if (has_error()) { + if (!this->error().IsInitialized()) return false; + } + if (has_close_producer()) { + if (!this->close_producer().IsInitialized()) return false; + } + if (has_close_consumer()) { + if (!this->close_consumer().IsInitialized()) return false; + } + if (has_producer_success()) { + if (!this->producer_success().IsInitialized()) return false; + } + if (has_redeliverunacknowledgedmessages()) { + if (!this->redeliverunacknowledgedmessages().IsInitialized()) return false; + } + if (has_partitionmetadata()) { + if (!this->partitionmetadata().IsInitialized()) return false; + } + if (has_partitionmetadataresponse()) { + if (!this->partitionmetadataresponse().IsInitialized()) return false; + } + if (has_lookuptopic()) { + if (!this->lookuptopic().IsInitialized()) return false; + } + if (has_lookuptopicresponse()) { + if (!this->lookuptopicresponse().IsInitialized()) return false; + } + return true; +} + +void BaseCommand::Swap(BaseCommand* other) { + if (other != this) { + std::swap(type_, other->type_); + std::swap(connect_, other->connect_); + std::swap(connected_, other->connected_); + std::swap(subscribe_, other->subscribe_); + std::swap(producer_, other->producer_); + std::swap(send_, other->send_); + std::swap(send_receipt_, other->send_receipt_); + std::swap(send_error_, other->send_error_); + std::swap(message_, other->message_); + std::swap(ack_, other->ack_); + std::swap(flow_, other->flow_); + std::swap(unsubscribe_, other->unsubscribe_); + std::swap(success_, other->success_); + std::swap(error_, other->error_); + std::swap(close_producer_, other->close_producer_); + std::swap(close_consumer_, other->close_consumer_); + std::swap(producer_success_, other->producer_success_); + std::swap(ping_, other->ping_); + std::swap(pong_, other->pong_); + std::swap(redeliverunacknowledgedmessages_, other->redeliverunacknowledgedmessages_); + std::swap(partitionmetadata_, other->partitionmetadata_); + std::swap(partitionmetadataresponse_, other->partitionmetadataresponse_); + std::swap(lookuptopic_, other->lookuptopic_); + std::swap(lookuptopicresponse_, other->lookuptopicresponse_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string BaseCommand::GetTypeName() const { + return "pulsar.proto.BaseCommand"; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace proto +} // namespace pulsar + +// @@protoc_insertion_point(global_scope) diff --git a/pulsar-client-cpp/lib/PulsarApi.pb.h b/pulsar-client-cpp/lib/PulsarApi.pb.h new file mode 100644 index 0000000000000..df8733f5ea380 --- /dev/null +++ b/pulsar-client-cpp/lib/PulsarApi.pb.h @@ -0,0 +1,8437 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: PulsarApi.proto + +#ifndef PROTOBUF_PulsarApi_2eproto__INCLUDED +#define PROTOBUF_PulsarApi_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2006000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2006000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace pulsar { +namespace proto { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_PulsarApi_2eproto(); +void protobuf_AssignDesc_PulsarApi_2eproto(); +void protobuf_ShutdownFile_PulsarApi_2eproto(); + +class MessageIdData; +class KeyValue; +class MessageMetadata; +class SingleMessageMetadata; +class CommandConnect; +class CommandConnected; +class CommandSubscribe; +class CommandPartitionedTopicMetadata; +class CommandPartitionedTopicMetadataResponse; +class CommandLookupTopic; +class CommandLookupTopicResponse; +class CommandProducer; +class CommandSend; +class CommandSendReceipt; +class CommandSendError; +class CommandMessage; +class CommandAck; +class CommandFlow; +class CommandUnsubscribe; +class CommandCloseProducer; +class CommandCloseConsumer; +class CommandRedeliverUnacknowledgedMessages; +class CommandSuccess; +class CommandProducerSuccess; +class CommandError; +class CommandPing; +class CommandPong; +class BaseCommand; + +enum CommandSubscribe_SubType { + CommandSubscribe_SubType_Exclusive = 0, + CommandSubscribe_SubType_Shared = 1, + CommandSubscribe_SubType_Failover = 2 +}; +bool CommandSubscribe_SubType_IsValid(int value); +const CommandSubscribe_SubType CommandSubscribe_SubType_SubType_MIN = CommandSubscribe_SubType_Exclusive; +const CommandSubscribe_SubType CommandSubscribe_SubType_SubType_MAX = CommandSubscribe_SubType_Failover; +const int CommandSubscribe_SubType_SubType_ARRAYSIZE = CommandSubscribe_SubType_SubType_MAX + 1; + +enum CommandPartitionedTopicMetadataResponse_LookupType { + CommandPartitionedTopicMetadataResponse_LookupType_Success = 0, + CommandPartitionedTopicMetadataResponse_LookupType_Failed = 1 +}; +bool CommandPartitionedTopicMetadataResponse_LookupType_IsValid(int value); +const CommandPartitionedTopicMetadataResponse_LookupType CommandPartitionedTopicMetadataResponse_LookupType_LookupType_MIN = CommandPartitionedTopicMetadataResponse_LookupType_Success; +const CommandPartitionedTopicMetadataResponse_LookupType CommandPartitionedTopicMetadataResponse_LookupType_LookupType_MAX = CommandPartitionedTopicMetadataResponse_LookupType_Failed; +const int CommandPartitionedTopicMetadataResponse_LookupType_LookupType_ARRAYSIZE = CommandPartitionedTopicMetadataResponse_LookupType_LookupType_MAX + 1; + +enum CommandLookupTopicResponse_LookupType { + CommandLookupTopicResponse_LookupType_Redirect = 0, + CommandLookupTopicResponse_LookupType_Connect = 1, + CommandLookupTopicResponse_LookupType_Failed = 2 +}; +bool CommandLookupTopicResponse_LookupType_IsValid(int value); +const CommandLookupTopicResponse_LookupType CommandLookupTopicResponse_LookupType_LookupType_MIN = CommandLookupTopicResponse_LookupType_Redirect; +const CommandLookupTopicResponse_LookupType CommandLookupTopicResponse_LookupType_LookupType_MAX = CommandLookupTopicResponse_LookupType_Failed; +const int CommandLookupTopicResponse_LookupType_LookupType_ARRAYSIZE = CommandLookupTopicResponse_LookupType_LookupType_MAX + 1; + +enum CommandAck_AckType { + CommandAck_AckType_Individual = 0, + CommandAck_AckType_Cumulative = 1 +}; +bool CommandAck_AckType_IsValid(int value); +const CommandAck_AckType CommandAck_AckType_AckType_MIN = CommandAck_AckType_Individual; +const CommandAck_AckType CommandAck_AckType_AckType_MAX = CommandAck_AckType_Cumulative; +const int CommandAck_AckType_AckType_ARRAYSIZE = CommandAck_AckType_AckType_MAX + 1; + +enum CommandAck_ValidationError { + CommandAck_ValidationError_UncompressedSizeCorruption = 0, + CommandAck_ValidationError_DecompressionError = 1, + CommandAck_ValidationError_ChecksumMismatch = 2, + CommandAck_ValidationError_BatchDeSerializeError = 3 +}; +bool CommandAck_ValidationError_IsValid(int value); +const CommandAck_ValidationError CommandAck_ValidationError_ValidationError_MIN = CommandAck_ValidationError_UncompressedSizeCorruption; +const CommandAck_ValidationError CommandAck_ValidationError_ValidationError_MAX = CommandAck_ValidationError_BatchDeSerializeError; +const int CommandAck_ValidationError_ValidationError_ARRAYSIZE = CommandAck_ValidationError_ValidationError_MAX + 1; + +enum BaseCommand_Type { + BaseCommand_Type_CONNECT = 2, + BaseCommand_Type_CONNECTED = 3, + BaseCommand_Type_SUBSCRIBE = 4, + BaseCommand_Type_PRODUCER = 5, + BaseCommand_Type_SEND = 6, + BaseCommand_Type_SEND_RECEIPT = 7, + BaseCommand_Type_SEND_ERROR = 8, + BaseCommand_Type_MESSAGE = 9, + BaseCommand_Type_ACK = 10, + BaseCommand_Type_FLOW = 11, + BaseCommand_Type_UNSUBSCRIBE = 12, + BaseCommand_Type_SUCCESS = 13, + BaseCommand_Type_ERROR = 14, + BaseCommand_Type_CLOSE_PRODUCER = 15, + BaseCommand_Type_CLOSE_CONSUMER = 16, + BaseCommand_Type_PRODUCER_SUCCESS = 17, + BaseCommand_Type_PING = 18, + BaseCommand_Type_PONG = 19, + BaseCommand_Type_REDELIVER_UNACKNOWLEDGED_MESSAGES = 20, + BaseCommand_Type_PARTITIONED_METADATA = 21, + BaseCommand_Type_PARTITIONED_METADATA_RESPONSE = 22, + BaseCommand_Type_LOOKUP = 23, + BaseCommand_Type_LOOKUP_RESPONSE = 24 +}; +bool BaseCommand_Type_IsValid(int value); +const BaseCommand_Type BaseCommand_Type_Type_MIN = BaseCommand_Type_CONNECT; +const BaseCommand_Type BaseCommand_Type_Type_MAX = BaseCommand_Type_LOOKUP_RESPONSE; +const int BaseCommand_Type_Type_ARRAYSIZE = BaseCommand_Type_Type_MAX + 1; + +enum CompressionType { + NONE = 0, + LZ4 = 1, + ZLIB = 2 +}; +bool CompressionType_IsValid(int value); +const CompressionType CompressionType_MIN = NONE; +const CompressionType CompressionType_MAX = ZLIB; +const int CompressionType_ARRAYSIZE = CompressionType_MAX + 1; + +enum ServerError { + UnknownError = 0, + MetadataError = 1, + PersistenceError = 2, + AuthenticationError = 3, + AuthorizationError = 4, + ConsumerBusy = 5, + ServiceNotReady = 6, + ProducerBlockedQuotaExceededError = 7, + ProducerBlockedQuotaExceededException = 8, + ChecksumError = 9 +}; +bool ServerError_IsValid(int value); +const ServerError ServerError_MIN = UnknownError; +const ServerError ServerError_MAX = ChecksumError; +const int ServerError_ARRAYSIZE = ServerError_MAX + 1; + +enum AuthMethod { + AuthMethodNone = 0, + AuthMethodYcaV1 = 1, + AuthMethodAthens = 2 +}; +bool AuthMethod_IsValid(int value); +const AuthMethod AuthMethod_MIN = AuthMethodNone; +const AuthMethod AuthMethod_MAX = AuthMethodAthens; +const int AuthMethod_ARRAYSIZE = AuthMethod_MAX + 1; + +enum ProtocolVersion { + v0 = 0, + v1 = 1, + v2 = 2, + v3 = 3, + v4 = 4, + v5 = 5, + v6 = 6 +}; +bool ProtocolVersion_IsValid(int value); +const ProtocolVersion ProtocolVersion_MIN = v0; +const ProtocolVersion ProtocolVersion_MAX = v6; +const int ProtocolVersion_ARRAYSIZE = ProtocolVersion_MAX + 1; + +// =================================================================== + +class MessageIdData : public ::google::protobuf::MessageLite { + public: + MessageIdData(); + virtual ~MessageIdData(); + + MessageIdData(const MessageIdData& from); + + inline MessageIdData& operator=(const MessageIdData& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const MessageIdData& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const MessageIdData* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(MessageIdData* other); + + // implements Message ---------------------------------------------- + + MessageIdData* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const MessageIdData& from); + void MergeFrom(const MessageIdData& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 ledgerId = 1; + inline bool has_ledgerid() const; + inline void clear_ledgerid(); + static const int kLedgerIdFieldNumber = 1; + inline ::google::protobuf::uint64 ledgerid() const; + inline void set_ledgerid(::google::protobuf::uint64 value); + + // required uint64 entryId = 2; + inline bool has_entryid() const; + inline void clear_entryid(); + static const int kEntryIdFieldNumber = 2; + inline ::google::protobuf::uint64 entryid() const; + inline void set_entryid(::google::protobuf::uint64 value); + + // optional int32 partition = 3 [default = -1]; + inline bool has_partition() const; + inline void clear_partition(); + static const int kPartitionFieldNumber = 3; + inline ::google::protobuf::int32 partition() const; + inline void set_partition(::google::protobuf::int32 value); + + // optional int32 batch_index = 4 [default = -1]; + inline bool has_batch_index() const; + inline void clear_batch_index(); + static const int kBatchIndexFieldNumber = 4; + inline ::google::protobuf::int32 batch_index() const; + inline void set_batch_index(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:pulsar.proto.MessageIdData) + private: + inline void set_has_ledgerid(); + inline void clear_has_ledgerid(); + inline void set_has_entryid(); + inline void clear_has_entryid(); + inline void set_has_partition(); + inline void clear_has_partition(); + inline void set_has_batch_index(); + inline void clear_has_batch_index(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 ledgerid_; + ::google::protobuf::uint64 entryid_; + ::google::protobuf::int32 partition_; + ::google::protobuf::int32 batch_index_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static MessageIdData* default_instance_; +}; +// ------------------------------------------------------------------- + +class KeyValue : public ::google::protobuf::MessageLite { + public: + KeyValue(); + virtual ~KeyValue(); + + KeyValue(const KeyValue& from); + + inline KeyValue& operator=(const KeyValue& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const KeyValue& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const KeyValue* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(KeyValue* other); + + // implements Message ---------------------------------------------- + + KeyValue* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const KeyValue& from); + void MergeFrom(const KeyValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string key = 1; + inline bool has_key() const; + inline void clear_key(); + static const int kKeyFieldNumber = 1; + inline const ::std::string& key() const; + inline void set_key(const ::std::string& value); + inline void set_key(const char* value); + inline void set_key(const char* value, size_t size); + inline ::std::string* mutable_key(); + inline ::std::string* release_key(); + inline void set_allocated_key(::std::string* key); + + // required string value = 2; + inline bool has_value() const; + inline void clear_value(); + static const int kValueFieldNumber = 2; + inline const ::std::string& value() const; + inline void set_value(const ::std::string& value); + inline void set_value(const char* value); + inline void set_value(const char* value, size_t size); + inline ::std::string* mutable_value(); + inline ::std::string* release_value(); + inline void set_allocated_value(::std::string* value); + + // @@protoc_insertion_point(class_scope:pulsar.proto.KeyValue) + private: + inline void set_has_key(); + inline void clear_has_key(); + inline void set_has_value(); + inline void clear_has_value(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* key_; + ::std::string* value_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static KeyValue* default_instance_; +}; +// ------------------------------------------------------------------- + +class MessageMetadata : public ::google::protobuf::MessageLite { + public: + MessageMetadata(); + virtual ~MessageMetadata(); + + MessageMetadata(const MessageMetadata& from); + + inline MessageMetadata& operator=(const MessageMetadata& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const MessageMetadata& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const MessageMetadata* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(MessageMetadata* other); + + // implements Message ---------------------------------------------- + + MessageMetadata* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const MessageMetadata& from); + void MergeFrom(const MessageMetadata& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string producer_name = 1; + inline bool has_producer_name() const; + inline void clear_producer_name(); + static const int kProducerNameFieldNumber = 1; + inline const ::std::string& producer_name() const; + inline void set_producer_name(const ::std::string& value); + inline void set_producer_name(const char* value); + inline void set_producer_name(const char* value, size_t size); + inline ::std::string* mutable_producer_name(); + inline ::std::string* release_producer_name(); + inline void set_allocated_producer_name(::std::string* producer_name); + + // required uint64 sequence_id = 2; + inline bool has_sequence_id() const; + inline void clear_sequence_id(); + static const int kSequenceIdFieldNumber = 2; + inline ::google::protobuf::uint64 sequence_id() const; + inline void set_sequence_id(::google::protobuf::uint64 value); + + // required uint64 publish_time = 3; + inline bool has_publish_time() const; + inline void clear_publish_time(); + static const int kPublishTimeFieldNumber = 3; + inline ::google::protobuf::uint64 publish_time() const; + inline void set_publish_time(::google::protobuf::uint64 value); + + // repeated .pulsar.proto.KeyValue properties = 4; + inline int properties_size() const; + inline void clear_properties(); + static const int kPropertiesFieldNumber = 4; + inline const ::pulsar::proto::KeyValue& properties(int index) const; + inline ::pulsar::proto::KeyValue* mutable_properties(int index); + inline ::pulsar::proto::KeyValue* add_properties(); + inline const ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue >& + properties() const; + inline ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue >* + mutable_properties(); + + // optional string replicated_from = 5; + inline bool has_replicated_from() const; + inline void clear_replicated_from(); + static const int kReplicatedFromFieldNumber = 5; + inline const ::std::string& replicated_from() const; + inline void set_replicated_from(const ::std::string& value); + inline void set_replicated_from(const char* value); + inline void set_replicated_from(const char* value, size_t size); + inline ::std::string* mutable_replicated_from(); + inline ::std::string* release_replicated_from(); + inline void set_allocated_replicated_from(::std::string* replicated_from); + + // optional string partition_key = 6; + inline bool has_partition_key() const; + inline void clear_partition_key(); + static const int kPartitionKeyFieldNumber = 6; + inline const ::std::string& partition_key() const; + inline void set_partition_key(const ::std::string& value); + inline void set_partition_key(const char* value); + inline void set_partition_key(const char* value, size_t size); + inline ::std::string* mutable_partition_key(); + inline ::std::string* release_partition_key(); + inline void set_allocated_partition_key(::std::string* partition_key); + + // repeated string replicate_to = 7; + inline int replicate_to_size() const; + inline void clear_replicate_to(); + static const int kReplicateToFieldNumber = 7; + inline const ::std::string& replicate_to(int index) const; + inline ::std::string* mutable_replicate_to(int index); + inline void set_replicate_to(int index, const ::std::string& value); + inline void set_replicate_to(int index, const char* value); + inline void set_replicate_to(int index, const char* value, size_t size); + inline ::std::string* add_replicate_to(); + inline void add_replicate_to(const ::std::string& value); + inline void add_replicate_to(const char* value); + inline void add_replicate_to(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& replicate_to() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_replicate_to(); + + // optional .pulsar.proto.CompressionType compression = 8 [default = NONE]; + inline bool has_compression() const; + inline void clear_compression(); + static const int kCompressionFieldNumber = 8; + inline ::pulsar::proto::CompressionType compression() const; + inline void set_compression(::pulsar::proto::CompressionType value); + + // optional uint32 uncompressed_size = 9 [default = 0]; + inline bool has_uncompressed_size() const; + inline void clear_uncompressed_size(); + static const int kUncompressedSizeFieldNumber = 9; + inline ::google::protobuf::uint32 uncompressed_size() const; + inline void set_uncompressed_size(::google::protobuf::uint32 value); + + // optional int32 num_messages_in_batch = 11 [default = 1]; + inline bool has_num_messages_in_batch() const; + inline void clear_num_messages_in_batch(); + static const int kNumMessagesInBatchFieldNumber = 11; + inline ::google::protobuf::int32 num_messages_in_batch() const; + inline void set_num_messages_in_batch(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:pulsar.proto.MessageMetadata) + private: + inline void set_has_producer_name(); + inline void clear_has_producer_name(); + inline void set_has_sequence_id(); + inline void clear_has_sequence_id(); + inline void set_has_publish_time(); + inline void clear_has_publish_time(); + inline void set_has_replicated_from(); + inline void clear_has_replicated_from(); + inline void set_has_partition_key(); + inline void clear_has_partition_key(); + inline void set_has_compression(); + inline void clear_has_compression(); + inline void set_has_uncompressed_size(); + inline void clear_has_uncompressed_size(); + inline void set_has_num_messages_in_batch(); + inline void clear_has_num_messages_in_batch(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* producer_name_; + ::google::protobuf::uint64 sequence_id_; + ::google::protobuf::uint64 publish_time_; + ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue > properties_; + ::std::string* replicated_from_; + ::std::string* partition_key_; + ::google::protobuf::RepeatedPtrField< ::std::string> replicate_to_; + int compression_; + ::google::protobuf::uint32 uncompressed_size_; + ::google::protobuf::int32 num_messages_in_batch_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static MessageMetadata* default_instance_; +}; +// ------------------------------------------------------------------- + +class SingleMessageMetadata : public ::google::protobuf::MessageLite { + public: + SingleMessageMetadata(); + virtual ~SingleMessageMetadata(); + + SingleMessageMetadata(const SingleMessageMetadata& from); + + inline SingleMessageMetadata& operator=(const SingleMessageMetadata& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const SingleMessageMetadata& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const SingleMessageMetadata* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(SingleMessageMetadata* other); + + // implements Message ---------------------------------------------- + + SingleMessageMetadata* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const SingleMessageMetadata& from); + void MergeFrom(const SingleMessageMetadata& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .pulsar.proto.KeyValue properties = 1; + inline int properties_size() const; + inline void clear_properties(); + static const int kPropertiesFieldNumber = 1; + inline const ::pulsar::proto::KeyValue& properties(int index) const; + inline ::pulsar::proto::KeyValue* mutable_properties(int index); + inline ::pulsar::proto::KeyValue* add_properties(); + inline const ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue >& + properties() const; + inline ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue >* + mutable_properties(); + + // optional string partition_key = 2; + inline bool has_partition_key() const; + inline void clear_partition_key(); + static const int kPartitionKeyFieldNumber = 2; + inline const ::std::string& partition_key() const; + inline void set_partition_key(const ::std::string& value); + inline void set_partition_key(const char* value); + inline void set_partition_key(const char* value, size_t size); + inline ::std::string* mutable_partition_key(); + inline ::std::string* release_partition_key(); + inline void set_allocated_partition_key(::std::string* partition_key); + + // required int32 payload_size = 3; + inline bool has_payload_size() const; + inline void clear_payload_size(); + static const int kPayloadSizeFieldNumber = 3; + inline ::google::protobuf::int32 payload_size() const; + inline void set_payload_size(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:pulsar.proto.SingleMessageMetadata) + private: + inline void set_has_partition_key(); + inline void clear_has_partition_key(); + inline void set_has_payload_size(); + inline void clear_has_payload_size(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue > properties_; + ::std::string* partition_key_; + ::google::protobuf::int32 payload_size_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static SingleMessageMetadata* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandConnect : public ::google::protobuf::MessageLite { + public: + CommandConnect(); + virtual ~CommandConnect(); + + CommandConnect(const CommandConnect& from); + + inline CommandConnect& operator=(const CommandConnect& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandConnect& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandConnect* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandConnect* other); + + // implements Message ---------------------------------------------- + + CommandConnect* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandConnect& from); + void MergeFrom(const CommandConnect& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string client_version = 1; + inline bool has_client_version() const; + inline void clear_client_version(); + static const int kClientVersionFieldNumber = 1; + inline const ::std::string& client_version() const; + inline void set_client_version(const ::std::string& value); + inline void set_client_version(const char* value); + inline void set_client_version(const char* value, size_t size); + inline ::std::string* mutable_client_version(); + inline ::std::string* release_client_version(); + inline void set_allocated_client_version(::std::string* client_version); + + // optional .pulsar.proto.AuthMethod auth_method = 2; + inline bool has_auth_method() const; + inline void clear_auth_method(); + static const int kAuthMethodFieldNumber = 2; + inline ::pulsar::proto::AuthMethod auth_method() const; + inline void set_auth_method(::pulsar::proto::AuthMethod value); + + // optional string auth_method_name = 5; + inline bool has_auth_method_name() const; + inline void clear_auth_method_name(); + static const int kAuthMethodNameFieldNumber = 5; + inline const ::std::string& auth_method_name() const; + inline void set_auth_method_name(const ::std::string& value); + inline void set_auth_method_name(const char* value); + inline void set_auth_method_name(const char* value, size_t size); + inline ::std::string* mutable_auth_method_name(); + inline ::std::string* release_auth_method_name(); + inline void set_allocated_auth_method_name(::std::string* auth_method_name); + + // optional bytes auth_data = 3; + inline bool has_auth_data() const; + inline void clear_auth_data(); + static const int kAuthDataFieldNumber = 3; + inline const ::std::string& auth_data() const; + inline void set_auth_data(const ::std::string& value); + inline void set_auth_data(const char* value); + inline void set_auth_data(const void* value, size_t size); + inline ::std::string* mutable_auth_data(); + inline ::std::string* release_auth_data(); + inline void set_allocated_auth_data(::std::string* auth_data); + + // optional int32 protocol_version = 4 [default = 0]; + inline bool has_protocol_version() const; + inline void clear_protocol_version(); + static const int kProtocolVersionFieldNumber = 4; + inline ::google::protobuf::int32 protocol_version() const; + inline void set_protocol_version(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandConnect) + private: + inline void set_has_client_version(); + inline void clear_has_client_version(); + inline void set_has_auth_method(); + inline void clear_has_auth_method(); + inline void set_has_auth_method_name(); + inline void clear_has_auth_method_name(); + inline void set_has_auth_data(); + inline void clear_has_auth_data(); + inline void set_has_protocol_version(); + inline void clear_has_protocol_version(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* client_version_; + ::std::string* auth_method_name_; + int auth_method_; + ::google::protobuf::int32 protocol_version_; + ::std::string* auth_data_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandConnect* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandConnected : public ::google::protobuf::MessageLite { + public: + CommandConnected(); + virtual ~CommandConnected(); + + CommandConnected(const CommandConnected& from); + + inline CommandConnected& operator=(const CommandConnected& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandConnected& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandConnected* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandConnected* other); + + // implements Message ---------------------------------------------- + + CommandConnected* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandConnected& from); + void MergeFrom(const CommandConnected& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string server_version = 1; + inline bool has_server_version() const; + inline void clear_server_version(); + static const int kServerVersionFieldNumber = 1; + inline const ::std::string& server_version() const; + inline void set_server_version(const ::std::string& value); + inline void set_server_version(const char* value); + inline void set_server_version(const char* value, size_t size); + inline ::std::string* mutable_server_version(); + inline ::std::string* release_server_version(); + inline void set_allocated_server_version(::std::string* server_version); + + // optional int32 protocol_version = 2 [default = 0]; + inline bool has_protocol_version() const; + inline void clear_protocol_version(); + static const int kProtocolVersionFieldNumber = 2; + inline ::google::protobuf::int32 protocol_version() const; + inline void set_protocol_version(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandConnected) + private: + inline void set_has_server_version(); + inline void clear_has_server_version(); + inline void set_has_protocol_version(); + inline void clear_has_protocol_version(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* server_version_; + ::google::protobuf::int32 protocol_version_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandConnected* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandSubscribe : public ::google::protobuf::MessageLite { + public: + CommandSubscribe(); + virtual ~CommandSubscribe(); + + CommandSubscribe(const CommandSubscribe& from); + + inline CommandSubscribe& operator=(const CommandSubscribe& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandSubscribe& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandSubscribe* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandSubscribe* other); + + // implements Message ---------------------------------------------- + + CommandSubscribe* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandSubscribe& from); + void MergeFrom(const CommandSubscribe& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + typedef CommandSubscribe_SubType SubType; + static const SubType Exclusive = CommandSubscribe_SubType_Exclusive; + static const SubType Shared = CommandSubscribe_SubType_Shared; + static const SubType Failover = CommandSubscribe_SubType_Failover; + static inline bool SubType_IsValid(int value) { + return CommandSubscribe_SubType_IsValid(value); + } + static const SubType SubType_MIN = + CommandSubscribe_SubType_SubType_MIN; + static const SubType SubType_MAX = + CommandSubscribe_SubType_SubType_MAX; + static const int SubType_ARRAYSIZE = + CommandSubscribe_SubType_SubType_ARRAYSIZE; + + // accessors ------------------------------------------------------- + + // required string topic = 1; + inline bool has_topic() const; + inline void clear_topic(); + static const int kTopicFieldNumber = 1; + inline const ::std::string& topic() const; + inline void set_topic(const ::std::string& value); + inline void set_topic(const char* value); + inline void set_topic(const char* value, size_t size); + inline ::std::string* mutable_topic(); + inline ::std::string* release_topic(); + inline void set_allocated_topic(::std::string* topic); + + // required string subscription = 2; + inline bool has_subscription() const; + inline void clear_subscription(); + static const int kSubscriptionFieldNumber = 2; + inline const ::std::string& subscription() const; + inline void set_subscription(const ::std::string& value); + inline void set_subscription(const char* value); + inline void set_subscription(const char* value, size_t size); + inline ::std::string* mutable_subscription(); + inline ::std::string* release_subscription(); + inline void set_allocated_subscription(::std::string* subscription); + + // required .pulsar.proto.CommandSubscribe.SubType subType = 3; + inline bool has_subtype() const; + inline void clear_subtype(); + static const int kSubTypeFieldNumber = 3; + inline ::pulsar::proto::CommandSubscribe_SubType subtype() const; + inline void set_subtype(::pulsar::proto::CommandSubscribe_SubType value); + + // required uint64 consumer_id = 4; + inline bool has_consumer_id() const; + inline void clear_consumer_id(); + static const int kConsumerIdFieldNumber = 4; + inline ::google::protobuf::uint64 consumer_id() const; + inline void set_consumer_id(::google::protobuf::uint64 value); + + // required uint64 request_id = 5; + inline bool has_request_id() const; + inline void clear_request_id(); + static const int kRequestIdFieldNumber = 5; + inline ::google::protobuf::uint64 request_id() const; + inline void set_request_id(::google::protobuf::uint64 value); + + // optional string consumer_name = 6; + inline bool has_consumer_name() const; + inline void clear_consumer_name(); + static const int kConsumerNameFieldNumber = 6; + inline const ::std::string& consumer_name() const; + inline void set_consumer_name(const ::std::string& value); + inline void set_consumer_name(const char* value); + inline void set_consumer_name(const char* value, size_t size); + inline ::std::string* mutable_consumer_name(); + inline ::std::string* release_consumer_name(); + inline void set_allocated_consumer_name(::std::string* consumer_name); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandSubscribe) + private: + inline void set_has_topic(); + inline void clear_has_topic(); + inline void set_has_subscription(); + inline void clear_has_subscription(); + inline void set_has_subtype(); + inline void clear_has_subtype(); + inline void set_has_consumer_id(); + inline void clear_has_consumer_id(); + inline void set_has_request_id(); + inline void clear_has_request_id(); + inline void set_has_consumer_name(); + inline void clear_has_consumer_name(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* topic_; + ::std::string* subscription_; + ::google::protobuf::uint64 consumer_id_; + ::google::protobuf::uint64 request_id_; + ::std::string* consumer_name_; + int subtype_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandSubscribe* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandPartitionedTopicMetadata : public ::google::protobuf::MessageLite { + public: + CommandPartitionedTopicMetadata(); + virtual ~CommandPartitionedTopicMetadata(); + + CommandPartitionedTopicMetadata(const CommandPartitionedTopicMetadata& from); + + inline CommandPartitionedTopicMetadata& operator=(const CommandPartitionedTopicMetadata& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandPartitionedTopicMetadata& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandPartitionedTopicMetadata* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandPartitionedTopicMetadata* other); + + // implements Message ---------------------------------------------- + + CommandPartitionedTopicMetadata* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandPartitionedTopicMetadata& from); + void MergeFrom(const CommandPartitionedTopicMetadata& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string topic = 1; + inline bool has_topic() const; + inline void clear_topic(); + static const int kTopicFieldNumber = 1; + inline const ::std::string& topic() const; + inline void set_topic(const ::std::string& value); + inline void set_topic(const char* value); + inline void set_topic(const char* value, size_t size); + inline ::std::string* mutable_topic(); + inline ::std::string* release_topic(); + inline void set_allocated_topic(::std::string* topic); + + // required uint64 request_id = 2; + inline bool has_request_id() const; + inline void clear_request_id(); + static const int kRequestIdFieldNumber = 2; + inline ::google::protobuf::uint64 request_id() const; + inline void set_request_id(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandPartitionedTopicMetadata) + private: + inline void set_has_topic(); + inline void clear_has_topic(); + inline void set_has_request_id(); + inline void clear_has_request_id(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* topic_; + ::google::protobuf::uint64 request_id_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandPartitionedTopicMetadata* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandPartitionedTopicMetadataResponse : public ::google::protobuf::MessageLite { + public: + CommandPartitionedTopicMetadataResponse(); + virtual ~CommandPartitionedTopicMetadataResponse(); + + CommandPartitionedTopicMetadataResponse(const CommandPartitionedTopicMetadataResponse& from); + + inline CommandPartitionedTopicMetadataResponse& operator=(const CommandPartitionedTopicMetadataResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandPartitionedTopicMetadataResponse& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandPartitionedTopicMetadataResponse* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandPartitionedTopicMetadataResponse* other); + + // implements Message ---------------------------------------------- + + CommandPartitionedTopicMetadataResponse* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandPartitionedTopicMetadataResponse& from); + void MergeFrom(const CommandPartitionedTopicMetadataResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + typedef CommandPartitionedTopicMetadataResponse_LookupType LookupType; + static const LookupType Success = CommandPartitionedTopicMetadataResponse_LookupType_Success; + static const LookupType Failed = CommandPartitionedTopicMetadataResponse_LookupType_Failed; + static inline bool LookupType_IsValid(int value) { + return CommandPartitionedTopicMetadataResponse_LookupType_IsValid(value); + } + static const LookupType LookupType_MIN = + CommandPartitionedTopicMetadataResponse_LookupType_LookupType_MIN; + static const LookupType LookupType_MAX = + CommandPartitionedTopicMetadataResponse_LookupType_LookupType_MAX; + static const int LookupType_ARRAYSIZE = + CommandPartitionedTopicMetadataResponse_LookupType_LookupType_ARRAYSIZE; + + // accessors ------------------------------------------------------- + + // optional uint32 partitions = 1; + inline bool has_partitions() const; + inline void clear_partitions(); + static const int kPartitionsFieldNumber = 1; + inline ::google::protobuf::uint32 partitions() const; + inline void set_partitions(::google::protobuf::uint32 value); + + // required uint64 request_id = 2; + inline bool has_request_id() const; + inline void clear_request_id(); + static const int kRequestIdFieldNumber = 2; + inline ::google::protobuf::uint64 request_id() const; + inline void set_request_id(::google::protobuf::uint64 value); + + // optional .pulsar.proto.CommandPartitionedTopicMetadataResponse.LookupType response = 3; + inline bool has_response() const; + inline void clear_response(); + static const int kResponseFieldNumber = 3; + inline ::pulsar::proto::CommandPartitionedTopicMetadataResponse_LookupType response() const; + inline void set_response(::pulsar::proto::CommandPartitionedTopicMetadataResponse_LookupType value); + + // optional .pulsar.proto.ServerError error = 4; + inline bool has_error() const; + inline void clear_error(); + static const int kErrorFieldNumber = 4; + inline ::pulsar::proto::ServerError error() const; + inline void set_error(::pulsar::proto::ServerError value); + + // optional string message = 5; + inline bool has_message() const; + inline void clear_message(); + static const int kMessageFieldNumber = 5; + inline const ::std::string& message() const; + inline void set_message(const ::std::string& value); + inline void set_message(const char* value); + inline void set_message(const char* value, size_t size); + inline ::std::string* mutable_message(); + inline ::std::string* release_message(); + inline void set_allocated_message(::std::string* message); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandPartitionedTopicMetadataResponse) + private: + inline void set_has_partitions(); + inline void clear_has_partitions(); + inline void set_has_request_id(); + inline void clear_has_request_id(); + inline void set_has_response(); + inline void clear_has_response(); + inline void set_has_error(); + inline void clear_has_error(); + inline void set_has_message(); + inline void clear_has_message(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 request_id_; + ::google::protobuf::uint32 partitions_; + int response_; + ::std::string* message_; + int error_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandPartitionedTopicMetadataResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandLookupTopic : public ::google::protobuf::MessageLite { + public: + CommandLookupTopic(); + virtual ~CommandLookupTopic(); + + CommandLookupTopic(const CommandLookupTopic& from); + + inline CommandLookupTopic& operator=(const CommandLookupTopic& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandLookupTopic& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandLookupTopic* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandLookupTopic* other); + + // implements Message ---------------------------------------------- + + CommandLookupTopic* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandLookupTopic& from); + void MergeFrom(const CommandLookupTopic& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string topic = 1; + inline bool has_topic() const; + inline void clear_topic(); + static const int kTopicFieldNumber = 1; + inline const ::std::string& topic() const; + inline void set_topic(const ::std::string& value); + inline void set_topic(const char* value); + inline void set_topic(const char* value, size_t size); + inline ::std::string* mutable_topic(); + inline ::std::string* release_topic(); + inline void set_allocated_topic(::std::string* topic); + + // required uint64 request_id = 2; + inline bool has_request_id() const; + inline void clear_request_id(); + static const int kRequestIdFieldNumber = 2; + inline ::google::protobuf::uint64 request_id() const; + inline void set_request_id(::google::protobuf::uint64 value); + + // optional bool authoritative = 3 [default = false]; + inline bool has_authoritative() const; + inline void clear_authoritative(); + static const int kAuthoritativeFieldNumber = 3; + inline bool authoritative() const; + inline void set_authoritative(bool value); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandLookupTopic) + private: + inline void set_has_topic(); + inline void clear_has_topic(); + inline void set_has_request_id(); + inline void clear_has_request_id(); + inline void set_has_authoritative(); + inline void clear_has_authoritative(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* topic_; + ::google::protobuf::uint64 request_id_; + bool authoritative_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandLookupTopic* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandLookupTopicResponse : public ::google::protobuf::MessageLite { + public: + CommandLookupTopicResponse(); + virtual ~CommandLookupTopicResponse(); + + CommandLookupTopicResponse(const CommandLookupTopicResponse& from); + + inline CommandLookupTopicResponse& operator=(const CommandLookupTopicResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandLookupTopicResponse& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandLookupTopicResponse* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandLookupTopicResponse* other); + + // implements Message ---------------------------------------------- + + CommandLookupTopicResponse* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandLookupTopicResponse& from); + void MergeFrom(const CommandLookupTopicResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + typedef CommandLookupTopicResponse_LookupType LookupType; + static const LookupType Redirect = CommandLookupTopicResponse_LookupType_Redirect; + static const LookupType Connect = CommandLookupTopicResponse_LookupType_Connect; + static const LookupType Failed = CommandLookupTopicResponse_LookupType_Failed; + static inline bool LookupType_IsValid(int value) { + return CommandLookupTopicResponse_LookupType_IsValid(value); + } + static const LookupType LookupType_MIN = + CommandLookupTopicResponse_LookupType_LookupType_MIN; + static const LookupType LookupType_MAX = + CommandLookupTopicResponse_LookupType_LookupType_MAX; + static const int LookupType_ARRAYSIZE = + CommandLookupTopicResponse_LookupType_LookupType_ARRAYSIZE; + + // accessors ------------------------------------------------------- + + // optional string brokerServiceUrl = 1; + inline bool has_brokerserviceurl() const; + inline void clear_brokerserviceurl(); + static const int kBrokerServiceUrlFieldNumber = 1; + inline const ::std::string& brokerserviceurl() const; + inline void set_brokerserviceurl(const ::std::string& value); + inline void set_brokerserviceurl(const char* value); + inline void set_brokerserviceurl(const char* value, size_t size); + inline ::std::string* mutable_brokerserviceurl(); + inline ::std::string* release_brokerserviceurl(); + inline void set_allocated_brokerserviceurl(::std::string* brokerserviceurl); + + // optional string brokerServiceUrlTls = 2; + inline bool has_brokerserviceurltls() const; + inline void clear_brokerserviceurltls(); + static const int kBrokerServiceUrlTlsFieldNumber = 2; + inline const ::std::string& brokerserviceurltls() const; + inline void set_brokerserviceurltls(const ::std::string& value); + inline void set_brokerserviceurltls(const char* value); + inline void set_brokerserviceurltls(const char* value, size_t size); + inline ::std::string* mutable_brokerserviceurltls(); + inline ::std::string* release_brokerserviceurltls(); + inline void set_allocated_brokerserviceurltls(::std::string* brokerserviceurltls); + + // optional .pulsar.proto.CommandLookupTopicResponse.LookupType response = 3; + inline bool has_response() const; + inline void clear_response(); + static const int kResponseFieldNumber = 3; + inline ::pulsar::proto::CommandLookupTopicResponse_LookupType response() const; + inline void set_response(::pulsar::proto::CommandLookupTopicResponse_LookupType value); + + // required uint64 request_id = 4; + inline bool has_request_id() const; + inline void clear_request_id(); + static const int kRequestIdFieldNumber = 4; + inline ::google::protobuf::uint64 request_id() const; + inline void set_request_id(::google::protobuf::uint64 value); + + // optional bool authoritative = 5 [default = false]; + inline bool has_authoritative() const; + inline void clear_authoritative(); + static const int kAuthoritativeFieldNumber = 5; + inline bool authoritative() const; + inline void set_authoritative(bool value); + + // optional .pulsar.proto.ServerError error = 6; + inline bool has_error() const; + inline void clear_error(); + static const int kErrorFieldNumber = 6; + inline ::pulsar::proto::ServerError error() const; + inline void set_error(::pulsar::proto::ServerError value); + + // optional string message = 7; + inline bool has_message() const; + inline void clear_message(); + static const int kMessageFieldNumber = 7; + inline const ::std::string& message() const; + inline void set_message(const ::std::string& value); + inline void set_message(const char* value); + inline void set_message(const char* value, size_t size); + inline ::std::string* mutable_message(); + inline ::std::string* release_message(); + inline void set_allocated_message(::std::string* message); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandLookupTopicResponse) + private: + inline void set_has_brokerserviceurl(); + inline void clear_has_brokerserviceurl(); + inline void set_has_brokerserviceurltls(); + inline void clear_has_brokerserviceurltls(); + inline void set_has_response(); + inline void clear_has_response(); + inline void set_has_request_id(); + inline void clear_has_request_id(); + inline void set_has_authoritative(); + inline void clear_has_authoritative(); + inline void set_has_error(); + inline void clear_has_error(); + inline void set_has_message(); + inline void clear_has_message(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* brokerserviceurl_; + ::std::string* brokerserviceurltls_; + ::google::protobuf::uint64 request_id_; + int response_; + bool authoritative_; + ::std::string* message_; + int error_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandLookupTopicResponse* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandProducer : public ::google::protobuf::MessageLite { + public: + CommandProducer(); + virtual ~CommandProducer(); + + CommandProducer(const CommandProducer& from); + + inline CommandProducer& operator=(const CommandProducer& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandProducer& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandProducer* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandProducer* other); + + // implements Message ---------------------------------------------- + + CommandProducer* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandProducer& from); + void MergeFrom(const CommandProducer& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string topic = 1; + inline bool has_topic() const; + inline void clear_topic(); + static const int kTopicFieldNumber = 1; + inline const ::std::string& topic() const; + inline void set_topic(const ::std::string& value); + inline void set_topic(const char* value); + inline void set_topic(const char* value, size_t size); + inline ::std::string* mutable_topic(); + inline ::std::string* release_topic(); + inline void set_allocated_topic(::std::string* topic); + + // required uint64 producer_id = 2; + inline bool has_producer_id() const; + inline void clear_producer_id(); + static const int kProducerIdFieldNumber = 2; + inline ::google::protobuf::uint64 producer_id() const; + inline void set_producer_id(::google::protobuf::uint64 value); + + // required uint64 request_id = 3; + inline bool has_request_id() const; + inline void clear_request_id(); + static const int kRequestIdFieldNumber = 3; + inline ::google::protobuf::uint64 request_id() const; + inline void set_request_id(::google::protobuf::uint64 value); + + // optional string producer_name = 4; + inline bool has_producer_name() const; + inline void clear_producer_name(); + static const int kProducerNameFieldNumber = 4; + inline const ::std::string& producer_name() const; + inline void set_producer_name(const ::std::string& value); + inline void set_producer_name(const char* value); + inline void set_producer_name(const char* value, size_t size); + inline ::std::string* mutable_producer_name(); + inline ::std::string* release_producer_name(); + inline void set_allocated_producer_name(::std::string* producer_name); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandProducer) + private: + inline void set_has_topic(); + inline void clear_has_topic(); + inline void set_has_producer_id(); + inline void clear_has_producer_id(); + inline void set_has_request_id(); + inline void clear_has_request_id(); + inline void set_has_producer_name(); + inline void clear_has_producer_name(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* topic_; + ::google::protobuf::uint64 producer_id_; + ::google::protobuf::uint64 request_id_; + ::std::string* producer_name_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandProducer* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandSend : public ::google::protobuf::MessageLite { + public: + CommandSend(); + virtual ~CommandSend(); + + CommandSend(const CommandSend& from); + + inline CommandSend& operator=(const CommandSend& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandSend& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandSend* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandSend* other); + + // implements Message ---------------------------------------------- + + CommandSend* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandSend& from); + void MergeFrom(const CommandSend& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 producer_id = 1; + inline bool has_producer_id() const; + inline void clear_producer_id(); + static const int kProducerIdFieldNumber = 1; + inline ::google::protobuf::uint64 producer_id() const; + inline void set_producer_id(::google::protobuf::uint64 value); + + // required uint64 sequence_id = 2; + inline bool has_sequence_id() const; + inline void clear_sequence_id(); + static const int kSequenceIdFieldNumber = 2; + inline ::google::protobuf::uint64 sequence_id() const; + inline void set_sequence_id(::google::protobuf::uint64 value); + + // optional int32 num_messages = 3 [default = 1]; + inline bool has_num_messages() const; + inline void clear_num_messages(); + static const int kNumMessagesFieldNumber = 3; + inline ::google::protobuf::int32 num_messages() const; + inline void set_num_messages(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandSend) + private: + inline void set_has_producer_id(); + inline void clear_has_producer_id(); + inline void set_has_sequence_id(); + inline void clear_has_sequence_id(); + inline void set_has_num_messages(); + inline void clear_has_num_messages(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 producer_id_; + ::google::protobuf::uint64 sequence_id_; + ::google::protobuf::int32 num_messages_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandSend* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandSendReceipt : public ::google::protobuf::MessageLite { + public: + CommandSendReceipt(); + virtual ~CommandSendReceipt(); + + CommandSendReceipt(const CommandSendReceipt& from); + + inline CommandSendReceipt& operator=(const CommandSendReceipt& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandSendReceipt& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandSendReceipt* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandSendReceipt* other); + + // implements Message ---------------------------------------------- + + CommandSendReceipt* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandSendReceipt& from); + void MergeFrom(const CommandSendReceipt& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 producer_id = 1; + inline bool has_producer_id() const; + inline void clear_producer_id(); + static const int kProducerIdFieldNumber = 1; + inline ::google::protobuf::uint64 producer_id() const; + inline void set_producer_id(::google::protobuf::uint64 value); + + // required uint64 sequence_id = 2; + inline bool has_sequence_id() const; + inline void clear_sequence_id(); + static const int kSequenceIdFieldNumber = 2; + inline ::google::protobuf::uint64 sequence_id() const; + inline void set_sequence_id(::google::protobuf::uint64 value); + + // optional .pulsar.proto.MessageIdData message_id = 3; + inline bool has_message_id() const; + inline void clear_message_id(); + static const int kMessageIdFieldNumber = 3; + inline const ::pulsar::proto::MessageIdData& message_id() const; + inline ::pulsar::proto::MessageIdData* mutable_message_id(); + inline ::pulsar::proto::MessageIdData* release_message_id(); + inline void set_allocated_message_id(::pulsar::proto::MessageIdData* message_id); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandSendReceipt) + private: + inline void set_has_producer_id(); + inline void clear_has_producer_id(); + inline void set_has_sequence_id(); + inline void clear_has_sequence_id(); + inline void set_has_message_id(); + inline void clear_has_message_id(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 producer_id_; + ::google::protobuf::uint64 sequence_id_; + ::pulsar::proto::MessageIdData* message_id_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandSendReceipt* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandSendError : public ::google::protobuf::MessageLite { + public: + CommandSendError(); + virtual ~CommandSendError(); + + CommandSendError(const CommandSendError& from); + + inline CommandSendError& operator=(const CommandSendError& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandSendError& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandSendError* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandSendError* other); + + // implements Message ---------------------------------------------- + + CommandSendError* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandSendError& from); + void MergeFrom(const CommandSendError& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 producer_id = 1; + inline bool has_producer_id() const; + inline void clear_producer_id(); + static const int kProducerIdFieldNumber = 1; + inline ::google::protobuf::uint64 producer_id() const; + inline void set_producer_id(::google::protobuf::uint64 value); + + // required uint64 sequence_id = 2; + inline bool has_sequence_id() const; + inline void clear_sequence_id(); + static const int kSequenceIdFieldNumber = 2; + inline ::google::protobuf::uint64 sequence_id() const; + inline void set_sequence_id(::google::protobuf::uint64 value); + + // required .pulsar.proto.ServerError error = 3; + inline bool has_error() const; + inline void clear_error(); + static const int kErrorFieldNumber = 3; + inline ::pulsar::proto::ServerError error() const; + inline void set_error(::pulsar::proto::ServerError value); + + // required string message = 4; + inline bool has_message() const; + inline void clear_message(); + static const int kMessageFieldNumber = 4; + inline const ::std::string& message() const; + inline void set_message(const ::std::string& value); + inline void set_message(const char* value); + inline void set_message(const char* value, size_t size); + inline ::std::string* mutable_message(); + inline ::std::string* release_message(); + inline void set_allocated_message(::std::string* message); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandSendError) + private: + inline void set_has_producer_id(); + inline void clear_has_producer_id(); + inline void set_has_sequence_id(); + inline void clear_has_sequence_id(); + inline void set_has_error(); + inline void clear_has_error(); + inline void set_has_message(); + inline void clear_has_message(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 producer_id_; + ::google::protobuf::uint64 sequence_id_; + ::std::string* message_; + int error_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandSendError* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandMessage : public ::google::protobuf::MessageLite { + public: + CommandMessage(); + virtual ~CommandMessage(); + + CommandMessage(const CommandMessage& from); + + inline CommandMessage& operator=(const CommandMessage& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandMessage& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandMessage* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandMessage* other); + + // implements Message ---------------------------------------------- + + CommandMessage* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandMessage& from); + void MergeFrom(const CommandMessage& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 consumer_id = 1; + inline bool has_consumer_id() const; + inline void clear_consumer_id(); + static const int kConsumerIdFieldNumber = 1; + inline ::google::protobuf::uint64 consumer_id() const; + inline void set_consumer_id(::google::protobuf::uint64 value); + + // required .pulsar.proto.MessageIdData message_id = 2; + inline bool has_message_id() const; + inline void clear_message_id(); + static const int kMessageIdFieldNumber = 2; + inline const ::pulsar::proto::MessageIdData& message_id() const; + inline ::pulsar::proto::MessageIdData* mutable_message_id(); + inline ::pulsar::proto::MessageIdData* release_message_id(); + inline void set_allocated_message_id(::pulsar::proto::MessageIdData* message_id); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandMessage) + private: + inline void set_has_consumer_id(); + inline void clear_has_consumer_id(); + inline void set_has_message_id(); + inline void clear_has_message_id(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 consumer_id_; + ::pulsar::proto::MessageIdData* message_id_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandMessage* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandAck : public ::google::protobuf::MessageLite { + public: + CommandAck(); + virtual ~CommandAck(); + + CommandAck(const CommandAck& from); + + inline CommandAck& operator=(const CommandAck& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandAck& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandAck* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandAck* other); + + // implements Message ---------------------------------------------- + + CommandAck* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandAck& from); + void MergeFrom(const CommandAck& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + typedef CommandAck_AckType AckType; + static const AckType Individual = CommandAck_AckType_Individual; + static const AckType Cumulative = CommandAck_AckType_Cumulative; + static inline bool AckType_IsValid(int value) { + return CommandAck_AckType_IsValid(value); + } + static const AckType AckType_MIN = + CommandAck_AckType_AckType_MIN; + static const AckType AckType_MAX = + CommandAck_AckType_AckType_MAX; + static const int AckType_ARRAYSIZE = + CommandAck_AckType_AckType_ARRAYSIZE; + + typedef CommandAck_ValidationError ValidationError; + static const ValidationError UncompressedSizeCorruption = CommandAck_ValidationError_UncompressedSizeCorruption; + static const ValidationError DecompressionError = CommandAck_ValidationError_DecompressionError; + static const ValidationError ChecksumMismatch = CommandAck_ValidationError_ChecksumMismatch; + static const ValidationError BatchDeSerializeError = CommandAck_ValidationError_BatchDeSerializeError; + static inline bool ValidationError_IsValid(int value) { + return CommandAck_ValidationError_IsValid(value); + } + static const ValidationError ValidationError_MIN = + CommandAck_ValidationError_ValidationError_MIN; + static const ValidationError ValidationError_MAX = + CommandAck_ValidationError_ValidationError_MAX; + static const int ValidationError_ARRAYSIZE = + CommandAck_ValidationError_ValidationError_ARRAYSIZE; + + // accessors ------------------------------------------------------- + + // required uint64 consumer_id = 1; + inline bool has_consumer_id() const; + inline void clear_consumer_id(); + static const int kConsumerIdFieldNumber = 1; + inline ::google::protobuf::uint64 consumer_id() const; + inline void set_consumer_id(::google::protobuf::uint64 value); + + // required .pulsar.proto.CommandAck.AckType ack_type = 2; + inline bool has_ack_type() const; + inline void clear_ack_type(); + static const int kAckTypeFieldNumber = 2; + inline ::pulsar::proto::CommandAck_AckType ack_type() const; + inline void set_ack_type(::pulsar::proto::CommandAck_AckType value); + + // required .pulsar.proto.MessageIdData message_id = 3; + inline bool has_message_id() const; + inline void clear_message_id(); + static const int kMessageIdFieldNumber = 3; + inline const ::pulsar::proto::MessageIdData& message_id() const; + inline ::pulsar::proto::MessageIdData* mutable_message_id(); + inline ::pulsar::proto::MessageIdData* release_message_id(); + inline void set_allocated_message_id(::pulsar::proto::MessageIdData* message_id); + + // optional .pulsar.proto.CommandAck.ValidationError validation_error = 4; + inline bool has_validation_error() const; + inline void clear_validation_error(); + static const int kValidationErrorFieldNumber = 4; + inline ::pulsar::proto::CommandAck_ValidationError validation_error() const; + inline void set_validation_error(::pulsar::proto::CommandAck_ValidationError value); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandAck) + private: + inline void set_has_consumer_id(); + inline void clear_has_consumer_id(); + inline void set_has_ack_type(); + inline void clear_has_ack_type(); + inline void set_has_message_id(); + inline void clear_has_message_id(); + inline void set_has_validation_error(); + inline void clear_has_validation_error(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 consumer_id_; + ::pulsar::proto::MessageIdData* message_id_; + int ack_type_; + int validation_error_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandAck* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandFlow : public ::google::protobuf::MessageLite { + public: + CommandFlow(); + virtual ~CommandFlow(); + + CommandFlow(const CommandFlow& from); + + inline CommandFlow& operator=(const CommandFlow& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandFlow& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandFlow* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandFlow* other); + + // implements Message ---------------------------------------------- + + CommandFlow* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandFlow& from); + void MergeFrom(const CommandFlow& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 consumer_id = 1; + inline bool has_consumer_id() const; + inline void clear_consumer_id(); + static const int kConsumerIdFieldNumber = 1; + inline ::google::protobuf::uint64 consumer_id() const; + inline void set_consumer_id(::google::protobuf::uint64 value); + + // required uint32 messagePermits = 2; + inline bool has_messagepermits() const; + inline void clear_messagepermits(); + static const int kMessagePermitsFieldNumber = 2; + inline ::google::protobuf::uint32 messagepermits() const; + inline void set_messagepermits(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandFlow) + private: + inline void set_has_consumer_id(); + inline void clear_has_consumer_id(); + inline void set_has_messagepermits(); + inline void clear_has_messagepermits(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 consumer_id_; + ::google::protobuf::uint32 messagepermits_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandFlow* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandUnsubscribe : public ::google::protobuf::MessageLite { + public: + CommandUnsubscribe(); + virtual ~CommandUnsubscribe(); + + CommandUnsubscribe(const CommandUnsubscribe& from); + + inline CommandUnsubscribe& operator=(const CommandUnsubscribe& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandUnsubscribe& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandUnsubscribe* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandUnsubscribe* other); + + // implements Message ---------------------------------------------- + + CommandUnsubscribe* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandUnsubscribe& from); + void MergeFrom(const CommandUnsubscribe& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 consumer_id = 1; + inline bool has_consumer_id() const; + inline void clear_consumer_id(); + static const int kConsumerIdFieldNumber = 1; + inline ::google::protobuf::uint64 consumer_id() const; + inline void set_consumer_id(::google::protobuf::uint64 value); + + // required uint64 request_id = 2; + inline bool has_request_id() const; + inline void clear_request_id(); + static const int kRequestIdFieldNumber = 2; + inline ::google::protobuf::uint64 request_id() const; + inline void set_request_id(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandUnsubscribe) + private: + inline void set_has_consumer_id(); + inline void clear_has_consumer_id(); + inline void set_has_request_id(); + inline void clear_has_request_id(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 consumer_id_; + ::google::protobuf::uint64 request_id_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandUnsubscribe* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandCloseProducer : public ::google::protobuf::MessageLite { + public: + CommandCloseProducer(); + virtual ~CommandCloseProducer(); + + CommandCloseProducer(const CommandCloseProducer& from); + + inline CommandCloseProducer& operator=(const CommandCloseProducer& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandCloseProducer& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandCloseProducer* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandCloseProducer* other); + + // implements Message ---------------------------------------------- + + CommandCloseProducer* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandCloseProducer& from); + void MergeFrom(const CommandCloseProducer& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 producer_id = 1; + inline bool has_producer_id() const; + inline void clear_producer_id(); + static const int kProducerIdFieldNumber = 1; + inline ::google::protobuf::uint64 producer_id() const; + inline void set_producer_id(::google::protobuf::uint64 value); + + // required uint64 request_id = 2; + inline bool has_request_id() const; + inline void clear_request_id(); + static const int kRequestIdFieldNumber = 2; + inline ::google::protobuf::uint64 request_id() const; + inline void set_request_id(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandCloseProducer) + private: + inline void set_has_producer_id(); + inline void clear_has_producer_id(); + inline void set_has_request_id(); + inline void clear_has_request_id(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 producer_id_; + ::google::protobuf::uint64 request_id_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandCloseProducer* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandCloseConsumer : public ::google::protobuf::MessageLite { + public: + CommandCloseConsumer(); + virtual ~CommandCloseConsumer(); + + CommandCloseConsumer(const CommandCloseConsumer& from); + + inline CommandCloseConsumer& operator=(const CommandCloseConsumer& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandCloseConsumer& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandCloseConsumer* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandCloseConsumer* other); + + // implements Message ---------------------------------------------- + + CommandCloseConsumer* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandCloseConsumer& from); + void MergeFrom(const CommandCloseConsumer& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 consumer_id = 1; + inline bool has_consumer_id() const; + inline void clear_consumer_id(); + static const int kConsumerIdFieldNumber = 1; + inline ::google::protobuf::uint64 consumer_id() const; + inline void set_consumer_id(::google::protobuf::uint64 value); + + // required uint64 request_id = 2; + inline bool has_request_id() const; + inline void clear_request_id(); + static const int kRequestIdFieldNumber = 2; + inline ::google::protobuf::uint64 request_id() const; + inline void set_request_id(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandCloseConsumer) + private: + inline void set_has_consumer_id(); + inline void clear_has_consumer_id(); + inline void set_has_request_id(); + inline void clear_has_request_id(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 consumer_id_; + ::google::protobuf::uint64 request_id_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandCloseConsumer* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandRedeliverUnacknowledgedMessages : public ::google::protobuf::MessageLite { + public: + CommandRedeliverUnacknowledgedMessages(); + virtual ~CommandRedeliverUnacknowledgedMessages(); + + CommandRedeliverUnacknowledgedMessages(const CommandRedeliverUnacknowledgedMessages& from); + + inline CommandRedeliverUnacknowledgedMessages& operator=(const CommandRedeliverUnacknowledgedMessages& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandRedeliverUnacknowledgedMessages& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandRedeliverUnacknowledgedMessages* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandRedeliverUnacknowledgedMessages* other); + + // implements Message ---------------------------------------------- + + CommandRedeliverUnacknowledgedMessages* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandRedeliverUnacknowledgedMessages& from); + void MergeFrom(const CommandRedeliverUnacknowledgedMessages& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 consumer_id = 1; + inline bool has_consumer_id() const; + inline void clear_consumer_id(); + static const int kConsumerIdFieldNumber = 1; + inline ::google::protobuf::uint64 consumer_id() const; + inline void set_consumer_id(::google::protobuf::uint64 value); + + // repeated .pulsar.proto.MessageIdData message_ids = 2; + inline int message_ids_size() const; + inline void clear_message_ids(); + static const int kMessageIdsFieldNumber = 2; + inline const ::pulsar::proto::MessageIdData& message_ids(int index) const; + inline ::pulsar::proto::MessageIdData* mutable_message_ids(int index); + inline ::pulsar::proto::MessageIdData* add_message_ids(); + inline const ::google::protobuf::RepeatedPtrField< ::pulsar::proto::MessageIdData >& + message_ids() const; + inline ::google::protobuf::RepeatedPtrField< ::pulsar::proto::MessageIdData >* + mutable_message_ids(); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandRedeliverUnacknowledgedMessages) + private: + inline void set_has_consumer_id(); + inline void clear_has_consumer_id(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 consumer_id_; + ::google::protobuf::RepeatedPtrField< ::pulsar::proto::MessageIdData > message_ids_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandRedeliverUnacknowledgedMessages* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandSuccess : public ::google::protobuf::MessageLite { + public: + CommandSuccess(); + virtual ~CommandSuccess(); + + CommandSuccess(const CommandSuccess& from); + + inline CommandSuccess& operator=(const CommandSuccess& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandSuccess& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandSuccess* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandSuccess* other); + + // implements Message ---------------------------------------------- + + CommandSuccess* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandSuccess& from); + void MergeFrom(const CommandSuccess& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 request_id = 1; + inline bool has_request_id() const; + inline void clear_request_id(); + static const int kRequestIdFieldNumber = 1; + inline ::google::protobuf::uint64 request_id() const; + inline void set_request_id(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandSuccess) + private: + inline void set_has_request_id(); + inline void clear_has_request_id(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 request_id_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandSuccess* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandProducerSuccess : public ::google::protobuf::MessageLite { + public: + CommandProducerSuccess(); + virtual ~CommandProducerSuccess(); + + CommandProducerSuccess(const CommandProducerSuccess& from); + + inline CommandProducerSuccess& operator=(const CommandProducerSuccess& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandProducerSuccess& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandProducerSuccess* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandProducerSuccess* other); + + // implements Message ---------------------------------------------- + + CommandProducerSuccess* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandProducerSuccess& from); + void MergeFrom(const CommandProducerSuccess& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 request_id = 1; + inline bool has_request_id() const; + inline void clear_request_id(); + static const int kRequestIdFieldNumber = 1; + inline ::google::protobuf::uint64 request_id() const; + inline void set_request_id(::google::protobuf::uint64 value); + + // required string producer_name = 2; + inline bool has_producer_name() const; + inline void clear_producer_name(); + static const int kProducerNameFieldNumber = 2; + inline const ::std::string& producer_name() const; + inline void set_producer_name(const ::std::string& value); + inline void set_producer_name(const char* value); + inline void set_producer_name(const char* value, size_t size); + inline ::std::string* mutable_producer_name(); + inline ::std::string* release_producer_name(); + inline void set_allocated_producer_name(::std::string* producer_name); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandProducerSuccess) + private: + inline void set_has_request_id(); + inline void clear_has_request_id(); + inline void set_has_producer_name(); + inline void clear_has_producer_name(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 request_id_; + ::std::string* producer_name_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandProducerSuccess* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandError : public ::google::protobuf::MessageLite { + public: + CommandError(); + virtual ~CommandError(); + + CommandError(const CommandError& from); + + inline CommandError& operator=(const CommandError& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandError& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandError* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandError* other); + + // implements Message ---------------------------------------------- + + CommandError* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandError& from); + void MergeFrom(const CommandError& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 request_id = 1; + inline bool has_request_id() const; + inline void clear_request_id(); + static const int kRequestIdFieldNumber = 1; + inline ::google::protobuf::uint64 request_id() const; + inline void set_request_id(::google::protobuf::uint64 value); + + // required .pulsar.proto.ServerError error = 2; + inline bool has_error() const; + inline void clear_error(); + static const int kErrorFieldNumber = 2; + inline ::pulsar::proto::ServerError error() const; + inline void set_error(::pulsar::proto::ServerError value); + + // required string message = 3; + inline bool has_message() const; + inline void clear_message(); + static const int kMessageFieldNumber = 3; + inline const ::std::string& message() const; + inline void set_message(const ::std::string& value); + inline void set_message(const char* value); + inline void set_message(const char* value, size_t size); + inline ::std::string* mutable_message(); + inline ::std::string* release_message(); + inline void set_allocated_message(::std::string* message); + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandError) + private: + inline void set_has_request_id(); + inline void clear_has_request_id(); + inline void set_has_error(); + inline void clear_has_error(); + inline void set_has_message(); + inline void clear_has_message(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 request_id_; + ::std::string* message_; + int error_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandError* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandPing : public ::google::protobuf::MessageLite { + public: + CommandPing(); + virtual ~CommandPing(); + + CommandPing(const CommandPing& from); + + inline CommandPing& operator=(const CommandPing& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandPing& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandPing* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandPing* other); + + // implements Message ---------------------------------------------- + + CommandPing* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandPing& from); + void MergeFrom(const CommandPing& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandPing) + private: + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandPing* default_instance_; +}; +// ------------------------------------------------------------------- + +class CommandPong : public ::google::protobuf::MessageLite { + public: + CommandPong(); + virtual ~CommandPong(); + + CommandPong(const CommandPong& from); + + inline CommandPong& operator=(const CommandPong& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const CommandPong& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandPong* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(CommandPong* other); + + // implements Message ---------------------------------------------- + + CommandPong* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const CommandPong& from); + void MergeFrom(const CommandPong& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:pulsar.proto.CommandPong) + private: + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static CommandPong* default_instance_; +}; +// ------------------------------------------------------------------- + +class BaseCommand : public ::google::protobuf::MessageLite { + public: + BaseCommand(); + virtual ~BaseCommand(); + + BaseCommand(const BaseCommand& from); + + inline BaseCommand& operator=(const BaseCommand& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const BaseCommand& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const BaseCommand* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(BaseCommand* other); + + // implements Message ---------------------------------------------- + + BaseCommand* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const BaseCommand& from); + void MergeFrom(const BaseCommand& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + typedef BaseCommand_Type Type; + static const Type CONNECT = BaseCommand_Type_CONNECT; + static const Type CONNECTED = BaseCommand_Type_CONNECTED; + static const Type SUBSCRIBE = BaseCommand_Type_SUBSCRIBE; + static const Type PRODUCER = BaseCommand_Type_PRODUCER; + static const Type SEND = BaseCommand_Type_SEND; + static const Type SEND_RECEIPT = BaseCommand_Type_SEND_RECEIPT; + static const Type SEND_ERROR = BaseCommand_Type_SEND_ERROR; + static const Type MESSAGE = BaseCommand_Type_MESSAGE; + static const Type ACK = BaseCommand_Type_ACK; + static const Type FLOW = BaseCommand_Type_FLOW; + static const Type UNSUBSCRIBE = BaseCommand_Type_UNSUBSCRIBE; + static const Type SUCCESS = BaseCommand_Type_SUCCESS; + static const Type ERROR = BaseCommand_Type_ERROR; + static const Type CLOSE_PRODUCER = BaseCommand_Type_CLOSE_PRODUCER; + static const Type CLOSE_CONSUMER = BaseCommand_Type_CLOSE_CONSUMER; + static const Type PRODUCER_SUCCESS = BaseCommand_Type_PRODUCER_SUCCESS; + static const Type PING = BaseCommand_Type_PING; + static const Type PONG = BaseCommand_Type_PONG; + static const Type REDELIVER_UNACKNOWLEDGED_MESSAGES = BaseCommand_Type_REDELIVER_UNACKNOWLEDGED_MESSAGES; + static const Type PARTITIONED_METADATA = BaseCommand_Type_PARTITIONED_METADATA; + static const Type PARTITIONED_METADATA_RESPONSE = BaseCommand_Type_PARTITIONED_METADATA_RESPONSE; + static const Type LOOKUP = BaseCommand_Type_LOOKUP; + static const Type LOOKUP_RESPONSE = BaseCommand_Type_LOOKUP_RESPONSE; + static inline bool Type_IsValid(int value) { + return BaseCommand_Type_IsValid(value); + } + static const Type Type_MIN = + BaseCommand_Type_Type_MIN; + static const Type Type_MAX = + BaseCommand_Type_Type_MAX; + static const int Type_ARRAYSIZE = + BaseCommand_Type_Type_ARRAYSIZE; + + // accessors ------------------------------------------------------- + + // required .pulsar.proto.BaseCommand.Type type = 1; + inline bool has_type() const; + inline void clear_type(); + static const int kTypeFieldNumber = 1; + inline ::pulsar::proto::BaseCommand_Type type() const; + inline void set_type(::pulsar::proto::BaseCommand_Type value); + + // optional .pulsar.proto.CommandConnect connect = 2; + inline bool has_connect() const; + inline void clear_connect(); + static const int kConnectFieldNumber = 2; + inline const ::pulsar::proto::CommandConnect& connect() const; + inline ::pulsar::proto::CommandConnect* mutable_connect(); + inline ::pulsar::proto::CommandConnect* release_connect(); + inline void set_allocated_connect(::pulsar::proto::CommandConnect* connect); + + // optional .pulsar.proto.CommandConnected connected = 3; + inline bool has_connected() const; + inline void clear_connected(); + static const int kConnectedFieldNumber = 3; + inline const ::pulsar::proto::CommandConnected& connected() const; + inline ::pulsar::proto::CommandConnected* mutable_connected(); + inline ::pulsar::proto::CommandConnected* release_connected(); + inline void set_allocated_connected(::pulsar::proto::CommandConnected* connected); + + // optional .pulsar.proto.CommandSubscribe subscribe = 4; + inline bool has_subscribe() const; + inline void clear_subscribe(); + static const int kSubscribeFieldNumber = 4; + inline const ::pulsar::proto::CommandSubscribe& subscribe() const; + inline ::pulsar::proto::CommandSubscribe* mutable_subscribe(); + inline ::pulsar::proto::CommandSubscribe* release_subscribe(); + inline void set_allocated_subscribe(::pulsar::proto::CommandSubscribe* subscribe); + + // optional .pulsar.proto.CommandProducer producer = 5; + inline bool has_producer() const; + inline void clear_producer(); + static const int kProducerFieldNumber = 5; + inline const ::pulsar::proto::CommandProducer& producer() const; + inline ::pulsar::proto::CommandProducer* mutable_producer(); + inline ::pulsar::proto::CommandProducer* release_producer(); + inline void set_allocated_producer(::pulsar::proto::CommandProducer* producer); + + // optional .pulsar.proto.CommandSend send = 6; + inline bool has_send() const; + inline void clear_send(); + static const int kSendFieldNumber = 6; + inline const ::pulsar::proto::CommandSend& send() const; + inline ::pulsar::proto::CommandSend* mutable_send(); + inline ::pulsar::proto::CommandSend* release_send(); + inline void set_allocated_send(::pulsar::proto::CommandSend* send); + + // optional .pulsar.proto.CommandSendReceipt send_receipt = 7; + inline bool has_send_receipt() const; + inline void clear_send_receipt(); + static const int kSendReceiptFieldNumber = 7; + inline const ::pulsar::proto::CommandSendReceipt& send_receipt() const; + inline ::pulsar::proto::CommandSendReceipt* mutable_send_receipt(); + inline ::pulsar::proto::CommandSendReceipt* release_send_receipt(); + inline void set_allocated_send_receipt(::pulsar::proto::CommandSendReceipt* send_receipt); + + // optional .pulsar.proto.CommandSendError send_error = 8; + inline bool has_send_error() const; + inline void clear_send_error(); + static const int kSendErrorFieldNumber = 8; + inline const ::pulsar::proto::CommandSendError& send_error() const; + inline ::pulsar::proto::CommandSendError* mutable_send_error(); + inline ::pulsar::proto::CommandSendError* release_send_error(); + inline void set_allocated_send_error(::pulsar::proto::CommandSendError* send_error); + + // optional .pulsar.proto.CommandMessage message = 9; + inline bool has_message() const; + inline void clear_message(); + static const int kMessageFieldNumber = 9; + inline const ::pulsar::proto::CommandMessage& message() const; + inline ::pulsar::proto::CommandMessage* mutable_message(); + inline ::pulsar::proto::CommandMessage* release_message(); + inline void set_allocated_message(::pulsar::proto::CommandMessage* message); + + // optional .pulsar.proto.CommandAck ack = 10; + inline bool has_ack() const; + inline void clear_ack(); + static const int kAckFieldNumber = 10; + inline const ::pulsar::proto::CommandAck& ack() const; + inline ::pulsar::proto::CommandAck* mutable_ack(); + inline ::pulsar::proto::CommandAck* release_ack(); + inline void set_allocated_ack(::pulsar::proto::CommandAck* ack); + + // optional .pulsar.proto.CommandFlow flow = 11; + inline bool has_flow() const; + inline void clear_flow(); + static const int kFlowFieldNumber = 11; + inline const ::pulsar::proto::CommandFlow& flow() const; + inline ::pulsar::proto::CommandFlow* mutable_flow(); + inline ::pulsar::proto::CommandFlow* release_flow(); + inline void set_allocated_flow(::pulsar::proto::CommandFlow* flow); + + // optional .pulsar.proto.CommandUnsubscribe unsubscribe = 12; + inline bool has_unsubscribe() const; + inline void clear_unsubscribe(); + static const int kUnsubscribeFieldNumber = 12; + inline const ::pulsar::proto::CommandUnsubscribe& unsubscribe() const; + inline ::pulsar::proto::CommandUnsubscribe* mutable_unsubscribe(); + inline ::pulsar::proto::CommandUnsubscribe* release_unsubscribe(); + inline void set_allocated_unsubscribe(::pulsar::proto::CommandUnsubscribe* unsubscribe); + + // optional .pulsar.proto.CommandSuccess success = 13; + inline bool has_success() const; + inline void clear_success(); + static const int kSuccessFieldNumber = 13; + inline const ::pulsar::proto::CommandSuccess& success() const; + inline ::pulsar::proto::CommandSuccess* mutable_success(); + inline ::pulsar::proto::CommandSuccess* release_success(); + inline void set_allocated_success(::pulsar::proto::CommandSuccess* success); + + // optional .pulsar.proto.CommandError error = 14; + inline bool has_error() const; + inline void clear_error(); + static const int kErrorFieldNumber = 14; + inline const ::pulsar::proto::CommandError& error() const; + inline ::pulsar::proto::CommandError* mutable_error(); + inline ::pulsar::proto::CommandError* release_error(); + inline void set_allocated_error(::pulsar::proto::CommandError* error); + + // optional .pulsar.proto.CommandCloseProducer close_producer = 15; + inline bool has_close_producer() const; + inline void clear_close_producer(); + static const int kCloseProducerFieldNumber = 15; + inline const ::pulsar::proto::CommandCloseProducer& close_producer() const; + inline ::pulsar::proto::CommandCloseProducer* mutable_close_producer(); + inline ::pulsar::proto::CommandCloseProducer* release_close_producer(); + inline void set_allocated_close_producer(::pulsar::proto::CommandCloseProducer* close_producer); + + // optional .pulsar.proto.CommandCloseConsumer close_consumer = 16; + inline bool has_close_consumer() const; + inline void clear_close_consumer(); + static const int kCloseConsumerFieldNumber = 16; + inline const ::pulsar::proto::CommandCloseConsumer& close_consumer() const; + inline ::pulsar::proto::CommandCloseConsumer* mutable_close_consumer(); + inline ::pulsar::proto::CommandCloseConsumer* release_close_consumer(); + inline void set_allocated_close_consumer(::pulsar::proto::CommandCloseConsumer* close_consumer); + + // optional .pulsar.proto.CommandProducerSuccess producer_success = 17; + inline bool has_producer_success() const; + inline void clear_producer_success(); + static const int kProducerSuccessFieldNumber = 17; + inline const ::pulsar::proto::CommandProducerSuccess& producer_success() const; + inline ::pulsar::proto::CommandProducerSuccess* mutable_producer_success(); + inline ::pulsar::proto::CommandProducerSuccess* release_producer_success(); + inline void set_allocated_producer_success(::pulsar::proto::CommandProducerSuccess* producer_success); + + // optional .pulsar.proto.CommandPing ping = 18; + inline bool has_ping() const; + inline void clear_ping(); + static const int kPingFieldNumber = 18; + inline const ::pulsar::proto::CommandPing& ping() const; + inline ::pulsar::proto::CommandPing* mutable_ping(); + inline ::pulsar::proto::CommandPing* release_ping(); + inline void set_allocated_ping(::pulsar::proto::CommandPing* ping); + + // optional .pulsar.proto.CommandPong pong = 19; + inline bool has_pong() const; + inline void clear_pong(); + static const int kPongFieldNumber = 19; + inline const ::pulsar::proto::CommandPong& pong() const; + inline ::pulsar::proto::CommandPong* mutable_pong(); + inline ::pulsar::proto::CommandPong* release_pong(); + inline void set_allocated_pong(::pulsar::proto::CommandPong* pong); + + // optional .pulsar.proto.CommandRedeliverUnacknowledgedMessages redeliverUnacknowledgedMessages = 20; + inline bool has_redeliverunacknowledgedmessages() const; + inline void clear_redeliverunacknowledgedmessages(); + static const int kRedeliverUnacknowledgedMessagesFieldNumber = 20; + inline const ::pulsar::proto::CommandRedeliverUnacknowledgedMessages& redeliverunacknowledgedmessages() const; + inline ::pulsar::proto::CommandRedeliverUnacknowledgedMessages* mutable_redeliverunacknowledgedmessages(); + inline ::pulsar::proto::CommandRedeliverUnacknowledgedMessages* release_redeliverunacknowledgedmessages(); + inline void set_allocated_redeliverunacknowledgedmessages(::pulsar::proto::CommandRedeliverUnacknowledgedMessages* redeliverunacknowledgedmessages); + + // optional .pulsar.proto.CommandPartitionedTopicMetadata partitionMetadata = 21; + inline bool has_partitionmetadata() const; + inline void clear_partitionmetadata(); + static const int kPartitionMetadataFieldNumber = 21; + inline const ::pulsar::proto::CommandPartitionedTopicMetadata& partitionmetadata() const; + inline ::pulsar::proto::CommandPartitionedTopicMetadata* mutable_partitionmetadata(); + inline ::pulsar::proto::CommandPartitionedTopicMetadata* release_partitionmetadata(); + inline void set_allocated_partitionmetadata(::pulsar::proto::CommandPartitionedTopicMetadata* partitionmetadata); + + // optional .pulsar.proto.CommandPartitionedTopicMetadataResponse partitionMetadataResponse = 22; + inline bool has_partitionmetadataresponse() const; + inline void clear_partitionmetadataresponse(); + static const int kPartitionMetadataResponseFieldNumber = 22; + inline const ::pulsar::proto::CommandPartitionedTopicMetadataResponse& partitionmetadataresponse() const; + inline ::pulsar::proto::CommandPartitionedTopicMetadataResponse* mutable_partitionmetadataresponse(); + inline ::pulsar::proto::CommandPartitionedTopicMetadataResponse* release_partitionmetadataresponse(); + inline void set_allocated_partitionmetadataresponse(::pulsar::proto::CommandPartitionedTopicMetadataResponse* partitionmetadataresponse); + + // optional .pulsar.proto.CommandLookupTopic lookupTopic = 23; + inline bool has_lookuptopic() const; + inline void clear_lookuptopic(); + static const int kLookupTopicFieldNumber = 23; + inline const ::pulsar::proto::CommandLookupTopic& lookuptopic() const; + inline ::pulsar::proto::CommandLookupTopic* mutable_lookuptopic(); + inline ::pulsar::proto::CommandLookupTopic* release_lookuptopic(); + inline void set_allocated_lookuptopic(::pulsar::proto::CommandLookupTopic* lookuptopic); + + // optional .pulsar.proto.CommandLookupTopicResponse lookupTopicResponse = 24; + inline bool has_lookuptopicresponse() const; + inline void clear_lookuptopicresponse(); + static const int kLookupTopicResponseFieldNumber = 24; + inline const ::pulsar::proto::CommandLookupTopicResponse& lookuptopicresponse() const; + inline ::pulsar::proto::CommandLookupTopicResponse* mutable_lookuptopicresponse(); + inline ::pulsar::proto::CommandLookupTopicResponse* release_lookuptopicresponse(); + inline void set_allocated_lookuptopicresponse(::pulsar::proto::CommandLookupTopicResponse* lookuptopicresponse); + + // @@protoc_insertion_point(class_scope:pulsar.proto.BaseCommand) + private: + inline void set_has_type(); + inline void clear_has_type(); + inline void set_has_connect(); + inline void clear_has_connect(); + inline void set_has_connected(); + inline void clear_has_connected(); + inline void set_has_subscribe(); + inline void clear_has_subscribe(); + inline void set_has_producer(); + inline void clear_has_producer(); + inline void set_has_send(); + inline void clear_has_send(); + inline void set_has_send_receipt(); + inline void clear_has_send_receipt(); + inline void set_has_send_error(); + inline void clear_has_send_error(); + inline void set_has_message(); + inline void clear_has_message(); + inline void set_has_ack(); + inline void clear_has_ack(); + inline void set_has_flow(); + inline void clear_has_flow(); + inline void set_has_unsubscribe(); + inline void clear_has_unsubscribe(); + inline void set_has_success(); + inline void clear_has_success(); + inline void set_has_error(); + inline void clear_has_error(); + inline void set_has_close_producer(); + inline void clear_has_close_producer(); + inline void set_has_close_consumer(); + inline void clear_has_close_consumer(); + inline void set_has_producer_success(); + inline void clear_has_producer_success(); + inline void set_has_ping(); + inline void clear_has_ping(); + inline void set_has_pong(); + inline void clear_has_pong(); + inline void set_has_redeliverunacknowledgedmessages(); + inline void clear_has_redeliverunacknowledgedmessages(); + inline void set_has_partitionmetadata(); + inline void clear_has_partitionmetadata(); + inline void set_has_partitionmetadataresponse(); + inline void clear_has_partitionmetadataresponse(); + inline void set_has_lookuptopic(); + inline void clear_has_lookuptopic(); + inline void set_has_lookuptopicresponse(); + inline void clear_has_lookuptopicresponse(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::pulsar::proto::CommandConnect* connect_; + ::pulsar::proto::CommandConnected* connected_; + ::pulsar::proto::CommandSubscribe* subscribe_; + ::pulsar::proto::CommandProducer* producer_; + ::pulsar::proto::CommandSend* send_; + ::pulsar::proto::CommandSendReceipt* send_receipt_; + ::pulsar::proto::CommandSendError* send_error_; + ::pulsar::proto::CommandMessage* message_; + ::pulsar::proto::CommandAck* ack_; + ::pulsar::proto::CommandFlow* flow_; + ::pulsar::proto::CommandUnsubscribe* unsubscribe_; + ::pulsar::proto::CommandSuccess* success_; + ::pulsar::proto::CommandError* error_; + ::pulsar::proto::CommandCloseProducer* close_producer_; + ::pulsar::proto::CommandCloseConsumer* close_consumer_; + ::pulsar::proto::CommandProducerSuccess* producer_success_; + ::pulsar::proto::CommandPing* ping_; + ::pulsar::proto::CommandPong* pong_; + ::pulsar::proto::CommandRedeliverUnacknowledgedMessages* redeliverunacknowledgedmessages_; + ::pulsar::proto::CommandPartitionedTopicMetadata* partitionmetadata_; + ::pulsar::proto::CommandPartitionedTopicMetadataResponse* partitionmetadataresponse_; + ::pulsar::proto::CommandLookupTopic* lookuptopic_; + ::pulsar::proto::CommandLookupTopicResponse* lookuptopicresponse_; + int type_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_PulsarApi_2eproto_impl(); + #else + friend void protobuf_AddDesc_PulsarApi_2eproto(); + #endif + friend void protobuf_AssignDesc_PulsarApi_2eproto(); + friend void protobuf_ShutdownFile_PulsarApi_2eproto(); + + void InitAsDefaultInstance(); + static BaseCommand* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// MessageIdData + +// required uint64 ledgerId = 1; +inline bool MessageIdData::has_ledgerid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MessageIdData::set_has_ledgerid() { + _has_bits_[0] |= 0x00000001u; +} +inline void MessageIdData::clear_has_ledgerid() { + _has_bits_[0] &= ~0x00000001u; +} +inline void MessageIdData::clear_ledgerid() { + ledgerid_ = GOOGLE_ULONGLONG(0); + clear_has_ledgerid(); +} +inline ::google::protobuf::uint64 MessageIdData::ledgerid() const { + // @@protoc_insertion_point(field_get:pulsar.proto.MessageIdData.ledgerId) + return ledgerid_; +} +inline void MessageIdData::set_ledgerid(::google::protobuf::uint64 value) { + set_has_ledgerid(); + ledgerid_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.MessageIdData.ledgerId) +} + +// required uint64 entryId = 2; +inline bool MessageIdData::has_entryid() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void MessageIdData::set_has_entryid() { + _has_bits_[0] |= 0x00000002u; +} +inline void MessageIdData::clear_has_entryid() { + _has_bits_[0] &= ~0x00000002u; +} +inline void MessageIdData::clear_entryid() { + entryid_ = GOOGLE_ULONGLONG(0); + clear_has_entryid(); +} +inline ::google::protobuf::uint64 MessageIdData::entryid() const { + // @@protoc_insertion_point(field_get:pulsar.proto.MessageIdData.entryId) + return entryid_; +} +inline void MessageIdData::set_entryid(::google::protobuf::uint64 value) { + set_has_entryid(); + entryid_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.MessageIdData.entryId) +} + +// optional int32 partition = 3 [default = -1]; +inline bool MessageIdData::has_partition() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void MessageIdData::set_has_partition() { + _has_bits_[0] |= 0x00000004u; +} +inline void MessageIdData::clear_has_partition() { + _has_bits_[0] &= ~0x00000004u; +} +inline void MessageIdData::clear_partition() { + partition_ = -1; + clear_has_partition(); +} +inline ::google::protobuf::int32 MessageIdData::partition() const { + // @@protoc_insertion_point(field_get:pulsar.proto.MessageIdData.partition) + return partition_; +} +inline void MessageIdData::set_partition(::google::protobuf::int32 value) { + set_has_partition(); + partition_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.MessageIdData.partition) +} + +// optional int32 batch_index = 4 [default = -1]; +inline bool MessageIdData::has_batch_index() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void MessageIdData::set_has_batch_index() { + _has_bits_[0] |= 0x00000008u; +} +inline void MessageIdData::clear_has_batch_index() { + _has_bits_[0] &= ~0x00000008u; +} +inline void MessageIdData::clear_batch_index() { + batch_index_ = -1; + clear_has_batch_index(); +} +inline ::google::protobuf::int32 MessageIdData::batch_index() const { + // @@protoc_insertion_point(field_get:pulsar.proto.MessageIdData.batch_index) + return batch_index_; +} +inline void MessageIdData::set_batch_index(::google::protobuf::int32 value) { + set_has_batch_index(); + batch_index_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.MessageIdData.batch_index) +} + +// ------------------------------------------------------------------- + +// KeyValue + +// required string key = 1; +inline bool KeyValue::has_key() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void KeyValue::set_has_key() { + _has_bits_[0] |= 0x00000001u; +} +inline void KeyValue::clear_has_key() { + _has_bits_[0] &= ~0x00000001u; +} +inline void KeyValue::clear_key() { + if (key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + key_->clear(); + } + clear_has_key(); +} +inline const ::std::string& KeyValue::key() const { + // @@protoc_insertion_point(field_get:pulsar.proto.KeyValue.key) + return *key_; +} +inline void KeyValue::set_key(const ::std::string& value) { + set_has_key(); + if (key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + key_ = new ::std::string; + } + key_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.KeyValue.key) +} +inline void KeyValue::set_key(const char* value) { + set_has_key(); + if (key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + key_ = new ::std::string; + } + key_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.KeyValue.key) +} +inline void KeyValue::set_key(const char* value, size_t size) { + set_has_key(); + if (key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + key_ = new ::std::string; + } + key_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.KeyValue.key) +} +inline ::std::string* KeyValue::mutable_key() { + set_has_key(); + if (key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + key_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.KeyValue.key) + return key_; +} +inline ::std::string* KeyValue::release_key() { + clear_has_key(); + if (key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = key_; + key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void KeyValue::set_allocated_key(::std::string* key) { + if (key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete key_; + } + if (key) { + set_has_key(); + key_ = key; + } else { + clear_has_key(); + key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.KeyValue.key) +} + +// required string value = 2; +inline bool KeyValue::has_value() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void KeyValue::set_has_value() { + _has_bits_[0] |= 0x00000002u; +} +inline void KeyValue::clear_has_value() { + _has_bits_[0] &= ~0x00000002u; +} +inline void KeyValue::clear_value() { + if (value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + value_->clear(); + } + clear_has_value(); +} +inline const ::std::string& KeyValue::value() const { + // @@protoc_insertion_point(field_get:pulsar.proto.KeyValue.value) + return *value_; +} +inline void KeyValue::set_value(const ::std::string& value) { + set_has_value(); + if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + value_ = new ::std::string; + } + value_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.KeyValue.value) +} +inline void KeyValue::set_value(const char* value) { + set_has_value(); + if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + value_ = new ::std::string; + } + value_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.KeyValue.value) +} +inline void KeyValue::set_value(const char* value, size_t size) { + set_has_value(); + if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + value_ = new ::std::string; + } + value_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.KeyValue.value) +} +inline ::std::string* KeyValue::mutable_value() { + set_has_value(); + if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + value_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.KeyValue.value) + return value_; +} +inline ::std::string* KeyValue::release_value() { + clear_has_value(); + if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = value_; + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void KeyValue::set_allocated_value(::std::string* value) { + if (value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete value_; + } + if (value) { + set_has_value(); + value_ = value; + } else { + clear_has_value(); + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.KeyValue.value) +} + +// ------------------------------------------------------------------- + +// MessageMetadata + +// required string producer_name = 1; +inline bool MessageMetadata::has_producer_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MessageMetadata::set_has_producer_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void MessageMetadata::clear_has_producer_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void MessageMetadata::clear_producer_name() { + if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_->clear(); + } + clear_has_producer_name(); +} +inline const ::std::string& MessageMetadata::producer_name() const { + // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.producer_name) + return *producer_name_; +} +inline void MessageMetadata::set_producer_name(const ::std::string& value) { + set_has_producer_name(); + if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_ = new ::std::string; + } + producer_name_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.producer_name) +} +inline void MessageMetadata::set_producer_name(const char* value) { + set_has_producer_name(); + if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_ = new ::std::string; + } + producer_name_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.MessageMetadata.producer_name) +} +inline void MessageMetadata::set_producer_name(const char* value, size_t size) { + set_has_producer_name(); + if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_ = new ::std::string; + } + producer_name_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.MessageMetadata.producer_name) +} +inline ::std::string* MessageMetadata::mutable_producer_name() { + set_has_producer_name(); + if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.MessageMetadata.producer_name) + return producer_name_; +} +inline ::std::string* MessageMetadata::release_producer_name() { + clear_has_producer_name(); + if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = producer_name_; + producer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void MessageMetadata::set_allocated_producer_name(::std::string* producer_name) { + if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete producer_name_; + } + if (producer_name) { + set_has_producer_name(); + producer_name_ = producer_name; + } else { + clear_has_producer_name(); + producer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.MessageMetadata.producer_name) +} + +// required uint64 sequence_id = 2; +inline bool MessageMetadata::has_sequence_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void MessageMetadata::set_has_sequence_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void MessageMetadata::clear_has_sequence_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void MessageMetadata::clear_sequence_id() { + sequence_id_ = GOOGLE_ULONGLONG(0); + clear_has_sequence_id(); +} +inline ::google::protobuf::uint64 MessageMetadata::sequence_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.sequence_id) + return sequence_id_; +} +inline void MessageMetadata::set_sequence_id(::google::protobuf::uint64 value) { + set_has_sequence_id(); + sequence_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.sequence_id) +} + +// required uint64 publish_time = 3; +inline bool MessageMetadata::has_publish_time() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void MessageMetadata::set_has_publish_time() { + _has_bits_[0] |= 0x00000004u; +} +inline void MessageMetadata::clear_has_publish_time() { + _has_bits_[0] &= ~0x00000004u; +} +inline void MessageMetadata::clear_publish_time() { + publish_time_ = GOOGLE_ULONGLONG(0); + clear_has_publish_time(); +} +inline ::google::protobuf::uint64 MessageMetadata::publish_time() const { + // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.publish_time) + return publish_time_; +} +inline void MessageMetadata::set_publish_time(::google::protobuf::uint64 value) { + set_has_publish_time(); + publish_time_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.publish_time) +} + +// repeated .pulsar.proto.KeyValue properties = 4; +inline int MessageMetadata::properties_size() const { + return properties_.size(); +} +inline void MessageMetadata::clear_properties() { + properties_.Clear(); +} +inline const ::pulsar::proto::KeyValue& MessageMetadata::properties(int index) const { + // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.properties) + return properties_.Get(index); +} +inline ::pulsar::proto::KeyValue* MessageMetadata::mutable_properties(int index) { + // @@protoc_insertion_point(field_mutable:pulsar.proto.MessageMetadata.properties) + return properties_.Mutable(index); +} +inline ::pulsar::proto::KeyValue* MessageMetadata::add_properties() { + // @@protoc_insertion_point(field_add:pulsar.proto.MessageMetadata.properties) + return properties_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue >& +MessageMetadata::properties() const { + // @@protoc_insertion_point(field_list:pulsar.proto.MessageMetadata.properties) + return properties_; +} +inline ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue >* +MessageMetadata::mutable_properties() { + // @@protoc_insertion_point(field_mutable_list:pulsar.proto.MessageMetadata.properties) + return &properties_; +} + +// optional string replicated_from = 5; +inline bool MessageMetadata::has_replicated_from() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void MessageMetadata::set_has_replicated_from() { + _has_bits_[0] |= 0x00000010u; +} +inline void MessageMetadata::clear_has_replicated_from() { + _has_bits_[0] &= ~0x00000010u; +} +inline void MessageMetadata::clear_replicated_from() { + if (replicated_from_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + replicated_from_->clear(); + } + clear_has_replicated_from(); +} +inline const ::std::string& MessageMetadata::replicated_from() const { + // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.replicated_from) + return *replicated_from_; +} +inline void MessageMetadata::set_replicated_from(const ::std::string& value) { + set_has_replicated_from(); + if (replicated_from_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + replicated_from_ = new ::std::string; + } + replicated_from_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.replicated_from) +} +inline void MessageMetadata::set_replicated_from(const char* value) { + set_has_replicated_from(); + if (replicated_from_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + replicated_from_ = new ::std::string; + } + replicated_from_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.MessageMetadata.replicated_from) +} +inline void MessageMetadata::set_replicated_from(const char* value, size_t size) { + set_has_replicated_from(); + if (replicated_from_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + replicated_from_ = new ::std::string; + } + replicated_from_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.MessageMetadata.replicated_from) +} +inline ::std::string* MessageMetadata::mutable_replicated_from() { + set_has_replicated_from(); + if (replicated_from_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + replicated_from_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.MessageMetadata.replicated_from) + return replicated_from_; +} +inline ::std::string* MessageMetadata::release_replicated_from() { + clear_has_replicated_from(); + if (replicated_from_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = replicated_from_; + replicated_from_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void MessageMetadata::set_allocated_replicated_from(::std::string* replicated_from) { + if (replicated_from_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete replicated_from_; + } + if (replicated_from) { + set_has_replicated_from(); + replicated_from_ = replicated_from; + } else { + clear_has_replicated_from(); + replicated_from_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.MessageMetadata.replicated_from) +} + +// optional string partition_key = 6; +inline bool MessageMetadata::has_partition_key() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void MessageMetadata::set_has_partition_key() { + _has_bits_[0] |= 0x00000020u; +} +inline void MessageMetadata::clear_has_partition_key() { + _has_bits_[0] &= ~0x00000020u; +} +inline void MessageMetadata::clear_partition_key() { + if (partition_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + partition_key_->clear(); + } + clear_has_partition_key(); +} +inline const ::std::string& MessageMetadata::partition_key() const { + // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.partition_key) + return *partition_key_; +} +inline void MessageMetadata::set_partition_key(const ::std::string& value) { + set_has_partition_key(); + if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + partition_key_ = new ::std::string; + } + partition_key_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.partition_key) +} +inline void MessageMetadata::set_partition_key(const char* value) { + set_has_partition_key(); + if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + partition_key_ = new ::std::string; + } + partition_key_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.MessageMetadata.partition_key) +} +inline void MessageMetadata::set_partition_key(const char* value, size_t size) { + set_has_partition_key(); + if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + partition_key_ = new ::std::string; + } + partition_key_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.MessageMetadata.partition_key) +} +inline ::std::string* MessageMetadata::mutable_partition_key() { + set_has_partition_key(); + if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + partition_key_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.MessageMetadata.partition_key) + return partition_key_; +} +inline ::std::string* MessageMetadata::release_partition_key() { + clear_has_partition_key(); + if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = partition_key_; + partition_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void MessageMetadata::set_allocated_partition_key(::std::string* partition_key) { + if (partition_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete partition_key_; + } + if (partition_key) { + set_has_partition_key(); + partition_key_ = partition_key; + } else { + clear_has_partition_key(); + partition_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.MessageMetadata.partition_key) +} + +// repeated string replicate_to = 7; +inline int MessageMetadata::replicate_to_size() const { + return replicate_to_.size(); +} +inline void MessageMetadata::clear_replicate_to() { + replicate_to_.Clear(); +} +inline const ::std::string& MessageMetadata::replicate_to(int index) const { + // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.replicate_to) + return replicate_to_.Get(index); +} +inline ::std::string* MessageMetadata::mutable_replicate_to(int index) { + // @@protoc_insertion_point(field_mutable:pulsar.proto.MessageMetadata.replicate_to) + return replicate_to_.Mutable(index); +} +inline void MessageMetadata::set_replicate_to(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.replicate_to) + replicate_to_.Mutable(index)->assign(value); +} +inline void MessageMetadata::set_replicate_to(int index, const char* value) { + replicate_to_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.MessageMetadata.replicate_to) +} +inline void MessageMetadata::set_replicate_to(int index, const char* value, size_t size) { + replicate_to_.Mutable(index)->assign( + reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.MessageMetadata.replicate_to) +} +inline ::std::string* MessageMetadata::add_replicate_to() { + return replicate_to_.Add(); +} +inline void MessageMetadata::add_replicate_to(const ::std::string& value) { + replicate_to_.Add()->assign(value); + // @@protoc_insertion_point(field_add:pulsar.proto.MessageMetadata.replicate_to) +} +inline void MessageMetadata::add_replicate_to(const char* value) { + replicate_to_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:pulsar.proto.MessageMetadata.replicate_to) +} +inline void MessageMetadata::add_replicate_to(const char* value, size_t size) { + replicate_to_.Add()->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_add_pointer:pulsar.proto.MessageMetadata.replicate_to) +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +MessageMetadata::replicate_to() const { + // @@protoc_insertion_point(field_list:pulsar.proto.MessageMetadata.replicate_to) + return replicate_to_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +MessageMetadata::mutable_replicate_to() { + // @@protoc_insertion_point(field_mutable_list:pulsar.proto.MessageMetadata.replicate_to) + return &replicate_to_; +} + +// optional .pulsar.proto.CompressionType compression = 8 [default = NONE]; +inline bool MessageMetadata::has_compression() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void MessageMetadata::set_has_compression() { + _has_bits_[0] |= 0x00000080u; +} +inline void MessageMetadata::clear_has_compression() { + _has_bits_[0] &= ~0x00000080u; +} +inline void MessageMetadata::clear_compression() { + compression_ = 0; + clear_has_compression(); +} +inline ::pulsar::proto::CompressionType MessageMetadata::compression() const { + // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.compression) + return static_cast< ::pulsar::proto::CompressionType >(compression_); +} +inline void MessageMetadata::set_compression(::pulsar::proto::CompressionType value) { + assert(::pulsar::proto::CompressionType_IsValid(value)); + set_has_compression(); + compression_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.compression) +} + +// optional uint32 uncompressed_size = 9 [default = 0]; +inline bool MessageMetadata::has_uncompressed_size() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void MessageMetadata::set_has_uncompressed_size() { + _has_bits_[0] |= 0x00000100u; +} +inline void MessageMetadata::clear_has_uncompressed_size() { + _has_bits_[0] &= ~0x00000100u; +} +inline void MessageMetadata::clear_uncompressed_size() { + uncompressed_size_ = 0u; + clear_has_uncompressed_size(); +} +inline ::google::protobuf::uint32 MessageMetadata::uncompressed_size() const { + // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.uncompressed_size) + return uncompressed_size_; +} +inline void MessageMetadata::set_uncompressed_size(::google::protobuf::uint32 value) { + set_has_uncompressed_size(); + uncompressed_size_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.uncompressed_size) +} + +// optional int32 num_messages_in_batch = 11 [default = 1]; +inline bool MessageMetadata::has_num_messages_in_batch() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +inline void MessageMetadata::set_has_num_messages_in_batch() { + _has_bits_[0] |= 0x00000200u; +} +inline void MessageMetadata::clear_has_num_messages_in_batch() { + _has_bits_[0] &= ~0x00000200u; +} +inline void MessageMetadata::clear_num_messages_in_batch() { + num_messages_in_batch_ = 1; + clear_has_num_messages_in_batch(); +} +inline ::google::protobuf::int32 MessageMetadata::num_messages_in_batch() const { + // @@protoc_insertion_point(field_get:pulsar.proto.MessageMetadata.num_messages_in_batch) + return num_messages_in_batch_; +} +inline void MessageMetadata::set_num_messages_in_batch(::google::protobuf::int32 value) { + set_has_num_messages_in_batch(); + num_messages_in_batch_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.MessageMetadata.num_messages_in_batch) +} + +// ------------------------------------------------------------------- + +// SingleMessageMetadata + +// repeated .pulsar.proto.KeyValue properties = 1; +inline int SingleMessageMetadata::properties_size() const { + return properties_.size(); +} +inline void SingleMessageMetadata::clear_properties() { + properties_.Clear(); +} +inline const ::pulsar::proto::KeyValue& SingleMessageMetadata::properties(int index) const { + // @@protoc_insertion_point(field_get:pulsar.proto.SingleMessageMetadata.properties) + return properties_.Get(index); +} +inline ::pulsar::proto::KeyValue* SingleMessageMetadata::mutable_properties(int index) { + // @@protoc_insertion_point(field_mutable:pulsar.proto.SingleMessageMetadata.properties) + return properties_.Mutable(index); +} +inline ::pulsar::proto::KeyValue* SingleMessageMetadata::add_properties() { + // @@protoc_insertion_point(field_add:pulsar.proto.SingleMessageMetadata.properties) + return properties_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue >& +SingleMessageMetadata::properties() const { + // @@protoc_insertion_point(field_list:pulsar.proto.SingleMessageMetadata.properties) + return properties_; +} +inline ::google::protobuf::RepeatedPtrField< ::pulsar::proto::KeyValue >* +SingleMessageMetadata::mutable_properties() { + // @@protoc_insertion_point(field_mutable_list:pulsar.proto.SingleMessageMetadata.properties) + return &properties_; +} + +// optional string partition_key = 2; +inline bool SingleMessageMetadata::has_partition_key() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void SingleMessageMetadata::set_has_partition_key() { + _has_bits_[0] |= 0x00000002u; +} +inline void SingleMessageMetadata::clear_has_partition_key() { + _has_bits_[0] &= ~0x00000002u; +} +inline void SingleMessageMetadata::clear_partition_key() { + if (partition_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + partition_key_->clear(); + } + clear_has_partition_key(); +} +inline const ::std::string& SingleMessageMetadata::partition_key() const { + // @@protoc_insertion_point(field_get:pulsar.proto.SingleMessageMetadata.partition_key) + return *partition_key_; +} +inline void SingleMessageMetadata::set_partition_key(const ::std::string& value) { + set_has_partition_key(); + if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + partition_key_ = new ::std::string; + } + partition_key_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.SingleMessageMetadata.partition_key) +} +inline void SingleMessageMetadata::set_partition_key(const char* value) { + set_has_partition_key(); + if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + partition_key_ = new ::std::string; + } + partition_key_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.SingleMessageMetadata.partition_key) +} +inline void SingleMessageMetadata::set_partition_key(const char* value, size_t size) { + set_has_partition_key(); + if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + partition_key_ = new ::std::string; + } + partition_key_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.SingleMessageMetadata.partition_key) +} +inline ::std::string* SingleMessageMetadata::mutable_partition_key() { + set_has_partition_key(); + if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + partition_key_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.SingleMessageMetadata.partition_key) + return partition_key_; +} +inline ::std::string* SingleMessageMetadata::release_partition_key() { + clear_has_partition_key(); + if (partition_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = partition_key_; + partition_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void SingleMessageMetadata::set_allocated_partition_key(::std::string* partition_key) { + if (partition_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete partition_key_; + } + if (partition_key) { + set_has_partition_key(); + partition_key_ = partition_key; + } else { + clear_has_partition_key(); + partition_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.SingleMessageMetadata.partition_key) +} + +// required int32 payload_size = 3; +inline bool SingleMessageMetadata::has_payload_size() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void SingleMessageMetadata::set_has_payload_size() { + _has_bits_[0] |= 0x00000004u; +} +inline void SingleMessageMetadata::clear_has_payload_size() { + _has_bits_[0] &= ~0x00000004u; +} +inline void SingleMessageMetadata::clear_payload_size() { + payload_size_ = 0; + clear_has_payload_size(); +} +inline ::google::protobuf::int32 SingleMessageMetadata::payload_size() const { + // @@protoc_insertion_point(field_get:pulsar.proto.SingleMessageMetadata.payload_size) + return payload_size_; +} +inline void SingleMessageMetadata::set_payload_size(::google::protobuf::int32 value) { + set_has_payload_size(); + payload_size_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.SingleMessageMetadata.payload_size) +} + +// ------------------------------------------------------------------- + +// CommandConnect + +// required string client_version = 1; +inline bool CommandConnect::has_client_version() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandConnect::set_has_client_version() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandConnect::clear_has_client_version() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandConnect::clear_client_version() { + if (client_version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + client_version_->clear(); + } + clear_has_client_version(); +} +inline const ::std::string& CommandConnect::client_version() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandConnect.client_version) + return *client_version_; +} +inline void CommandConnect::set_client_version(const ::std::string& value) { + set_has_client_version(); + if (client_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + client_version_ = new ::std::string; + } + client_version_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandConnect.client_version) +} +inline void CommandConnect::set_client_version(const char* value) { + set_has_client_version(); + if (client_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + client_version_ = new ::std::string; + } + client_version_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandConnect.client_version) +} +inline void CommandConnect::set_client_version(const char* value, size_t size) { + set_has_client_version(); + if (client_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + client_version_ = new ::std::string; + } + client_version_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandConnect.client_version) +} +inline ::std::string* CommandConnect::mutable_client_version() { + set_has_client_version(); + if (client_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + client_version_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandConnect.client_version) + return client_version_; +} +inline ::std::string* CommandConnect::release_client_version() { + clear_has_client_version(); + if (client_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = client_version_; + client_version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandConnect::set_allocated_client_version(::std::string* client_version) { + if (client_version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete client_version_; + } + if (client_version) { + set_has_client_version(); + client_version_ = client_version; + } else { + clear_has_client_version(); + client_version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandConnect.client_version) +} + +// optional .pulsar.proto.AuthMethod auth_method = 2; +inline bool CommandConnect::has_auth_method() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandConnect::set_has_auth_method() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandConnect::clear_has_auth_method() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandConnect::clear_auth_method() { + auth_method_ = 0; + clear_has_auth_method(); +} +inline ::pulsar::proto::AuthMethod CommandConnect::auth_method() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandConnect.auth_method) + return static_cast< ::pulsar::proto::AuthMethod >(auth_method_); +} +inline void CommandConnect::set_auth_method(::pulsar::proto::AuthMethod value) { + assert(::pulsar::proto::AuthMethod_IsValid(value)); + set_has_auth_method(); + auth_method_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandConnect.auth_method) +} + +// optional string auth_method_name = 5; +inline bool CommandConnect::has_auth_method_name() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void CommandConnect::set_has_auth_method_name() { + _has_bits_[0] |= 0x00000004u; +} +inline void CommandConnect::clear_has_auth_method_name() { + _has_bits_[0] &= ~0x00000004u; +} +inline void CommandConnect::clear_auth_method_name() { + if (auth_method_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + auth_method_name_->clear(); + } + clear_has_auth_method_name(); +} +inline const ::std::string& CommandConnect::auth_method_name() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandConnect.auth_method_name) + return *auth_method_name_; +} +inline void CommandConnect::set_auth_method_name(const ::std::string& value) { + set_has_auth_method_name(); + if (auth_method_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + auth_method_name_ = new ::std::string; + } + auth_method_name_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandConnect.auth_method_name) +} +inline void CommandConnect::set_auth_method_name(const char* value) { + set_has_auth_method_name(); + if (auth_method_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + auth_method_name_ = new ::std::string; + } + auth_method_name_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandConnect.auth_method_name) +} +inline void CommandConnect::set_auth_method_name(const char* value, size_t size) { + set_has_auth_method_name(); + if (auth_method_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + auth_method_name_ = new ::std::string; + } + auth_method_name_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandConnect.auth_method_name) +} +inline ::std::string* CommandConnect::mutable_auth_method_name() { + set_has_auth_method_name(); + if (auth_method_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + auth_method_name_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandConnect.auth_method_name) + return auth_method_name_; +} +inline ::std::string* CommandConnect::release_auth_method_name() { + clear_has_auth_method_name(); + if (auth_method_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = auth_method_name_; + auth_method_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandConnect::set_allocated_auth_method_name(::std::string* auth_method_name) { + if (auth_method_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete auth_method_name_; + } + if (auth_method_name) { + set_has_auth_method_name(); + auth_method_name_ = auth_method_name; + } else { + clear_has_auth_method_name(); + auth_method_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandConnect.auth_method_name) +} + +// optional bytes auth_data = 3; +inline bool CommandConnect::has_auth_data() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void CommandConnect::set_has_auth_data() { + _has_bits_[0] |= 0x00000008u; +} +inline void CommandConnect::clear_has_auth_data() { + _has_bits_[0] &= ~0x00000008u; +} +inline void CommandConnect::clear_auth_data() { + if (auth_data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + auth_data_->clear(); + } + clear_has_auth_data(); +} +inline const ::std::string& CommandConnect::auth_data() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandConnect.auth_data) + return *auth_data_; +} +inline void CommandConnect::set_auth_data(const ::std::string& value) { + set_has_auth_data(); + if (auth_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + auth_data_ = new ::std::string; + } + auth_data_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandConnect.auth_data) +} +inline void CommandConnect::set_auth_data(const char* value) { + set_has_auth_data(); + if (auth_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + auth_data_ = new ::std::string; + } + auth_data_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandConnect.auth_data) +} +inline void CommandConnect::set_auth_data(const void* value, size_t size) { + set_has_auth_data(); + if (auth_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + auth_data_ = new ::std::string; + } + auth_data_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandConnect.auth_data) +} +inline ::std::string* CommandConnect::mutable_auth_data() { + set_has_auth_data(); + if (auth_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + auth_data_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandConnect.auth_data) + return auth_data_; +} +inline ::std::string* CommandConnect::release_auth_data() { + clear_has_auth_data(); + if (auth_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = auth_data_; + auth_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandConnect::set_allocated_auth_data(::std::string* auth_data) { + if (auth_data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete auth_data_; + } + if (auth_data) { + set_has_auth_data(); + auth_data_ = auth_data; + } else { + clear_has_auth_data(); + auth_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandConnect.auth_data) +} + +// optional int32 protocol_version = 4 [default = 0]; +inline bool CommandConnect::has_protocol_version() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void CommandConnect::set_has_protocol_version() { + _has_bits_[0] |= 0x00000010u; +} +inline void CommandConnect::clear_has_protocol_version() { + _has_bits_[0] &= ~0x00000010u; +} +inline void CommandConnect::clear_protocol_version() { + protocol_version_ = 0; + clear_has_protocol_version(); +} +inline ::google::protobuf::int32 CommandConnect::protocol_version() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandConnect.protocol_version) + return protocol_version_; +} +inline void CommandConnect::set_protocol_version(::google::protobuf::int32 value) { + set_has_protocol_version(); + protocol_version_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandConnect.protocol_version) +} + +// ------------------------------------------------------------------- + +// CommandConnected + +// required string server_version = 1; +inline bool CommandConnected::has_server_version() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandConnected::set_has_server_version() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandConnected::clear_has_server_version() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandConnected::clear_server_version() { + if (server_version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + server_version_->clear(); + } + clear_has_server_version(); +} +inline const ::std::string& CommandConnected::server_version() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandConnected.server_version) + return *server_version_; +} +inline void CommandConnected::set_server_version(const ::std::string& value) { + set_has_server_version(); + if (server_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + server_version_ = new ::std::string; + } + server_version_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandConnected.server_version) +} +inline void CommandConnected::set_server_version(const char* value) { + set_has_server_version(); + if (server_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + server_version_ = new ::std::string; + } + server_version_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandConnected.server_version) +} +inline void CommandConnected::set_server_version(const char* value, size_t size) { + set_has_server_version(); + if (server_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + server_version_ = new ::std::string; + } + server_version_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandConnected.server_version) +} +inline ::std::string* CommandConnected::mutable_server_version() { + set_has_server_version(); + if (server_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + server_version_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandConnected.server_version) + return server_version_; +} +inline ::std::string* CommandConnected::release_server_version() { + clear_has_server_version(); + if (server_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = server_version_; + server_version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandConnected::set_allocated_server_version(::std::string* server_version) { + if (server_version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete server_version_; + } + if (server_version) { + set_has_server_version(); + server_version_ = server_version; + } else { + clear_has_server_version(); + server_version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandConnected.server_version) +} + +// optional int32 protocol_version = 2 [default = 0]; +inline bool CommandConnected::has_protocol_version() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandConnected::set_has_protocol_version() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandConnected::clear_has_protocol_version() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandConnected::clear_protocol_version() { + protocol_version_ = 0; + clear_has_protocol_version(); +} +inline ::google::protobuf::int32 CommandConnected::protocol_version() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandConnected.protocol_version) + return protocol_version_; +} +inline void CommandConnected::set_protocol_version(::google::protobuf::int32 value) { + set_has_protocol_version(); + protocol_version_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandConnected.protocol_version) +} + +// ------------------------------------------------------------------- + +// CommandSubscribe + +// required string topic = 1; +inline bool CommandSubscribe::has_topic() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandSubscribe::set_has_topic() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandSubscribe::clear_has_topic() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandSubscribe::clear_topic() { + if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_->clear(); + } + clear_has_topic(); +} +inline const ::std::string& CommandSubscribe::topic() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandSubscribe.topic) + return *topic_; +} +inline void CommandSubscribe::set_topic(const ::std::string& value) { + set_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_ = new ::std::string; + } + topic_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandSubscribe.topic) +} +inline void CommandSubscribe::set_topic(const char* value) { + set_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_ = new ::std::string; + } + topic_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandSubscribe.topic) +} +inline void CommandSubscribe::set_topic(const char* value, size_t size) { + set_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_ = new ::std::string; + } + topic_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandSubscribe.topic) +} +inline ::std::string* CommandSubscribe::mutable_topic() { + set_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandSubscribe.topic) + return topic_; +} +inline ::std::string* CommandSubscribe::release_topic() { + clear_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = topic_; + topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandSubscribe::set_allocated_topic(::std::string* topic) { + if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete topic_; + } + if (topic) { + set_has_topic(); + topic_ = topic; + } else { + clear_has_topic(); + topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandSubscribe.topic) +} + +// required string subscription = 2; +inline bool CommandSubscribe::has_subscription() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandSubscribe::set_has_subscription() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandSubscribe::clear_has_subscription() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandSubscribe::clear_subscription() { + if (subscription_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + subscription_->clear(); + } + clear_has_subscription(); +} +inline const ::std::string& CommandSubscribe::subscription() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandSubscribe.subscription) + return *subscription_; +} +inline void CommandSubscribe::set_subscription(const ::std::string& value) { + set_has_subscription(); + if (subscription_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + subscription_ = new ::std::string; + } + subscription_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandSubscribe.subscription) +} +inline void CommandSubscribe::set_subscription(const char* value) { + set_has_subscription(); + if (subscription_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + subscription_ = new ::std::string; + } + subscription_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandSubscribe.subscription) +} +inline void CommandSubscribe::set_subscription(const char* value, size_t size) { + set_has_subscription(); + if (subscription_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + subscription_ = new ::std::string; + } + subscription_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandSubscribe.subscription) +} +inline ::std::string* CommandSubscribe::mutable_subscription() { + set_has_subscription(); + if (subscription_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + subscription_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandSubscribe.subscription) + return subscription_; +} +inline ::std::string* CommandSubscribe::release_subscription() { + clear_has_subscription(); + if (subscription_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = subscription_; + subscription_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandSubscribe::set_allocated_subscription(::std::string* subscription) { + if (subscription_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete subscription_; + } + if (subscription) { + set_has_subscription(); + subscription_ = subscription; + } else { + clear_has_subscription(); + subscription_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandSubscribe.subscription) +} + +// required .pulsar.proto.CommandSubscribe.SubType subType = 3; +inline bool CommandSubscribe::has_subtype() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void CommandSubscribe::set_has_subtype() { + _has_bits_[0] |= 0x00000004u; +} +inline void CommandSubscribe::clear_has_subtype() { + _has_bits_[0] &= ~0x00000004u; +} +inline void CommandSubscribe::clear_subtype() { + subtype_ = 0; + clear_has_subtype(); +} +inline ::pulsar::proto::CommandSubscribe_SubType CommandSubscribe::subtype() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandSubscribe.subType) + return static_cast< ::pulsar::proto::CommandSubscribe_SubType >(subtype_); +} +inline void CommandSubscribe::set_subtype(::pulsar::proto::CommandSubscribe_SubType value) { + assert(::pulsar::proto::CommandSubscribe_SubType_IsValid(value)); + set_has_subtype(); + subtype_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandSubscribe.subType) +} + +// required uint64 consumer_id = 4; +inline bool CommandSubscribe::has_consumer_id() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void CommandSubscribe::set_has_consumer_id() { + _has_bits_[0] |= 0x00000008u; +} +inline void CommandSubscribe::clear_has_consumer_id() { + _has_bits_[0] &= ~0x00000008u; +} +inline void CommandSubscribe::clear_consumer_id() { + consumer_id_ = GOOGLE_ULONGLONG(0); + clear_has_consumer_id(); +} +inline ::google::protobuf::uint64 CommandSubscribe::consumer_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandSubscribe.consumer_id) + return consumer_id_; +} +inline void CommandSubscribe::set_consumer_id(::google::protobuf::uint64 value) { + set_has_consumer_id(); + consumer_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandSubscribe.consumer_id) +} + +// required uint64 request_id = 5; +inline bool CommandSubscribe::has_request_id() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void CommandSubscribe::set_has_request_id() { + _has_bits_[0] |= 0x00000010u; +} +inline void CommandSubscribe::clear_has_request_id() { + _has_bits_[0] &= ~0x00000010u; +} +inline void CommandSubscribe::clear_request_id() { + request_id_ = GOOGLE_ULONGLONG(0); + clear_has_request_id(); +} +inline ::google::protobuf::uint64 CommandSubscribe::request_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandSubscribe.request_id) + return request_id_; +} +inline void CommandSubscribe::set_request_id(::google::protobuf::uint64 value) { + set_has_request_id(); + request_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandSubscribe.request_id) +} + +// optional string consumer_name = 6; +inline bool CommandSubscribe::has_consumer_name() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void CommandSubscribe::set_has_consumer_name() { + _has_bits_[0] |= 0x00000020u; +} +inline void CommandSubscribe::clear_has_consumer_name() { + _has_bits_[0] &= ~0x00000020u; +} +inline void CommandSubscribe::clear_consumer_name() { + if (consumer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + consumer_name_->clear(); + } + clear_has_consumer_name(); +} +inline const ::std::string& CommandSubscribe::consumer_name() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandSubscribe.consumer_name) + return *consumer_name_; +} +inline void CommandSubscribe::set_consumer_name(const ::std::string& value) { + set_has_consumer_name(); + if (consumer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + consumer_name_ = new ::std::string; + } + consumer_name_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandSubscribe.consumer_name) +} +inline void CommandSubscribe::set_consumer_name(const char* value) { + set_has_consumer_name(); + if (consumer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + consumer_name_ = new ::std::string; + } + consumer_name_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandSubscribe.consumer_name) +} +inline void CommandSubscribe::set_consumer_name(const char* value, size_t size) { + set_has_consumer_name(); + if (consumer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + consumer_name_ = new ::std::string; + } + consumer_name_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandSubscribe.consumer_name) +} +inline ::std::string* CommandSubscribe::mutable_consumer_name() { + set_has_consumer_name(); + if (consumer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + consumer_name_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandSubscribe.consumer_name) + return consumer_name_; +} +inline ::std::string* CommandSubscribe::release_consumer_name() { + clear_has_consumer_name(); + if (consumer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = consumer_name_; + consumer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandSubscribe::set_allocated_consumer_name(::std::string* consumer_name) { + if (consumer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete consumer_name_; + } + if (consumer_name) { + set_has_consumer_name(); + consumer_name_ = consumer_name; + } else { + clear_has_consumer_name(); + consumer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandSubscribe.consumer_name) +} + +// ------------------------------------------------------------------- + +// CommandPartitionedTopicMetadata + +// required string topic = 1; +inline bool CommandPartitionedTopicMetadata::has_topic() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandPartitionedTopicMetadata::set_has_topic() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandPartitionedTopicMetadata::clear_has_topic() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandPartitionedTopicMetadata::clear_topic() { + if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_->clear(); + } + clear_has_topic(); +} +inline const ::std::string& CommandPartitionedTopicMetadata::topic() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandPartitionedTopicMetadata.topic) + return *topic_; +} +inline void CommandPartitionedTopicMetadata::set_topic(const ::std::string& value) { + set_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_ = new ::std::string; + } + topic_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandPartitionedTopicMetadata.topic) +} +inline void CommandPartitionedTopicMetadata::set_topic(const char* value) { + set_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_ = new ::std::string; + } + topic_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandPartitionedTopicMetadata.topic) +} +inline void CommandPartitionedTopicMetadata::set_topic(const char* value, size_t size) { + set_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_ = new ::std::string; + } + topic_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandPartitionedTopicMetadata.topic) +} +inline ::std::string* CommandPartitionedTopicMetadata::mutable_topic() { + set_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandPartitionedTopicMetadata.topic) + return topic_; +} +inline ::std::string* CommandPartitionedTopicMetadata::release_topic() { + clear_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = topic_; + topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandPartitionedTopicMetadata::set_allocated_topic(::std::string* topic) { + if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete topic_; + } + if (topic) { + set_has_topic(); + topic_ = topic; + } else { + clear_has_topic(); + topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandPartitionedTopicMetadata.topic) +} + +// required uint64 request_id = 2; +inline bool CommandPartitionedTopicMetadata::has_request_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandPartitionedTopicMetadata::set_has_request_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandPartitionedTopicMetadata::clear_has_request_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandPartitionedTopicMetadata::clear_request_id() { + request_id_ = GOOGLE_ULONGLONG(0); + clear_has_request_id(); +} +inline ::google::protobuf::uint64 CommandPartitionedTopicMetadata::request_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandPartitionedTopicMetadata.request_id) + return request_id_; +} +inline void CommandPartitionedTopicMetadata::set_request_id(::google::protobuf::uint64 value) { + set_has_request_id(); + request_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandPartitionedTopicMetadata.request_id) +} + +// ------------------------------------------------------------------- + +// CommandPartitionedTopicMetadataResponse + +// optional uint32 partitions = 1; +inline bool CommandPartitionedTopicMetadataResponse::has_partitions() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandPartitionedTopicMetadataResponse::set_has_partitions() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandPartitionedTopicMetadataResponse::clear_has_partitions() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandPartitionedTopicMetadataResponse::clear_partitions() { + partitions_ = 0u; + clear_has_partitions(); +} +inline ::google::protobuf::uint32 CommandPartitionedTopicMetadataResponse::partitions() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandPartitionedTopicMetadataResponse.partitions) + return partitions_; +} +inline void CommandPartitionedTopicMetadataResponse::set_partitions(::google::protobuf::uint32 value) { + set_has_partitions(); + partitions_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandPartitionedTopicMetadataResponse.partitions) +} + +// required uint64 request_id = 2; +inline bool CommandPartitionedTopicMetadataResponse::has_request_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandPartitionedTopicMetadataResponse::set_has_request_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandPartitionedTopicMetadataResponse::clear_has_request_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandPartitionedTopicMetadataResponse::clear_request_id() { + request_id_ = GOOGLE_ULONGLONG(0); + clear_has_request_id(); +} +inline ::google::protobuf::uint64 CommandPartitionedTopicMetadataResponse::request_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandPartitionedTopicMetadataResponse.request_id) + return request_id_; +} +inline void CommandPartitionedTopicMetadataResponse::set_request_id(::google::protobuf::uint64 value) { + set_has_request_id(); + request_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandPartitionedTopicMetadataResponse.request_id) +} + +// optional .pulsar.proto.CommandPartitionedTopicMetadataResponse.LookupType response = 3; +inline bool CommandPartitionedTopicMetadataResponse::has_response() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void CommandPartitionedTopicMetadataResponse::set_has_response() { + _has_bits_[0] |= 0x00000004u; +} +inline void CommandPartitionedTopicMetadataResponse::clear_has_response() { + _has_bits_[0] &= ~0x00000004u; +} +inline void CommandPartitionedTopicMetadataResponse::clear_response() { + response_ = 0; + clear_has_response(); +} +inline ::pulsar::proto::CommandPartitionedTopicMetadataResponse_LookupType CommandPartitionedTopicMetadataResponse::response() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandPartitionedTopicMetadataResponse.response) + return static_cast< ::pulsar::proto::CommandPartitionedTopicMetadataResponse_LookupType >(response_); +} +inline void CommandPartitionedTopicMetadataResponse::set_response(::pulsar::proto::CommandPartitionedTopicMetadataResponse_LookupType value) { + assert(::pulsar::proto::CommandPartitionedTopicMetadataResponse_LookupType_IsValid(value)); + set_has_response(); + response_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandPartitionedTopicMetadataResponse.response) +} + +// optional .pulsar.proto.ServerError error = 4; +inline bool CommandPartitionedTopicMetadataResponse::has_error() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void CommandPartitionedTopicMetadataResponse::set_has_error() { + _has_bits_[0] |= 0x00000008u; +} +inline void CommandPartitionedTopicMetadataResponse::clear_has_error() { + _has_bits_[0] &= ~0x00000008u; +} +inline void CommandPartitionedTopicMetadataResponse::clear_error() { + error_ = 0; + clear_has_error(); +} +inline ::pulsar::proto::ServerError CommandPartitionedTopicMetadataResponse::error() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandPartitionedTopicMetadataResponse.error) + return static_cast< ::pulsar::proto::ServerError >(error_); +} +inline void CommandPartitionedTopicMetadataResponse::set_error(::pulsar::proto::ServerError value) { + assert(::pulsar::proto::ServerError_IsValid(value)); + set_has_error(); + error_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandPartitionedTopicMetadataResponse.error) +} + +// optional string message = 5; +inline bool CommandPartitionedTopicMetadataResponse::has_message() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void CommandPartitionedTopicMetadataResponse::set_has_message() { + _has_bits_[0] |= 0x00000010u; +} +inline void CommandPartitionedTopicMetadataResponse::clear_has_message() { + _has_bits_[0] &= ~0x00000010u; +} +inline void CommandPartitionedTopicMetadataResponse::clear_message() { + if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_->clear(); + } + clear_has_message(); +} +inline const ::std::string& CommandPartitionedTopicMetadataResponse::message() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandPartitionedTopicMetadataResponse.message) + return *message_; +} +inline void CommandPartitionedTopicMetadataResponse::set_message(const ::std::string& value) { + set_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_ = new ::std::string; + } + message_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandPartitionedTopicMetadataResponse.message) +} +inline void CommandPartitionedTopicMetadataResponse::set_message(const char* value) { + set_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_ = new ::std::string; + } + message_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandPartitionedTopicMetadataResponse.message) +} +inline void CommandPartitionedTopicMetadataResponse::set_message(const char* value, size_t size) { + set_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_ = new ::std::string; + } + message_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandPartitionedTopicMetadataResponse.message) +} +inline ::std::string* CommandPartitionedTopicMetadataResponse::mutable_message() { + set_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandPartitionedTopicMetadataResponse.message) + return message_; +} +inline ::std::string* CommandPartitionedTopicMetadataResponse::release_message() { + clear_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = message_; + message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandPartitionedTopicMetadataResponse::set_allocated_message(::std::string* message) { + if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete message_; + } + if (message) { + set_has_message(); + message_ = message; + } else { + clear_has_message(); + message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandPartitionedTopicMetadataResponse.message) +} + +// ------------------------------------------------------------------- + +// CommandLookupTopic + +// required string topic = 1; +inline bool CommandLookupTopic::has_topic() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandLookupTopic::set_has_topic() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandLookupTopic::clear_has_topic() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandLookupTopic::clear_topic() { + if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_->clear(); + } + clear_has_topic(); +} +inline const ::std::string& CommandLookupTopic::topic() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopic.topic) + return *topic_; +} +inline void CommandLookupTopic::set_topic(const ::std::string& value) { + set_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_ = new ::std::string; + } + topic_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopic.topic) +} +inline void CommandLookupTopic::set_topic(const char* value) { + set_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_ = new ::std::string; + } + topic_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandLookupTopic.topic) +} +inline void CommandLookupTopic::set_topic(const char* value, size_t size) { + set_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_ = new ::std::string; + } + topic_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandLookupTopic.topic) +} +inline ::std::string* CommandLookupTopic::mutable_topic() { + set_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandLookupTopic.topic) + return topic_; +} +inline ::std::string* CommandLookupTopic::release_topic() { + clear_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = topic_; + topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandLookupTopic::set_allocated_topic(::std::string* topic) { + if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete topic_; + } + if (topic) { + set_has_topic(); + topic_ = topic; + } else { + clear_has_topic(); + topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandLookupTopic.topic) +} + +// required uint64 request_id = 2; +inline bool CommandLookupTopic::has_request_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandLookupTopic::set_has_request_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandLookupTopic::clear_has_request_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandLookupTopic::clear_request_id() { + request_id_ = GOOGLE_ULONGLONG(0); + clear_has_request_id(); +} +inline ::google::protobuf::uint64 CommandLookupTopic::request_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopic.request_id) + return request_id_; +} +inline void CommandLookupTopic::set_request_id(::google::protobuf::uint64 value) { + set_has_request_id(); + request_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopic.request_id) +} + +// optional bool authoritative = 3 [default = false]; +inline bool CommandLookupTopic::has_authoritative() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void CommandLookupTopic::set_has_authoritative() { + _has_bits_[0] |= 0x00000004u; +} +inline void CommandLookupTopic::clear_has_authoritative() { + _has_bits_[0] &= ~0x00000004u; +} +inline void CommandLookupTopic::clear_authoritative() { + authoritative_ = false; + clear_has_authoritative(); +} +inline bool CommandLookupTopic::authoritative() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopic.authoritative) + return authoritative_; +} +inline void CommandLookupTopic::set_authoritative(bool value) { + set_has_authoritative(); + authoritative_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopic.authoritative) +} + +// ------------------------------------------------------------------- + +// CommandLookupTopicResponse + +// optional string brokerServiceUrl = 1; +inline bool CommandLookupTopicResponse::has_brokerserviceurl() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandLookupTopicResponse::set_has_brokerserviceurl() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandLookupTopicResponse::clear_has_brokerserviceurl() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandLookupTopicResponse::clear_brokerserviceurl() { + if (brokerserviceurl_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + brokerserviceurl_->clear(); + } + clear_has_brokerserviceurl(); +} +inline const ::std::string& CommandLookupTopicResponse::brokerserviceurl() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrl) + return *brokerserviceurl_; +} +inline void CommandLookupTopicResponse::set_brokerserviceurl(const ::std::string& value) { + set_has_brokerserviceurl(); + if (brokerserviceurl_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + brokerserviceurl_ = new ::std::string; + } + brokerserviceurl_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrl) +} +inline void CommandLookupTopicResponse::set_brokerserviceurl(const char* value) { + set_has_brokerserviceurl(); + if (brokerserviceurl_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + brokerserviceurl_ = new ::std::string; + } + brokerserviceurl_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrl) +} +inline void CommandLookupTopicResponse::set_brokerserviceurl(const char* value, size_t size) { + set_has_brokerserviceurl(); + if (brokerserviceurl_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + brokerserviceurl_ = new ::std::string; + } + brokerserviceurl_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrl) +} +inline ::std::string* CommandLookupTopicResponse::mutable_brokerserviceurl() { + set_has_brokerserviceurl(); + if (brokerserviceurl_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + brokerserviceurl_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrl) + return brokerserviceurl_; +} +inline ::std::string* CommandLookupTopicResponse::release_brokerserviceurl() { + clear_has_brokerserviceurl(); + if (brokerserviceurl_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = brokerserviceurl_; + brokerserviceurl_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandLookupTopicResponse::set_allocated_brokerserviceurl(::std::string* brokerserviceurl) { + if (brokerserviceurl_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete brokerserviceurl_; + } + if (brokerserviceurl) { + set_has_brokerserviceurl(); + brokerserviceurl_ = brokerserviceurl; + } else { + clear_has_brokerserviceurl(); + brokerserviceurl_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrl) +} + +// optional string brokerServiceUrlTls = 2; +inline bool CommandLookupTopicResponse::has_brokerserviceurltls() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandLookupTopicResponse::set_has_brokerserviceurltls() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandLookupTopicResponse::clear_has_brokerserviceurltls() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandLookupTopicResponse::clear_brokerserviceurltls() { + if (brokerserviceurltls_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + brokerserviceurltls_->clear(); + } + clear_has_brokerserviceurltls(); +} +inline const ::std::string& CommandLookupTopicResponse::brokerserviceurltls() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrlTls) + return *brokerserviceurltls_; +} +inline void CommandLookupTopicResponse::set_brokerserviceurltls(const ::std::string& value) { + set_has_brokerserviceurltls(); + if (brokerserviceurltls_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + brokerserviceurltls_ = new ::std::string; + } + brokerserviceurltls_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrlTls) +} +inline void CommandLookupTopicResponse::set_brokerserviceurltls(const char* value) { + set_has_brokerserviceurltls(); + if (brokerserviceurltls_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + brokerserviceurltls_ = new ::std::string; + } + brokerserviceurltls_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrlTls) +} +inline void CommandLookupTopicResponse::set_brokerserviceurltls(const char* value, size_t size) { + set_has_brokerserviceurltls(); + if (brokerserviceurltls_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + brokerserviceurltls_ = new ::std::string; + } + brokerserviceurltls_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrlTls) +} +inline ::std::string* CommandLookupTopicResponse::mutable_brokerserviceurltls() { + set_has_brokerserviceurltls(); + if (brokerserviceurltls_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + brokerserviceurltls_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrlTls) + return brokerserviceurltls_; +} +inline ::std::string* CommandLookupTopicResponse::release_brokerserviceurltls() { + clear_has_brokerserviceurltls(); + if (brokerserviceurltls_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = brokerserviceurltls_; + brokerserviceurltls_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandLookupTopicResponse::set_allocated_brokerserviceurltls(::std::string* brokerserviceurltls) { + if (brokerserviceurltls_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete brokerserviceurltls_; + } + if (brokerserviceurltls) { + set_has_brokerserviceurltls(); + brokerserviceurltls_ = brokerserviceurltls; + } else { + clear_has_brokerserviceurltls(); + brokerserviceurltls_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandLookupTopicResponse.brokerServiceUrlTls) +} + +// optional .pulsar.proto.CommandLookupTopicResponse.LookupType response = 3; +inline bool CommandLookupTopicResponse::has_response() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void CommandLookupTopicResponse::set_has_response() { + _has_bits_[0] |= 0x00000004u; +} +inline void CommandLookupTopicResponse::clear_has_response() { + _has_bits_[0] &= ~0x00000004u; +} +inline void CommandLookupTopicResponse::clear_response() { + response_ = 0; + clear_has_response(); +} +inline ::pulsar::proto::CommandLookupTopicResponse_LookupType CommandLookupTopicResponse::response() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopicResponse.response) + return static_cast< ::pulsar::proto::CommandLookupTopicResponse_LookupType >(response_); +} +inline void CommandLookupTopicResponse::set_response(::pulsar::proto::CommandLookupTopicResponse_LookupType value) { + assert(::pulsar::proto::CommandLookupTopicResponse_LookupType_IsValid(value)); + set_has_response(); + response_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopicResponse.response) +} + +// required uint64 request_id = 4; +inline bool CommandLookupTopicResponse::has_request_id() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void CommandLookupTopicResponse::set_has_request_id() { + _has_bits_[0] |= 0x00000008u; +} +inline void CommandLookupTopicResponse::clear_has_request_id() { + _has_bits_[0] &= ~0x00000008u; +} +inline void CommandLookupTopicResponse::clear_request_id() { + request_id_ = GOOGLE_ULONGLONG(0); + clear_has_request_id(); +} +inline ::google::protobuf::uint64 CommandLookupTopicResponse::request_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopicResponse.request_id) + return request_id_; +} +inline void CommandLookupTopicResponse::set_request_id(::google::protobuf::uint64 value) { + set_has_request_id(); + request_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopicResponse.request_id) +} + +// optional bool authoritative = 5 [default = false]; +inline bool CommandLookupTopicResponse::has_authoritative() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void CommandLookupTopicResponse::set_has_authoritative() { + _has_bits_[0] |= 0x00000010u; +} +inline void CommandLookupTopicResponse::clear_has_authoritative() { + _has_bits_[0] &= ~0x00000010u; +} +inline void CommandLookupTopicResponse::clear_authoritative() { + authoritative_ = false; + clear_has_authoritative(); +} +inline bool CommandLookupTopicResponse::authoritative() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopicResponse.authoritative) + return authoritative_; +} +inline void CommandLookupTopicResponse::set_authoritative(bool value) { + set_has_authoritative(); + authoritative_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopicResponse.authoritative) +} + +// optional .pulsar.proto.ServerError error = 6; +inline bool CommandLookupTopicResponse::has_error() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void CommandLookupTopicResponse::set_has_error() { + _has_bits_[0] |= 0x00000020u; +} +inline void CommandLookupTopicResponse::clear_has_error() { + _has_bits_[0] &= ~0x00000020u; +} +inline void CommandLookupTopicResponse::clear_error() { + error_ = 0; + clear_has_error(); +} +inline ::pulsar::proto::ServerError CommandLookupTopicResponse::error() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopicResponse.error) + return static_cast< ::pulsar::proto::ServerError >(error_); +} +inline void CommandLookupTopicResponse::set_error(::pulsar::proto::ServerError value) { + assert(::pulsar::proto::ServerError_IsValid(value)); + set_has_error(); + error_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopicResponse.error) +} + +// optional string message = 7; +inline bool CommandLookupTopicResponse::has_message() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void CommandLookupTopicResponse::set_has_message() { + _has_bits_[0] |= 0x00000040u; +} +inline void CommandLookupTopicResponse::clear_has_message() { + _has_bits_[0] &= ~0x00000040u; +} +inline void CommandLookupTopicResponse::clear_message() { + if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_->clear(); + } + clear_has_message(); +} +inline const ::std::string& CommandLookupTopicResponse::message() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandLookupTopicResponse.message) + return *message_; +} +inline void CommandLookupTopicResponse::set_message(const ::std::string& value) { + set_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_ = new ::std::string; + } + message_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandLookupTopicResponse.message) +} +inline void CommandLookupTopicResponse::set_message(const char* value) { + set_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_ = new ::std::string; + } + message_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandLookupTopicResponse.message) +} +inline void CommandLookupTopicResponse::set_message(const char* value, size_t size) { + set_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_ = new ::std::string; + } + message_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandLookupTopicResponse.message) +} +inline ::std::string* CommandLookupTopicResponse::mutable_message() { + set_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandLookupTopicResponse.message) + return message_; +} +inline ::std::string* CommandLookupTopicResponse::release_message() { + clear_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = message_; + message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandLookupTopicResponse::set_allocated_message(::std::string* message) { + if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete message_; + } + if (message) { + set_has_message(); + message_ = message; + } else { + clear_has_message(); + message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandLookupTopicResponse.message) +} + +// ------------------------------------------------------------------- + +// CommandProducer + +// required string topic = 1; +inline bool CommandProducer::has_topic() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandProducer::set_has_topic() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandProducer::clear_has_topic() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandProducer::clear_topic() { + if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_->clear(); + } + clear_has_topic(); +} +inline const ::std::string& CommandProducer::topic() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandProducer.topic) + return *topic_; +} +inline void CommandProducer::set_topic(const ::std::string& value) { + set_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_ = new ::std::string; + } + topic_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandProducer.topic) +} +inline void CommandProducer::set_topic(const char* value) { + set_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_ = new ::std::string; + } + topic_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandProducer.topic) +} +inline void CommandProducer::set_topic(const char* value, size_t size) { + set_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_ = new ::std::string; + } + topic_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandProducer.topic) +} +inline ::std::string* CommandProducer::mutable_topic() { + set_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + topic_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandProducer.topic) + return topic_; +} +inline ::std::string* CommandProducer::release_topic() { + clear_has_topic(); + if (topic_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = topic_; + topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandProducer::set_allocated_topic(::std::string* topic) { + if (topic_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete topic_; + } + if (topic) { + set_has_topic(); + topic_ = topic; + } else { + clear_has_topic(); + topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandProducer.topic) +} + +// required uint64 producer_id = 2; +inline bool CommandProducer::has_producer_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandProducer::set_has_producer_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandProducer::clear_has_producer_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandProducer::clear_producer_id() { + producer_id_ = GOOGLE_ULONGLONG(0); + clear_has_producer_id(); +} +inline ::google::protobuf::uint64 CommandProducer::producer_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandProducer.producer_id) + return producer_id_; +} +inline void CommandProducer::set_producer_id(::google::protobuf::uint64 value) { + set_has_producer_id(); + producer_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandProducer.producer_id) +} + +// required uint64 request_id = 3; +inline bool CommandProducer::has_request_id() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void CommandProducer::set_has_request_id() { + _has_bits_[0] |= 0x00000004u; +} +inline void CommandProducer::clear_has_request_id() { + _has_bits_[0] &= ~0x00000004u; +} +inline void CommandProducer::clear_request_id() { + request_id_ = GOOGLE_ULONGLONG(0); + clear_has_request_id(); +} +inline ::google::protobuf::uint64 CommandProducer::request_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandProducer.request_id) + return request_id_; +} +inline void CommandProducer::set_request_id(::google::protobuf::uint64 value) { + set_has_request_id(); + request_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandProducer.request_id) +} + +// optional string producer_name = 4; +inline bool CommandProducer::has_producer_name() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void CommandProducer::set_has_producer_name() { + _has_bits_[0] |= 0x00000008u; +} +inline void CommandProducer::clear_has_producer_name() { + _has_bits_[0] &= ~0x00000008u; +} +inline void CommandProducer::clear_producer_name() { + if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_->clear(); + } + clear_has_producer_name(); +} +inline const ::std::string& CommandProducer::producer_name() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandProducer.producer_name) + return *producer_name_; +} +inline void CommandProducer::set_producer_name(const ::std::string& value) { + set_has_producer_name(); + if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_ = new ::std::string; + } + producer_name_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandProducer.producer_name) +} +inline void CommandProducer::set_producer_name(const char* value) { + set_has_producer_name(); + if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_ = new ::std::string; + } + producer_name_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandProducer.producer_name) +} +inline void CommandProducer::set_producer_name(const char* value, size_t size) { + set_has_producer_name(); + if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_ = new ::std::string; + } + producer_name_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandProducer.producer_name) +} +inline ::std::string* CommandProducer::mutable_producer_name() { + set_has_producer_name(); + if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandProducer.producer_name) + return producer_name_; +} +inline ::std::string* CommandProducer::release_producer_name() { + clear_has_producer_name(); + if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = producer_name_; + producer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandProducer::set_allocated_producer_name(::std::string* producer_name) { + if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete producer_name_; + } + if (producer_name) { + set_has_producer_name(); + producer_name_ = producer_name; + } else { + clear_has_producer_name(); + producer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandProducer.producer_name) +} + +// ------------------------------------------------------------------- + +// CommandSend + +// required uint64 producer_id = 1; +inline bool CommandSend::has_producer_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandSend::set_has_producer_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandSend::clear_has_producer_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandSend::clear_producer_id() { + producer_id_ = GOOGLE_ULONGLONG(0); + clear_has_producer_id(); +} +inline ::google::protobuf::uint64 CommandSend::producer_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandSend.producer_id) + return producer_id_; +} +inline void CommandSend::set_producer_id(::google::protobuf::uint64 value) { + set_has_producer_id(); + producer_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandSend.producer_id) +} + +// required uint64 sequence_id = 2; +inline bool CommandSend::has_sequence_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandSend::set_has_sequence_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandSend::clear_has_sequence_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandSend::clear_sequence_id() { + sequence_id_ = GOOGLE_ULONGLONG(0); + clear_has_sequence_id(); +} +inline ::google::protobuf::uint64 CommandSend::sequence_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandSend.sequence_id) + return sequence_id_; +} +inline void CommandSend::set_sequence_id(::google::protobuf::uint64 value) { + set_has_sequence_id(); + sequence_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandSend.sequence_id) +} + +// optional int32 num_messages = 3 [default = 1]; +inline bool CommandSend::has_num_messages() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void CommandSend::set_has_num_messages() { + _has_bits_[0] |= 0x00000004u; +} +inline void CommandSend::clear_has_num_messages() { + _has_bits_[0] &= ~0x00000004u; +} +inline void CommandSend::clear_num_messages() { + num_messages_ = 1; + clear_has_num_messages(); +} +inline ::google::protobuf::int32 CommandSend::num_messages() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandSend.num_messages) + return num_messages_; +} +inline void CommandSend::set_num_messages(::google::protobuf::int32 value) { + set_has_num_messages(); + num_messages_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandSend.num_messages) +} + +// ------------------------------------------------------------------- + +// CommandSendReceipt + +// required uint64 producer_id = 1; +inline bool CommandSendReceipt::has_producer_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandSendReceipt::set_has_producer_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandSendReceipt::clear_has_producer_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandSendReceipt::clear_producer_id() { + producer_id_ = GOOGLE_ULONGLONG(0); + clear_has_producer_id(); +} +inline ::google::protobuf::uint64 CommandSendReceipt::producer_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandSendReceipt.producer_id) + return producer_id_; +} +inline void CommandSendReceipt::set_producer_id(::google::protobuf::uint64 value) { + set_has_producer_id(); + producer_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandSendReceipt.producer_id) +} + +// required uint64 sequence_id = 2; +inline bool CommandSendReceipt::has_sequence_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandSendReceipt::set_has_sequence_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandSendReceipt::clear_has_sequence_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandSendReceipt::clear_sequence_id() { + sequence_id_ = GOOGLE_ULONGLONG(0); + clear_has_sequence_id(); +} +inline ::google::protobuf::uint64 CommandSendReceipt::sequence_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandSendReceipt.sequence_id) + return sequence_id_; +} +inline void CommandSendReceipt::set_sequence_id(::google::protobuf::uint64 value) { + set_has_sequence_id(); + sequence_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandSendReceipt.sequence_id) +} + +// optional .pulsar.proto.MessageIdData message_id = 3; +inline bool CommandSendReceipt::has_message_id() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void CommandSendReceipt::set_has_message_id() { + _has_bits_[0] |= 0x00000004u; +} +inline void CommandSendReceipt::clear_has_message_id() { + _has_bits_[0] &= ~0x00000004u; +} +inline void CommandSendReceipt::clear_message_id() { + if (message_id_ != NULL) message_id_->::pulsar::proto::MessageIdData::Clear(); + clear_has_message_id(); +} +inline const ::pulsar::proto::MessageIdData& CommandSendReceipt::message_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandSendReceipt.message_id) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return message_id_ != NULL ? *message_id_ : *default_instance().message_id_; +#else + return message_id_ != NULL ? *message_id_ : *default_instance_->message_id_; +#endif +} +inline ::pulsar::proto::MessageIdData* CommandSendReceipt::mutable_message_id() { + set_has_message_id(); + if (message_id_ == NULL) message_id_ = new ::pulsar::proto::MessageIdData; + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandSendReceipt.message_id) + return message_id_; +} +inline ::pulsar::proto::MessageIdData* CommandSendReceipt::release_message_id() { + clear_has_message_id(); + ::pulsar::proto::MessageIdData* temp = message_id_; + message_id_ = NULL; + return temp; +} +inline void CommandSendReceipt::set_allocated_message_id(::pulsar::proto::MessageIdData* message_id) { + delete message_id_; + message_id_ = message_id; + if (message_id) { + set_has_message_id(); + } else { + clear_has_message_id(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandSendReceipt.message_id) +} + +// ------------------------------------------------------------------- + +// CommandSendError + +// required uint64 producer_id = 1; +inline bool CommandSendError::has_producer_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandSendError::set_has_producer_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandSendError::clear_has_producer_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandSendError::clear_producer_id() { + producer_id_ = GOOGLE_ULONGLONG(0); + clear_has_producer_id(); +} +inline ::google::protobuf::uint64 CommandSendError::producer_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandSendError.producer_id) + return producer_id_; +} +inline void CommandSendError::set_producer_id(::google::protobuf::uint64 value) { + set_has_producer_id(); + producer_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandSendError.producer_id) +} + +// required uint64 sequence_id = 2; +inline bool CommandSendError::has_sequence_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandSendError::set_has_sequence_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandSendError::clear_has_sequence_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandSendError::clear_sequence_id() { + sequence_id_ = GOOGLE_ULONGLONG(0); + clear_has_sequence_id(); +} +inline ::google::protobuf::uint64 CommandSendError::sequence_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandSendError.sequence_id) + return sequence_id_; +} +inline void CommandSendError::set_sequence_id(::google::protobuf::uint64 value) { + set_has_sequence_id(); + sequence_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandSendError.sequence_id) +} + +// required .pulsar.proto.ServerError error = 3; +inline bool CommandSendError::has_error() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void CommandSendError::set_has_error() { + _has_bits_[0] |= 0x00000004u; +} +inline void CommandSendError::clear_has_error() { + _has_bits_[0] &= ~0x00000004u; +} +inline void CommandSendError::clear_error() { + error_ = 0; + clear_has_error(); +} +inline ::pulsar::proto::ServerError CommandSendError::error() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandSendError.error) + return static_cast< ::pulsar::proto::ServerError >(error_); +} +inline void CommandSendError::set_error(::pulsar::proto::ServerError value) { + assert(::pulsar::proto::ServerError_IsValid(value)); + set_has_error(); + error_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandSendError.error) +} + +// required string message = 4; +inline bool CommandSendError::has_message() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void CommandSendError::set_has_message() { + _has_bits_[0] |= 0x00000008u; +} +inline void CommandSendError::clear_has_message() { + _has_bits_[0] &= ~0x00000008u; +} +inline void CommandSendError::clear_message() { + if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_->clear(); + } + clear_has_message(); +} +inline const ::std::string& CommandSendError::message() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandSendError.message) + return *message_; +} +inline void CommandSendError::set_message(const ::std::string& value) { + set_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_ = new ::std::string; + } + message_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandSendError.message) +} +inline void CommandSendError::set_message(const char* value) { + set_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_ = new ::std::string; + } + message_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandSendError.message) +} +inline void CommandSendError::set_message(const char* value, size_t size) { + set_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_ = new ::std::string; + } + message_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandSendError.message) +} +inline ::std::string* CommandSendError::mutable_message() { + set_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandSendError.message) + return message_; +} +inline ::std::string* CommandSendError::release_message() { + clear_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = message_; + message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandSendError::set_allocated_message(::std::string* message) { + if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete message_; + } + if (message) { + set_has_message(); + message_ = message; + } else { + clear_has_message(); + message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandSendError.message) +} + +// ------------------------------------------------------------------- + +// CommandMessage + +// required uint64 consumer_id = 1; +inline bool CommandMessage::has_consumer_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandMessage::set_has_consumer_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandMessage::clear_has_consumer_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandMessage::clear_consumer_id() { + consumer_id_ = GOOGLE_ULONGLONG(0); + clear_has_consumer_id(); +} +inline ::google::protobuf::uint64 CommandMessage::consumer_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandMessage.consumer_id) + return consumer_id_; +} +inline void CommandMessage::set_consumer_id(::google::protobuf::uint64 value) { + set_has_consumer_id(); + consumer_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandMessage.consumer_id) +} + +// required .pulsar.proto.MessageIdData message_id = 2; +inline bool CommandMessage::has_message_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandMessage::set_has_message_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandMessage::clear_has_message_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandMessage::clear_message_id() { + if (message_id_ != NULL) message_id_->::pulsar::proto::MessageIdData::Clear(); + clear_has_message_id(); +} +inline const ::pulsar::proto::MessageIdData& CommandMessage::message_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandMessage.message_id) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return message_id_ != NULL ? *message_id_ : *default_instance().message_id_; +#else + return message_id_ != NULL ? *message_id_ : *default_instance_->message_id_; +#endif +} +inline ::pulsar::proto::MessageIdData* CommandMessage::mutable_message_id() { + set_has_message_id(); + if (message_id_ == NULL) message_id_ = new ::pulsar::proto::MessageIdData; + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandMessage.message_id) + return message_id_; +} +inline ::pulsar::proto::MessageIdData* CommandMessage::release_message_id() { + clear_has_message_id(); + ::pulsar::proto::MessageIdData* temp = message_id_; + message_id_ = NULL; + return temp; +} +inline void CommandMessage::set_allocated_message_id(::pulsar::proto::MessageIdData* message_id) { + delete message_id_; + message_id_ = message_id; + if (message_id) { + set_has_message_id(); + } else { + clear_has_message_id(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandMessage.message_id) +} + +// ------------------------------------------------------------------- + +// CommandAck + +// required uint64 consumer_id = 1; +inline bool CommandAck::has_consumer_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandAck::set_has_consumer_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandAck::clear_has_consumer_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandAck::clear_consumer_id() { + consumer_id_ = GOOGLE_ULONGLONG(0); + clear_has_consumer_id(); +} +inline ::google::protobuf::uint64 CommandAck::consumer_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandAck.consumer_id) + return consumer_id_; +} +inline void CommandAck::set_consumer_id(::google::protobuf::uint64 value) { + set_has_consumer_id(); + consumer_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandAck.consumer_id) +} + +// required .pulsar.proto.CommandAck.AckType ack_type = 2; +inline bool CommandAck::has_ack_type() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandAck::set_has_ack_type() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandAck::clear_has_ack_type() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandAck::clear_ack_type() { + ack_type_ = 0; + clear_has_ack_type(); +} +inline ::pulsar::proto::CommandAck_AckType CommandAck::ack_type() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandAck.ack_type) + return static_cast< ::pulsar::proto::CommandAck_AckType >(ack_type_); +} +inline void CommandAck::set_ack_type(::pulsar::proto::CommandAck_AckType value) { + assert(::pulsar::proto::CommandAck_AckType_IsValid(value)); + set_has_ack_type(); + ack_type_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandAck.ack_type) +} + +// required .pulsar.proto.MessageIdData message_id = 3; +inline bool CommandAck::has_message_id() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void CommandAck::set_has_message_id() { + _has_bits_[0] |= 0x00000004u; +} +inline void CommandAck::clear_has_message_id() { + _has_bits_[0] &= ~0x00000004u; +} +inline void CommandAck::clear_message_id() { + if (message_id_ != NULL) message_id_->::pulsar::proto::MessageIdData::Clear(); + clear_has_message_id(); +} +inline const ::pulsar::proto::MessageIdData& CommandAck::message_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandAck.message_id) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return message_id_ != NULL ? *message_id_ : *default_instance().message_id_; +#else + return message_id_ != NULL ? *message_id_ : *default_instance_->message_id_; +#endif +} +inline ::pulsar::proto::MessageIdData* CommandAck::mutable_message_id() { + set_has_message_id(); + if (message_id_ == NULL) message_id_ = new ::pulsar::proto::MessageIdData; + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandAck.message_id) + return message_id_; +} +inline ::pulsar::proto::MessageIdData* CommandAck::release_message_id() { + clear_has_message_id(); + ::pulsar::proto::MessageIdData* temp = message_id_; + message_id_ = NULL; + return temp; +} +inline void CommandAck::set_allocated_message_id(::pulsar::proto::MessageIdData* message_id) { + delete message_id_; + message_id_ = message_id; + if (message_id) { + set_has_message_id(); + } else { + clear_has_message_id(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandAck.message_id) +} + +// optional .pulsar.proto.CommandAck.ValidationError validation_error = 4; +inline bool CommandAck::has_validation_error() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void CommandAck::set_has_validation_error() { + _has_bits_[0] |= 0x00000008u; +} +inline void CommandAck::clear_has_validation_error() { + _has_bits_[0] &= ~0x00000008u; +} +inline void CommandAck::clear_validation_error() { + validation_error_ = 0; + clear_has_validation_error(); +} +inline ::pulsar::proto::CommandAck_ValidationError CommandAck::validation_error() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandAck.validation_error) + return static_cast< ::pulsar::proto::CommandAck_ValidationError >(validation_error_); +} +inline void CommandAck::set_validation_error(::pulsar::proto::CommandAck_ValidationError value) { + assert(::pulsar::proto::CommandAck_ValidationError_IsValid(value)); + set_has_validation_error(); + validation_error_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandAck.validation_error) +} + +// ------------------------------------------------------------------- + +// CommandFlow + +// required uint64 consumer_id = 1; +inline bool CommandFlow::has_consumer_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandFlow::set_has_consumer_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandFlow::clear_has_consumer_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandFlow::clear_consumer_id() { + consumer_id_ = GOOGLE_ULONGLONG(0); + clear_has_consumer_id(); +} +inline ::google::protobuf::uint64 CommandFlow::consumer_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandFlow.consumer_id) + return consumer_id_; +} +inline void CommandFlow::set_consumer_id(::google::protobuf::uint64 value) { + set_has_consumer_id(); + consumer_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandFlow.consumer_id) +} + +// required uint32 messagePermits = 2; +inline bool CommandFlow::has_messagepermits() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandFlow::set_has_messagepermits() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandFlow::clear_has_messagepermits() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandFlow::clear_messagepermits() { + messagepermits_ = 0u; + clear_has_messagepermits(); +} +inline ::google::protobuf::uint32 CommandFlow::messagepermits() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandFlow.messagePermits) + return messagepermits_; +} +inline void CommandFlow::set_messagepermits(::google::protobuf::uint32 value) { + set_has_messagepermits(); + messagepermits_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandFlow.messagePermits) +} + +// ------------------------------------------------------------------- + +// CommandUnsubscribe + +// required uint64 consumer_id = 1; +inline bool CommandUnsubscribe::has_consumer_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandUnsubscribe::set_has_consumer_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandUnsubscribe::clear_has_consumer_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandUnsubscribe::clear_consumer_id() { + consumer_id_ = GOOGLE_ULONGLONG(0); + clear_has_consumer_id(); +} +inline ::google::protobuf::uint64 CommandUnsubscribe::consumer_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandUnsubscribe.consumer_id) + return consumer_id_; +} +inline void CommandUnsubscribe::set_consumer_id(::google::protobuf::uint64 value) { + set_has_consumer_id(); + consumer_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandUnsubscribe.consumer_id) +} + +// required uint64 request_id = 2; +inline bool CommandUnsubscribe::has_request_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandUnsubscribe::set_has_request_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandUnsubscribe::clear_has_request_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandUnsubscribe::clear_request_id() { + request_id_ = GOOGLE_ULONGLONG(0); + clear_has_request_id(); +} +inline ::google::protobuf::uint64 CommandUnsubscribe::request_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandUnsubscribe.request_id) + return request_id_; +} +inline void CommandUnsubscribe::set_request_id(::google::protobuf::uint64 value) { + set_has_request_id(); + request_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandUnsubscribe.request_id) +} + +// ------------------------------------------------------------------- + +// CommandCloseProducer + +// required uint64 producer_id = 1; +inline bool CommandCloseProducer::has_producer_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandCloseProducer::set_has_producer_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandCloseProducer::clear_has_producer_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandCloseProducer::clear_producer_id() { + producer_id_ = GOOGLE_ULONGLONG(0); + clear_has_producer_id(); +} +inline ::google::protobuf::uint64 CommandCloseProducer::producer_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandCloseProducer.producer_id) + return producer_id_; +} +inline void CommandCloseProducer::set_producer_id(::google::protobuf::uint64 value) { + set_has_producer_id(); + producer_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandCloseProducer.producer_id) +} + +// required uint64 request_id = 2; +inline bool CommandCloseProducer::has_request_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandCloseProducer::set_has_request_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandCloseProducer::clear_has_request_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandCloseProducer::clear_request_id() { + request_id_ = GOOGLE_ULONGLONG(0); + clear_has_request_id(); +} +inline ::google::protobuf::uint64 CommandCloseProducer::request_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandCloseProducer.request_id) + return request_id_; +} +inline void CommandCloseProducer::set_request_id(::google::protobuf::uint64 value) { + set_has_request_id(); + request_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandCloseProducer.request_id) +} + +// ------------------------------------------------------------------- + +// CommandCloseConsumer + +// required uint64 consumer_id = 1; +inline bool CommandCloseConsumer::has_consumer_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandCloseConsumer::set_has_consumer_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandCloseConsumer::clear_has_consumer_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandCloseConsumer::clear_consumer_id() { + consumer_id_ = GOOGLE_ULONGLONG(0); + clear_has_consumer_id(); +} +inline ::google::protobuf::uint64 CommandCloseConsumer::consumer_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandCloseConsumer.consumer_id) + return consumer_id_; +} +inline void CommandCloseConsumer::set_consumer_id(::google::protobuf::uint64 value) { + set_has_consumer_id(); + consumer_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandCloseConsumer.consumer_id) +} + +// required uint64 request_id = 2; +inline bool CommandCloseConsumer::has_request_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandCloseConsumer::set_has_request_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandCloseConsumer::clear_has_request_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandCloseConsumer::clear_request_id() { + request_id_ = GOOGLE_ULONGLONG(0); + clear_has_request_id(); +} +inline ::google::protobuf::uint64 CommandCloseConsumer::request_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandCloseConsumer.request_id) + return request_id_; +} +inline void CommandCloseConsumer::set_request_id(::google::protobuf::uint64 value) { + set_has_request_id(); + request_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandCloseConsumer.request_id) +} + +// ------------------------------------------------------------------- + +// CommandRedeliverUnacknowledgedMessages + +// required uint64 consumer_id = 1; +inline bool CommandRedeliverUnacknowledgedMessages::has_consumer_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandRedeliverUnacknowledgedMessages::set_has_consumer_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandRedeliverUnacknowledgedMessages::clear_has_consumer_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandRedeliverUnacknowledgedMessages::clear_consumer_id() { + consumer_id_ = GOOGLE_ULONGLONG(0); + clear_has_consumer_id(); +} +inline ::google::protobuf::uint64 CommandRedeliverUnacknowledgedMessages::consumer_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandRedeliverUnacknowledgedMessages.consumer_id) + return consumer_id_; +} +inline void CommandRedeliverUnacknowledgedMessages::set_consumer_id(::google::protobuf::uint64 value) { + set_has_consumer_id(); + consumer_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandRedeliverUnacknowledgedMessages.consumer_id) +} + +// repeated .pulsar.proto.MessageIdData message_ids = 2; +inline int CommandRedeliverUnacknowledgedMessages::message_ids_size() const { + return message_ids_.size(); +} +inline void CommandRedeliverUnacknowledgedMessages::clear_message_ids() { + message_ids_.Clear(); +} +inline const ::pulsar::proto::MessageIdData& CommandRedeliverUnacknowledgedMessages::message_ids(int index) const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandRedeliverUnacknowledgedMessages.message_ids) + return message_ids_.Get(index); +} +inline ::pulsar::proto::MessageIdData* CommandRedeliverUnacknowledgedMessages::mutable_message_ids(int index) { + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandRedeliverUnacknowledgedMessages.message_ids) + return message_ids_.Mutable(index); +} +inline ::pulsar::proto::MessageIdData* CommandRedeliverUnacknowledgedMessages::add_message_ids() { + // @@protoc_insertion_point(field_add:pulsar.proto.CommandRedeliverUnacknowledgedMessages.message_ids) + return message_ids_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::pulsar::proto::MessageIdData >& +CommandRedeliverUnacknowledgedMessages::message_ids() const { + // @@protoc_insertion_point(field_list:pulsar.proto.CommandRedeliverUnacknowledgedMessages.message_ids) + return message_ids_; +} +inline ::google::protobuf::RepeatedPtrField< ::pulsar::proto::MessageIdData >* +CommandRedeliverUnacknowledgedMessages::mutable_message_ids() { + // @@protoc_insertion_point(field_mutable_list:pulsar.proto.CommandRedeliverUnacknowledgedMessages.message_ids) + return &message_ids_; +} + +// ------------------------------------------------------------------- + +// CommandSuccess + +// required uint64 request_id = 1; +inline bool CommandSuccess::has_request_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandSuccess::set_has_request_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandSuccess::clear_has_request_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandSuccess::clear_request_id() { + request_id_ = GOOGLE_ULONGLONG(0); + clear_has_request_id(); +} +inline ::google::protobuf::uint64 CommandSuccess::request_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandSuccess.request_id) + return request_id_; +} +inline void CommandSuccess::set_request_id(::google::protobuf::uint64 value) { + set_has_request_id(); + request_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandSuccess.request_id) +} + +// ------------------------------------------------------------------- + +// CommandProducerSuccess + +// required uint64 request_id = 1; +inline bool CommandProducerSuccess::has_request_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandProducerSuccess::set_has_request_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandProducerSuccess::clear_has_request_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandProducerSuccess::clear_request_id() { + request_id_ = GOOGLE_ULONGLONG(0); + clear_has_request_id(); +} +inline ::google::protobuf::uint64 CommandProducerSuccess::request_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandProducerSuccess.request_id) + return request_id_; +} +inline void CommandProducerSuccess::set_request_id(::google::protobuf::uint64 value) { + set_has_request_id(); + request_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandProducerSuccess.request_id) +} + +// required string producer_name = 2; +inline bool CommandProducerSuccess::has_producer_name() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandProducerSuccess::set_has_producer_name() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandProducerSuccess::clear_has_producer_name() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandProducerSuccess::clear_producer_name() { + if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_->clear(); + } + clear_has_producer_name(); +} +inline const ::std::string& CommandProducerSuccess::producer_name() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandProducerSuccess.producer_name) + return *producer_name_; +} +inline void CommandProducerSuccess::set_producer_name(const ::std::string& value) { + set_has_producer_name(); + if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_ = new ::std::string; + } + producer_name_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandProducerSuccess.producer_name) +} +inline void CommandProducerSuccess::set_producer_name(const char* value) { + set_has_producer_name(); + if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_ = new ::std::string; + } + producer_name_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandProducerSuccess.producer_name) +} +inline void CommandProducerSuccess::set_producer_name(const char* value, size_t size) { + set_has_producer_name(); + if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_ = new ::std::string; + } + producer_name_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandProducerSuccess.producer_name) +} +inline ::std::string* CommandProducerSuccess::mutable_producer_name() { + set_has_producer_name(); + if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + producer_name_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandProducerSuccess.producer_name) + return producer_name_; +} +inline ::std::string* CommandProducerSuccess::release_producer_name() { + clear_has_producer_name(); + if (producer_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = producer_name_; + producer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandProducerSuccess::set_allocated_producer_name(::std::string* producer_name) { + if (producer_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete producer_name_; + } + if (producer_name) { + set_has_producer_name(); + producer_name_ = producer_name; + } else { + clear_has_producer_name(); + producer_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandProducerSuccess.producer_name) +} + +// ------------------------------------------------------------------- + +// CommandError + +// required uint64 request_id = 1; +inline bool CommandError::has_request_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CommandError::set_has_request_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void CommandError::clear_has_request_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CommandError::clear_request_id() { + request_id_ = GOOGLE_ULONGLONG(0); + clear_has_request_id(); +} +inline ::google::protobuf::uint64 CommandError::request_id() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandError.request_id) + return request_id_; +} +inline void CommandError::set_request_id(::google::protobuf::uint64 value) { + set_has_request_id(); + request_id_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandError.request_id) +} + +// required .pulsar.proto.ServerError error = 2; +inline bool CommandError::has_error() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CommandError::set_has_error() { + _has_bits_[0] |= 0x00000002u; +} +inline void CommandError::clear_has_error() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CommandError::clear_error() { + error_ = 0; + clear_has_error(); +} +inline ::pulsar::proto::ServerError CommandError::error() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandError.error) + return static_cast< ::pulsar::proto::ServerError >(error_); +} +inline void CommandError::set_error(::pulsar::proto::ServerError value) { + assert(::pulsar::proto::ServerError_IsValid(value)); + set_has_error(); + error_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.CommandError.error) +} + +// required string message = 3; +inline bool CommandError::has_message() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void CommandError::set_has_message() { + _has_bits_[0] |= 0x00000004u; +} +inline void CommandError::clear_has_message() { + _has_bits_[0] &= ~0x00000004u; +} +inline void CommandError::clear_message() { + if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_->clear(); + } + clear_has_message(); +} +inline const ::std::string& CommandError::message() const { + // @@protoc_insertion_point(field_get:pulsar.proto.CommandError.message) + return *message_; +} +inline void CommandError::set_message(const ::std::string& value) { + set_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_ = new ::std::string; + } + message_->assign(value); + // @@protoc_insertion_point(field_set:pulsar.proto.CommandError.message) +} +inline void CommandError::set_message(const char* value) { + set_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_ = new ::std::string; + } + message_->assign(value); + // @@protoc_insertion_point(field_set_char:pulsar.proto.CommandError.message) +} +inline void CommandError::set_message(const char* value, size_t size) { + set_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_ = new ::std::string; + } + message_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:pulsar.proto.CommandError.message) +} +inline ::std::string* CommandError::mutable_message() { + set_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + message_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:pulsar.proto.CommandError.message) + return message_; +} +inline ::std::string* CommandError::release_message() { + clear_has_message(); + if (message_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = message_; + message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void CommandError::set_allocated_message(::std::string* message) { + if (message_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete message_; + } + if (message) { + set_has_message(); + message_ = message; + } else { + clear_has_message(); + message_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.CommandError.message) +} + +// ------------------------------------------------------------------- + +// CommandPing + +// ------------------------------------------------------------------- + +// CommandPong + +// ------------------------------------------------------------------- + +// BaseCommand + +// required .pulsar.proto.BaseCommand.Type type = 1; +inline bool BaseCommand::has_type() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void BaseCommand::set_has_type() { + _has_bits_[0] |= 0x00000001u; +} +inline void BaseCommand::clear_has_type() { + _has_bits_[0] &= ~0x00000001u; +} +inline void BaseCommand::clear_type() { + type_ = 2; + clear_has_type(); +} +inline ::pulsar::proto::BaseCommand_Type BaseCommand::type() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.type) + return static_cast< ::pulsar::proto::BaseCommand_Type >(type_); +} +inline void BaseCommand::set_type(::pulsar::proto::BaseCommand_Type value) { + assert(::pulsar::proto::BaseCommand_Type_IsValid(value)); + set_has_type(); + type_ = value; + // @@protoc_insertion_point(field_set:pulsar.proto.BaseCommand.type) +} + +// optional .pulsar.proto.CommandConnect connect = 2; +inline bool BaseCommand::has_connect() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void BaseCommand::set_has_connect() { + _has_bits_[0] |= 0x00000002u; +} +inline void BaseCommand::clear_has_connect() { + _has_bits_[0] &= ~0x00000002u; +} +inline void BaseCommand::clear_connect() { + if (connect_ != NULL) connect_->::pulsar::proto::CommandConnect::Clear(); + clear_has_connect(); +} +inline const ::pulsar::proto::CommandConnect& BaseCommand::connect() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.connect) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return connect_ != NULL ? *connect_ : *default_instance().connect_; +#else + return connect_ != NULL ? *connect_ : *default_instance_->connect_; +#endif +} +inline ::pulsar::proto::CommandConnect* BaseCommand::mutable_connect() { + set_has_connect(); + if (connect_ == NULL) connect_ = new ::pulsar::proto::CommandConnect; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.connect) + return connect_; +} +inline ::pulsar::proto::CommandConnect* BaseCommand::release_connect() { + clear_has_connect(); + ::pulsar::proto::CommandConnect* temp = connect_; + connect_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_connect(::pulsar::proto::CommandConnect* connect) { + delete connect_; + connect_ = connect; + if (connect) { + set_has_connect(); + } else { + clear_has_connect(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.connect) +} + +// optional .pulsar.proto.CommandConnected connected = 3; +inline bool BaseCommand::has_connected() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void BaseCommand::set_has_connected() { + _has_bits_[0] |= 0x00000004u; +} +inline void BaseCommand::clear_has_connected() { + _has_bits_[0] &= ~0x00000004u; +} +inline void BaseCommand::clear_connected() { + if (connected_ != NULL) connected_->::pulsar::proto::CommandConnected::Clear(); + clear_has_connected(); +} +inline const ::pulsar::proto::CommandConnected& BaseCommand::connected() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.connected) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return connected_ != NULL ? *connected_ : *default_instance().connected_; +#else + return connected_ != NULL ? *connected_ : *default_instance_->connected_; +#endif +} +inline ::pulsar::proto::CommandConnected* BaseCommand::mutable_connected() { + set_has_connected(); + if (connected_ == NULL) connected_ = new ::pulsar::proto::CommandConnected; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.connected) + return connected_; +} +inline ::pulsar::proto::CommandConnected* BaseCommand::release_connected() { + clear_has_connected(); + ::pulsar::proto::CommandConnected* temp = connected_; + connected_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_connected(::pulsar::proto::CommandConnected* connected) { + delete connected_; + connected_ = connected; + if (connected) { + set_has_connected(); + } else { + clear_has_connected(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.connected) +} + +// optional .pulsar.proto.CommandSubscribe subscribe = 4; +inline bool BaseCommand::has_subscribe() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void BaseCommand::set_has_subscribe() { + _has_bits_[0] |= 0x00000008u; +} +inline void BaseCommand::clear_has_subscribe() { + _has_bits_[0] &= ~0x00000008u; +} +inline void BaseCommand::clear_subscribe() { + if (subscribe_ != NULL) subscribe_->::pulsar::proto::CommandSubscribe::Clear(); + clear_has_subscribe(); +} +inline const ::pulsar::proto::CommandSubscribe& BaseCommand::subscribe() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.subscribe) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return subscribe_ != NULL ? *subscribe_ : *default_instance().subscribe_; +#else + return subscribe_ != NULL ? *subscribe_ : *default_instance_->subscribe_; +#endif +} +inline ::pulsar::proto::CommandSubscribe* BaseCommand::mutable_subscribe() { + set_has_subscribe(); + if (subscribe_ == NULL) subscribe_ = new ::pulsar::proto::CommandSubscribe; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.subscribe) + return subscribe_; +} +inline ::pulsar::proto::CommandSubscribe* BaseCommand::release_subscribe() { + clear_has_subscribe(); + ::pulsar::proto::CommandSubscribe* temp = subscribe_; + subscribe_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_subscribe(::pulsar::proto::CommandSubscribe* subscribe) { + delete subscribe_; + subscribe_ = subscribe; + if (subscribe) { + set_has_subscribe(); + } else { + clear_has_subscribe(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.subscribe) +} + +// optional .pulsar.proto.CommandProducer producer = 5; +inline bool BaseCommand::has_producer() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void BaseCommand::set_has_producer() { + _has_bits_[0] |= 0x00000010u; +} +inline void BaseCommand::clear_has_producer() { + _has_bits_[0] &= ~0x00000010u; +} +inline void BaseCommand::clear_producer() { + if (producer_ != NULL) producer_->::pulsar::proto::CommandProducer::Clear(); + clear_has_producer(); +} +inline const ::pulsar::proto::CommandProducer& BaseCommand::producer() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.producer) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return producer_ != NULL ? *producer_ : *default_instance().producer_; +#else + return producer_ != NULL ? *producer_ : *default_instance_->producer_; +#endif +} +inline ::pulsar::proto::CommandProducer* BaseCommand::mutable_producer() { + set_has_producer(); + if (producer_ == NULL) producer_ = new ::pulsar::proto::CommandProducer; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.producer) + return producer_; +} +inline ::pulsar::proto::CommandProducer* BaseCommand::release_producer() { + clear_has_producer(); + ::pulsar::proto::CommandProducer* temp = producer_; + producer_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_producer(::pulsar::proto::CommandProducer* producer) { + delete producer_; + producer_ = producer; + if (producer) { + set_has_producer(); + } else { + clear_has_producer(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.producer) +} + +// optional .pulsar.proto.CommandSend send = 6; +inline bool BaseCommand::has_send() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void BaseCommand::set_has_send() { + _has_bits_[0] |= 0x00000020u; +} +inline void BaseCommand::clear_has_send() { + _has_bits_[0] &= ~0x00000020u; +} +inline void BaseCommand::clear_send() { + if (send_ != NULL) send_->::pulsar::proto::CommandSend::Clear(); + clear_has_send(); +} +inline const ::pulsar::proto::CommandSend& BaseCommand::send() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.send) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return send_ != NULL ? *send_ : *default_instance().send_; +#else + return send_ != NULL ? *send_ : *default_instance_->send_; +#endif +} +inline ::pulsar::proto::CommandSend* BaseCommand::mutable_send() { + set_has_send(); + if (send_ == NULL) send_ = new ::pulsar::proto::CommandSend; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.send) + return send_; +} +inline ::pulsar::proto::CommandSend* BaseCommand::release_send() { + clear_has_send(); + ::pulsar::proto::CommandSend* temp = send_; + send_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_send(::pulsar::proto::CommandSend* send) { + delete send_; + send_ = send; + if (send) { + set_has_send(); + } else { + clear_has_send(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.send) +} + +// optional .pulsar.proto.CommandSendReceipt send_receipt = 7; +inline bool BaseCommand::has_send_receipt() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void BaseCommand::set_has_send_receipt() { + _has_bits_[0] |= 0x00000040u; +} +inline void BaseCommand::clear_has_send_receipt() { + _has_bits_[0] &= ~0x00000040u; +} +inline void BaseCommand::clear_send_receipt() { + if (send_receipt_ != NULL) send_receipt_->::pulsar::proto::CommandSendReceipt::Clear(); + clear_has_send_receipt(); +} +inline const ::pulsar::proto::CommandSendReceipt& BaseCommand::send_receipt() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.send_receipt) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return send_receipt_ != NULL ? *send_receipt_ : *default_instance().send_receipt_; +#else + return send_receipt_ != NULL ? *send_receipt_ : *default_instance_->send_receipt_; +#endif +} +inline ::pulsar::proto::CommandSendReceipt* BaseCommand::mutable_send_receipt() { + set_has_send_receipt(); + if (send_receipt_ == NULL) send_receipt_ = new ::pulsar::proto::CommandSendReceipt; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.send_receipt) + return send_receipt_; +} +inline ::pulsar::proto::CommandSendReceipt* BaseCommand::release_send_receipt() { + clear_has_send_receipt(); + ::pulsar::proto::CommandSendReceipt* temp = send_receipt_; + send_receipt_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_send_receipt(::pulsar::proto::CommandSendReceipt* send_receipt) { + delete send_receipt_; + send_receipt_ = send_receipt; + if (send_receipt) { + set_has_send_receipt(); + } else { + clear_has_send_receipt(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.send_receipt) +} + +// optional .pulsar.proto.CommandSendError send_error = 8; +inline bool BaseCommand::has_send_error() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void BaseCommand::set_has_send_error() { + _has_bits_[0] |= 0x00000080u; +} +inline void BaseCommand::clear_has_send_error() { + _has_bits_[0] &= ~0x00000080u; +} +inline void BaseCommand::clear_send_error() { + if (send_error_ != NULL) send_error_->::pulsar::proto::CommandSendError::Clear(); + clear_has_send_error(); +} +inline const ::pulsar::proto::CommandSendError& BaseCommand::send_error() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.send_error) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return send_error_ != NULL ? *send_error_ : *default_instance().send_error_; +#else + return send_error_ != NULL ? *send_error_ : *default_instance_->send_error_; +#endif +} +inline ::pulsar::proto::CommandSendError* BaseCommand::mutable_send_error() { + set_has_send_error(); + if (send_error_ == NULL) send_error_ = new ::pulsar::proto::CommandSendError; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.send_error) + return send_error_; +} +inline ::pulsar::proto::CommandSendError* BaseCommand::release_send_error() { + clear_has_send_error(); + ::pulsar::proto::CommandSendError* temp = send_error_; + send_error_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_send_error(::pulsar::proto::CommandSendError* send_error) { + delete send_error_; + send_error_ = send_error; + if (send_error) { + set_has_send_error(); + } else { + clear_has_send_error(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.send_error) +} + +// optional .pulsar.proto.CommandMessage message = 9; +inline bool BaseCommand::has_message() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void BaseCommand::set_has_message() { + _has_bits_[0] |= 0x00000100u; +} +inline void BaseCommand::clear_has_message() { + _has_bits_[0] &= ~0x00000100u; +} +inline void BaseCommand::clear_message() { + if (message_ != NULL) message_->::pulsar::proto::CommandMessage::Clear(); + clear_has_message(); +} +inline const ::pulsar::proto::CommandMessage& BaseCommand::message() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.message) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return message_ != NULL ? *message_ : *default_instance().message_; +#else + return message_ != NULL ? *message_ : *default_instance_->message_; +#endif +} +inline ::pulsar::proto::CommandMessage* BaseCommand::mutable_message() { + set_has_message(); + if (message_ == NULL) message_ = new ::pulsar::proto::CommandMessage; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.message) + return message_; +} +inline ::pulsar::proto::CommandMessage* BaseCommand::release_message() { + clear_has_message(); + ::pulsar::proto::CommandMessage* temp = message_; + message_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_message(::pulsar::proto::CommandMessage* message) { + delete message_; + message_ = message; + if (message) { + set_has_message(); + } else { + clear_has_message(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.message) +} + +// optional .pulsar.proto.CommandAck ack = 10; +inline bool BaseCommand::has_ack() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +inline void BaseCommand::set_has_ack() { + _has_bits_[0] |= 0x00000200u; +} +inline void BaseCommand::clear_has_ack() { + _has_bits_[0] &= ~0x00000200u; +} +inline void BaseCommand::clear_ack() { + if (ack_ != NULL) ack_->::pulsar::proto::CommandAck::Clear(); + clear_has_ack(); +} +inline const ::pulsar::proto::CommandAck& BaseCommand::ack() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.ack) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return ack_ != NULL ? *ack_ : *default_instance().ack_; +#else + return ack_ != NULL ? *ack_ : *default_instance_->ack_; +#endif +} +inline ::pulsar::proto::CommandAck* BaseCommand::mutable_ack() { + set_has_ack(); + if (ack_ == NULL) ack_ = new ::pulsar::proto::CommandAck; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.ack) + return ack_; +} +inline ::pulsar::proto::CommandAck* BaseCommand::release_ack() { + clear_has_ack(); + ::pulsar::proto::CommandAck* temp = ack_; + ack_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_ack(::pulsar::proto::CommandAck* ack) { + delete ack_; + ack_ = ack; + if (ack) { + set_has_ack(); + } else { + clear_has_ack(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.ack) +} + +// optional .pulsar.proto.CommandFlow flow = 11; +inline bool BaseCommand::has_flow() const { + return (_has_bits_[0] & 0x00000400u) != 0; +} +inline void BaseCommand::set_has_flow() { + _has_bits_[0] |= 0x00000400u; +} +inline void BaseCommand::clear_has_flow() { + _has_bits_[0] &= ~0x00000400u; +} +inline void BaseCommand::clear_flow() { + if (flow_ != NULL) flow_->::pulsar::proto::CommandFlow::Clear(); + clear_has_flow(); +} +inline const ::pulsar::proto::CommandFlow& BaseCommand::flow() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.flow) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return flow_ != NULL ? *flow_ : *default_instance().flow_; +#else + return flow_ != NULL ? *flow_ : *default_instance_->flow_; +#endif +} +inline ::pulsar::proto::CommandFlow* BaseCommand::mutable_flow() { + set_has_flow(); + if (flow_ == NULL) flow_ = new ::pulsar::proto::CommandFlow; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.flow) + return flow_; +} +inline ::pulsar::proto::CommandFlow* BaseCommand::release_flow() { + clear_has_flow(); + ::pulsar::proto::CommandFlow* temp = flow_; + flow_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_flow(::pulsar::proto::CommandFlow* flow) { + delete flow_; + flow_ = flow; + if (flow) { + set_has_flow(); + } else { + clear_has_flow(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.flow) +} + +// optional .pulsar.proto.CommandUnsubscribe unsubscribe = 12; +inline bool BaseCommand::has_unsubscribe() const { + return (_has_bits_[0] & 0x00000800u) != 0; +} +inline void BaseCommand::set_has_unsubscribe() { + _has_bits_[0] |= 0x00000800u; +} +inline void BaseCommand::clear_has_unsubscribe() { + _has_bits_[0] &= ~0x00000800u; +} +inline void BaseCommand::clear_unsubscribe() { + if (unsubscribe_ != NULL) unsubscribe_->::pulsar::proto::CommandUnsubscribe::Clear(); + clear_has_unsubscribe(); +} +inline const ::pulsar::proto::CommandUnsubscribe& BaseCommand::unsubscribe() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.unsubscribe) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return unsubscribe_ != NULL ? *unsubscribe_ : *default_instance().unsubscribe_; +#else + return unsubscribe_ != NULL ? *unsubscribe_ : *default_instance_->unsubscribe_; +#endif +} +inline ::pulsar::proto::CommandUnsubscribe* BaseCommand::mutable_unsubscribe() { + set_has_unsubscribe(); + if (unsubscribe_ == NULL) unsubscribe_ = new ::pulsar::proto::CommandUnsubscribe; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.unsubscribe) + return unsubscribe_; +} +inline ::pulsar::proto::CommandUnsubscribe* BaseCommand::release_unsubscribe() { + clear_has_unsubscribe(); + ::pulsar::proto::CommandUnsubscribe* temp = unsubscribe_; + unsubscribe_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_unsubscribe(::pulsar::proto::CommandUnsubscribe* unsubscribe) { + delete unsubscribe_; + unsubscribe_ = unsubscribe; + if (unsubscribe) { + set_has_unsubscribe(); + } else { + clear_has_unsubscribe(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.unsubscribe) +} + +// optional .pulsar.proto.CommandSuccess success = 13; +inline bool BaseCommand::has_success() const { + return (_has_bits_[0] & 0x00001000u) != 0; +} +inline void BaseCommand::set_has_success() { + _has_bits_[0] |= 0x00001000u; +} +inline void BaseCommand::clear_has_success() { + _has_bits_[0] &= ~0x00001000u; +} +inline void BaseCommand::clear_success() { + if (success_ != NULL) success_->::pulsar::proto::CommandSuccess::Clear(); + clear_has_success(); +} +inline const ::pulsar::proto::CommandSuccess& BaseCommand::success() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.success) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return success_ != NULL ? *success_ : *default_instance().success_; +#else + return success_ != NULL ? *success_ : *default_instance_->success_; +#endif +} +inline ::pulsar::proto::CommandSuccess* BaseCommand::mutable_success() { + set_has_success(); + if (success_ == NULL) success_ = new ::pulsar::proto::CommandSuccess; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.success) + return success_; +} +inline ::pulsar::proto::CommandSuccess* BaseCommand::release_success() { + clear_has_success(); + ::pulsar::proto::CommandSuccess* temp = success_; + success_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_success(::pulsar::proto::CommandSuccess* success) { + delete success_; + success_ = success; + if (success) { + set_has_success(); + } else { + clear_has_success(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.success) +} + +// optional .pulsar.proto.CommandError error = 14; +inline bool BaseCommand::has_error() const { + return (_has_bits_[0] & 0x00002000u) != 0; +} +inline void BaseCommand::set_has_error() { + _has_bits_[0] |= 0x00002000u; +} +inline void BaseCommand::clear_has_error() { + _has_bits_[0] &= ~0x00002000u; +} +inline void BaseCommand::clear_error() { + if (error_ != NULL) error_->::pulsar::proto::CommandError::Clear(); + clear_has_error(); +} +inline const ::pulsar::proto::CommandError& BaseCommand::error() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.error) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return error_ != NULL ? *error_ : *default_instance().error_; +#else + return error_ != NULL ? *error_ : *default_instance_->error_; +#endif +} +inline ::pulsar::proto::CommandError* BaseCommand::mutable_error() { + set_has_error(); + if (error_ == NULL) error_ = new ::pulsar::proto::CommandError; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.error) + return error_; +} +inline ::pulsar::proto::CommandError* BaseCommand::release_error() { + clear_has_error(); + ::pulsar::proto::CommandError* temp = error_; + error_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_error(::pulsar::proto::CommandError* error) { + delete error_; + error_ = error; + if (error) { + set_has_error(); + } else { + clear_has_error(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.error) +} + +// optional .pulsar.proto.CommandCloseProducer close_producer = 15; +inline bool BaseCommand::has_close_producer() const { + return (_has_bits_[0] & 0x00004000u) != 0; +} +inline void BaseCommand::set_has_close_producer() { + _has_bits_[0] |= 0x00004000u; +} +inline void BaseCommand::clear_has_close_producer() { + _has_bits_[0] &= ~0x00004000u; +} +inline void BaseCommand::clear_close_producer() { + if (close_producer_ != NULL) close_producer_->::pulsar::proto::CommandCloseProducer::Clear(); + clear_has_close_producer(); +} +inline const ::pulsar::proto::CommandCloseProducer& BaseCommand::close_producer() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.close_producer) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return close_producer_ != NULL ? *close_producer_ : *default_instance().close_producer_; +#else + return close_producer_ != NULL ? *close_producer_ : *default_instance_->close_producer_; +#endif +} +inline ::pulsar::proto::CommandCloseProducer* BaseCommand::mutable_close_producer() { + set_has_close_producer(); + if (close_producer_ == NULL) close_producer_ = new ::pulsar::proto::CommandCloseProducer; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.close_producer) + return close_producer_; +} +inline ::pulsar::proto::CommandCloseProducer* BaseCommand::release_close_producer() { + clear_has_close_producer(); + ::pulsar::proto::CommandCloseProducer* temp = close_producer_; + close_producer_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_close_producer(::pulsar::proto::CommandCloseProducer* close_producer) { + delete close_producer_; + close_producer_ = close_producer; + if (close_producer) { + set_has_close_producer(); + } else { + clear_has_close_producer(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.close_producer) +} + +// optional .pulsar.proto.CommandCloseConsumer close_consumer = 16; +inline bool BaseCommand::has_close_consumer() const { + return (_has_bits_[0] & 0x00008000u) != 0; +} +inline void BaseCommand::set_has_close_consumer() { + _has_bits_[0] |= 0x00008000u; +} +inline void BaseCommand::clear_has_close_consumer() { + _has_bits_[0] &= ~0x00008000u; +} +inline void BaseCommand::clear_close_consumer() { + if (close_consumer_ != NULL) close_consumer_->::pulsar::proto::CommandCloseConsumer::Clear(); + clear_has_close_consumer(); +} +inline const ::pulsar::proto::CommandCloseConsumer& BaseCommand::close_consumer() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.close_consumer) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return close_consumer_ != NULL ? *close_consumer_ : *default_instance().close_consumer_; +#else + return close_consumer_ != NULL ? *close_consumer_ : *default_instance_->close_consumer_; +#endif +} +inline ::pulsar::proto::CommandCloseConsumer* BaseCommand::mutable_close_consumer() { + set_has_close_consumer(); + if (close_consumer_ == NULL) close_consumer_ = new ::pulsar::proto::CommandCloseConsumer; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.close_consumer) + return close_consumer_; +} +inline ::pulsar::proto::CommandCloseConsumer* BaseCommand::release_close_consumer() { + clear_has_close_consumer(); + ::pulsar::proto::CommandCloseConsumer* temp = close_consumer_; + close_consumer_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_close_consumer(::pulsar::proto::CommandCloseConsumer* close_consumer) { + delete close_consumer_; + close_consumer_ = close_consumer; + if (close_consumer) { + set_has_close_consumer(); + } else { + clear_has_close_consumer(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.close_consumer) +} + +// optional .pulsar.proto.CommandProducerSuccess producer_success = 17; +inline bool BaseCommand::has_producer_success() const { + return (_has_bits_[0] & 0x00010000u) != 0; +} +inline void BaseCommand::set_has_producer_success() { + _has_bits_[0] |= 0x00010000u; +} +inline void BaseCommand::clear_has_producer_success() { + _has_bits_[0] &= ~0x00010000u; +} +inline void BaseCommand::clear_producer_success() { + if (producer_success_ != NULL) producer_success_->::pulsar::proto::CommandProducerSuccess::Clear(); + clear_has_producer_success(); +} +inline const ::pulsar::proto::CommandProducerSuccess& BaseCommand::producer_success() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.producer_success) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return producer_success_ != NULL ? *producer_success_ : *default_instance().producer_success_; +#else + return producer_success_ != NULL ? *producer_success_ : *default_instance_->producer_success_; +#endif +} +inline ::pulsar::proto::CommandProducerSuccess* BaseCommand::mutable_producer_success() { + set_has_producer_success(); + if (producer_success_ == NULL) producer_success_ = new ::pulsar::proto::CommandProducerSuccess; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.producer_success) + return producer_success_; +} +inline ::pulsar::proto::CommandProducerSuccess* BaseCommand::release_producer_success() { + clear_has_producer_success(); + ::pulsar::proto::CommandProducerSuccess* temp = producer_success_; + producer_success_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_producer_success(::pulsar::proto::CommandProducerSuccess* producer_success) { + delete producer_success_; + producer_success_ = producer_success; + if (producer_success) { + set_has_producer_success(); + } else { + clear_has_producer_success(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.producer_success) +} + +// optional .pulsar.proto.CommandPing ping = 18; +inline bool BaseCommand::has_ping() const { + return (_has_bits_[0] & 0x00020000u) != 0; +} +inline void BaseCommand::set_has_ping() { + _has_bits_[0] |= 0x00020000u; +} +inline void BaseCommand::clear_has_ping() { + _has_bits_[0] &= ~0x00020000u; +} +inline void BaseCommand::clear_ping() { + if (ping_ != NULL) ping_->::pulsar::proto::CommandPing::Clear(); + clear_has_ping(); +} +inline const ::pulsar::proto::CommandPing& BaseCommand::ping() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.ping) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return ping_ != NULL ? *ping_ : *default_instance().ping_; +#else + return ping_ != NULL ? *ping_ : *default_instance_->ping_; +#endif +} +inline ::pulsar::proto::CommandPing* BaseCommand::mutable_ping() { + set_has_ping(); + if (ping_ == NULL) ping_ = new ::pulsar::proto::CommandPing; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.ping) + return ping_; +} +inline ::pulsar::proto::CommandPing* BaseCommand::release_ping() { + clear_has_ping(); + ::pulsar::proto::CommandPing* temp = ping_; + ping_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_ping(::pulsar::proto::CommandPing* ping) { + delete ping_; + ping_ = ping; + if (ping) { + set_has_ping(); + } else { + clear_has_ping(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.ping) +} + +// optional .pulsar.proto.CommandPong pong = 19; +inline bool BaseCommand::has_pong() const { + return (_has_bits_[0] & 0x00040000u) != 0; +} +inline void BaseCommand::set_has_pong() { + _has_bits_[0] |= 0x00040000u; +} +inline void BaseCommand::clear_has_pong() { + _has_bits_[0] &= ~0x00040000u; +} +inline void BaseCommand::clear_pong() { + if (pong_ != NULL) pong_->::pulsar::proto::CommandPong::Clear(); + clear_has_pong(); +} +inline const ::pulsar::proto::CommandPong& BaseCommand::pong() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.pong) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return pong_ != NULL ? *pong_ : *default_instance().pong_; +#else + return pong_ != NULL ? *pong_ : *default_instance_->pong_; +#endif +} +inline ::pulsar::proto::CommandPong* BaseCommand::mutable_pong() { + set_has_pong(); + if (pong_ == NULL) pong_ = new ::pulsar::proto::CommandPong; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.pong) + return pong_; +} +inline ::pulsar::proto::CommandPong* BaseCommand::release_pong() { + clear_has_pong(); + ::pulsar::proto::CommandPong* temp = pong_; + pong_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_pong(::pulsar::proto::CommandPong* pong) { + delete pong_; + pong_ = pong; + if (pong) { + set_has_pong(); + } else { + clear_has_pong(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.pong) +} + +// optional .pulsar.proto.CommandRedeliverUnacknowledgedMessages redeliverUnacknowledgedMessages = 20; +inline bool BaseCommand::has_redeliverunacknowledgedmessages() const { + return (_has_bits_[0] & 0x00080000u) != 0; +} +inline void BaseCommand::set_has_redeliverunacknowledgedmessages() { + _has_bits_[0] |= 0x00080000u; +} +inline void BaseCommand::clear_has_redeliverunacknowledgedmessages() { + _has_bits_[0] &= ~0x00080000u; +} +inline void BaseCommand::clear_redeliverunacknowledgedmessages() { + if (redeliverunacknowledgedmessages_ != NULL) redeliverunacknowledgedmessages_->::pulsar::proto::CommandRedeliverUnacknowledgedMessages::Clear(); + clear_has_redeliverunacknowledgedmessages(); +} +inline const ::pulsar::proto::CommandRedeliverUnacknowledgedMessages& BaseCommand::redeliverunacknowledgedmessages() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.redeliverUnacknowledgedMessages) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return redeliverunacknowledgedmessages_ != NULL ? *redeliverunacknowledgedmessages_ : *default_instance().redeliverunacknowledgedmessages_; +#else + return redeliverunacknowledgedmessages_ != NULL ? *redeliverunacknowledgedmessages_ : *default_instance_->redeliverunacknowledgedmessages_; +#endif +} +inline ::pulsar::proto::CommandRedeliverUnacknowledgedMessages* BaseCommand::mutable_redeliverunacknowledgedmessages() { + set_has_redeliverunacknowledgedmessages(); + if (redeliverunacknowledgedmessages_ == NULL) redeliverunacknowledgedmessages_ = new ::pulsar::proto::CommandRedeliverUnacknowledgedMessages; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.redeliverUnacknowledgedMessages) + return redeliverunacknowledgedmessages_; +} +inline ::pulsar::proto::CommandRedeliverUnacknowledgedMessages* BaseCommand::release_redeliverunacknowledgedmessages() { + clear_has_redeliverunacknowledgedmessages(); + ::pulsar::proto::CommandRedeliverUnacknowledgedMessages* temp = redeliverunacknowledgedmessages_; + redeliverunacknowledgedmessages_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_redeliverunacknowledgedmessages(::pulsar::proto::CommandRedeliverUnacknowledgedMessages* redeliverunacknowledgedmessages) { + delete redeliverunacknowledgedmessages_; + redeliverunacknowledgedmessages_ = redeliverunacknowledgedmessages; + if (redeliverunacknowledgedmessages) { + set_has_redeliverunacknowledgedmessages(); + } else { + clear_has_redeliverunacknowledgedmessages(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.redeliverUnacknowledgedMessages) +} + +// optional .pulsar.proto.CommandPartitionedTopicMetadata partitionMetadata = 21; +inline bool BaseCommand::has_partitionmetadata() const { + return (_has_bits_[0] & 0x00100000u) != 0; +} +inline void BaseCommand::set_has_partitionmetadata() { + _has_bits_[0] |= 0x00100000u; +} +inline void BaseCommand::clear_has_partitionmetadata() { + _has_bits_[0] &= ~0x00100000u; +} +inline void BaseCommand::clear_partitionmetadata() { + if (partitionmetadata_ != NULL) partitionmetadata_->::pulsar::proto::CommandPartitionedTopicMetadata::Clear(); + clear_has_partitionmetadata(); +} +inline const ::pulsar::proto::CommandPartitionedTopicMetadata& BaseCommand::partitionmetadata() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.partitionMetadata) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return partitionmetadata_ != NULL ? *partitionmetadata_ : *default_instance().partitionmetadata_; +#else + return partitionmetadata_ != NULL ? *partitionmetadata_ : *default_instance_->partitionmetadata_; +#endif +} +inline ::pulsar::proto::CommandPartitionedTopicMetadata* BaseCommand::mutable_partitionmetadata() { + set_has_partitionmetadata(); + if (partitionmetadata_ == NULL) partitionmetadata_ = new ::pulsar::proto::CommandPartitionedTopicMetadata; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.partitionMetadata) + return partitionmetadata_; +} +inline ::pulsar::proto::CommandPartitionedTopicMetadata* BaseCommand::release_partitionmetadata() { + clear_has_partitionmetadata(); + ::pulsar::proto::CommandPartitionedTopicMetadata* temp = partitionmetadata_; + partitionmetadata_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_partitionmetadata(::pulsar::proto::CommandPartitionedTopicMetadata* partitionmetadata) { + delete partitionmetadata_; + partitionmetadata_ = partitionmetadata; + if (partitionmetadata) { + set_has_partitionmetadata(); + } else { + clear_has_partitionmetadata(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.partitionMetadata) +} + +// optional .pulsar.proto.CommandPartitionedTopicMetadataResponse partitionMetadataResponse = 22; +inline bool BaseCommand::has_partitionmetadataresponse() const { + return (_has_bits_[0] & 0x00200000u) != 0; +} +inline void BaseCommand::set_has_partitionmetadataresponse() { + _has_bits_[0] |= 0x00200000u; +} +inline void BaseCommand::clear_has_partitionmetadataresponse() { + _has_bits_[0] &= ~0x00200000u; +} +inline void BaseCommand::clear_partitionmetadataresponse() { + if (partitionmetadataresponse_ != NULL) partitionmetadataresponse_->::pulsar::proto::CommandPartitionedTopicMetadataResponse::Clear(); + clear_has_partitionmetadataresponse(); +} +inline const ::pulsar::proto::CommandPartitionedTopicMetadataResponse& BaseCommand::partitionmetadataresponse() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.partitionMetadataResponse) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return partitionmetadataresponse_ != NULL ? *partitionmetadataresponse_ : *default_instance().partitionmetadataresponse_; +#else + return partitionmetadataresponse_ != NULL ? *partitionmetadataresponse_ : *default_instance_->partitionmetadataresponse_; +#endif +} +inline ::pulsar::proto::CommandPartitionedTopicMetadataResponse* BaseCommand::mutable_partitionmetadataresponse() { + set_has_partitionmetadataresponse(); + if (partitionmetadataresponse_ == NULL) partitionmetadataresponse_ = new ::pulsar::proto::CommandPartitionedTopicMetadataResponse; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.partitionMetadataResponse) + return partitionmetadataresponse_; +} +inline ::pulsar::proto::CommandPartitionedTopicMetadataResponse* BaseCommand::release_partitionmetadataresponse() { + clear_has_partitionmetadataresponse(); + ::pulsar::proto::CommandPartitionedTopicMetadataResponse* temp = partitionmetadataresponse_; + partitionmetadataresponse_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_partitionmetadataresponse(::pulsar::proto::CommandPartitionedTopicMetadataResponse* partitionmetadataresponse) { + delete partitionmetadataresponse_; + partitionmetadataresponse_ = partitionmetadataresponse; + if (partitionmetadataresponse) { + set_has_partitionmetadataresponse(); + } else { + clear_has_partitionmetadataresponse(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.partitionMetadataResponse) +} + +// optional .pulsar.proto.CommandLookupTopic lookupTopic = 23; +inline bool BaseCommand::has_lookuptopic() const { + return (_has_bits_[0] & 0x00400000u) != 0; +} +inline void BaseCommand::set_has_lookuptopic() { + _has_bits_[0] |= 0x00400000u; +} +inline void BaseCommand::clear_has_lookuptopic() { + _has_bits_[0] &= ~0x00400000u; +} +inline void BaseCommand::clear_lookuptopic() { + if (lookuptopic_ != NULL) lookuptopic_->::pulsar::proto::CommandLookupTopic::Clear(); + clear_has_lookuptopic(); +} +inline const ::pulsar::proto::CommandLookupTopic& BaseCommand::lookuptopic() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.lookupTopic) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return lookuptopic_ != NULL ? *lookuptopic_ : *default_instance().lookuptopic_; +#else + return lookuptopic_ != NULL ? *lookuptopic_ : *default_instance_->lookuptopic_; +#endif +} +inline ::pulsar::proto::CommandLookupTopic* BaseCommand::mutable_lookuptopic() { + set_has_lookuptopic(); + if (lookuptopic_ == NULL) lookuptopic_ = new ::pulsar::proto::CommandLookupTopic; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.lookupTopic) + return lookuptopic_; +} +inline ::pulsar::proto::CommandLookupTopic* BaseCommand::release_lookuptopic() { + clear_has_lookuptopic(); + ::pulsar::proto::CommandLookupTopic* temp = lookuptopic_; + lookuptopic_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_lookuptopic(::pulsar::proto::CommandLookupTopic* lookuptopic) { + delete lookuptopic_; + lookuptopic_ = lookuptopic; + if (lookuptopic) { + set_has_lookuptopic(); + } else { + clear_has_lookuptopic(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.lookupTopic) +} + +// optional .pulsar.proto.CommandLookupTopicResponse lookupTopicResponse = 24; +inline bool BaseCommand::has_lookuptopicresponse() const { + return (_has_bits_[0] & 0x00800000u) != 0; +} +inline void BaseCommand::set_has_lookuptopicresponse() { + _has_bits_[0] |= 0x00800000u; +} +inline void BaseCommand::clear_has_lookuptopicresponse() { + _has_bits_[0] &= ~0x00800000u; +} +inline void BaseCommand::clear_lookuptopicresponse() { + if (lookuptopicresponse_ != NULL) lookuptopicresponse_->::pulsar::proto::CommandLookupTopicResponse::Clear(); + clear_has_lookuptopicresponse(); +} +inline const ::pulsar::proto::CommandLookupTopicResponse& BaseCommand::lookuptopicresponse() const { + // @@protoc_insertion_point(field_get:pulsar.proto.BaseCommand.lookupTopicResponse) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return lookuptopicresponse_ != NULL ? *lookuptopicresponse_ : *default_instance().lookuptopicresponse_; +#else + return lookuptopicresponse_ != NULL ? *lookuptopicresponse_ : *default_instance_->lookuptopicresponse_; +#endif +} +inline ::pulsar::proto::CommandLookupTopicResponse* BaseCommand::mutable_lookuptopicresponse() { + set_has_lookuptopicresponse(); + if (lookuptopicresponse_ == NULL) lookuptopicresponse_ = new ::pulsar::proto::CommandLookupTopicResponse; + // @@protoc_insertion_point(field_mutable:pulsar.proto.BaseCommand.lookupTopicResponse) + return lookuptopicresponse_; +} +inline ::pulsar::proto::CommandLookupTopicResponse* BaseCommand::release_lookuptopicresponse() { + clear_has_lookuptopicresponse(); + ::pulsar::proto::CommandLookupTopicResponse* temp = lookuptopicresponse_; + lookuptopicresponse_ = NULL; + return temp; +} +inline void BaseCommand::set_allocated_lookuptopicresponse(::pulsar::proto::CommandLookupTopicResponse* lookuptopicresponse) { + delete lookuptopicresponse_; + lookuptopicresponse_ = lookuptopicresponse; + if (lookuptopicresponse) { + set_has_lookuptopicresponse(); + } else { + clear_has_lookuptopicresponse(); + } + // @@protoc_insertion_point(field_set_allocated:pulsar.proto.BaseCommand.lookupTopicResponse) +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace proto +} // namespace pulsar + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_PulsarApi_2eproto__INCLUDED diff --git a/pulsar-client-cpp/lib/Result.cc b/pulsar-client-cpp/lib/Result.cc new file mode 100644 index 0000000000000..9e592b2b97769 --- /dev/null +++ b/pulsar-client-cpp/lib/Result.cc @@ -0,0 +1,99 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include + +#include + +using namespace pulsar; + +const char* pulsar::strResult(Result result) { + switch (result) { + case ResultOk: + return "OK"; + + case ResultUnknownError: + return "UnknownError"; + + case ResultInvalidConfiguration: + return "InvalidConfiguration"; + + case ResultTimeout: + return "Timeout"; + + case ResultLookupError: + return "LookupError"; + + case ResultConnectError: + return "ConnectError"; + + case ResultAuthenticationError: + return "AuthenticationError"; + + case ResultAuthorizationError: + return "AuthorizationError"; + + case ResultErrorGettingAuthenticationData: + return "ErrorGettingAuthenticationData"; + + case ResultBrokerMetadataError: + return "BrokerMetadataError"; + + case ResultBrokerPersistenceError: + return "BrokerPersistenceError"; + + case ResultConsumerBusy: + return "ConsumerBusy"; + + case ResultNotConnected: + return "NotConnected"; + + case ResultReadError: + return "ReadError"; + + case ResultAlreadyClosed: + return "AlreadyClosed"; + + case ResultInvalidMessage: + return "InvalidMessage"; + + case ResultConsumerNotInitialized: + return "ConsumerNotInitialized"; + + case ResultProducerNotInitialized: + return "ProducerNotInitialized"; + + case ResultInvalidTopicName: + return "InvalidTopicName"; + + case ResultServiceUnitNotReady: + return "ServiceUnitNotReady"; + + case ResultInvalidUrl: + return "InvalidUrl"; + + default: + return "UnknownErrorCode"; + }; +} + +#pragma GCC visibility push(default) + +std::ostream& operator<<(std::ostream& s, Result result) { + return s << strResult(result); +} + +#pragma GCC visibility pop diff --git a/pulsar-client-cpp/lib/RoundRobinMessageRouter.cc b/pulsar-client-cpp/lib/RoundRobinMessageRouter.cc new file mode 100644 index 0000000000000..ba46350572f8f --- /dev/null +++ b/pulsar-client-cpp/lib/RoundRobinMessageRouter.cc @@ -0,0 +1,40 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "RoundRobinMessageRouter.h" +#include + +namespace pulsar { + RoundRobinMessageRouter::RoundRobinMessageRouter(unsigned int numPartitions):prevPartition_(0), numPartitions_(numPartitions) { + } + + RoundRobinMessageRouter::~RoundRobinMessageRouter() { + } + + //override + int RoundRobinMessageRouter::getPartition(const Message& msg) { + //if message has a key, hash the key and return the partition + if (msg.hasPartitionKey()) { + static StringHash hash; + return hash(msg.getPartitionKey()) % numPartitions_; + } else { + Lock lock(mutex_); + //else pick the next partition + return prevPartition_++ % numPartitions_; + } + } + +} diff --git a/pulsar-client-cpp/lib/RoundRobinMessageRouter.h b/pulsar-client-cpp/lib/RoundRobinMessageRouter.h new file mode 100644 index 0000000000000..44d910846b6e8 --- /dev/null +++ b/pulsar-client-cpp/lib/RoundRobinMessageRouter.h @@ -0,0 +1,38 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef PULSAR_RR_MESSAGE_ROUTER_HEADER_ +#define PULSAR_RR_MESSAGE_ROUTER_HEADER_ + +#include +#include +#include + +namespace pulsar { + class RoundRobinMessageRouter : public MessageRoutingPolicy { + public: + RoundRobinMessageRouter (unsigned int numPartitions); + virtual ~RoundRobinMessageRouter(); + virtual int getPartition(const Message& msg); + private: + boost::mutex mutex_; + unsigned int prevPartition_; + unsigned int numPartitions_; + }; + typedef boost::hash StringHash; + typedef boost::unique_lock Lock; +} +#endif // PULSAR_RR_MESSAGE_ROUTER_HEADER_ diff --git a/pulsar-client-cpp/lib/ServiceUnitId.h b/pulsar-client-cpp/lib/ServiceUnitId.h new file mode 100644 index 0000000000000..4efb3265c458f --- /dev/null +++ b/pulsar-client-cpp/lib/ServiceUnitId.h @@ -0,0 +1,29 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef _PULSAR_SERVICE_UNIT_ID_HEADER_ +#define _PULSAR_SERVICE_UNIT_ID_HEADER_ + +#include +#include + +class ServiceUnitId { + public: + virtual ~ServiceUnitId() { + } +}; + +#endif diff --git a/pulsar-client-cpp/lib/SharedBuffer.h b/pulsar-client-cpp/lib/SharedBuffer.h new file mode 100644 index 0000000000000..1da697ab86bb6 --- /dev/null +++ b/pulsar-client-cpp/lib/SharedBuffer.h @@ -0,0 +1,282 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_SHARED_BUFFER_H_ +#define LIB_SHARED_BUFFER_H_ + +#include +#include +#include + +#include + +namespace pulsar { +namespace detail { + +class SharedBufferInternal : public std::vector { + public: + SharedBufferInternal(int size) + : std::vector(size) { + } + + inline char* ptr() { + return &(*this)[0]; + } + + void resize(int newSize) { + std::vector::resize(newSize); + } + + int capacity() const { + return std::vector::capacity(); + } +}; + +} + +class SharedBuffer { + public: + + explicit SharedBuffer() + : data_(), + ptr_(0), + readIdx_(0), + writeIdx_(0), + capacity_(0) { + } + + /** + * Allocate a buffer of given size + */ + static SharedBuffer allocate(const uint32_t size) { + return SharedBuffer(size); + } + + /** + * Create a buffer with a copy of memory pointed by ptr + */ + static SharedBuffer copy(const char* ptr, uint32_t size) { + SharedBuffer buf = allocate(size); + buf.write(ptr, size); + return buf; + } + + static SharedBuffer copyFrom(const SharedBuffer& other, uint32_t capacity) { + assert(other.readableBytes() <= capacity); + SharedBuffer buf = allocate(capacity); + buf.write(other.data(), other.readableBytes()); + return buf; + } + + /** + * Create a buffer that wraps the passed pointer, without copying the memory + */ + static SharedBuffer wrap(char* ptr, size_t size) { + return SharedBuffer(ptr, size); + } + + inline const char* data() const { + return ptr_ + readIdx_; + } + + inline char* mutableData() { + return ptr_ + writeIdx_; + } + + /** + * Return a shared buffer that include a portion of current buffer. No memory is copied + */ + SharedBuffer slice(uint32_t offset) { + SharedBuffer buf(*this); + buf.consume(offset); + return buf; + } + + SharedBuffer slice(uint32_t offset, uint32_t length) { + SharedBuffer buf(*this); + buf.consume(offset); + assert(buf.readableBytes() >= length); + buf.writeIdx_ = buf.readIdx_ + length; + return buf; + } + + uint32_t readUnsignedInt() { + assert(readableBytes() >= sizeof(uint32_t)); + uint32_t value = ntohl(*(uint32_t* ) data()); + consume(sizeof(uint32_t)); + return value; + } + + uint16_t readUnsignedShort() { + assert(readableBytes() >= sizeof(uint16_t)); + uint16_t value = ntohs(*(uint16_t* ) data()); + consume(sizeof(uint16_t)); + return value; + } + + void writeUnsignedInt(uint32_t value) { + assert(writableBytes() >= sizeof(uint32_t)); + *(uint32_t*) (mutableData()) = htonl(value); + bytesWritten(sizeof(value)); + } + + void writeUnsignedShort(uint16_t value) { + assert(writableBytes() >= sizeof(uint16_t)); + *(uint16_t*) (mutableData()) = htons(value); + bytesWritten(sizeof(value)); + } + + inline uint32_t readableBytes() const { + return writeIdx_ - readIdx_; + } + + inline uint32_t writableBytes() const { + return capacity_ - writeIdx_; + } + + inline bool readable() const { + return readableBytes() > 0; + } + + inline bool writable() const { + return writableBytes() > 0; + } + + boost::asio::const_buffers_1 const_asio_buffer() const { + return boost::asio::const_buffers_1(ptr_ + readIdx_, readableBytes()); + } + + boost::asio::mutable_buffers_1 asio_buffer() { + assert(data_); + return boost::asio::buffer(ptr_ + writeIdx_, writableBytes()); + } + + void write(const char* data, uint32_t size) { + assert(size <= writableBytes()); + + std::copy(data, data + size, mutableData()); + bytesWritten(size); + } + + // Mark that some bytes were written into the buffer + inline void bytesWritten(uint32_t size) { + assert(size <= writableBytes()); + writeIdx_ += size; + } + + // Return current writer index + uint32_t writerIndex() { + return writeIdx_; + } + + // skip writerIndex + void skipBytes(uint32_t size) { + assert(writeIdx_ + size <= capacity_); + writeIdx_ += size; + } + + // set writerIndex + void setWriterIndex(uint32_t index) { + assert(index <= capacity_); + writeIdx_ = index; + } + + // Return current reader index + uint32_t readerIndex() { + return readIdx_; + } + + // set readerIndex + void setReaderIndex(uint32_t index) { + assert(index <= capacity_); + readIdx_ = index; + } + + inline void consume(uint32_t size) { + assert(size <= readableBytes()); + readIdx_ += size; + } + + inline void rollback(uint32_t size) { + assert(size <= readIdx_); + readIdx_ -= size; + } + + inline void reset() { + readIdx_ = 0; + writeIdx_ = 0; + } + + private: + + typedef boost::shared_ptr BufferPtr; + + BufferPtr data_; + char* ptr_; + uint32_t readIdx_; + uint32_t writeIdx_; + uint32_t capacity_; + + SharedBuffer(char *ptr, size_t size) + : data_(), + ptr_(ptr), + readIdx_(0), + writeIdx_(size), + capacity_(size) { + } + + explicit SharedBuffer(size_t size) + : data_(boost::make_shared(size)), + ptr_(data_->ptr()), + readIdx_(0), + writeIdx_(0), + capacity_(size) { + } + +}; + +template +class CompositeSharedBuffer { + public: + + void set(int idx, const SharedBuffer& buffer) { + sharedBuffers_[idx] = buffer; + asioBuffers_[idx] = buffer.const_asio_buffer(); + } + + // Implement the ConstBufferSequence requirements. + typedef boost::asio::const_buffer value_type; + typedef boost::asio::const_buffer* iterator; + typedef const boost::asio::const_buffer* const_iterator; + + const boost::asio::const_buffer* begin() const { + return &(asioBuffers_.at(0)); + } + + const boost::asio::const_buffer* end() const { + return begin() + Size; + } + + private: + boost::array sharedBuffers_; + boost::array asioBuffers_; +}; + +typedef CompositeSharedBuffer<2> PairSharedBuffer; + +} + +#endif /* LIB_SHARED_BUFFER_H_ */ diff --git a/pulsar-client-cpp/lib/SinglePartitionMessageRouter.cc b/pulsar-client-cpp/lib/SinglePartitionMessageRouter.cc new file mode 100644 index 0000000000000..6d8cd393bce2f --- /dev/null +++ b/pulsar-client-cpp/lib/SinglePartitionMessageRouter.cc @@ -0,0 +1,38 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "SinglePartitionMessageRouter.h" +#include // rand() +#include +namespace pulsar { + SinglePartitionMessageRouter::~SinglePartitionMessageRouter(){} + SinglePartitionMessageRouter::SinglePartitionMessageRouter(unsigned int numPartitions):numPartitions_(numPartitions) { + unsigned int random = rand(); + selectedSinglePartition_ = random % numPartitions_; + } + + //override + int SinglePartitionMessageRouter::getPartition(const Message& msg) { + //if message has a key, hash the key and return the partition + if (msg.hasPartitionKey()) { + StringHash hash; + return hash(msg.getPartitionKey()) % numPartitions_; + } else { + //else pick the next partition + return selectedSinglePartition_; + } + } +} diff --git a/pulsar-client-cpp/lib/SinglePartitionMessageRouter.h b/pulsar-client-cpp/lib/SinglePartitionMessageRouter.h new file mode 100644 index 0000000000000..c634b368590d7 --- /dev/null +++ b/pulsar-client-cpp/lib/SinglePartitionMessageRouter.h @@ -0,0 +1,37 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef PULSAR_SINGLE_PARTITION_MESSAGE_ROUTER_HEADER_ +#define PULSAR_SINGLE_PARTITION_MESSAGE_ROUTER_HEADER_ + +#include +#include + +namespace pulsar { + + class SinglePartitionMessageRouter : public MessageRoutingPolicy { + public: + SinglePartitionMessageRouter(unsigned int numPartitions); + typedef boost::hash StringHash; + virtual ~SinglePartitionMessageRouter(); + virtual int getPartition(const Message& msg); + private: + unsigned int numPartitions_; + int selectedSinglePartition_; + }; + +} +#endif // PULSAR_SINGLE_PARTITION_MESSAGE_ROUTER_HEADER_ diff --git a/pulsar-client-cpp/lib/UnAckedMessageTrackerDisabled.h b/pulsar-client-cpp/lib/UnAckedMessageTrackerDisabled.h new file mode 100644 index 0000000000000..217217609abdc --- /dev/null +++ b/pulsar-client-cpp/lib/UnAckedMessageTrackerDisabled.h @@ -0,0 +1,35 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_UNACKEDMESSAGETRACKERDISABLED_H_ +#define LIB_UNACKEDMESSAGETRACKERDISABLED_H_ +#include "lib/UnAckedMessageTrackerInterface.h" +namespace pulsar { + +class UnAckedMessageTrackerDisabled : public UnAckedMessageTrackerInterface { + public: + bool add(const MessageId& m) { + return false; + } + bool remove(const MessageId& m) { + return false; + } + void removeMessagesTill(const MessageId& msgId) { + } +}; + +} +#endif /* LIB_UNACKEDMESSAGETRACKERDISABLED_H_ */ diff --git a/pulsar-client-cpp/lib/UnAckedMessageTrackerEnabled.cc b/pulsar-client-cpp/lib/UnAckedMessageTrackerEnabled.cc new file mode 100644 index 0000000000000..912ce634b80db --- /dev/null +++ b/pulsar-client-cpp/lib/UnAckedMessageTrackerEnabled.cc @@ -0,0 +1,108 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "UnAckedMessageTrackerEnabled.h" + +DECLARE_LOG_OBJECT(); + +namespace pulsar { + +void UnAckedMessageTrackerEnabled::timeoutHandler(const boost::system::error_code& ec) { + if (ec) { + LOG_DEBUG("Ignoring timer cancelled event, code[" << ec <<"]"); + } else { + timeoutHandler(); + } +} + +void UnAckedMessageTrackerEnabled::timeoutHandler() { + timeoutHandlerHelper(); + ExecutorServicePtr executorService = client_->getIOExecutorProvider()->get(); + timer_ = executorService->createDeadlineTimer(); + timer_->expires_from_now(boost::posix_time::milliseconds(timeoutMs_)); + timer_->async_wait( + boost::bind(&pulsar::UnAckedMessageTrackerEnabled::timeoutHandler, this, + boost::asio::placeholders::error)); +} + +void UnAckedMessageTrackerEnabled::timeoutHandlerHelper() { + boost::unique_lock acquire(lock_); + LOG_DEBUG( + "UnAckedMessageTrackerEnabled::timeoutHandlerHelper invoked for consumerPtr_ " << consumerReference_.getName().c_str()); + if (!oldSet_.empty()) { + LOG_INFO( + consumerReference_.getName().c_str() << ": " << oldSet_.size() << " Messages were not acked within "<< timeoutMs_ <<" time"); + oldSet_.clear(); + currentSet_.clear(); + consumerReference_.redeliverUnacknowledgedMessages(); + } + oldSet_.swap(currentSet_); +} + +UnAckedMessageTrackerEnabled::UnAckedMessageTrackerEnabled(long timeoutMs, + const ClientImplPtr client, + ConsumerImplBase& consumer) + : consumerReference_(consumer) { + timeoutMs_ = timeoutMs; + client_ = client; + timeoutHandler(); +} + +bool UnAckedMessageTrackerEnabled::add(const MessageId& m) { + boost::unique_lock acquire(lock_); + oldSet_.erase(m); + return currentSet_.insert(m).second; +} + +bool UnAckedMessageTrackerEnabled::isEmpty() { + boost::unique_lock acquire(lock_); + return oldSet_.empty() && currentSet_.empty(); +} + +bool UnAckedMessageTrackerEnabled::remove(const MessageId& m) { + boost::unique_lock acquire(lock_); + return oldSet_.erase(m) || currentSet_.erase(m); +} + +long UnAckedMessageTrackerEnabled::size() { + boost::unique_lock acquire(lock_); + return oldSet_.size() + currentSet_.size(); +} + +void UnAckedMessageTrackerEnabled::removeMessagesTill(const MessageId& msgId) { + boost::unique_lock acquire(lock_); + for (std::set::iterator it = oldSet_.begin(); it != oldSet_.end();) { + if (*it < msgId && it->partition_ == msgId.partition_) { + oldSet_.erase(it++); + } else { + it++; + } + } + for (std::set::iterator it = currentSet_.begin(); it != currentSet_.end();) { + if (*it < msgId && it->partition_ == msgId.partition_) { + currentSet_.erase(it++); + } else { + it++; + } + } +} + +UnAckedMessageTrackerEnabled::~UnAckedMessageTrackerEnabled() { + if (timer_) { + timer_->cancel(); + } +} +} /* namespace pulsar */ diff --git a/pulsar-client-cpp/lib/UnAckedMessageTrackerEnabled.h b/pulsar-client-cpp/lib/UnAckedMessageTrackerEnabled.h new file mode 100644 index 0000000000000..47a0ab263bfdc --- /dev/null +++ b/pulsar-client-cpp/lib/UnAckedMessageTrackerEnabled.h @@ -0,0 +1,45 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_UNACKEDMESSAGETRACKERENABLED_H_ +#define LIB_UNACKEDMESSAGETRACKERENABLED_H_ +#include "lib/UnAckedMessageTrackerInterface.h" +namespace pulsar { + +class UnAckedMessageTrackerEnabled : public UnAckedMessageTrackerInterface { + public: + ~UnAckedMessageTrackerEnabled(); + UnAckedMessageTrackerEnabled(long timeoutMs, const ClientImplPtr, ConsumerImplBase&); + bool add(const MessageId& m); + bool remove(const MessageId& m); + void removeMessagesTill(const MessageId& msgId); + void timeoutHandler(); + private: + void timeoutHandler(const boost::system::error_code& ec); + void timeoutHandlerHelper(); + bool isEmpty(); + long size(); + std::set currentSet_; + std::set oldSet_; + boost::mutex lock_; + DeadlineTimerPtr timer_; + ConsumerImplBase& consumerReference_; + ClientImplPtr client_; + long timeoutMs_; +}; +} + +#endif /* LIB_UNACKEDMESSAGETRACKERENABLED_H_ */ diff --git a/pulsar-client-cpp/lib/UnAckedMessageTrackerInterface.h b/pulsar-client-cpp/lib/UnAckedMessageTrackerInterface.h new file mode 100644 index 0000000000000..73b70d3f73cd5 --- /dev/null +++ b/pulsar-client-cpp/lib/UnAckedMessageTrackerInterface.h @@ -0,0 +1,50 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_UNACKEDMESSAGETRACKERINTERFACE_H_ +#define LIB_UNACKEDMESSAGETRACKERINTERFACE_H_ +#include +#include +#include +#include +#include +#include "pulsar/MessageId.h" +#include +#include +#include "lib/ClientImpl.h" +#include "lib/ConsumerImplBase.h" +#include +#include +#include +#include "lib/PulsarApi.pb.h" +#include +#include +namespace pulsar { + +class UnAckedMessageTrackerInterface { + public: + virtual ~UnAckedMessageTrackerInterface() { + } + UnAckedMessageTrackerInterface() { + } + virtual bool add(const MessageId& m) = 0; + virtual bool remove(const MessageId& m) = 0; + virtual void removeMessagesTill(const MessageId& msgId) = 0; +}; + +typedef boost::scoped_ptr UnAckedMessageTrackerScopedPtr; +} +#endif /* LIB_UNACKEDMESSAGETRACKERINTERFACE_H_ */ diff --git a/pulsar-client-cpp/lib/UnboundedBlockingQueue.h b/pulsar-client-cpp/lib/UnboundedBlockingQueue.h new file mode 100644 index 0000000000000..4a598fce636e7 --- /dev/null +++ b/pulsar-client-cpp/lib/UnboundedBlockingQueue.h @@ -0,0 +1,147 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_UNBOUNDEDBLOCKINGQUEUE_H_ +#define LIB_UNBOUNDEDBLOCKINGQUEUE_H_ + +#include +#include +#include +// For struct QueueNotEmpty +#include "BlockingQueue.h" + +template +class UnboundedBlockingQueue { + public: + typedef typename boost::circular_buffer Container; + typedef typename Container::iterator iterator; + typedef typename Container::const_iterator const_iterator; + + UnboundedBlockingQueue(size_t maxSize) + : mutex_(), + queue_(maxSize) { + } + + ~UnboundedBlockingQueue() { + Lock lock(mutex_); + queue_.clear(); + } + + void push(const T& value) { + Lock lock(mutex_); + // If the queue is full, wait for space to be available + bool wasEmpty = queue_.empty(); + if (queue_.full()) { + queue_.set_capacity(queue_.size() * 2); + } + queue_.push_back(value); + lock.unlock(); + + if (wasEmpty) { + // Notify that an element is pushed + queueEmptyCondition_.notify_one(); + } + } + + void pop() { + Lock lock(mutex_); + // If the queue is empty, wait until an element is available to be popped + queueEmptyCondition_.wait(lock, QueueNotEmpty >(*this)); + queue_.pop_front(); + lock.unlock(); + } + + void pop(T& value) { + Lock lock(mutex_); + // If the queue is empty, wait until an element is available to be popped + queueEmptyCondition_.wait(lock, QueueNotEmpty >(*this)); + value = queue_.front(); + queue_.pop_front(); + lock.unlock(); + } + + bool pop(T& value, const boost::posix_time::time_duration& timeout) { + Lock lock(mutex_); + if (!queueEmptyCondition_.timed_wait(lock, timeout, + QueueNotEmpty >(*this))) { + return false; + } + + value = queue_.front(); + queue_.pop_front(); + lock.unlock(); + + return true; + } + + // Check the 1st element of the queue + bool peek(T& value) { + Lock lock(mutex_); + if (queue_.empty()) { + return false; + } + + value = queue_.front(); + return true; + } + + // Remove all elements from the queue + void clear() { + Lock lock(mutex_); + queue_.clear(); + } + + size_t size() const { + Lock lock(mutex_); + return queue_.size(); + } + + bool empty() const { + Lock lock(mutex_); + return isEmptyNoMutex(); + } + + const_iterator begin() const { + return queue_.begin(); + } + + const_iterator end() const { + return queue_.end(); + } + + iterator begin() { + return queue_.begin(); + } + + iterator end() { + return queue_.end(); + } + + private: + + bool isEmptyNoMutex() const { + return queue_.empty(); + } + + mutable boost::mutex mutex_; + boost::condition_variable queueEmptyCondition_; + Container queue_; + + typedef boost::unique_lock Lock; + friend struct QueueNotEmpty > ; +}; + +#endif /* LIB_BLOCKINGQUEUE_H_ */ diff --git a/pulsar-client-cpp/lib/Url.cc b/pulsar-client-cpp/lib/Url.cc new file mode 100644 index 0000000000000..09803be6512d0 --- /dev/null +++ b/pulsar-client-cpp/lib/Url.cc @@ -0,0 +1,84 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "Url.h" + +#include +#include +#include + +namespace pulsar { + +static const std::map initDefaultPortsMap() { + std::map defaultPortsMap; + defaultPortsMap["http"] = 80; + defaultPortsMap["https"] = 443; + defaultPortsMap["pulsar"] = 6650; + defaultPortsMap["pulsar+ssl"] = 6651; + return defaultPortsMap; +} + +static const std::map& defaultPortsMap() { + static std::map defaultPortsMap = initDefaultPortsMap(); + return defaultPortsMap; +} + +bool Url::parse(const std::string& urlStr, Url& url) { + std::vector values; + static const boost::regex expression( + // proto host port + "^(\?:([^:/\?#]+)://)\?(\\w+[^/\?#:]*)(\?::(\\d+))\?" + // path file parameters + "(/\?(\?:[^\?#/]*/)*)\?([^\?#]*)\?(\\\?(.*))\?"); + + boost::cmatch groups; + if (!boost::regex_match(urlStr.c_str(), groups, expression)) { + // Invalid url + return false; + } + + url.protocol_ = std::string(groups[1].first, groups[1].second); + url.host_ = std::string(groups[2].first, groups[2].second); + std::string portStr(groups[3].first, groups[3].second); + + if (!portStr.empty()) { + url.port_ = atoi(groups[3].first); + } else { + std::map::const_iterator it = defaultPortsMap().find(url.protocol_); + if (it != defaultPortsMap().end()) { + url.port_ = it->second; + } else { + // Invalid port + return false; + } + } + + return true; +} + +const std::string& Url::protocol() const { + return protocol_; +} + +const std::string& Url::host() const { + return host_; +} + +const int Url::port() const { + return port_; +} + +} // pulsar diff --git a/pulsar-client-cpp/lib/Url.h b/pulsar-client-cpp/lib/Url.h new file mode 100644 index 0000000000000..e922a9b887738 --- /dev/null +++ b/pulsar-client-cpp/lib/Url.h @@ -0,0 +1,47 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_URL_H_ +#define LIB_URL_H_ + +#include + +#pragma GCC visibility push(default) + +namespace pulsar { + +/** + * URL parsing utility + */ +class Url { +public: + static bool parse(const std::string& urlStr, Url& url); + + const std::string& protocol() const; + const std::string& host() const; + const int port() const; + +private: + std::string protocol_; + std::string host_; + int port_; +}; + +} // pulsar + +#pragma GCC visibility pop + +#endif /* LIB_URL_H_ */ diff --git a/pulsar-client-cpp/lib/UtilAllocator.h b/pulsar-client-cpp/lib/UtilAllocator.h new file mode 100644 index 0000000000000..5d21e851305a4 --- /dev/null +++ b/pulsar-client-cpp/lib/UtilAllocator.h @@ -0,0 +1,83 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_UTILALLOCATOR_H_ +#define LIB_UTILALLOCATOR_H_ + +#include + +class HandlerAllocator : private boost::noncopyable { + public: + HandlerAllocator() + : inUse_(false) { + } + + void* allocate(std::size_t size) { + if (!inUse_ && size < storage_.size) { + inUse_ = true; + return storage_.address(); + } else { + return ::operator new(size); + } + } + + void deallocate(void* pointer) { + if (pointer == storage_.address()) { + inUse_ = false; + } else { + ::operator delete(pointer); + } + } + + private: + // Storage space used for handler-based custom memory allocation. + boost::aligned_storage<1024> storage_; + bool inUse_; +}; + +template +class AllocHandler { + public: + AllocHandler(HandlerAllocator& a, Handler h) + : allocator_(a), + handler_(h) { + } + + template + void operator()(Arg1 arg1) { + handler_(arg1); + } + + template + void operator()(Arg1 arg1, Arg2 arg2) { + handler_(arg1, arg2); + } + + friend void* asio_handler_allocate(std::size_t size, AllocHandler* thisHandler) { + return thisHandler->allocator_.allocate(size); + } + + friend void asio_handler_deallocate(void* ptr, std::size_t, + AllocHandler* thisHandler) { + thisHandler->allocator_.deallocate(ptr); + } + + private: + HandlerAllocator& allocator_; + Handler handler_; +}; + +#endif /* LIB_UTILALLOCATOR_H_ */ diff --git a/pulsar-client-cpp/lib/Utils.h b/pulsar-client-cpp/lib/Utils.h new file mode 100644 index 0000000000000..3ef3074d2a367 --- /dev/null +++ b/pulsar-client-cpp/lib/Utils.h @@ -0,0 +1,70 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef UTILS_HPP_ +#define UTILS_HPP_ + +#include + +#include "Future.h" + +namespace pulsar { + +struct WaitForCallback { + Promise& m_promise; + + WaitForCallback(Promise& promise) + : m_promise(promise) { + } + + void operator()(Result result) { + m_promise.setValue(result); + } +}; + +template +struct WaitForCallbackValue { + Promise & m_promise; + + WaitForCallbackValue(Promise& promise) + : m_promise(promise) { + } + + void operator()(Result result, const T& value) { + if (result == ResultOk) { + m_promise.setValue(value); + } else { + m_promise.setFailed(result); + } + } +}; + +template +struct WaitForCallbackType { + Promise& m_promise; + + WaitForCallbackType(Promise& promise) + : m_promise(promise) { + } + + void operator()(T result) { + m_promise.setValue(result); + } +}; + +} + +#endif /* UTILS_HPP_ */ diff --git a/pulsar-client-cpp/lib/Version.h b/pulsar-client-cpp/lib/Version.h new file mode 100644 index 0000000000000..9dfbb76947461 --- /dev/null +++ b/pulsar-client-cpp/lib/Version.h @@ -0,0 +1,24 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef LIB_VERSION_H_ +#define LIB_VERSION_H_ + +#ifndef _PULSAR_VERSION_ +#define _PULSAR_VERSION_ "1.17" +#endif + +#endif /* LIB_VERSION_H_ */ diff --git a/pulsar-client-cpp/lib/auth/AuthTls.cc b/pulsar-client-cpp/lib/auth/AuthTls.cc new file mode 100644 index 0000000000000..4cfca6b1ba8b3 --- /dev/null +++ b/pulsar-client-cpp/lib/auth/AuthTls.cc @@ -0,0 +1,25 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "AuthTls.h" + +namespace pulsar { + +extern "C" Authentication* create(const std::string ¶ms) { + return new AuthTls(params); +} + +} diff --git a/pulsar-client-cpp/lib/auth/AuthTls.h b/pulsar-client-cpp/lib/auth/AuthTls.h new file mode 100644 index 0000000000000..e7d68dd88c8d0 --- /dev/null +++ b/pulsar-client-cpp/lib/auth/AuthTls.h @@ -0,0 +1,49 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef PULSAR_AUTH_TLS_H_ +#define PULSAR_AUTH_TLS_H_ + +#include +#include +#include + +namespace pulsar { + +class AuthTls : public Authentication { +public: + AuthTls(const std::string& params) { + } + + ~AuthTls() { + } + + static AuthenticationPtr create(const std::string& params) { + return boost::shared_ptr(new AuthTls(params)); + } + + const std::string getAuthMethodName() const { + return "tls"; + } + + Result getAuthData(std::string& authDataContent) const { + authDataContent = "THIS_SHOULD_BE_REPLACED"; + return ResultOk; + } +}; + +} +#endif /* PULSAR_AUTH_TLS_H_ */ diff --git a/pulsar-client-cpp/lib/auth/CMakeLists.txt b/pulsar-client-cpp/lib/auth/CMakeLists.txt new file mode 100644 index 0000000000000..37b2e8f3ce9e1 --- /dev/null +++ b/pulsar-client-cpp/lib/auth/CMakeLists.txt @@ -0,0 +1,3 @@ +add_library(authTls MODULE AuthTls.cc) +target_link_libraries(authTls ${CLIENT_LIBS}) +set_target_properties(authTls PROPERTIES OUTPUT_NAME authtls) diff --git a/pulsar-client-cpp/lib/checksum/ChecksumProvider.cc b/pulsar-client-cpp/lib/checksum/ChecksumProvider.cc new file mode 100644 index 0000000000000..ed80c3130e10c --- /dev/null +++ b/pulsar-client-cpp/lib/checksum/ChecksumProvider.cc @@ -0,0 +1,60 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "ChecksumProvider.h" + +#include +#include "crc32c_sse42.h" +#include "crc32c_sw.h" + +namespace pulsar { +bool isCrc32cSupported = crc32cSupported(); + +bool crc32cSupported() { + return crc32c_initialize(); +} + +/** + * computes crc32c checksum: uses sse4.2 hardware-instruction to compute crc32c if machine supports else it computes using sw algo + * @param + * previousChecksum = in case of incremental-checksum-computation pass previous computed else pass 0 in other case. + * data = for which checksum will be computed + * length = length of data from offset + */ +uint32_t computeChecksum(uint32_t previousChecksum, const void * data, int length) { + if (isCrc32cSupported) { + return crc32cHw(previousChecksum, data, length); + } else { + return crc32cSw(previousChecksum, data, length); + } +} + +/** + * Computes crc32c using hardware sse4.2 instruction + */ +uint32_t crc32cHw(uint32_t previousChecksum, const void * data, int length) { + assert(isCrc32cSupported); + return crc32c(previousChecksum, data, length, 0); +} + +/** + * Computes crc32c using sw crc-table algo + */ +uint32_t crc32cSw(uint32_t previousChecksum, const void * data, int length) { + return crc32c_sw(previousChecksum, data, length); +} + +} diff --git a/pulsar-client-cpp/lib/checksum/ChecksumProvider.h b/pulsar-client-cpp/lib/checksum/ChecksumProvider.h new file mode 100644 index 0000000000000..1937a5ea2af0a --- /dev/null +++ b/pulsar-client-cpp/lib/checksum/ChecksumProvider.h @@ -0,0 +1,34 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef _CHECKSUM_PROVIDER_H_ +#define _CHECKSUM_PROVIDER_H_ + +#include + +#pragma GCC visibility push(default) + +namespace pulsar { + +bool crc32cSupported(); +uint32_t computeChecksum(uint32_t previousChecksum, const void *data, int length); +uint32_t crc32cHw(uint32_t previousChecksum, const void * data, int length); +uint32_t crc32cSw(uint32_t previousChecksum, const void * data, int length); +} + +#pragma GCC visibility pop + +#endif // _CHECKSUM_PROVIDER_H_ diff --git a/pulsar-client-cpp/lib/checksum/crc32c_sse42.cc b/pulsar-client-cpp/lib/checksum/crc32c_sse42.cc new file mode 100644 index 0000000000000..1185acc51362e --- /dev/null +++ b/pulsar-client-cpp/lib/checksum/crc32c_sse42.cc @@ -0,0 +1,232 @@ +/******************************************************************************* + * Copyright 2014 Trevor Robinson + * + * Licensed 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. + ******************************************************************************/ +#include "crc32c_sse42.h" + +#include +#include // SSE4.2 +#include // PCLMUL + +#ifdef _MSC_VER +# include +#else +# include +#endif + +//#define CRC32C_DEBUG +#define CRC32C_PCLMULQDQ + +#ifdef CRC32C_DEBUG +# include +# define DEBUG_PRINTF1(fmt, v1) printf(fmt, v1) +# define DEBUG_PRINTF2(fmt, v1, v2) printf(fmt, v1, v2) +# define DEBUG_PRINTF3(fmt, v1, v2, v3) printf(fmt, v1, v2, v3) +# define DEBUG_PRINTF4(fmt, v1, v2, v3, v4) printf(fmt, v1, v2, v3, v4) +#else +# define DEBUG_PRINTF1(fmt, v1) +# define DEBUG_PRINTF2(fmt, v1, v2) +# define DEBUG_PRINTF3(fmt, v1, v2, v3) +# define DEBUG_PRINTF4(fmt, v1, v2, v3, v4) +#endif + +static bool initialized = false; +static bool has_sse42 = false; +static bool has_pclmulqdq = false; + +bool crc32c_initialize() { + if (!initialized) { + const uint32_t cpuid_ecx_sse42 = (1 << 20); + const uint32_t cpuid_ecx_pclmulqdq = (1 << 1); + +#ifdef _MSC_VER + int CPUInfo[4] = {}; + __cpuid(CPUInfo, 1); + has_sse42 = (CPUInfo[2] & cpuid_ecx_sse42) != 0; + has_pclmulqdq = (CPUInfo[2] & cpuid_ecx_pclmulqdq) != 0; +#else + unsigned int eax, ebx, ecx, edx; + if (__get_cpuid(1, &eax, &ebx, &ecx, &edx)) { + has_sse42 = (ecx & cpuid_ecx_sse42) != 0; + has_pclmulqdq = (ecx & cpuid_ecx_pclmulqdq) != 0; + } +#endif + DEBUG_PRINTF1("has_sse42 = %d\n", has_sse42);DEBUG_PRINTF1("has_pclmulqdq = %d\n", has_pclmulqdq); + initialized = true; + } + return has_sse42; +} + +#include "gf2.hpp" + +chunk_config::chunk_config(size_t words, const chunk_config* next) + : words(words), + next(next) { + assert(words > 0); + assert(!next || next->words < words); + const size_t loop_bytes = loops() * 8; + make_shift_table(loop_bytes, shift1); + make_shift_table(loop_bytes * 2, shift2); +} + +void chunk_config::make_shift_table(size_t bytes, uint32_t table[256]) { + bitmatrix<32, 32> op; + op.lower_shift(); + op[0] = 0x82f63b78; // reversed CRC-32C polynomial + bitmatrix<32, 32> m; + pow(m, op, bytes * 8); + for (unsigned int i = 0; i < 256; ++i) + table[i] = (const bitvector<32> ) mul(m, bitvector<32>(i)); +} + +static uint32_t crc32c_chunk(uint32_t crc, const void *buf, const chunk_config& config) { + DEBUG_PRINTF3(" crc32c_chunk(crc = 0x%08x, buf = %p, config.words = " SIZE_T_FORMAT ")", crc, buf, config.words); + + const uint64_t *pq = (const uint64_t*) buf; + uint64_t crc0 = config.extra() > 1 ? _mm_crc32_u64(crc, *pq++) : crc; + uint64_t crc1 = 0; + uint64_t crc2 = 0; + const size_t loops = config.loops(); + for (unsigned int i = 0; i < loops; ++i, ++pq) { + crc1 = _mm_crc32_u64(crc1, pq[1 * loops]); + crc2 = _mm_crc32_u64(crc2, pq[2 * loops]); + crc0 = _mm_crc32_u64(crc0, pq[0 * loops]); + } + pq += 2 * loops; + uint64_t tmp = *pq++; +# ifdef CRC32C_PCLMULQDQ + if (has_pclmulqdq) { + __m128i k = _mm_set_epi64x(config.shift1[1], config.shift2[1]); + __m128i mul1 = _mm_clmulepi64_si128(_mm_cvtsi64_si128((int64_t ) crc1), k, 0x10); + __m128i mul0 = _mm_clmulepi64_si128(_mm_cvtsi64_si128((int64_t ) crc0), k, 0x00); + tmp ^= (uint64_t) _mm_cvtsi128_si64(mul1); + tmp ^= (uint64_t) _mm_cvtsi128_si64(mul0); + } else +# endif + { + tmp ^= config.shift1[crc1 & 0xff]; + tmp ^= ((uint64_t) config.shift1[(crc1 >> 8) & 0xff]) << 8; + tmp ^= ((uint64_t) config.shift1[(crc1 >> 16) & 0xff]) << 16; + tmp ^= ((uint64_t) config.shift1[(crc1 >> 24) & 0xff]) << 24; + + tmp ^= config.shift2[crc0 & 0xff]; + tmp ^= ((uint64_t) config.shift2[(crc0 >> 8) & 0xff]) << 8; + tmp ^= ((uint64_t) config.shift2[(crc0 >> 16) & 0xff]) << 16; + tmp ^= ((uint64_t) config.shift2[(crc0 >> 24) & 0xff]) << 24; + } + crc2 = _mm_crc32_u64(crc2, tmp); + if (config.extra() > 2) // only if words is divisible by 3 + crc2 = _mm_crc32_u64(crc2, *pq); + crc = (uint32_t) crc2; + + DEBUG_PRINTF1(" = 0x%08x\n", crc); + return crc; +} + +static uint32_t crc32c_words(uint32_t crc, const void *buf, size_t count) { + DEBUG_PRINTF3(" crc32c_words(crc = 0x%08x, buf = %p, count = " SIZE_T_FORMAT ")", crc, buf, count); + + const uint64_t *pq = (const uint64_t*) buf; + size_t loops = (count + 7) / 8; + assert(loops > 0); + switch (count & 7) { + case 0: + do { + crc = (uint32_t) _mm_crc32_u64(crc, *pq++); + case 7: + crc = (uint32_t) _mm_crc32_u64(crc, *pq++); + case 6: + crc = (uint32_t) _mm_crc32_u64(crc, *pq++); + case 5: + crc = (uint32_t) _mm_crc32_u64(crc, *pq++); + case 4: + crc = (uint32_t) _mm_crc32_u64(crc, *pq++); + case 3: + crc = (uint32_t) _mm_crc32_u64(crc, *pq++); + case 2: + crc = (uint32_t) _mm_crc32_u64(crc, *pq++); + case 1: + crc = (uint32_t) _mm_crc32_u64(crc, *pq++); + } while (--loops > 0); + } + + DEBUG_PRINTF1(" = 0x%08x\n", crc); + return crc; +} + +static uint32_t crc32c_bytes(uint32_t crc, const void *buf, size_t count) { + DEBUG_PRINTF3(" crc32c_bytes(crc = 0x%08x, buf = %p, count = " SIZE_T_FORMAT ")", crc, buf, count); + + const uint8_t *pc = (const uint8_t*) buf; + size_t loops = (count + 7) / 8; + assert(loops > 0); + switch (count & 7) { + case 0: + do { + crc = (uint32_t) _mm_crc32_u8(crc, *pc++); + case 7: + crc = (uint32_t) _mm_crc32_u8(crc, *pc++); + case 6: + crc = (uint32_t) _mm_crc32_u8(crc, *pc++); + case 5: + crc = (uint32_t) _mm_crc32_u8(crc, *pc++); + case 4: + crc = (uint32_t) _mm_crc32_u8(crc, *pc++); + case 3: + crc = (uint32_t) _mm_crc32_u8(crc, *pc++); + case 2: + crc = (uint32_t) _mm_crc32_u8(crc, *pc++); + case 1: + crc = (uint32_t) _mm_crc32_u8(crc, *pc++); + } while (--loops > 0); + } + + DEBUG_PRINTF1(" = 0x%08x\n", crc); + return crc; +} + +uint32_t crc32c(uint32_t init, const void *buf, size_t len, const chunk_config* config) { + DEBUG_PRINTF3("crc32c(init = 0x%08x, buf = %p, len = " SIZE_T_FORMAT ")\n", init, buf, len); + + uint32_t crc = ~init; + const char *pc = (const char*) buf; + if (len >= 24) { + if ((uintptr_t) pc & 7) { + size_t unaligned = 8 - ((uintptr_t) pc & 7); + crc = crc32c_bytes(crc, pc, unaligned); + pc += unaligned; + len -= unaligned; + } + size_t words = len / 8; + while (config) { + while (words >= config->words) { + crc = crc32c_chunk(crc, pc, *config); + pc += config->words * 8; + words -= config->words; + } + config = config->next; + } + if (words > 0) { + crc = crc32c_words(crc, pc, words); + pc += words * 8; + } + len &= 7; + } + if (len) + crc = crc32c_bytes(crc, pc, len); + crc = ~crc; + + DEBUG_PRINTF1("crc = 0x%08x\n", crc); + return crc; +} diff --git a/pulsar-client-cpp/lib/checksum/crc32c_sse42.h b/pulsar-client-cpp/lib/checksum/crc32c_sse42.h new file mode 100644 index 0000000000000..6cd2298cbae40 --- /dev/null +++ b/pulsar-client-cpp/lib/checksum/crc32c_sse42.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 2014 Trevor Robinson + * + * Licensed 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. + ******************************************************************************/ +#include "int_types.h" + +bool crc32c_initialize(); + +class chunk_config { + public: + enum { + min_words = 4 + }; + + const size_t words; + const chunk_config* const next; + uint32_t shift1[256]; + uint32_t shift2[256]; + + chunk_config(size_t words, const chunk_config* next = 0); + + size_t loops() const { + return (words - 1) / 3; + } + size_t extra() const { + return (words - 1) % 3 + 1; + } + + private: + chunk_config& operator=(const chunk_config&); + + static void make_shift_table(size_t bytes, uint32_t table[256]); +}; + +uint32_t crc32c(uint32_t init, const void *buf, size_t len, const chunk_config* config); diff --git a/pulsar-client-cpp/lib/checksum/crc32c_sw.cc b/pulsar-client-cpp/lib/checksum/crc32c_sw.cc new file mode 100644 index 0000000000000..d900808c02754 --- /dev/null +++ b/pulsar-client-cpp/lib/checksum/crc32c_sw.cc @@ -0,0 +1,102 @@ +/* crc32c.c -- compute CRC-32C using the Intel crc32 instruction + * Copyright (C) 2013 Mark Adler + * Version 1.1 1 Aug 2013 Mark Adler + */ + +/* + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler + madler@alumni.caltech.edu + */ + +/* Use hardware CRC instruction on Intel SSE 4.2 processors. This computes a + CRC-32C, *not* the CRC-32 used by Ethernet and zip, gzip, etc. A software + version is provided as a fall-back, as well as for speed comparisons. */ + +/* Version history: + 1.0 10 Feb 2013 First version + 1.1 1 Aug 2013 Correct comments on why three crc instructions in parallel + */ + +#include "crc32c_sw.h" +#include +#include +#include +#include +#include + +/* CRC-32C (iSCSI) polynomial in reversed bit order. */ +#define POLY 0x82f63b78 + +/* Table for a quadword-at-a-time software crc. */ +static pthread_once_t crc32c_once_sw = PTHREAD_ONCE_INIT; +static uint32_t crc32c_table[8][256]; + +/* Construct table for software CRC-32C calculation. */ +static void crc32c_init_sw(void) { + uint32_t n, crc, k; + + for (n = 0; n < 256; n++) { + crc = n; + crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; + crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; + crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; + crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; + crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; + crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; + crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; + crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1; + crc32c_table[0][n] = crc; + } + for (n = 0; n < 256; n++) { + crc = crc32c_table[0][n]; + for (k = 1; k < 8; k++) { + crc = crc32c_table[0][crc & 0xff] ^ (crc >> 8); + crc32c_table[k][n] = crc; + } + } +} + +/* Table-driven software version as a fall-back. This is about 15 times slower + than using the hardware instructions. This assumes little-endian integers, + as is the case on Intel processors that the assembler code here is for. */ +uint32_t crc32c_sw(uint32_t crci, const void *buf, int len) { + const char* next = (const char*) buf; + uint64_t crc; + + pthread_once(&crc32c_once_sw, crc32c_init_sw); + crc = crci ^ 0xffffffff; + while (len && ((uintptr_t) next & 7) != 0) { + crc = crc32c_table[0][(crc ^ *next++) & 0xff] ^ (crc >> 8); + len--; + } + while (len >= 8) { + crc ^= *(uint64_t *) next; + crc = crc32c_table[7][crc & 0xff] ^ crc32c_table[6][(crc >> 8) & 0xff] + ^ crc32c_table[5][(crc >> 16) & 0xff] ^ crc32c_table[4][(crc >> 24) & 0xff] + ^ crc32c_table[3][(crc >> 32) & 0xff] ^ crc32c_table[2][(crc >> 40) & 0xff] + ^ crc32c_table[1][(crc >> 48) & 0xff] ^ crc32c_table[0][crc >> 56]; + next += 8; + len -= 8; + } + while (len) { + crc = crc32c_table[0][(crc ^ *next++) & 0xff] ^ (crc >> 8); + len--; + } + return (uint32_t) crc ^ 0xffffffff; +} diff --git a/pulsar-client-cpp/lib/checksum/crc32c_sw.h b/pulsar-client-cpp/lib/checksum/crc32c_sw.h new file mode 100644 index 0000000000000..744c9558de5df --- /dev/null +++ b/pulsar-client-cpp/lib/checksum/crc32c_sw.h @@ -0,0 +1,8 @@ +#ifndef LOGGING_CRC32C_SW_H__ +#define LOGGING_CRC32C_SW_H__ + +#include + +uint32_t crc32c_sw(uint32_t crc, const void* data, int length); + +#endif diff --git a/pulsar-client-cpp/lib/checksum/gf2.hpp b/pulsar-client-cpp/lib/checksum/gf2.hpp new file mode 100644 index 0000000000000..b7348a4f58e34 --- /dev/null +++ b/pulsar-client-cpp/lib/checksum/gf2.hpp @@ -0,0 +1,199 @@ +/******************************************************************************* + * Copyright 2014 Trevor Robinson + * + * Licensed 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. + ******************************************************************************/ +#include "int_types.h" +#include // std::swap + +#ifdef _MSC_VER +#pragma warning(disable:4146) // unary minus operator applied to unsigned type, result still unsigned +#endif + +// Type trait for unsigned integers of at least N bytes +template +struct uint_bytes { + enum { + is_defined = 0 + }; +}; + +template +struct defined_uint_bytes { + enum { + is_defined = 1 + }; + typedef T type; +}; + +template<> struct uint_bytes<1> : defined_uint_bytes { +}; +template<> struct uint_bytes<2> : defined_uint_bytes { +}; +template<> struct uint_bytes<3> : defined_uint_bytes { +}; +template<> struct uint_bytes<4> : defined_uint_bytes { +}; +template<> struct uint_bytes<5> : defined_uint_bytes { +}; +template<> struct uint_bytes<6> : defined_uint_bytes { +}; +template<> struct uint_bytes<7> : defined_uint_bytes { +}; +template<> struct uint_bytes<8> : defined_uint_bytes { +}; + +// Type trait for unsigned integers of at least N bits +template +struct uint_bits : uint_bytes<(N + 7) / 8> { + enum { + bits = 8 * sizeof(typename uint_bits::type) + }; +}; + +// Bit vector of N bits; currently just exposes an unsigned integer +template +class bitvector { + typedef typename uint_bits::type type; + type value; + public: + bitvector() { + } + bitvector(type value) + : value(value) { + } + operator type&() { + return value; + } + operator type() const { + return value; + } +}; + +// Bit matrix of M columns by N rows +template +class bitmatrix { + typedef bitvector row; + row value[N]; + public: + bitmatrix() { + } + explicit bitmatrix(bool b) { + if (b) + identity(); + else + null(); + } + void null() { + for (unsigned int i = 0; i < N; ++i) + value[i] = 0; + } + void identity() { + for (unsigned int i = 0; i < N; ++i) + value[i] = i < M ? (const row) 1 << i : 0; + } + void lower_shift() { + for (unsigned int i = 0; i < N; ++i) + value[i] = i > 0 && i <= M ? (const row) 1 << (i - 1) : 0; + } + void upper_shift() { + for (unsigned int i = 0; i < N; ++i) + value[i] = i + 1 < M ? (const row) 1 << (i + 1) : 0; + } + operator bitvector*() { + return value; + } + operator const bitvector*() const { + return value; + } +}; + +/* + * Multiplies MxN matrix A by N-row vector B in GF(2). + * + * For M,N = 3: + * + * | a b c | | x | | ax + by + cz | + * A = | d e f |, B = | y |, AB = | dx + ey + fz | + * | g h i | | z | | gx + hy + iz | + * + * In GF(2), addition corresponds to XOR and multiplication to AND: + * + * | (a & x) ^ (b & y) ^ (c & z) | + * AB = | (d & x) ^ (e & y) ^ (f & z) | + * | (g & x) ^ (h & y) ^ (i & z) | + * + * Trading variable names for [row,column] indices: + * + * AB = (A[,0] & B[0]) ^ (A[,1] & B[1]) ^ (A[,2] & B[2]) ^ ... + * + * Assuming columns are represented as words and rows as bit offsets, + * all rows of AB can be calculated in parallel: + * + * AB = (A[0] & -((B >> 0) & 1) ^ (A[1] & -((B >> 1) & 1) ^ ... + */ +template +bitvector mul(const bitmatrix& a, const bitvector b) { + bitvector result(0); + for (unsigned int i = 0; i < N; ++i) + result ^= a[i] & -((b >> i) & 1); + return result; +} + +/* + * Multiplies MxN matrix A by NxP matrix B in GF(2). + * + * For M,N,P = 3: + * + * | a b c | | j k l | | (aj + bm + cp) (ak + bn + cq) (al + bo + cr) | + * A = | d e f |, B = | m n o |, AB = | (dj + em + fp) (dk + en + fq) (dl + eo + fr) | + * | g h i | | p q r | | (gj + hm + ip) (gk + hn + iq) (gl + ho + ir) | + */ +template +void mul(bitmatrix& result, const bitmatrix& a, const bitmatrix& b) { + for (unsigned int i = 0; i < P; i++) + result[i] = mul(a, b[i]); +} + +/* + * Squares an NxN matrix in GF(2). + */ +template +void sqr(bitmatrix& result, const bitmatrix& a) { + mul(result, a, a); +} + +/* + * Raises an NxN matrix to the power n in GF(2) by squaring. + */ +template +void pow(bitmatrix& result, const bitmatrix& a, uint64_t n) { + result.identity(); + if (n > 0) { + bitmatrix square = a; + bitmatrix temp; + bitmatrix *ptemp = &temp, *psquare = &square, *presult = &result; + for (;;) { + if (n & 1) { + mul(*ptemp, *presult, *psquare); + std::swap(ptemp, presult); + } + if (!(n >>= 1)) + break; + sqr(*ptemp, *psquare); + std::swap(ptemp, psquare); + } + if (presult != &result) + result = *presult; + } +} diff --git a/pulsar-client-cpp/lib/checksum/int_types.h b/pulsar-client-cpp/lib/checksum/int_types.h new file mode 100644 index 0000000000000..16c5c85489cf5 --- /dev/null +++ b/pulsar-client-cpp/lib/checksum/int_types.h @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2014 Trevor Robinson + * + * Licensed 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. + ******************************************************************************/ +#include // size_t + +#if defined(_MSC_VER) && _MSC_VER < 1600 // stdint.h added in MSVC 2010 + +typedef __int8 int8_t; +typedef __int16 int16_t; +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; + +#else + +# include + +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 // MSVC 2015 + +# define SIZE_T_FORMAT "%Iu" + +#else + +# define SIZE_T_FORMAT "%zu" + +#endif diff --git a/pulsar-client-cpp/lib/lz4/lz4.c b/pulsar-client-cpp/lib/lz4/lz4.c new file mode 100644 index 0000000000000..08cf6b5cd72b8 --- /dev/null +++ b/pulsar-client-cpp/lib/lz4/lz4.c @@ -0,0 +1,1516 @@ +/* + LZ4 - Fast LZ compression algorithm + Copyright (C) 2011-2015, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - LZ4 source repository : https://github.com/Cyan4973/lz4 + - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c +*/ + + +/************************************** +* Tuning parameters +**************************************/ +/* + * HEAPMODE : + * Select how default compression functions will allocate memory for their hash table, + * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()). + */ +#define HEAPMODE 0 + +/* + * ACCELERATION_DEFAULT : + * Select "acceleration" for LZ4_compress_fast() when parameter value <= 0 + */ +#define ACCELERATION_DEFAULT 1 + + +/************************************** +* CPU Feature Detection +**************************************/ +/* + * LZ4_FORCE_SW_BITCOUNT + * Define this parameter if your target system or compiler does not support hardware bit count + */ +#if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for Windows CE does not support Hardware bit count */ +# define LZ4_FORCE_SW_BITCOUNT +#endif + + +/************************************** +* Includes +**************************************/ +#include "lz4.h" + + +/************************************** +* Compiler Options +**************************************/ +#ifdef _MSC_VER /* Visual Studio */ +# define FORCE_INLINE static __forceinline +# include +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +# pragma warning(disable : 4293) /* disable: C4293: too large shift (32-bits) */ +#else +# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ +# if defined(__GNUC__) || defined(__clang__) +# define FORCE_INLINE static inline __attribute__((always_inline)) +# else +# define FORCE_INLINE static inline +# endif +# else +# define FORCE_INLINE static +# endif /* __STDC_VERSION__ */ +#endif /* _MSC_VER */ + +/* LZ4_GCC_VERSION is defined into lz4.h */ +#if (LZ4_GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__) +# define expect(expr,value) (__builtin_expect ((expr),(value)) ) +#else +# define expect(expr,value) (expr) +#endif + +#define likely(expr) expect((expr) != 0, 1) +#define unlikely(expr) expect((expr) != 0, 0) + + +/************************************** +* Memory routines +**************************************/ +#include /* malloc, calloc, free */ +#define ALLOCATOR(n,s) calloc(n,s) +#define FREEMEM free +#include /* memset, memcpy */ +#define MEM_INIT memset + + +/************************************** +* Basic Types +**************************************/ +#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ +# include + typedef uint8_t BYTE; + typedef uint16_t U16; + typedef uint32_t U32; + typedef int32_t S32; + typedef uint64_t U64; +#else + typedef unsigned char BYTE; + typedef unsigned short U16; + typedef unsigned int U32; + typedef signed int S32; + typedef unsigned long long U64; +#endif + + +/************************************** +* Reading and writing into memory +**************************************/ +#define STEPSIZE sizeof(size_t) + +static unsigned LZ4_64bits(void) { return sizeof(void*)==8; } + +static unsigned LZ4_isLittleEndian(void) +{ + const union { U32 i; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ + return one.c[0]; +} + + +static U16 LZ4_read16(const void* memPtr) +{ + U16 val16; + memcpy(&val16, memPtr, 2); + return val16; +} + +static U16 LZ4_readLE16(const void* memPtr) +{ + if (LZ4_isLittleEndian()) + { + return LZ4_read16(memPtr); + } + else + { + const BYTE* p = (const BYTE*)memPtr; + return (U16)((U16)p[0] + (p[1]<<8)); + } +} + +static void LZ4_writeLE16(void* memPtr, U16 value) +{ + if (LZ4_isLittleEndian()) + { + memcpy(memPtr, &value, 2); + } + else + { + BYTE* p = (BYTE*)memPtr; + p[0] = (BYTE) value; + p[1] = (BYTE)(value>>8); + } +} + +static U32 LZ4_read32(const void* memPtr) +{ + U32 val32; + memcpy(&val32, memPtr, 4); + return val32; +} + +static U64 LZ4_read64(const void* memPtr) +{ + U64 val64; + memcpy(&val64, memPtr, 8); + return val64; +} + +static size_t LZ4_read_ARCH(const void* p) +{ + if (LZ4_64bits()) + return (size_t)LZ4_read64(p); + else + return (size_t)LZ4_read32(p); +} + + +static void LZ4_copy4(void* dstPtr, const void* srcPtr) { memcpy(dstPtr, srcPtr, 4); } + +static void LZ4_copy8(void* dstPtr, const void* srcPtr) { memcpy(dstPtr, srcPtr, 8); } + +/* customized version of memcpy, which may overwrite up to 7 bytes beyond dstEnd */ +static void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd) +{ + BYTE* d = (BYTE*)dstPtr; + const BYTE* s = (const BYTE*)srcPtr; + BYTE* e = (BYTE*)dstEnd; + do { LZ4_copy8(d,s); d+=8; s+=8; } while (d>3); +# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (__builtin_ctzll((U64)val) >> 3); +# else + static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; + return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; +# endif + } + else /* 32 bits */ + { +# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r; + _BitScanForward( &r, (U32)val ); + return (int)(r>>3); +# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (__builtin_ctz((U32)val) >> 3); +# else + static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 }; + return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; +# endif + } + } + else /* Big Endian CPU */ + { + if (LZ4_64bits()) + { +# if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r = 0; + _BitScanReverse64( &r, val ); + return (unsigned)(r>>3); +# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (__builtin_clzll((U64)val) >> 3); +# else + unsigned r; + if (!(val>>32)) { r=4; } else { r=0; val>>=32; } + if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } + r += (!val); + return r; +# endif + } + else /* 32 bits */ + { +# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r = 0; + _BitScanReverse( &r, (unsigned long)val ); + return (unsigned)(r>>3); +# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (__builtin_clz((U32)val) >> 3); +# else + unsigned r; + if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; } + r += (!val); + return r; +# endif + } + } +} + +static unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit) +{ + const BYTE* const pStart = pIn; + + while (likely(pIn compression run slower on incompressible data */ + + +/************************************** +* Local Structures and types +**************************************/ +typedef struct { + U32 hashTable[HASH_SIZE_U32]; + U32 currentOffset; + U32 initCheck; + const BYTE* dictionary; + BYTE* bufferStart; /* obsolete, used for slideInputBuffer */ + U32 dictSize; +} LZ4_stream_t_internal; + +typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive; +typedef enum { byPtr, byU32, byU16 } tableType_t; + +typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive; +typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive; + +typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive; +typedef enum { full = 0, partial = 1 } earlyEnd_directive; + + +/************************************** +* Local Utils +**************************************/ +int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; } +int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); } +int LZ4_sizeofState() { return LZ4_STREAMSIZE; } + + + +/******************************** +* Compression functions +********************************/ + +static U32 LZ4_hashSequence(U32 sequence, tableType_t const tableType) +{ + if (tableType == byU16) + return (((sequence) * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); + else + return (((sequence) * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); +} + +static const U64 prime5bytes = 889523592379ULL; +static U32 LZ4_hashSequence64(size_t sequence, tableType_t const tableType) +{ + const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG+1 : LZ4_HASHLOG; + const U32 hashMask = (1<> (40 - hashLog)) & hashMask; +} + +static U32 LZ4_hashSequenceT(size_t sequence, tableType_t const tableType) +{ + if (LZ4_64bits()) + return LZ4_hashSequence64(sequence, tableType); + return LZ4_hashSequence((U32)sequence, tableType); +} + +static U32 LZ4_hashPosition(const void* p, tableType_t tableType) { return LZ4_hashSequenceT(LZ4_read_ARCH(p), tableType); } + +static void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t const tableType, const BYTE* srcBase) +{ + switch (tableType) + { + case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = p; return; } + case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); return; } + case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); return; } + } +} + +static void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) +{ + U32 h = LZ4_hashPosition(p, tableType); + LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase); +} + +static const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase) +{ + if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; } + if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return hashTable[h] + srcBase; } + { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */ +} + +static const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) +{ + U32 h = LZ4_hashPosition(p, tableType); + return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase); +} + +FORCE_INLINE int LZ4_compress_generic( + void* const ctx, + const char* const source, + char* const dest, + const int inputSize, + const int maxOutputSize, + const limitedOutput_directive outputLimited, + const tableType_t tableType, + const dict_directive dict, + const dictIssue_directive dictIssue, + const U32 acceleration) +{ + LZ4_stream_t_internal* const dictPtr = (LZ4_stream_t_internal*)ctx; + + const BYTE* ip = (const BYTE*) source; + const BYTE* base; + const BYTE* lowLimit; + const BYTE* const lowRefLimit = ip - dictPtr->dictSize; + const BYTE* const dictionary = dictPtr->dictionary; + const BYTE* const dictEnd = dictionary + dictPtr->dictSize; + const size_t dictDelta = dictEnd - (const BYTE*)source; + const BYTE* anchor = (const BYTE*) source; + const BYTE* const iend = ip + inputSize; + const BYTE* const mflimit = iend - MFLIMIT; + const BYTE* const matchlimit = iend - LASTLITERALS; + + BYTE* op = (BYTE*) dest; + BYTE* const olimit = op + maxOutputSize; + + U32 forwardH; + size_t refDelta=0; + + /* Init conditions */ + if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */ + switch(dict) + { + case noDict: + default: + base = (const BYTE*)source; + lowLimit = (const BYTE*)source; + break; + case withPrefix64k: + base = (const BYTE*)source - dictPtr->currentOffset; + lowLimit = (const BYTE*)source - dictPtr->dictSize; + break; + case usingExtDict: + base = (const BYTE*)source - dictPtr->currentOffset; + lowLimit = (const BYTE*)source; + break; + } + if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */ + if (inputSize> LZ4_skipTrigger); + + if (unlikely(forwardIp > mflimit)) goto _last_literals; + + match = LZ4_getPositionOnHash(h, ctx, tableType, base); + if (dict==usingExtDict) + { + if (match<(const BYTE*)source) + { + refDelta = dictDelta; + lowLimit = dictionary; + } + else + { + refDelta = 0; + lowLimit = (const BYTE*)source; + } + } + forwardH = LZ4_hashPosition(forwardIp, tableType); + LZ4_putPositionOnHash(ip, h, ctx, tableType, base); + + } while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0) + || ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip)) + || (LZ4_read32(match+refDelta) != LZ4_read32(ip)) ); + } + + /* Catch up */ + while ((ip>anchor) && (match+refDelta > lowLimit) && (unlikely(ip[-1]==match[refDelta-1]))) { ip--; match--; } + + { + /* Encode Literal length */ + unsigned litLength = (unsigned)(ip - anchor); + token = op++; + if ((outputLimited) && (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit))) + return 0; /* Check output limit */ + if (litLength>=RUN_MASK) + { + int len = (int)litLength-RUN_MASK; + *token=(RUN_MASK<= 255 ; len-=255) *op++ = 255; + *op++ = (BYTE)len; + } + else *token = (BYTE)(litLength< matchlimit) limit = matchlimit; + matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, limit); + ip += MINMATCH + matchLength; + if (ip==limit) + { + unsigned more = LZ4_count(ip, (const BYTE*)source, matchlimit); + matchLength += more; + ip += more; + } + } + else + { + matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); + ip += MINMATCH + matchLength; + } + + if ((outputLimited) && (unlikely(op + (1 + LASTLITERALS) + (matchLength>>8) > olimit))) + return 0; /* Check output limit */ + if (matchLength>=ML_MASK) + { + *token += ML_MASK; + matchLength -= ML_MASK; + for (; matchLength >= 510 ; matchLength-=510) { *op++ = 255; *op++ = 255; } + if (matchLength >= 255) { matchLength-=255; *op++ = 255; } + *op++ = (BYTE)matchLength; + } + else *token += (BYTE)(matchLength); + } + + anchor = ip; + + /* Test end of chunk */ + if (ip > mflimit) break; + + /* Fill table */ + LZ4_putPosition(ip-2, ctx, tableType, base); + + /* Test next position */ + match = LZ4_getPosition(ip, ctx, tableType, base); + if (dict==usingExtDict) + { + if (match<(const BYTE*)source) + { + refDelta = dictDelta; + lowLimit = dictionary; + } + else + { + refDelta = 0; + lowLimit = (const BYTE*)source; + } + } + LZ4_putPosition(ip, ctx, tableType, base); + if ( ((dictIssue==dictSmall) ? (match>=lowRefLimit) : 1) + && (match+MAX_DISTANCE>=ip) + && (LZ4_read32(match+refDelta)==LZ4_read32(ip)) ) + { token=op++; *token=0; goto _next_match; } + + /* Prepare next loop */ + forwardH = LZ4_hashPosition(++ip, tableType); + } + +_last_literals: + /* Encode Last Literals */ + { + const size_t lastRun = (size_t)(iend - anchor); + if ((outputLimited) && ((op - (BYTE*)dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) + return 0; /* Check output limit */ + if (lastRun >= RUN_MASK) + { + size_t accumulator = lastRun - RUN_MASK; + *op++ = RUN_MASK << ML_BITS; + for(; accumulator >= 255 ; accumulator-=255) *op++ = 255; + *op++ = (BYTE) accumulator; + } + else + { + *op++ = (BYTE)(lastRun<= LZ4_compressBound(inputSize)) + { + if (inputSize < LZ4_64Klimit) + return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue, acceleration); + else + return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration); + } + else + { + if (inputSize < LZ4_64Klimit) + return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); + else + return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration); + } +} + + +int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) +{ +#if (HEAPMODE) + void* ctxPtr = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ +#else + LZ4_stream_t ctx; + void* ctxPtr = &ctx; +#endif + + int result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration); + +#if (HEAPMODE) + FREEMEM(ctxPtr); +#endif + return result; +} + + +int LZ4_compress_default(const char* source, char* dest, int inputSize, int maxOutputSize) +{ + return LZ4_compress_fast(source, dest, inputSize, maxOutputSize, 1); +} + + +/* hidden debug function */ +/* strangely enough, gcc generates faster code when this function is uncommented, even if unused */ +int LZ4_compress_fast_force(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) +{ + LZ4_stream_t ctx; + + LZ4_resetStream(&ctx); + + if (inputSize < LZ4_64Klimit) + return LZ4_compress_generic(&ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); + else + return LZ4_compress_generic(&ctx, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration); +} + + +/******************************** +* destSize variant +********************************/ + +static int LZ4_compress_destSize_generic( + void* const ctx, + const char* const src, + char* const dst, + int* const srcSizePtr, + const int targetDstSize, + const tableType_t tableType) +{ + const BYTE* ip = (const BYTE*) src; + const BYTE* base = (const BYTE*) src; + const BYTE* lowLimit = (const BYTE*) src; + const BYTE* anchor = ip; + const BYTE* const iend = ip + *srcSizePtr; + const BYTE* const mflimit = iend - MFLIMIT; + const BYTE* const matchlimit = iend - LASTLITERALS; + + BYTE* op = (BYTE*) dst; + BYTE* const oend = op + targetDstSize; + BYTE* const oMaxLit = op + targetDstSize - 2 /* offset */ - 8 /* because 8+MINMATCH==MFLIMIT */ - 1 /* token */; + BYTE* const oMaxMatch = op + targetDstSize - (LASTLITERALS + 1 /* token */); + BYTE* const oMaxSeq = oMaxLit - 1 /* token */; + + U32 forwardH; + + + /* Init conditions */ + if (targetDstSize < 1) return 0; /* Impossible to store anything */ + if ((U32)*srcSizePtr > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */ + if ((tableType == byU16) && (*srcSizePtr>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */ + if (*srcSizePtr> LZ4_skipTrigger); + + if (unlikely(forwardIp > mflimit)) + goto _last_literals; + + match = LZ4_getPositionOnHash(h, ctx, tableType, base); + forwardH = LZ4_hashPosition(forwardIp, tableType); + LZ4_putPositionOnHash(ip, h, ctx, tableType, base); + + } while ( ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip)) + || (LZ4_read32(match) != LZ4_read32(ip)) ); + } + + /* Catch up */ + while ((ip>anchor) && (match > lowLimit) && (unlikely(ip[-1]==match[-1]))) { ip--; match--; } + + { + /* Encode Literal length */ + unsigned litLength = (unsigned)(ip - anchor); + token = op++; + if (op + ((litLength+240)/255) + litLength > oMaxLit) + { + /* Not enough space for a last match */ + op--; + goto _last_literals; + } + if (litLength>=RUN_MASK) + { + unsigned len = litLength - RUN_MASK; + *token=(RUN_MASK<= 255 ; len-=255) *op++ = 255; + *op++ = (BYTE)len; + } + else *token = (BYTE)(litLength< oMaxMatch) + { + /* Match description too long : reduce it */ + matchLength = (15-1) + (oMaxMatch-op) * 255; + } + //printf("offset %5i, matchLength%5i \n", (int)(ip-match), matchLength + MINMATCH); + ip += MINMATCH + matchLength; + + if (matchLength>=ML_MASK) + { + *token += ML_MASK; + matchLength -= ML_MASK; + while (matchLength >= 255) { matchLength-=255; *op++ = 255; } + *op++ = (BYTE)matchLength; + } + else *token += (BYTE)(matchLength); + } + + anchor = ip; + + /* Test end of block */ + if (ip > mflimit) break; + if (op > oMaxSeq) break; + + /* Fill table */ + LZ4_putPosition(ip-2, ctx, tableType, base); + + /* Test next position */ + match = LZ4_getPosition(ip, ctx, tableType, base); + LZ4_putPosition(ip, ctx, tableType, base); + if ( (match+MAX_DISTANCE>=ip) + && (LZ4_read32(match)==LZ4_read32(ip)) ) + { token=op++; *token=0; goto _next_match; } + + /* Prepare next loop */ + forwardH = LZ4_hashPosition(++ip, tableType); + } + +_last_literals: + /* Encode Last Literals */ + { + size_t lastRunSize = (size_t)(iend - anchor); + if (op + 1 /* token */ + ((lastRunSize+240)/255) /* litLength */ + lastRunSize /* literals */ > oend) + { + /* adapt lastRunSize to fill 'dst' */ + lastRunSize = (oend-op) - 1; + lastRunSize -= (lastRunSize+240)/255; + } + ip = anchor + lastRunSize; + + if (lastRunSize >= RUN_MASK) + { + size_t accumulator = lastRunSize - RUN_MASK; + *op++ = RUN_MASK << ML_BITS; + for(; accumulator >= 255 ; accumulator-=255) *op++ = 255; + *op++ = (BYTE) accumulator; + } + else + { + *op++ = (BYTE)(lastRunSize<= LZ4_compressBound(*srcSizePtr)) /* compression success is guaranteed */ + { + return LZ4_compress_fast_extState(state, src, dst, *srcSizePtr, targetDstSize, 1); + } + else + { + if (*srcSizePtr < LZ4_64Klimit) + return LZ4_compress_destSize_generic(state, src, dst, srcSizePtr, targetDstSize, byU16); + else + return LZ4_compress_destSize_generic(state, src, dst, srcSizePtr, targetDstSize, LZ4_64bits() ? byU32 : byPtr); + } +} + + +int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize) +{ +#if (HEAPMODE) + void* ctx = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ +#else + LZ4_stream_t ctxBody; + void* ctx = &ctxBody; +#endif + + int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize); + +#if (HEAPMODE) + FREEMEM(ctx); +#endif + return result; +} + + + +/******************************** +* Streaming functions +********************************/ + +LZ4_stream_t* LZ4_createStream(void) +{ + LZ4_stream_t* lz4s = (LZ4_stream_t*)ALLOCATOR(8, LZ4_STREAMSIZE_U64); + LZ4_STATIC_ASSERT(LZ4_STREAMSIZE >= sizeof(LZ4_stream_t_internal)); /* A compilation error here means LZ4_STREAMSIZE is not large enough */ + LZ4_resetStream(lz4s); + return lz4s; +} + +void LZ4_resetStream (LZ4_stream_t* LZ4_stream) +{ + MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t)); +} + +int LZ4_freeStream (LZ4_stream_t* LZ4_stream) +{ + FREEMEM(LZ4_stream); + return (0); +} + + +#define HASH_UNIT sizeof(size_t) +int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) +{ + LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict; + const BYTE* p = (const BYTE*)dictionary; + const BYTE* const dictEnd = p + dictSize; + const BYTE* base; + + if ((dict->initCheck) || (dict->currentOffset > 1 GB)) /* Uninitialized structure, or reuse overflow */ + LZ4_resetStream(LZ4_dict); + + if (dictSize < (int)HASH_UNIT) + { + dict->dictionary = NULL; + dict->dictSize = 0; + return 0; + } + + if ((dictEnd - p) > 64 KB) p = dictEnd - 64 KB; + dict->currentOffset += 64 KB; + base = p - dict->currentOffset; + dict->dictionary = p; + dict->dictSize = (U32)(dictEnd - p); + dict->currentOffset += dict->dictSize; + + while (p <= dictEnd-HASH_UNIT) + { + LZ4_putPosition(p, dict->hashTable, byU32, base); + p+=3; + } + + return dict->dictSize; +} + + +static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src) +{ + if ((LZ4_dict->currentOffset > 0x80000000) || + ((size_t)LZ4_dict->currentOffset > (size_t)src)) /* address space overflow */ + { + /* rescale hash table */ + U32 delta = LZ4_dict->currentOffset - 64 KB; + const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize; + int i; + for (i=0; ihashTable[i] < delta) LZ4_dict->hashTable[i]=0; + else LZ4_dict->hashTable[i] -= delta; + } + LZ4_dict->currentOffset = 64 KB; + if (LZ4_dict->dictSize > 64 KB) LZ4_dict->dictSize = 64 KB; + LZ4_dict->dictionary = dictEnd - LZ4_dict->dictSize; + } +} + + +int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) +{ + LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_stream; + const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize; + + const BYTE* smallest = (const BYTE*) source; + if (streamPtr->initCheck) return 0; /* Uninitialized structure detected */ + if ((streamPtr->dictSize>0) && (smallest>dictEnd)) smallest = dictEnd; + LZ4_renormDictT(streamPtr, smallest); + if (acceleration < 1) acceleration = ACCELERATION_DEFAULT; + + /* Check overlapping input/dictionary space */ + { + const BYTE* sourceEnd = (const BYTE*) source + inputSize; + if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd)) + { + streamPtr->dictSize = (U32)(dictEnd - sourceEnd); + if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB; + if (streamPtr->dictSize < 4) streamPtr->dictSize = 0; + streamPtr->dictionary = dictEnd - streamPtr->dictSize; + } + } + + /* prefix mode : source data follows dictionary */ + if (dictEnd == (const BYTE*)source) + { + int result; + if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) + result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, dictSmall, acceleration); + else + result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, noDictIssue, acceleration); + streamPtr->dictSize += (U32)inputSize; + streamPtr->currentOffset += (U32)inputSize; + return result; + } + + /* external dictionary mode */ + { + int result; + if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) + result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, dictSmall, acceleration); + else + result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, noDictIssue, acceleration); + streamPtr->dictionary = (const BYTE*)source; + streamPtr->dictSize = (U32)inputSize; + streamPtr->currentOffset += (U32)inputSize; + return result; + } +} + + +/* Hidden debug function, to force external dictionary mode */ +int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int inputSize) +{ + LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_dict; + int result; + const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize; + + const BYTE* smallest = dictEnd; + if (smallest > (const BYTE*) source) smallest = (const BYTE*) source; + LZ4_renormDictT((LZ4_stream_t_internal*)LZ4_dict, smallest); + + result = LZ4_compress_generic(LZ4_dict, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue, 1); + + streamPtr->dictionary = (const BYTE*)source; + streamPtr->dictSize = (U32)inputSize; + streamPtr->currentOffset += (U32)inputSize; + + return result; +} + + +int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize) +{ + LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict; + const BYTE* previousDictEnd = dict->dictionary + dict->dictSize; + + if ((U32)dictSize > 64 KB) dictSize = 64 KB; /* useless to define a dictionary > 64 KB */ + if ((U32)dictSize > dict->dictSize) dictSize = dict->dictSize; + + memmove(safeBuffer, previousDictEnd - dictSize, dictSize); + + dict->dictionary = (const BYTE*)safeBuffer; + dict->dictSize = (U32)dictSize; + + return dictSize; +} + + + +/******************************* +* Decompression functions +*******************************/ +/* + * This generic decompression function cover all use cases. + * It shall be instantiated several times, using different sets of directives + * Note that it is essential this generic function is really inlined, + * in order to remove useless branches during compilation optimization. + */ +FORCE_INLINE int LZ4_decompress_generic( + const char* const source, + char* const dest, + int inputSize, + int outputSize, /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */ + + int endOnInput, /* endOnOutputSize, endOnInputSize */ + int partialDecoding, /* full, partial */ + int targetOutputSize, /* only used if partialDecoding==partial */ + int dict, /* noDict, withPrefix64k, usingExtDict */ + const BYTE* const lowPrefix, /* == dest if dict == noDict */ + const BYTE* const dictStart, /* only if dict==usingExtDict */ + const size_t dictSize /* note : = 0 if noDict */ + ) +{ + /* Local Variables */ + const BYTE* ip = (const BYTE*) source; + const BYTE* const iend = ip + inputSize; + + BYTE* op = (BYTE*) dest; + BYTE* const oend = op + outputSize; + BYTE* cpy; + BYTE* oexit = op + targetOutputSize; + const BYTE* const lowLimit = lowPrefix - dictSize; + + const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize; + const size_t dec32table[] = {4, 1, 2, 1, 4, 4, 4, 4}; + const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3}; + + const int safeDecode = (endOnInput==endOnInputSize); + const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB))); + + + /* Special cases */ + if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => decode everything */ + if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */ + if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1); + + + /* Main Loop */ + while (1) + { + unsigned token; + size_t length; + const BYTE* match; + + /* get literal length */ + token = *ip++; + if ((length=(token>>ML_BITS)) == RUN_MASK) + { + unsigned s; + do + { + s = *ip++; + length += s; + } + while (likely((endOnInput)?ip(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) ) + || ((!endOnInput) && (cpy>oend-COPYLENGTH))) + { + if (partialDecoding) + { + if (cpy > oend) goto _output_error; /* Error : write attempt beyond end of output buffer */ + if ((endOnInput) && (ip+length > iend)) goto _output_error; /* Error : read attempt beyond end of input buffer */ + } + else + { + if ((!endOnInput) && (cpy != oend)) goto _output_error; /* Error : block decoding must stop exactly there */ + if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; /* Error : input must be consumed */ + } + memcpy(op, ip, length); + ip += length; + op += length; + break; /* Necessarily EOF, due to parsing restrictions */ + } + LZ4_wildCopy(op, ip, cpy); + ip += length; op = cpy; + + /* get offset */ + match = cpy - LZ4_readLE16(ip); ip+=2; + if ((checkOffset) && (unlikely(match < lowLimit))) goto _output_error; /* Error : offset outside destination buffer */ + + /* get matchlength */ + length = token & ML_MASK; + if (length == ML_MASK) + { + unsigned s; + do + { + if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error; + s = *ip++; + length += s; + } while (s==255); + if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)op)) goto _output_error; /* overflow detection */ + } + length += MINMATCH; + + /* check external dictionary */ + if ((dict==usingExtDict) && (match < lowPrefix)) + { + if (unlikely(op+length > oend-LASTLITERALS)) goto _output_error; /* doesn't respect parsing restriction */ + + if (length <= (size_t)(lowPrefix-match)) + { + /* match can be copied as a single segment from external dictionary */ + match = dictEnd - (lowPrefix-match); + memmove(op, match, length); op += length; + } + else + { + /* match encompass external dictionary and current segment */ + size_t copySize = (size_t)(lowPrefix-match); + memcpy(op, dictEnd - copySize, copySize); + op += copySize; + copySize = length - copySize; + if (copySize > (size_t)(op-lowPrefix)) /* overlap within current segment */ + { + BYTE* const endOfMatch = op + copySize; + const BYTE* copyFrom = lowPrefix; + while (op < endOfMatch) *op++ = *copyFrom++; + } + else + { + memcpy(op, lowPrefix, copySize); + op += copySize; + } + } + continue; + } + + /* copy repeated sequence */ + cpy = op + length; + if (unlikely((op-match)<8)) + { + const size_t dec64 = dec64table[op-match]; + op[0] = match[0]; + op[1] = match[1]; + op[2] = match[2]; + op[3] = match[3]; + match += dec32table[op-match]; + LZ4_copy4(op+4, match); + op += 8; match -= dec64; + } else { LZ4_copy8(op, match); op+=8; match+=8; } + + if (unlikely(cpy>oend-12)) + { + if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last LASTLITERALS bytes must be literals */ + if (op < oend-8) + { + LZ4_wildCopy(op, match, oend-8); + match += (oend-8) - op; + op = oend-8; + } + while (opprefixSize = (size_t) dictSize; + lz4sd->prefixEnd = (const BYTE*) dictionary + dictSize; + lz4sd->externalDict = NULL; + lz4sd->extDictSize = 0; + return 1; +} + +/* +*_continue() : + These decoding functions allow decompression of multiple blocks in "streaming" mode. + Previously decoded blocks must still be available at the memory position where they were decoded. + If it's not possible, save the relevant part of decoded data into a safe buffer, + and indicate where it stands using LZ4_setStreamDecode() +*/ +int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize) +{ + LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; + int result; + + if (lz4sd->prefixEnd == (BYTE*)dest) + { + result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, + endOnInputSize, full, 0, + usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); + if (result <= 0) return result; + lz4sd->prefixSize += result; + lz4sd->prefixEnd += result; + } + else + { + lz4sd->extDictSize = lz4sd->prefixSize; + lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; + result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, + endOnInputSize, full, 0, + usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize); + if (result <= 0) return result; + lz4sd->prefixSize = result; + lz4sd->prefixEnd = (BYTE*)dest + result; + } + + return result; +} + +int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize) +{ + LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; + int result; + + if (lz4sd->prefixEnd == (BYTE*)dest) + { + result = LZ4_decompress_generic(source, dest, 0, originalSize, + endOnOutputSize, full, 0, + usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); + if (result <= 0) return result; + lz4sd->prefixSize += originalSize; + lz4sd->prefixEnd += originalSize; + } + else + { + lz4sd->extDictSize = lz4sd->prefixSize; + lz4sd->externalDict = (BYTE*)dest - lz4sd->extDictSize; + result = LZ4_decompress_generic(source, dest, 0, originalSize, + endOnOutputSize, full, 0, + usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize); + if (result <= 0) return result; + lz4sd->prefixSize = originalSize; + lz4sd->prefixEnd = (BYTE*)dest + originalSize; + } + + return result; +} + + +/* +Advanced decoding functions : +*_usingDict() : + These decoding functions work the same as "_continue" ones, + the dictionary must be explicitly provided within parameters +*/ + +FORCE_INLINE int LZ4_decompress_usingDict_generic(const char* source, char* dest, int compressedSize, int maxOutputSize, int safe, const char* dictStart, int dictSize) +{ + if (dictSize==0) + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest, NULL, 0); + if (dictStart+dictSize == dest) + { + if (dictSize >= (int)(64 KB - 1)) + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, withPrefix64k, (BYTE*)dest-64 KB, NULL, 0); + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest-dictSize, NULL, 0); + } + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize); +} + +int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize) +{ + return LZ4_decompress_usingDict_generic(source, dest, compressedSize, maxOutputSize, 1, dictStart, dictSize); +} + +int LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize) +{ + return LZ4_decompress_usingDict_generic(source, dest, 0, originalSize, 0, dictStart, dictSize); +} + +/* debug function */ +int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize) +{ + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize); +} + + +/*************************************************** +* Obsolete Functions +***************************************************/ +/* obsolete compression functions */ +int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize) { return LZ4_compress_default(source, dest, inputSize, maxOutputSize); } +int LZ4_compress(const char* source, char* dest, int inputSize) { return LZ4_compress_default(source, dest, inputSize, LZ4_compressBound(inputSize)); } +int LZ4_compress_limitedOutput_withState (void* state, const char* src, char* dst, int srcSize, int dstSize) { return LZ4_compress_fast_extState(state, src, dst, srcSize, dstSize, 1); } +int LZ4_compress_withState (void* state, const char* src, char* dst, int srcSize) { return LZ4_compress_fast_extState(state, src, dst, srcSize, LZ4_compressBound(srcSize), 1); } +int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_stream, const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_fast_continue(LZ4_stream, src, dst, srcSize, maxDstSize, 1); } +int LZ4_compress_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize) { return LZ4_compress_fast_continue(LZ4_stream, source, dest, inputSize, LZ4_compressBound(inputSize), 1); } + +/* +These function names are deprecated and should no longer be used. +They are only provided here for compatibility with older user programs. +- LZ4_uncompress is totally equivalent to LZ4_decompress_fast +- LZ4_uncompress_unknownOutputSize is totally equivalent to LZ4_decompress_safe +*/ +int LZ4_uncompress (const char* source, char* dest, int outputSize) { return LZ4_decompress_fast(source, dest, outputSize); } +int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize) { return LZ4_decompress_safe(source, dest, isize, maxOutputSize); } + + +/* Obsolete Streaming functions */ + +int LZ4_sizeofStreamState() { return LZ4_STREAMSIZE; } + +static void LZ4_init(LZ4_stream_t_internal* lz4ds, BYTE* base) +{ + MEM_INIT(lz4ds, 0, LZ4_STREAMSIZE); + lz4ds->bufferStart = base; +} + +int LZ4_resetStreamState(void* state, char* inputBuffer) +{ + if ((((size_t)state) & 3) != 0) return 1; /* Error : pointer is not aligned on 4-bytes boundary */ + LZ4_init((LZ4_stream_t_internal*)state, (BYTE*)inputBuffer); + return 0; +} + +void* LZ4_create (char* inputBuffer) +{ + void* lz4ds = ALLOCATOR(8, LZ4_STREAMSIZE_U64); + LZ4_init ((LZ4_stream_t_internal*)lz4ds, (BYTE*)inputBuffer); + return lz4ds; +} + +char* LZ4_slideInputBuffer (void* LZ4_Data) +{ + LZ4_stream_t_internal* ctx = (LZ4_stream_t_internal*)LZ4_Data; + int dictSize = LZ4_saveDict((LZ4_stream_t*)LZ4_Data, (char*)ctx->bufferStart, 64 KB); + return (char*)(ctx->bufferStart + dictSize); +} + +/* Obsolete streaming decompression functions */ + +int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize) +{ + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB); +} + +int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int originalSize) +{ + return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB); +} + +#endif /* LZ4_COMMONDEFS_ONLY */ + diff --git a/pulsar-client-cpp/lib/lz4/lz4.h b/pulsar-client-cpp/lib/lz4/lz4.h new file mode 100644 index 0000000000000..3e7400225612f --- /dev/null +++ b/pulsar-client-cpp/lib/lz4/lz4.h @@ -0,0 +1,360 @@ +/* + LZ4 - Fast LZ compression algorithm + Header File + Copyright (C) 2011-2015, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - LZ4 source repository : https://github.com/Cyan4973/lz4 + - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c +*/ +#pragma once + +#if defined (__cplusplus) +extern "C" { +#endif + +/* + * lz4.h provides block compression functions, and gives full buffer control to programmer. + * If you need to generate inter-operable compressed data (respecting LZ4 frame specification), + * and can let the library handle its own memory, please use lz4frame.h instead. +*/ + +/************************************** +* Version +**************************************/ +#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ +#define LZ4_VERSION_MINOR 7 /* for new (non-breaking) interface capabilities */ +#define LZ4_VERSION_RELEASE 1 /* for tweaks, bug-fixes, or development */ +#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) +int LZ4_versionNumber (void); + +/************************************** +* Tuning parameter +**************************************/ +/* + * LZ4_MEMORY_USAGE : + * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) + * Increasing memory usage improves compression ratio + * Reduced memory usage can improve speed, due to cache effect + * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache + */ +#define LZ4_MEMORY_USAGE 14 + + +/************************************** +* Simple Functions +**************************************/ + +int LZ4_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize); +int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize); + +/* +LZ4_compress_default() : + Compresses 'sourceSize' bytes from buffer 'source' + into already allocated 'dest' buffer of size 'maxDestSize'. + Compression is guaranteed to succeed if 'maxDestSize' >= LZ4_compressBound(sourceSize). + It also runs faster, so it's a recommended setting. + If the function cannot compress 'source' into a more limited 'dest' budget, + compression stops *immediately*, and the function result is zero. + As a consequence, 'dest' content is not valid. + This function never writes outside 'dest' buffer, nor read outside 'source' buffer. + sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE + maxDestSize : full or partial size of buffer 'dest' (which must be already allocated) + return : the number of bytes written into buffer 'dest' (necessarily <= maxOutputSize) + or 0 if compression fails + +LZ4_decompress_safe() : + compressedSize : is the precise full size of the compressed block. + maxDecompressedSize : is the size of destination buffer, which must be already allocated. + return : the number of bytes decompressed into destination buffer (necessarily <= maxDecompressedSize) + If destination buffer is not large enough, decoding will stop and output an error code (<0). + If the source stream is detected malformed, the function will stop decoding and return a negative result. + This function is protected against buffer overflow exploits, including malicious data packets. + It never writes outside output buffer, nor reads outside input buffer. +*/ + + +/************************************** +* Advanced Functions +**************************************/ +#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ +#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) + +/* +LZ4_compressBound() : + Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible) + This function is primarily useful for memory allocation purposes (destination buffer size). + Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example). + Note that LZ4_compress_default() compress faster when dest buffer size is >= LZ4_compressBound(srcSize) + inputSize : max supported value is LZ4_MAX_INPUT_SIZE + return : maximum output size in a "worst case" scenario + or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) +*/ +int LZ4_compressBound(int inputSize); + +/* +LZ4_compress_fast() : + Same as LZ4_compress_default(), but allows to select an "acceleration" factor. + The larger the acceleration value, the faster the algorithm, but also the lesser the compression. + It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed. + An acceleration value of "1" is the same as regular LZ4_compress_default() + Values <= 0 will be replaced by ACCELERATION_DEFAULT (see lz4.c), which is 1. +*/ +int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int maxDestSize, int acceleration); + + +/* +LZ4_compress_fast_extState() : + Same compression function, just using an externally allocated memory space to store compression state. + Use LZ4_sizeofState() to know how much memory must be allocated, + and allocate it on 8-bytes boundaries (using malloc() typically). + Then, provide it as 'void* state' to compression function. +*/ +int LZ4_sizeofState(void); +int LZ4_compress_fast_extState (void* state, const char* source, char* dest, int inputSize, int maxDestSize, int acceleration); + + +/* +LZ4_compress_destSize() : + Reverse the logic, by compressing as much data as possible from 'source' buffer + into already allocated buffer 'dest' of size 'targetDestSize'. + This function either compresses the entire 'source' content into 'dest' if it's large enough, + or fill 'dest' buffer completely with as much data as possible from 'source'. + *sourceSizePtr : will be modified to indicate how many bytes where read from 'source' to fill 'dest'. + New value is necessarily <= old value. + return : Nb bytes written into 'dest' (necessarily <= targetDestSize) + or 0 if compression fails +*/ +int LZ4_compress_destSize (const char* source, char* dest, int* sourceSizePtr, int targetDestSize); + + +/* +LZ4_decompress_fast() : + originalSize : is the original and therefore uncompressed size + return : the number of bytes read from the source buffer (in other words, the compressed size) + If the source stream is detected malformed, the function will stop decoding and return a negative result. + Destination buffer must be already allocated. Its size must be a minimum of 'originalSize' bytes. + note : This function fully respect memory boundaries for properly formed compressed data. + It is a bit faster than LZ4_decompress_safe(). + However, it does not provide any protection against intentionally modified data stream (malicious input). + Use this function in trusted environment only (data to decode comes from a trusted source). +*/ +int LZ4_decompress_fast (const char* source, char* dest, int originalSize); + +/* +LZ4_decompress_safe_partial() : + This function decompress a compressed block of size 'compressedSize' at position 'source' + into destination buffer 'dest' of size 'maxDecompressedSize'. + The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached, + reducing decompression time. + return : the number of bytes decoded in the destination buffer (necessarily <= maxDecompressedSize) + Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller. + Always control how many bytes were decoded. + If the source stream is detected malformed, the function will stop decoding and return a negative result. + This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets +*/ +int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize); + + +/*********************************************** +* Streaming Compression Functions +***********************************************/ +#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4) +#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(long long)) +/* + * LZ4_stream_t + * information structure to track an LZ4 stream. + * important : init this structure content before first use ! + * note : only allocated directly the structure if you are statically linking LZ4 + * If you are using liblz4 as a DLL, please use below construction methods instead. + */ +typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t; + +/* + * LZ4_resetStream + * Use this function to init an allocated LZ4_stream_t structure + */ +void LZ4_resetStream (LZ4_stream_t* streamPtr); + +/* + * LZ4_createStream will allocate and initialize an LZ4_stream_t structure + * LZ4_freeStream releases its memory. + * In the context of a DLL (liblz4), please use these methods rather than the static struct. + * They are more future proof, in case of a change of LZ4_stream_t size. + */ +LZ4_stream_t* LZ4_createStream(void); +int LZ4_freeStream (LZ4_stream_t* streamPtr); + +/* + * LZ4_loadDict + * Use this function to load a static dictionary into LZ4_stream. + * Any previous data will be forgotten, only 'dictionary' will remain in memory. + * Loading a size of 0 is allowed. + * Return : dictionary size, in bytes (necessarily <= 64 KB) + */ +int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize); + +/* + * LZ4_compress_fast_continue + * Compress buffer content 'src', using data from previously compressed blocks as dictionary to improve compression ratio. + * Important : Previous data blocks are assumed to still be present and unmodified ! + * 'dst' buffer must be already allocated. + * If maxDstSize >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster. + * If not, and if compressed data cannot fit into 'dst' buffer size, compression stops, and function returns a zero. + */ +int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int maxDstSize, int acceleration); + +/* + * LZ4_saveDict + * If previously compressed data block is not guaranteed to remain available at its memory location + * save it into a safer place (char* safeBuffer) + * Note : you don't need to call LZ4_loadDict() afterwards, + * dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue() + * Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error + */ +int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int dictSize); + + +/************************************************ +* Streaming Decompression Functions +************************************************/ + +#define LZ4_STREAMDECODESIZE_U64 4 +#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long)) +typedef struct { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; } LZ4_streamDecode_t; +/* + * LZ4_streamDecode_t + * information structure to track an LZ4 stream. + * init this structure content using LZ4_setStreamDecode or memset() before first use ! + * + * In the context of a DLL (liblz4) please prefer usage of construction methods below. + * They are more future proof, in case of a change of LZ4_streamDecode_t size in the future. + * LZ4_createStreamDecode will allocate and initialize an LZ4_streamDecode_t structure + * LZ4_freeStreamDecode releases its memory. + */ +LZ4_streamDecode_t* LZ4_createStreamDecode(void); +int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream); + +/* + * LZ4_setStreamDecode + * Use this function to instruct where to find the dictionary. + * Setting a size of 0 is allowed (same effect as reset). + * Return : 1 if OK, 0 if error + */ +int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize); + +/* +*_continue() : + These decoding functions allow decompression of multiple blocks in "streaming" mode. + Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB) + In the case of a ring buffers, decoding buffer must be either : + - Exactly same size as encoding buffer, with same update rule (block boundaries at same positions) + In which case, the decoding & encoding ring buffer can have any size, including very small ones ( < 64 KB). + - Larger than encoding buffer, by a minimum of maxBlockSize more bytes. + maxBlockSize is implementation dependent. It's the maximum size you intend to compress into a single block. + In which case, encoding and decoding buffers do not need to be synchronized, + and encoding ring buffer can have any size, including small ones ( < 64 KB). + - _At least_ 64 KB + 8 bytes + maxBlockSize. + In which case, encoding and decoding buffers do not need to be synchronized, + and encoding ring buffer can have any size, including larger than decoding buffer. + Whenever these conditions are not possible, save the last 64KB of decoded data into a safe buffer, + and indicate where it is saved using LZ4_setStreamDecode() +*/ +int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize); +int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize); + + +/* +Advanced decoding functions : +*_usingDict() : + These decoding functions work the same as + a combination of LZ4_setStreamDecode() followed by LZ4_decompress_x_continue() + They are stand-alone. They don't need nor update an LZ4_streamDecode_t structure. +*/ +int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize); +int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize); + + + +/************************************** +* Obsolete Functions +**************************************/ +/* Deprecate Warnings */ +/* Should these warnings messages be a problem, + it is generally possible to disable them, + with -Wno-deprecated-declarations for gcc + or _CRT_SECURE_NO_WARNINGS in Visual for example. + You can also define LZ4_DEPRECATE_WARNING_DEFBLOCK. */ +#ifndef LZ4_DEPRECATE_WARNING_DEFBLOCK +# define LZ4_DEPRECATE_WARNING_DEFBLOCK +# define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) +# if (LZ4_GCC_VERSION >= 405) || defined(__clang__) +# define LZ4_DEPRECATED(message) __attribute__((deprecated(message))) +# elif (LZ4_GCC_VERSION >= 301) +# define LZ4_DEPRECATED(message) __attribute__((deprecated)) +# elif defined(_MSC_VER) +# define LZ4_DEPRECATED(message) __declspec(deprecated(message)) +# else +# pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler") +# define LZ4_DEPRECATED(message) +# endif +#endif /* LZ4_DEPRECATE_WARNING_DEFBLOCK */ + +/* Obsolete compression functions */ +/* These functions are planned to start generate warnings by r131 approximately */ +int LZ4_compress (const char* source, char* dest, int sourceSize); +int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize); +int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); +int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); +int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize); +int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize); + +/* Obsolete decompression functions */ +/* These function names are completely deprecated and must no longer be used. + They are only provided here for compatibility with older programs. + - LZ4_uncompress is the same as LZ4_decompress_fast + - LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe + These function prototypes are now disabled; uncomment them only if you really need them. + It is highly recommended to stop using these prototypes and migrate to maintained ones */ +/* int LZ4_uncompress (const char* source, char* dest, int outputSize); */ +/* int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); */ + +/* Obsolete streaming functions; use new streaming interface whenever possible */ +LZ4_DEPRECATED("use LZ4_createStream() instead") void* LZ4_create (char* inputBuffer); +LZ4_DEPRECATED("use LZ4_createStream() instead") int LZ4_sizeofStreamState(void); +LZ4_DEPRECATED("use LZ4_resetStream() instead") int LZ4_resetStreamState(void* state, char* inputBuffer); +LZ4_DEPRECATED("use LZ4_saveDict() instead") char* LZ4_slideInputBuffer (void* state); + +/* Obsolete streaming decoding functions */ +LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize); +LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize); + + +#if defined (__cplusplus) +} +#endif diff --git a/pulsar-client-cpp/log4cxx.conf b/pulsar-client-cpp/log4cxx.conf new file mode 100644 index 0000000000000..ae26da2d9e96d --- /dev/null +++ b/pulsar-client-cpp/log4cxx.conf @@ -0,0 +1,29 @@ +# +# Copyright 2016 Yahoo Inc. +# +# Licensed 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. +# + +# Set root logger level to INFO and its only appender to A1. +log4j.rootLogger=INFO, A1 + +# A1 is set to be a ConsoleAppender. +log4j.appender.A1=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%d{yy-MM-dd HH:mm:ss.SSS} %X{pname}:%X{pid} %-5p %l- %m%n +log4j.appender.A1.serverFileAppender=org.apache.log4j.RollingFileAppender + +# Tweak the timestamp format so that it sorts easier +log4j.appender.A1.serverFileAppender.fileName=/tmp/pulsar_client_cpp.log diff --git a/pulsar-client-cpp/perf/CMakeLists.txt b/pulsar-client-cpp/perf/CMakeLists.txt new file mode 100644 index 0000000000000..bad8e8f0eeab0 --- /dev/null +++ b/pulsar-client-cpp/perf/CMakeLists.txt @@ -0,0 +1,33 @@ +# +# Copyright 2016 Yahoo Inc. +# +# Licensed 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. +# + +# Test tools +set (CMAKE_CXX_FLAGS "--std=c++0x ${CMAKE_CXX_FLAGS}") +add_definitions(-D_GLIBCXX_USE_NANOSLEEP) + +set(PERF_PRODUCER_SOURCES + PerfProducer.cc +) + +set(PERF_CONSUMER_SOURCES + PerfConsumer.cc +) + +add_executable(perfProducer ${PERF_PRODUCER_SOURCES}) +add_executable(perfConsumer ${PERF_CONSUMER_SOURCES}) + +target_link_libraries(perfProducer ${CLIENT_LIBS}) +target_link_libraries(perfConsumer ${CLIENT_LIBS}) diff --git a/pulsar-client-cpp/perf/PerfConsumer.cc b/pulsar-client-cpp/perf/PerfConsumer.cc new file mode 100644 index 0000000000000..2eebc995fee3f --- /dev/null +++ b/pulsar-client-cpp/perf/PerfConsumer.cc @@ -0,0 +1,280 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +DECLARE_LOG_OBJECT() + +#include +#include +#include +#include + +using namespace std::chrono; + +#include +#include +#include +#include +#include +#include +#include +#include +namespace po = boost::program_options; +using namespace boost::accumulators; + +#include + +#include +using namespace pulsar; + +static int64_t currentTimeMillis() { + using namespace boost::posix_time; + using boost::posix_time::milliseconds; + using boost::posix_time::seconds; + static ptime time_t_epoch(boost::gregorian::date(1970, 1, 1)); + + time_duration diff = microsec_clock::universal_time() - time_t_epoch; + return diff.total_milliseconds(); +} + +struct Arguments { + std::string topic; + int numTopics; + int numConsumers; + std::string subscriberName; + int waitTimeMs; + std::string serviceURL; + int receiverQueueSize; + int ioThreads; + int listenerThreads; +}; + +namespace pulsar { +class PulsarFriend { + public: + static Client getClient(const std::string& url, const ClientConfiguration conf, + bool poolConnections) { + return Client(url, conf, poolConnections); + } +}; +} + +#if __GNUC__ == 4 && __GNUC_MINOR__ == 4 +// Used for gcc-4.4.7 with boost-1.41 +#include +#else +#include +#endif + +// Counters +std::atomic messagesReceived; +std::atomic bytesReceived; + +typedef std::chrono::high_resolution_clock Clock; + +void handleAckComplete(Result) { +} + + +boost::mutex mutex; +typedef boost::unique_lock Lock; +typedef accumulator_set > LatencyAccumulator; +LatencyAccumulator e2eLatencyAccumulator(quantile_probability = 0.99); + +void messageListener(Consumer consumer, const Message& msg) { + ++messagesReceived; + bytesReceived += msg.getLength(); + + int64_t e2eLatencyMsec = currentTimeMillis() - msg.getPublishTimestamp(); + Lock lock(mutex); + e2eLatencyAccumulator(e2eLatencyMsec); + lock.unlock(); + + consumer.acknowledgeAsync(msg, handleAckComplete); +} + +std::vector consumers; + +void handleSubscribe(Result result, Consumer consumer, Latch latch) { + if (result != ResultOk) { + LOG_ERROR("Error creating consumer: "<< result); + exit(-1); + } + + Lock lock(mutex); + consumers.push_back(consumer); + + latch.countdown(); +} + +void startPerfConsumer(const Arguments& args) { + ClientConfiguration conf; + conf.setIOThreads(args.ioThreads); + conf.setMessageListenerThreads(args.listenerThreads); + + Client client(pulsar::PulsarFriend::getClient(args.serviceURL, conf, false)); + + ConsumerConfiguration consumerConf; + consumerConf.setMessageListener(messageListener); + consumerConf.setReceiverQueueSize(args.receiverQueueSize); + + Latch latch(args.numTopics * args.numConsumers); + + for (int i = 0; i < args.numTopics; i++) { + std::string topic = + (args.numTopics == 1) ? + args.topic : args.topic + "-" + boost::lexical_cast(i); + LOG_INFO("Adding " << args.numConsumers << " consumers on topic " << topic); + + for (int j = 0; j < args.numConsumers; j++) { + std::string subscriberName; + if (args.numConsumers > 1) { + subscriberName = args.subscriberName + "-" + boost::lexical_cast(j); + } else { + subscriberName = args.subscriberName; + } + + client.subscribeAsync(topic, subscriberName, consumerConf, + boost::bind(handleSubscribe, _1, _2, latch)); + } + } + + Clock::time_point oldTime = Clock::now(); + + latch.wait(); + LOG_INFO( + "Start receiving from " << args.numConsumers << " consumers on " << args.numTopics << " destinations"); + + while (true) { + std::this_thread::sleep_for(seconds(10)); + + Clock::time_point now = Clock::now(); + double elapsed = duration_cast < milliseconds > (now - oldTime).count() / 1e3; + + double rate = messagesReceived.exchange(0) / elapsed; + double throughput = bytesReceived.exchange(0) / elapsed / 1024 / 1024 * 8; + + Lock lock(mutex); + int64_t e2eLatencyAvgMs = rate > 0.0 ? mean(e2eLatencyAccumulator) : 0; + int64_t e2eLatency99pctMs = p_square_quantile(e2eLatencyAccumulator); + e2eLatencyAccumulator = LatencyAccumulator(quantile_probability = 0.99); + lock.unlock(); + + LOG_INFO("Throughput received: " << rate << " msg/s --- " << throughput << " Mbit/s ---" // + << " End-To-End latency: avg: " << e2eLatencyAvgMs << " ms -- 99pct: " << e2eLatency99pctMs << " ms"); + + oldTime = now; + } +} + +int main(int argc, char** argv) { + LogUtils::init("conf/log4cxx.conf"); + + // First try to read default values from config file if present + const std::string confFile = "conf/client.conf"; + std::string defaultServiceUrl; + + if (boost::filesystem::exists(confFile)) { + po::variables_map vm; + po::options_description confFileDesc; + confFileDesc.add_options() // + ("serviceURL", po::value()->default_value("pulsar://localhost:6650")); + + std::ifstream file(confFile.c_str()); + po::store(po::parse_config_file(file, confFileDesc, true), vm); + po::notify(vm); + + defaultServiceUrl = vm["serviceURL"].as(); + } + + Arguments args; + + // Declare the supported options. + po::positional_options_description positional; + positional.add("topic", 1); + + po::options_description desc("Allowed options"); + desc.add_options() // + ("help,h", "Print this help message") // + + ("num-topics,t", po::value(&args.numTopics)->default_value(1), "Number of topics") // + + ("num-consumers,n", po::value(&args.numConsumers)->default_value(1), + "Number of consumers (per topic)") // + + ("subscriber-name,s", po::value(&args.subscriberName)->default_value("sub"), + "Subscriber name prefix") // + + ("wait-time,w", po::value(&args.waitTimeMs)->default_value(1), + "Simulate a slow message consumer (Delay in ms)") // + + ("service-url,u", po::value(&args.serviceURL)->default_value(defaultServiceUrl), + "Pulsar Service URL") // + + ("receiver-queue-size,p", po::value(&args.receiverQueueSize)->default_value(1000), + "Size of the receiver queue") // + + ("io-threads,i", po::value(&args.ioThreads)->default_value(1), + "Number of IO threads to use") // + + ("listener-threads,l", po::value(&args.listenerThreads)->default_value(1), + "Number of listener threads"); + + po::options_description hidden; + hidden.add_options()("topic", po::value(&args.topic), "Topic name"); + + po::options_description allOptions; + allOptions.add(desc).add(hidden); + + po::variables_map map; + try { + po::store( + po::command_line_parser(argc, argv).options(allOptions).positional(positional).run(), + map); + po::notify(map); + } catch (const std::exception& e) { + std::cerr << "Error parsing parameters -- " << e.what() << std::endl << std::endl; + std::cerr << desc << std::endl; + return -1; + } + + if (map.count("help")) { + std::cerr << desc << std::endl; + return -1; + } + + if (map.count("topic") != 1) { + std::cerr << "Need to specify a topic name. eg: persistent://prop/cluster/ns/my-topic" + << std::endl << std::endl; + std::cerr << desc << std::endl; + return -1; + } + + LOG_INFO("--- Consumer configuration ---"); + for (po::variables_map::iterator it = map.begin(); it != map.end(); ++it) { + if (it->second.value().type() == typeid(std::string)) { + LOG_INFO(it->first << ": " << it->second.as()); + } else if (it->second.value().type() == typeid(int)) { + LOG_INFO(it->first << ": " << it->second.as()); + } else if (it->second.value().type() == typeid(double)) { + LOG_INFO(it->first << ": " << it->second.as()); + } + } + + LOG_INFO("------------------------------"); + + startPerfConsumer(args); +} diff --git a/pulsar-client-cpp/perf/PerfProducer.cc b/pulsar-client-cpp/perf/PerfProducer.cc new file mode 100644 index 0000000000000..fdb697775d553 --- /dev/null +++ b/pulsar-client-cpp/perf/PerfProducer.cc @@ -0,0 +1,315 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +DECLARE_LOG_OBJECT() + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +namespace po = boost::program_options; + +#include +#include +#include +#include +#include "RateLimiter.h" +#include +typedef boost::shared_ptr RateLimiterPtr; + +struct Arguments { + std::string topic; + double rate; + int msgSize; + int numTopics; + int numProducers; + int numOfThreadsPerProducer; + std::string serviceURL; + int producerQueueSize; + int ioThreads; + int listenerThreads; + long samplingPeriod; + long numberOfSamples; + unsigned int batchingMaxMessages; + long batchingMaxAllowedSizeInBytes; + long batchingMaxPublishDelayMs; +}; + +namespace pulsar { +class PulsarFriend { + public: + static Client getClient(const std::string& url, const ClientConfiguration conf, + bool poolConnections) { + return Client(url, conf, poolConnections); + } +}; +} + +// Stats +unsigned long messagesProduced; +unsigned long bytesProduced; +using namespace boost::accumulators; + +typedef accumulator_set > LatencyAccumulator; +LatencyAccumulator e2eLatencyAccumulator(quantile_probability = 0.99); +std::vector producerList; +std::vector threadList; + +boost::mutex mutex; +typedef boost::unique_lock Lock; + +typedef std::chrono::high_resolution_clock Clock; + +void sendCallback(pulsar::Result result, const pulsar::Message& msg, Clock::time_point& publishTime) { + LOG_DEBUG("result = " << result); + assert(result == pulsar::ResultOk); + uint64_t latencyUsec = std::chrono::duration_cast(Clock::now() - publishTime).count(); + Lock lock(mutex); + ++messagesProduced; + bytesProduced += msg.getLength(); + e2eLatencyAccumulator(latencyUsec); +} + +// Start a pulsar producer on a topic and keep producing messages +void runProducer(const Arguments& args, std::string topicName, int threadIndex, + RateLimiterPtr limiter, pulsar::Producer& producer) { + LOG_INFO("Producing messages for topic = " << topicName << ", threadIndex = " << threadIndex); + + boost::scoped_array payload(new char[args.msgSize]); + memset(payload.get(), 0, args.msgSize); + pulsar::MessageBuilder builder; + try { + while (true) { + if (args.rate != -1) { + limiter->aquire(); + } + pulsar::Message msg = builder.create().setAllocatedContent(payload.get(), args.msgSize).build(); + + producer.sendAsync(msg, boost::bind(sendCallback, _1, _2, Clock::now())); + boost::this_thread::interruption_point(); + } + } catch(const boost::thread_interrupted&) { + // Thread interruption request received, break the loop + LOG_INFO("Thread interrupted. Exiting thread."); + } +} + +void startPerfProducer(const Arguments& args, pulsar::ProducerConfiguration &producerConf, pulsar::Client &client) { + RateLimiterPtr limiter; + if (args.rate != -1) { + limiter = boost::make_shared(args.rate); + } + + producerList.resize(args.numTopics * args.numProducers); + for (int i = 0; i < args.numTopics; i++) { + std::string topic = + (args.numTopics == 1) ? + args.topic : args.topic + "-" + boost::lexical_cast(i); + LOG_INFO("Adding " << args.numProducers << " producers on topic " << topic); + + for (int j = 0; j < args.numProducers; j++) { + pulsar::Result result = client.createProducer(topic, producerConf, producerList[i*args.numProducers + j]); + if (result != pulsar::ResultOk) { + LOG_ERROR("Couldn't create producer: " << result); + exit(-1); + } else { + LOG_DEBUG("Created Producer at index " << i*args.numProducers + j); + } + + for (int k = 0; k < args.numOfThreadsPerProducer; k++) { + threadList.push_back(boost::thread(boost::bind(runProducer, args, topic, k, limiter, producerList[i*args.numProducers + j]))); + } + } + } +} + +int main(int argc, char** argv) { + LogUtils::init("conf/log4cxx.conf"); + + std::string defaultServiceUrl; + + // First try to read default values from config file if present + const std::string confFile = "conf/client.conf"; + + if (boost::filesystem::exists(confFile)) { + po::variables_map vm; + po::options_description confFileDesc; + confFileDesc.add_options() // + ("serviceURL", po::value()->default_value("pulsar://localhost:6650")); + + std::ifstream file(confFile.c_str()); + po::store(po::parse_config_file(file, confFileDesc, true), vm); + po::notify(vm); + + defaultServiceUrl = vm["serviceURL"].as(); + } + + Arguments args; + + // Declare the supported options. + po::positional_options_description positional; + positional.add("topic", 1); + + po::options_description desc("Allowed options"); + desc.add_options() // + ("help,h", "Print this help message") // + ("rate,r", po::value(&args.rate)->default_value(100.0), + "Publish rate msg/s across topics") // + ("size,s", po::value(&args.msgSize)->default_value(1024), "Message size") // + + ("num-topics,t", po::value(&args.numTopics)->default_value(1), "Number of topics") // + + ("num-producers,n", po::value(&args.numProducers)->default_value(1), + "Number of producers (per topic)") // + + ("num-threads-per-producers", po::value(&args.numOfThreadsPerProducer)->default_value(1), + "Number of threads (per producer)") // + + ("service-url,u", po::value(&args.serviceURL)->default_value(defaultServiceUrl), + "Pulsar Service URL") // + + ("producer-queue-size,p", po::value(&args.producerQueueSize)->default_value(1000), + "Max size of producer pending messages queue") // + + ("io-threads,i", po::value(&args.ioThreads)->default_value(1), + "Number of IO threads to use") // + + ("listener-threads,l", po::value(&args.listenerThreads)->default_value(1), + "Number of listener threads") // + + ("sampling-period", po::value(&args.samplingPeriod)->default_value(20), + "Time elapsed in seconds before reading are aggregated. Default: 20 sec") // + + ("num-of-samples", po::value(&args.numberOfSamples)->default_value(0), + "Number of samples to take. Default: 0 (run forever)") // + + ("batch-size", po::value(&args.batchingMaxMessages)->default_value(1), + "If batch size == 1 then batching is disabled. Default batch size == 1") // + + ("max-batch-size-in-bytes", po::value(&args.batchingMaxAllowedSizeInBytes)->default_value(128 * 1024), + "Use only is batch-size > 1, Default is 128 KB") // + + ("max-batch-publish-delay-in-ms", po::value(&args.batchingMaxPublishDelayMs)->default_value(3000), + "Use only is batch-size > 1, Default is 3 seconds"); + + po::options_description hidden; + hidden.add_options()("topic", po::value(&args.topic), "Topic name"); + + po::options_description allOptions; + allOptions.add(desc).add(hidden); + + po::variables_map map; + try { + po::store( + po::command_line_parser(argc, argv).options(allOptions).positional(positional).run(), + map); + po::notify(map); + } catch (const std::exception& e) { + std::cerr << "Error parsing parameters -- " << e.what() << std::endl << std::endl; + std::cerr << desc << std::endl; + return -1; + } + + if (map.count("help")) { + std::cerr << desc << std::endl; + return -1; + } + + if (map.count("topic") != 1) { + std::cerr << "Need to specify a topic name. eg: persistent://prop/cluster/ns/my-topic" + << std::endl << std::endl; + std::cerr << desc << std::endl; + return -1; + } + + LOG_INFO("--- Producer configuration ---"); + for (po::variables_map::iterator it = map.begin(); it != map.end(); ++it) { + if (it->second.value().type() == typeid(std::string)) { + LOG_INFO(it->first << ": " << it->second.as()); + } else if (it->second.value().type() == typeid(int)) { + LOG_INFO(it->first << ": " << it->second.as()); + } else if (it->second.value().type() == typeid(double)) { + LOG_INFO(it->first << ": " << it->second.as()); + } else if (it->second.value().type() == typeid(long)) { + LOG_INFO(it->first << ": " << it->second.as()); + } else if (it->second.value().type() == typeid(unsigned int)) { + LOG_INFO(it->first << ": " << it->second.as()); + } else { + LOG_INFO(it->first << ": " << "new data type used, please create an else condition in the code"); + } + } + + LOG_INFO("------------------------------"); + pulsar::ProducerConfiguration producerConf; + producerConf.setMaxPendingMessages(args.producerQueueSize); + if (args.batchingMaxMessages > 1) { + producerConf.setBatchingEnabled(true); + producerConf.setBatchingMaxMessages(args.batchingMaxMessages); + producerConf.setBatchingMaxAllowedSizeInBytes(args.batchingMaxAllowedSizeInBytes); + producerConf.setBatchingMaxPublishDelayMs(args.batchingMaxPublishDelayMs); + } + pulsar::ClientConfiguration conf; + conf.setIOThreads(args.ioThreads); + conf.setMessageListenerThreads(args.listenerThreads); + + pulsar::Client client(pulsar::PulsarFriend::getClient(args.serviceURL, conf, false)); + startPerfProducer(args, producerConf, client); + + Clock::time_point oldTime = Clock::now(); + unsigned long totalMessagesProduced = 0; + while (args.numberOfSamples--) { + std::this_thread::sleep_for(std::chrono::seconds(args.samplingPeriod)); + + Clock::time_point now = Clock::now(); + double elapsed = std::chrono::duration_cast(now - oldTime).count() / 1e3; + + Lock lock(mutex); + double rate = messagesProduced / elapsed; + double throughput = bytesProduced / elapsed / 1024 / 1024 * 8; + totalMessagesProduced += messagesProduced; + messagesProduced = 0; + bytesProduced = 0; + + double latencyAvgMs = mean(e2eLatencyAccumulator) / 1000.0; + double latency99pctMs = p_square_quantile(e2eLatencyAccumulator) / 1000.0; + e2eLatencyAccumulator = LatencyAccumulator(quantile_probability = 0.99); + lock.unlock(); + + LOG_INFO("Throughput produced: " << rate << " msg/s --- " << throughput << " Mbit/s --- " // + << "Lat avg: " << latencyAvgMs << " ms -- Lat 99pct: " << latency99pctMs << " ms"); + oldTime = now; + } + LOG_INFO("Total messagesProduced = " << totalMessagesProduced + messagesProduced); + for (int i = 0; i < threadList.size(); i++) { + threadList[i].interrupt(); + threadList[i].join(); + } + // Waiting for the sendCallbacks To Complete + usleep(2 * 1000 * 1000); + for (int i = 0; i < producerList.size(); i++) { + producerList[i].close(); + } + // Waiting for 2 seconds + usleep(2 * 1000 * 1000); +} diff --git a/pulsar-client-cpp/perf/RateLimiter.h b/pulsar-client-cpp/perf/RateLimiter.h new file mode 100644 index 0000000000000..5dfed3daf5292 --- /dev/null +++ b/pulsar-client-cpp/perf/RateLimiter.h @@ -0,0 +1,91 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef PERF_RATELIMITER_H_ +#define PERF_RATELIMITER_H_ + +#include +#include +#include + +namespace pulsar { + +class RateLimiter { + public: + RateLimiter(double rate); + + void aquire(); + + void aquire(int permits); + + private: + RateLimiter(const RateLimiter&); + RateLimiter& operator=(const RateLimiter&); + typedef std::chrono::high_resolution_clock Clock; + Clock::duration interval_; + + long storedPermits_; + double maxPermits_; + Clock::time_point nextFree_; + boost::mutex mutex_; + typedef boost::unique_lock Lock; +}; + +RateLimiter::RateLimiter(double rate) + : interval_(std::chrono::microseconds((long)(1e6 / rate))), + storedPermits_(0.0), + maxPermits_(rate), + nextFree_() { + assert(rate < 1e6 && "Exceeded maximum rate"); +} + +void RateLimiter::aquire() { + aquire(1); +} + +void RateLimiter::aquire(int permits) { + Clock::time_point now = Clock::now(); + + Lock lock(mutex_); + + if (now > nextFree_) { + storedPermits_ = std::min(maxPermits_, + storedPermits_ + (now - nextFree_) / interval_); + nextFree_ = now; + } + + Clock::duration wait = nextFree_ - now; + + // Determine how many stored and fresh permits to consume + long stored = std::min(permits, storedPermits_); + long fresh = permits - stored; + + // In the general RateLimiter, stored permits have no wait time, + // and thus we only have to wait for however many fresh permits we consume + Clock::duration next = fresh * interval_; + nextFree_ += next; + storedPermits_ -= stored; + + lock.unlock(); + + if (wait != Clock::duration::zero()) { + std::this_thread::sleep_for(wait); + } +} + +} // pulsar + +#endif /* PERF_RATELIMITER_H_ */ diff --git a/pulsar-client-cpp/tests/AuthPluginTest.cc b/pulsar-client-cpp/tests/AuthPluginTest.cc new file mode 100644 index 0000000000000..b3b3c6f9b0136 --- /dev/null +++ b/pulsar-client-cpp/tests/AuthPluginTest.cc @@ -0,0 +1,40 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "pulsar/Auth.h" +#include + +TEST(AuthPluginTest, testCreate) { + std::string data; + + pulsar::AuthenticationPtr auth = pulsar::Auth::create("../lib/auth/libauthtls.so"); + ASSERT_TRUE(auth != NULL); + ASSERT_EQ(auth->getAuthMethodName(), "tls"); + ASSERT_EQ(auth->getAuthData(data), pulsar::ResultOk); + ASSERT_EQ(data, "THIS_SHOULD_BE_REPLACED"); + ASSERT_EQ(auth.use_count(), 1); +} + +TEST(AuthPluginTest, testDisable) { + std::string data; + + pulsar::AuthenticationPtr auth = pulsar::Auth::Disabled(); + ASSERT_TRUE(auth != NULL); + ASSERT_EQ(auth->getAuthMethodName(), "none"); + ASSERT_EQ(auth->getAuthData(data), pulsar::ResultOk); + ASSERT_EQ(data, ""); + ASSERT_EQ(auth.use_count(), 1); +} diff --git a/pulsar-client-cpp/tests/BackoffTest.cc b/pulsar-client-cpp/tests/BackoffTest.cc new file mode 100644 index 0000000000000..80f669c2412bc --- /dev/null +++ b/pulsar-client-cpp/tests/BackoffTest.cc @@ -0,0 +1,37 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include "Backoff.h" + +using namespace pulsar; +using boost::posix_time::milliseconds; +using boost::posix_time::seconds; +TEST(BackoffTest, basicTest) { + Backoff backoff(milliseconds(5), seconds(60)); + ASSERT_EQ(backoff.next().total_milliseconds(), 5); + ASSERT_EQ(backoff.next().total_milliseconds(), 10); + backoff.reset(); + ASSERT_EQ(backoff.next().total_milliseconds(), 5); +} + +TEST(BackoffTest, maxTest) { + Backoff backoff(milliseconds(5), milliseconds(20)); + ASSERT_EQ(backoff.next().total_milliseconds(), 5); + ASSERT_EQ(backoff.next().total_milliseconds(), 10); + ASSERT_EQ(backoff.next().total_milliseconds(), 20); + ASSERT_EQ(backoff.next().total_milliseconds(), 20); +} diff --git a/pulsar-client-cpp/tests/BasicEndToEndTest.cc b/pulsar-client-cpp/tests/BasicEndToEndTest.cc new file mode 100644 index 0000000000000..d1490f955c677 --- /dev/null +++ b/pulsar-client-cpp/tests/BasicEndToEndTest.cc @@ -0,0 +1,814 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include +#include +#include +#include +#include "DestinationName.h" +#include +#include +#include "boost/date_time/posix_time/posix_time.hpp" +#include "CustomRoutingPolicy.h" +#include + +#include "HttpHelper.h" + +#include "lib/Future.h" +#include "lib/Utils.h" +DECLARE_LOG_OBJECT() + +using namespace pulsar; + +static int globalTestBatchMessagesCounter = 0; +static int globalCount = 0; +static int globalResendMessageCount = 0; +static std::string lookupUrl = "pulsar://localhost:8885"; +static std::string adminUrl = "http://localhost:8765/"; + +static void messageListenerFunction(Consumer consumer, const Message& msg) { + globalCount++; + consumer.acknowledge(msg); +} + +static void sendCallBack(Result r, const Message& msg) { + ASSERT_EQ(r, ResultOk); + std::string prefix = "msg-batch-"; + std::string messageContent = prefix + boost::lexical_cast(globalTestBatchMessagesCounter++); + ASSERT_EQ(messageContent, msg.getDataAsString()); + LOG_DEBUG("Received publish acknowledgement for " << msg.getDataAsString()); +} + +TEST(BasicEndToEndTest, testBatchMessages) +{ + ClientConfiguration config; + Client client(lookupUrl); + std::string topicName = "persistent://property/cluster/namespace/test-batch-messages"; + std::string subName = "subscription-name"; + Producer producer; + + // Enable batching on producer side + int batchSize = 2; + int numOfMessages = 1000; + ProducerConfiguration conf; + conf.setCompressionType(CompressionLZ4); + conf.setBatchingMaxMessages(batchSize); + conf.setBatchingEnabled(true); + + Promise producerPromise; + client.createProducerAsync(topicName, conf, WaitForCallbackValue(producerPromise)); + Future producerFuture = producerPromise.getFuture(); + Result result = producerFuture.get(producer); + ASSERT_EQ(ResultOk, result); + + Consumer consumer; + Promise consumerPromise; + client.subscribeAsync(topicName, subName, WaitForCallbackValue(consumerPromise)); + Future consumerFuture = consumerPromise.getFuture(); + result = consumerFuture.get(consumer); + ASSERT_EQ(ResultOk, result); + + // handling dangling subscriptions + consumer.unsubscribe(); + client.subscribe(topicName, subName, consumer); + + std::string temp = producer.getTopic(); + ASSERT_EQ(temp, topicName); + temp = consumer.getTopic(); + ASSERT_EQ(temp, topicName); + ASSERT_EQ(consumer.getSubscriptionName(), subName); + + // Send Asynchronously + std::string prefix = "msg-batch-"; + for (int i = 0; i(i); + Message msg = MessageBuilder().setContent(messageContent).setProperty("msgIndex", boost::lexical_cast(i)).build(); + producer.sendAsync(msg, &sendCallBack); + LOG_INFO("sending message " << messageContent); + } + + Message receivedMsg; + int i = 0; + while (consumer.receive(receivedMsg, 5000) == ResultOk) { + std::string expectedMessageContent = prefix + boost::lexical_cast(i); + LOG_INFO("Received Message with [ content - " << receivedMsg.getDataAsString() << "] [ messageID = " << receivedMsg.getMessageId() << "]"); + ASSERT_EQ(receivedMsg.getProperty("msgIndex"), boost::lexical_cast(i++)); + ASSERT_EQ(expectedMessageContent, receivedMsg.getDataAsString()); + ASSERT_EQ(ResultOk, consumer.acknowledge(receivedMsg)); + } + // Number of messages produced + ASSERT_EQ(globalTestBatchMessagesCounter, numOfMessages); + + // Number of messages consumed + ASSERT_EQ(i, numOfMessages); + +} + +void resendMessage(Result r, const Message& msg, Producer &producer) { + if (r != ResultOk) { + int attemptNumber = boost::lexical_cast(msg.getProperty("attempt#")); + if (attemptNumber++ < 3) { + globalResendMessageCount++; + producer.sendAsync(MessageBuilder().setProperty("attempt#", boost::lexical_cast(attemptNumber)).build(), + boost::bind(resendMessage, _1, _2, producer)); + } + } +} + + TEST(BasicEndToEndTest, testProduceConsume) +{ + ClientConfiguration config; + Client client(lookupUrl); + std::string topicName = "persistent://prop/unit/ns1/my-topic"; + std::string subName = "my-sub-name"; + Producer producer; + + Promise producerPromise; + client.createProducerAsync(topicName, WaitForCallbackValue(producerPromise)); + Future producerFuture = producerPromise.getFuture(); + Result result = producerFuture.get(producer); + ASSERT_EQ(ResultOk, result); + + Consumer consumer; + Promise consumerPromise; + client.subscribeAsync(topicName, subName, WaitForCallbackValue(consumerPromise)); + Future consumerFuture = consumerPromise.getFuture(); + result = consumerFuture.get(consumer); + ASSERT_EQ(ResultOk, result); + std::string temp = producer.getTopic(); + ASSERT_EQ(temp, topicName); + temp = consumer.getTopic(); + ASSERT_EQ(temp, topicName); + ASSERT_EQ(consumer.getSubscriptionName(), subName); + + // Send synchronously + std::string content = "msg-1-content"; + Message msg = MessageBuilder().setContent(content).build(); + result = producer.send(msg); + ASSERT_EQ(ResultOk, result); + + Message receivedMsg; + consumer.receive(receivedMsg); + ASSERT_EQ(content, receivedMsg.getDataAsString()); + ASSERT_EQ(ResultOk, consumer.unsubscribe()); + ASSERT_EQ(ResultAlreadyClosed, consumer.close()); + ASSERT_EQ(ResultOk, producer.close()); + ASSERT_EQ(ResultOk, client.close()); +} + + TEST(BasicEndToEndTest, testNonExistingTopic) +{ + Client client(lookupUrl); + Producer producer; + Result result = client.createProducer("persistent://prop/unit/ns1", producer); + ASSERT_EQ(ResultInvalidTopicName, result); + + Consumer consumer; + result = client.subscribe("persistent://prop/unit/ns1", "my-sub-name", consumer); + ASSERT_EQ(ResultInvalidTopicName, result); +} + + TEST(BasicEndToEndTest, testNonPersistentTopic) +{ + Client client(lookupUrl); + Producer producer; + Result result = client.createProducer("non-persistent://prop/unit/ns1/destination", producer); + ASSERT_EQ(ResultInvalidTopicName, result); + + Consumer consumer; + result = client.subscribe("non-persistent://prop/unit/ns1/destination", "my-sub-name", + consumer); + ASSERT_EQ(ResultInvalidTopicName, result); +} + + TEST(BasicEndToEndTest, testSingleClientMultipleSubscriptions) +{ + Client client(lookupUrl); + + Producer producer; + Result result = client.createProducer("persistent://prop/unit/ns1/my-topic-1", producer); + ASSERT_EQ(ResultOk, result); + + Consumer consumer1; + result = client.subscribe("persistent://prop/unit/ns1/my-topic-1", "my-sub-name", consumer1); + ASSERT_EQ(ResultOk, result); + + Consumer consumer2; + result = client.subscribe("persistent://prop/unit/ns1/my-topic-1", "my-sub-name", consumer2); + ASSERT_EQ(ResultConsumerBusy, result); + //at this point connection gets destroyed because this consumer creation fails +} + + TEST(BasicEndToEndTest, testMultipleClientsMultipleSubscriptions) +{ + Client client1(lookupUrl); + Client client2(lookupUrl); + + Producer producer1; + Result result = client1.createProducer("persistent://prop/unit/ns1/my-topic-2", producer1); + ASSERT_EQ(ResultOk, result); + + Consumer consumer1; + result = client1.subscribe("persistent://prop/unit/ns1/my-topic-2", "my-sub-name", consumer1); + ASSERT_EQ(ResultOk, result); + + Consumer consumer2; + result = client2.subscribe("persistent://prop/unit/ns1/my-topic-2", "my-sub-name", consumer2); + ASSERT_EQ(ResultConsumerBusy, result); + + ASSERT_EQ(ResultOk, producer1.close()); + ASSERT_EQ(ResultOk, consumer1.close()); + ASSERT_EQ(ResultAlreadyClosed, consumer1.close()); + ASSERT_EQ(ResultConsumerNotInitialized, consumer2.close()); + ASSERT_EQ(ResultOk, client1.close()); + + // 2 seconds + usleep(2 * 1000 * 1000); + + ASSERT_EQ(ResultOk, client2.close()); +} + + TEST(BasicEndToEndTest, testProduceAndConsumeAfterClientClose) +{ + Client client(lookupUrl); + + Producer producer; + Result result = client.createProducer("persistent://prop/unit/ns1/my-topic-3", producer); + ASSERT_EQ(ResultOk, result); + + Consumer consumer; + result = client.subscribe("persistent://prop/unit/ns1/my-topic-3", "my-sub-name", consumer); + ASSERT_EQ(ResultOk, result); + + // Send 10 messages synchronosly + std::string msgContent = "msg-content"; + LOG_INFO("Publishing 10 messages synchronously"); + int numMsg = 0; + for (; numMsg < 10; numMsg++) { + Message msg = MessageBuilder().setContent(msgContent).setProperty( + "msgIndex", boost::lexical_cast(numMsg)).build(); + ASSERT_EQ(ResultOk, producer.send(msg)); + } + + LOG_INFO("Trying to receive 10 messages"); + Message msgReceived; + for (int i = 0; i < 10; i++) { + consumer.receive(msgReceived, 1000); + LOG_INFO("Received message :" << msgReceived.getMessageId()); + ASSERT_EQ(msgContent, msgReceived.getDataAsString()); + ASSERT_EQ(boost::lexical_cast(i), msgReceived.getProperty("msgIndex")); + ASSERT_EQ(ResultOk, consumer.acknowledgeCumulative(msgReceived)); + } + + LOG_INFO("Closing client"); + ASSERT_EQ(ResultOk, client.close()); + + LOG_INFO("Trying to publish a message after closing the client"); + Message msg = MessageBuilder().setContent(msgContent).setProperty( + "msgIndex", boost::lexical_cast(numMsg)).build(); + + ASSERT_EQ(ResultAlreadyClosed, producer.send(msg)); + + LOG_INFO("Trying to consume a message after closing the client"); + ASSERT_EQ(ResultAlreadyClosed, consumer.receive(msgReceived)); +} + + TEST(BasicEndToEndTest, testIamSoFancyCharactersInTopicName) +{ + Client client(lookupUrl); + Producer producer; + Result result = client.createProducer("persistent://prop/unit/ns1/topic@%*)(&!%$#@#$> nameSpaceName = NamespaceName::get("property", "bf1", "nameSpace"); + ASSERT_STREQ(nameSpaceName->getCluster().c_str(), "bf1"); + ASSERT_STREQ(nameSpaceName->getLocalName().c_str(), "nameSpace"); + ASSERT_STREQ(nameSpaceName->getProperty().c_str(), "property"); +} + + TEST(BasicEndToEndTest, testConsumerClose) +{ + ClientConfiguration config; + Client client(lookupUrl); + std::string topicName = "persistent://prop/unit/ns1/testConsumerClose"; + std::string subName = "my-sub-name"; + Consumer consumer; + ASSERT_EQ(ResultOk, client.subscribe(topicName, subName, consumer)); + ASSERT_EQ(consumer.close(), ResultOk); + ASSERT_EQ(consumer.close(), ResultAlreadyClosed); +} + + TEST(BasicEndToEndTest, testDuplicateConsumerCreationOnPartitionedTopic) +{ + Client client(lookupUrl); + std::string topicName = "persistent://prop/unit/ns/partition-testDuplicateConsumerCreationOnPartitionedTopic"; + + // call admin api to make it partitioned + std::string url = lookupUrl + "/admin/persistent/prop/unit/ns/testDuplicateConsumerCreationOnPartitionedTopic/partitions"; + int res = makePutRequest(lookupUrl, "5"); + + if (res != 204 && res != 409) { + LOG_DEBUG("Unable to create partitioned topic."); + return; + } + + usleep(2 * 1000 * 1000); + + Producer producer; + ProducerConfiguration producerConfiguration; + producerConfiguration.setPartitionsRoutingMode(ProducerConfiguration::CustomPartition); + producerConfiguration.setMessageRouter(boost::make_shared()); + + Result result = client.createProducer(topicName, producer); + ASSERT_EQ(ResultOk, result); + for (int i = 0; i < 10; i++ ) { + boost::posix_time::ptime t(boost::posix_time::microsec_clock::universal_time()); + long nanoSeconds = t.time_of_day().total_nanoseconds(); + std::stringstream ss; + ss << nanoSeconds; + Message msg = MessageBuilder().setContent(ss.str()).build(); + ASSERT_EQ(ResultOk, producer.send(msg)); + } + + + LOG_INFO("Creating Subscriber"); + std::string consumerId = "CONSUMER"; + ConsumerConfiguration tempConsConfig; + tempConsConfig.setConsumerType(ConsumerExclusive); + ConsumerConfiguration consConfig = tempConsConfig; + ASSERT_EQ(consConfig.getConsumerType(), ConsumerExclusive); + Consumer consumer; + Result subscribeResult = client.subscribe(topicName, consumerId, + consConfig, consumer); + ASSERT_EQ(ResultOk, subscribeResult); + + LOG_INFO("Creating Another Subscriber"); + Consumer consumer2; + ASSERT_EQ(consumer2.getSubscriptionName(), ""); + subscribeResult = client.subscribe(topicName, consumerId, + consConfig, consumer2); + ASSERT_EQ(ResultConsumerBusy, subscribeResult); + consumer.close(); + producer.close(); +} + +TEST(BasicEndToEndTest, testRoundRobinRoutingPolicy) +{ + Client client(lookupUrl); + std::string topicName = "persistent://prop/unit/ns/partition-testRoundRobinRoutingPolicy"; + // call admin api to make it partitioned + std::string url = lookupUrl + "/admin/persistent/prop/unit/ns/partition-testRoundRobinRoutingPolicy/partitions"; + int res = makePutRequest(lookupUrl, "5"); + + if (res != 204 && res != 409) { + LOG_DEBUG("Unable to create partitioned topic."); + return; + } + + Producer producer; + ProducerConfiguration tempProducerConfiguration; + tempProducerConfiguration.setPartitionsRoutingMode(ProducerConfiguration::RoundRobinDistribution); + ProducerConfiguration producerConfiguration = tempProducerConfiguration; + Result result = client.createProducer(topicName, producerConfiguration, producer); + ASSERT_EQ(ResultOk, result); + ASSERT_EQ(producer.getTopic(), topicName); + + // Topic is partitioned into 5 partitions so each partition will receive two messages + LOG_INFO("Creating Subscriber"); + std::string consumerId = "CONSUMER"; + ConsumerConfiguration consConfig; + consConfig.setConsumerType(ConsumerExclusive); + consConfig.setReceiverQueueSize(2); + ASSERT_FALSE(consConfig.hasMessageListener()); + Consumer consumer[5]; + Result subscribeResult; + for (int i = 0; i < 5; i++) { + std::stringstream partitionedTopicName; + partitionedTopicName << topicName << "-partition-" << i; + + std::stringstream partitionedConsumerId; + partitionedConsumerId << consumerId << i; + subscribeResult = client.subscribe(partitionedTopicName.str(), partitionedConsumerId.str(), consConfig, consumer[i]); + + ASSERT_EQ(ResultOk, subscribeResult); + ASSERT_EQ(consumer[i].getTopic(), partitionedTopicName.str()); + } + + for (int i = 0; i < 10; i++ ) { + boost::posix_time::ptime t(boost::posix_time::microsec_clock::universal_time()); + long nanoSeconds = t.time_of_day().total_nanoseconds(); + std::stringstream ss; + ss << nanoSeconds; + Message msg = MessageBuilder().setContent(ss.str()).build(); + ASSERT_EQ(ResultOk, producer.send(msg)); + } + + Message m; + for (int i = 0; i < 2; i++) { + for (int partitionIndex = 0; partitionIndex < 5; partitionIndex++) { + ASSERT_EQ(ResultOk, consumer[partitionIndex].receive(m)); + ASSERT_EQ(ResultOk, consumer[partitionIndex].acknowledge(m)); + } + } + + for (int partitionIndex = 0; partitionIndex < 5; partitionIndex++) { + consumer[partitionIndex].close(); + } + producer.close(); + client.shutdown(); + +} + +TEST(BasicEndToEndTest, testMessageListener) +{ + Client client(lookupUrl); + std::string topicName = "persistent://prop/unit/ns/partition-testMessageListener"; + // call admin api to make it partitioned + std::string url = lookupUrl + "/admin/persistent/prop/unit/ns/partition-testMessageListener/partitions"; + int res = makePutRequest(lookupUrl, "5"); + + if (res != 204 && res != 409) { + LOG_DEBUG("Unable to create partitioned topic."); + return; + } + + Producer producer; + ProducerConfiguration producerConfiguration; + producerConfiguration.setPartitionsRoutingMode(ProducerConfiguration::UseSinglePartition); + Result result = client.createProducer(topicName, producerConfiguration, producer); + + // Initializing global Count + globalCount = 0; + + ConsumerConfiguration consumerConfig; + consumerConfig.setMessageListener(boost::bind(messageListenerFunction, _1, _2)); + Consumer consumer; + result = client.subscribe(topicName, "subscription-A", consumerConfig, consumer); + + ASSERT_EQ(ResultOk, result); + for (int i = 0; i < 10; i++ ) { + boost::posix_time::ptime t(boost::posix_time::microsec_clock::universal_time()); + long nanoSeconds = t.time_of_day().total_nanoseconds(); + std::stringstream ss; + ss << nanoSeconds; + Message msg = MessageBuilder().setContent(ss.str()).setPartitionKey(ss.str()).build(); + ASSERT_EQ(ResultOk, producer.send(msg)); + } + + // Sleeping for 5 seconds + usleep(5 * 1000 * 1000); + ASSERT_EQ(globalCount, 10); + consumer.close(); + producer.closeAsync(0); + client.close(); +} + +TEST(BasicEndToEndTest, testMessageListenerPause) +{ + Client client(lookupUrl); + std::string topicName = "persistent://property/cluster/namespace/partition-testMessageListener-pauses"; + + // call admin api to make it partitioned + std::string url = lookupUrl + "/admin/persistent/prop/unit/ns/partition-testMessageListener-pauses/partitions"; + int res = makePutRequest(lookupUrl, "5"); + + if (res != 204 && res != 409) { + LOG_DEBUG("Unable to create partitioned topic."); + return; + } + Producer producer; + ProducerConfiguration producerConfiguration; + producerConfiguration.setPartitionsRoutingMode(ProducerConfiguration::UseSinglePartition); + Result result = client.createProducer(topicName, producerConfiguration, producer); + + // Initializing global Count + globalCount = 0; + + ConsumerConfiguration consumerConfig; + consumerConfig.setMessageListener(boost::bind(messageListenerFunction, _1, _2)); + Consumer consumer; + // Removing dangling subscription from previous test failures + result = client.subscribe(topicName, "subscription-name", consumerConfig, consumer); + consumer.unsubscribe(); + + result = client.subscribe(topicName, "subscription-name", consumerConfig, consumer); + ASSERT_EQ(ResultOk, result); + int temp = 1000; + for (int i = 0; i < 10000; i++ ) { + if(i && i%1000 == 0) { + usleep(5 * 1000 * 1000); + ASSERT_EQ(globalCount, temp); + consumer.resumeMessageListener(); + usleep(5 * 1000 * 1000); + ASSERT_EQ(globalCount, i); + temp = globalCount; + consumer.pauseMessageListener(); + } + Message msg = MessageBuilder().build(); + ASSERT_EQ(ResultOk, producer.send(msg)); + } + + ASSERT_EQ(globalCount, temp); + consumer.resumeMessageListener(); + // Sleeping for 5 seconds + usleep(5 * 1000 * 1000); + ASSERT_EQ(globalCount, 10000); + consumer.close(); + producer.closeAsync(0); + client.close(); +} + + TEST(BasicEndToEndTest, testResendViaListener) +{ + Client client(lookupUrl); + std::string topicName = "persistent://my-property/my-cluster/my-namespace/testResendViaListener"; + + Producer producer; + + Promise producerPromise; + ProducerConfiguration producerConfiguration; + + // Setting timeout of 1 ms + producerConfiguration.setSendTimeout(1); + client.createProducerAsync(topicName, producerConfiguration, WaitForCallbackValue(producerPromise)); + Future producerFuture = producerPromise.getFuture(); + Result result = producerFuture.get(producer); + ASSERT_EQ(ResultOk, result); + + // Send asynchronously + producer.sendAsync(MessageBuilder().setProperty("attempt#", boost::lexical_cast(0)).build(), boost::bind(resendMessage, _1, _2, producer)); + + // 3 seconds + usleep(3 * 1000 * 1000); + + ASSERT_EQ(globalResendMessageCount, 3); +} diff --git a/pulsar-client-cpp/tests/BatchMessageTest.cc b/pulsar-client-cpp/tests/BatchMessageTest.cc new file mode 100644 index 0000000000000..a9d4b0b71c11a --- /dev/null +++ b/pulsar-client-cpp/tests/BatchMessageTest.cc @@ -0,0 +1,840 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include +#include +#include +#include +#include "DestinationName.h" +#include +#include +#include "boost/date_time/posix_time/posix_time.hpp" +#include "CustomRoutingPolicy.h" +#include +#include "lib/Future.h" +#include "lib/Utils.h" +#include +#include "LogUtils.h" +#include "PulsarFriend.h" +#include +#include "ConsumerTest.h" +#include "HttpHelper.h" +DECLARE_LOG_OBJECT(); + +using namespace pulsar; + +static int globalTestBatchMessagesCounter = 0; +static int globalCount = 0; +static std::string lookupUrl = "pulsar://localhost:8885"; +static std::string adminUrl = "http://localhost:8765/"; + +// ecpoch time in seconds +long epochTime=time(NULL); + +static void messageListenerFunction(Consumer consumer, const Message& msg) { + globalCount++; + consumer.acknowledge(msg); +} + +static void sendCallBack(Result r, const Message& msg) { + ASSERT_EQ(r, ResultOk); + globalTestBatchMessagesCounter++; + LOG_DEBUG("Received publish acknowledgement for " << msg.getDataAsString()); +} + +static int globalPublishCountSuccess = 0; +static int globalPublishCountQueueFull = 0; + +static void sendCallBackExpectingErrors(Result r, const Message& msg) { + LOG_DEBUG("Received publish acknowledgement for " << msg.getDataAsString() << ", Result = " << r); + if (r == ResultProducerQueueIsFull) { + globalPublishCountQueueFull++; + } else if (r == ResultOk) { + globalPublishCountSuccess++; + } +} + +TEST(BatchMessageTest, testProducerConfig) { + ProducerConfiguration conf; + ASSERT_DEATH(conf.setBatchingMaxMessages(1), ""); +} + +TEST(BatchMessageTest, testProducerTimeout) { + std::string testName=boost::lexical_cast(epochTime) + "testProducerTimeout"; + + Client client(lookupUrl); + std::string topicName = "persistent://property/cluster/namespace/" + testName; + std::string subName = "subscription-name"; + Producer producer; + + // Enable batching on producer side + int batchSize = 3; + int numOfMessages = 4; + int timeout = 4000; + ProducerConfiguration conf; + conf.setCompressionType(CompressionLZ4); + conf.setBatchingMaxMessages(batchSize); + conf.setBatchingMaxPublishDelayMs(timeout); + conf.setBatchingEnabled(true); + + Promise producerPromise; + client.createProducerAsync(topicName, conf, WaitForCallbackValue(producerPromise)); + Future producerFuture = producerPromise.getFuture(); + Result result = producerFuture.get(producer); + ASSERT_EQ(ResultOk, result); + + Consumer consumer; + Promise consumerPromise; + client.subscribeAsync(topicName, subName, WaitForCallbackValue(consumerPromise)); + Future consumerFuture = consumerPromise.getFuture(); + result = consumerFuture.get(consumer); + ASSERT_EQ(ResultOk, result); + + // handling dangling subscriptions + consumer.close(); + client.subscribe(topicName, subName, consumer); + + std::string temp = producer.getTopic(); + ASSERT_EQ(temp, topicName); + temp = consumer.getTopic(); + ASSERT_EQ(temp, topicName); + ASSERT_EQ(consumer.getSubscriptionName(), subName); + + // Send Asynchronously + std::string prefix = "msg-batch-test-produce-timeout-"; + for (int i = 0; i(i); + Message msg = MessageBuilder().setContent(messageContent).setProperty("type", "batch").setProperty("msgIndex", boost::lexical_cast(i)).build(); + LOG_INFO("sending message " << messageContent); + clock_t start, end; + /* Start the timer */ + start = time(NULL); + LOG_INFO("start = "<(i++)); + ASSERT_EQ(receivedMsg.getProperty("type"), "batch"); + ASSERT_EQ(expectedMessageContent, receivedMsg.getDataAsString()); + ASSERT_EQ(ResultOk, consumer.acknowledge(receivedMsg)); + } + // Number of messages consumed + ASSERT_EQ(i, numOfMessages); +} + +TEST(BatchMessageTest, testBatchSizeInBytes) { + std::string testName=boost::lexical_cast(epochTime) + "testBatchSizeInBytes"; + globalTestBatchMessagesCounter=0; + + + Client client(lookupUrl); + std::string topicName = "persistent://property/cluster/namespace/" + testName; + std::string subName = "subscription-name"; + Producer producer; + + // Enable batching on producer side + int batchSize = 1000; + int numOfMessages = 30; + ProducerConfiguration conf; + conf.setCompressionType(CompressionLZ4); + conf.setBatchingMaxMessages(batchSize); + conf.setBatchingMaxAllowedSizeInBytes(20); + conf.setBatchingEnabled(true); + + Promise producerPromise; + client.createProducerAsync(topicName, conf, WaitForCallbackValue(producerPromise)); + Future producerFuture = producerPromise.getFuture(); + Result result = producerFuture.get(producer); + ASSERT_EQ(ResultOk, result); + + Consumer consumer; + Promise consumerPromise; + client.subscribeAsync(topicName, subName, WaitForCallbackValue(consumerPromise)); + Future consumerFuture = consumerPromise.getFuture(); + result = consumerFuture.get(consumer); + ASSERT_EQ(ResultOk, result); + + // handling dangling subscriptions + consumer.close(); + client.subscribe(topicName, subName, consumer); + + std::string temp = producer.getTopic(); + ASSERT_EQ(temp, topicName); + temp = consumer.getTopic(); + ASSERT_EQ(temp, topicName); + ASSERT_EQ(consumer.getSubscriptionName(), subName); + + // Send Asynchronously + std::string prefix = "12345678"; + for (int i = 0; i(i); + Message msg = MessageBuilder().setContent(messageContent).setProperty("msgIndex", boost::lexical_cast(i)).build(); + producer.sendAsync(msg, &sendCallBack); + LOG_INFO("sending message " << messageContent); + } + + Message receivedMsg; + int i = 0; + while (consumer.receive(receivedMsg, 5000) == ResultOk) { + std::string expectedMessageContent = prefix + boost::lexical_cast(i); + LOG_INFO("Received Message with [ content - " << receivedMsg.getDataAsString() << "] [ messageID = " << receivedMsg.getMessageId() << "]"); + ASSERT_LT(pulsar::PulsarFriend::getBatchIndex((BatchMessageId&)receivedMsg.getMessageId()),2); + ASSERT_EQ(receivedMsg.getProperty("msgIndex"), boost::lexical_cast(i++)); + ASSERT_EQ(expectedMessageContent, receivedMsg.getDataAsString()); + ASSERT_EQ(ResultOk, consumer.acknowledge(receivedMsg)); + } + // Number of messages produced + ASSERT_EQ(globalTestBatchMessagesCounter, numOfMessages); + + // Number of messages consumed + ASSERT_EQ(i, numOfMessages); +} + +TEST(BatchMessageTest, testSmallReceiverQueueSize) { + std::string testName=boost::lexical_cast(epochTime) + "testSmallReceiverQueueSize"; + globalTestBatchMessagesCounter=0; + + + Client client(lookupUrl); + std::string topicName = "persistent://property/cluster/namespace/" + testName; + std::string subName = "subscription-name"; + Producer producer; + + // Enable batching on producer side + int batchSize = 1000; + int numOfMessages = 100000; + ProducerConfiguration conf; + conf.setCompressionType(CompressionLZ4); + conf.setBatchingMaxMessages(batchSize); + conf.setBatchingMaxPublishDelayMs(1); + conf.setBatchingEnabled(true); + + Promise producerPromise; + client.createProducerAsync(topicName, conf, WaitForCallbackValue(producerPromise)); + Future producerFuture = producerPromise.getFuture(); + Result result = producerFuture.get(producer); + ASSERT_EQ(ResultOk, result); + + Consumer consumer; + ConsumerConfiguration consumerConfig; + consumerConfig.setReceiverQueueSize(41); + + Promise consumerPromise; + client.subscribeAsync(topicName, subName, consumerConfig, WaitForCallbackValue(consumerPromise)); + Future consumerFuture = consumerPromise.getFuture(); + result = consumerFuture.get(consumer); + ASSERT_EQ(ResultOk, result); + + // handling dangling subscriptions + consumer.close(); + client.subscribe(topicName, subName, consumerConfig, consumer); + + std::string temp = producer.getTopic(); + ASSERT_EQ(temp, topicName); + temp = consumer.getTopic(); + ASSERT_EQ(temp, topicName); + ASSERT_EQ(consumer.getSubscriptionName(), subName); + + // Send Asynchronously + std::string prefix = testName; + for (int i = 0; i(i); + Message msg = MessageBuilder().setContent(messageContent).setProperty("msgIndex", boost::lexical_cast(i)).build(); + producer.sendAsync(msg, &sendCallBack); + LOG_DEBUG("sending message " << messageContent); + } + + usleep(10 * 1000 * 1000); + Message receivedMsg; + int i = 0; + while (consumer.receive(receivedMsg, 10000) == ResultOk) { + std::string expectedMessageContent = prefix + boost::lexical_cast(i); + LOG_DEBUG("Received Message with [ content - " << receivedMsg.getDataAsString() << "] [ messageID = " << receivedMsg.getMessageId() << "]"); + ASSERT_EQ(receivedMsg.getProperty("msgIndex"), boost::lexical_cast(i++)); + ASSERT_EQ(expectedMessageContent, receivedMsg.getDataAsString()); + ASSERT_EQ(ResultOk, consumer.acknowledge(receivedMsg)); + } + // Number of messages produced + ASSERT_EQ(globalTestBatchMessagesCounter, numOfMessages); + + // Number of messages consumed + ASSERT_EQ(i, numOfMessages); +} + +TEST(BatchMessageTest, testIndividualAck) { + std::string testName = boost::lexical_cast(epochTime) + "testIndividualAck"; + + + Client client(lookupUrl); + std::string topicName = "persistent://property/cluster/namespace/" + testName; + std::string subName = "subscription-name"; + Producer producer; + + // Enable batching on producer side + int batchSize = 5; + int numOfMessages = 10; + ProducerConfiguration conf; + conf.setBatchingMaxMessages(batchSize); + conf.setBatchingEnabled(true); + + Promise < Result, Producer > producerPromise; + client.createProducerAsync(topicName, conf, + WaitForCallbackValue < Producer > (producerPromise)); + Future < Result, Producer > producerFuture = producerPromise.getFuture(); + Result result = producerFuture.get(producer); + ASSERT_EQ(ResultOk, result); + + Consumer consumer; + ConsumerConfiguration consumerConfig; + consumerConfig.setReceiverQueueSize(1); + + Promise < Result, Consumer > consumerPromise; + client.subscribeAsync(topicName, subName, consumerConfig, + WaitForCallbackValue < Consumer > (consumerPromise)); + Future < Result, Consumer > consumerFuture = consumerPromise.getFuture(); + result = consumerFuture.get(consumer); + ASSERT_EQ(ResultOk, result); + + // handling dangling subscriptions + consumer.close(); + client.subscribe(topicName, subName, consumerConfig, consumer); + + std::string temp = producer.getTopic(); + ASSERT_EQ(temp, topicName); + temp = consumer.getTopic(); + ASSERT_EQ(temp, topicName); + ASSERT_EQ(consumer.getSubscriptionName(), subName); + + // Send Asynchronously + std::string prefix = testName; + for (int i = 0; i < numOfMessages; i++) { + std::string messageContent = prefix + boost::lexical_cast < std::string > (i); + Message msg = MessageBuilder().setContent(messageContent).setProperty( + "msgIndex", boost::lexical_cast < std::string > (i)).build(); + producer.sendAsync(msg, &sendCallBack); + LOG_INFO("sending message " << messageContent); + } + globalTestBatchMessagesCounter = 0; + Message receivedMsg; + int i = 0; + while (consumer.receive(receivedMsg, 5000) == ResultOk) { + std::string expectedMessageContent = prefix + boost::lexical_cast < std::string > (i); + LOG_INFO( + "Received Message with [ content - " << receivedMsg.getDataAsString() << "] [ messageID = " << receivedMsg.getMessageId() << "]"); + ASSERT_EQ(receivedMsg.getProperty("msgIndex"), boost::lexical_cast < std::string > (i++)); + ASSERT_EQ(expectedMessageContent, receivedMsg.getDataAsString()); + // Ack every 2nd message + if (i % 2 == 0) { + ASSERT_EQ(ResultOk, consumer.acknowledge(receivedMsg)); + } + } + // Number of messages produced + ASSERT_EQ(globalTestBatchMessagesCounter, numOfMessages); + + // Number of messages consumed + ASSERT_EQ(i, numOfMessages); + + // Unsubscribe and resubscribe + // Expecting all messages to be sent again + + consumer.close(); + client.subscribe(topicName, subName, consumerConfig, consumer); + + i = 0; + while (consumer.receive(receivedMsg, 5000) == ResultOk) { + std::string expectedMessageContent = prefix + boost::lexical_cast < std::string > (i); + LOG_INFO( + "Received Message with [ content - " << receivedMsg.getDataAsString() << "] [ messageID = " << receivedMsg.getMessageId() << "]"); + ASSERT_EQ(receivedMsg.getProperty("msgIndex"), boost::lexical_cast < std::string > (i++)); + ASSERT_EQ(expectedMessageContent, receivedMsg.getDataAsString()); + // Ack every first 5 and 10th message + if (i <= 5 || i == 10) { + ASSERT_EQ(ResultOk, consumer.acknowledge(receivedMsg)); + } + } + + // Number of messages consumed + ASSERT_EQ(i, numOfMessages); + + // Unsubscribe and resubscribe + // Expecting only one batch message to be resent + + consumer.close(); + client.subscribe(topicName, subName, consumerConfig, consumer); + + i = 0; + while (consumer.receive(receivedMsg, 5000) == ResultOk) { + std::string expectedMessageContent = prefix + boost::lexical_cast < std::string > (i + numOfMessages/2); + LOG_INFO( + "Received Message with [ content - " << receivedMsg.getDataAsString() << "] [ messageID = " << receivedMsg.getMessageId() << "]"); + ASSERT_EQ(receivedMsg.getProperty("msgIndex"), boost::lexical_cast < std::string > (i++ + numOfMessages/2)); + ASSERT_EQ(expectedMessageContent, receivedMsg.getDataAsString()); + // Ack first 4 message only + if (i <= 4) { + ASSERT_EQ(ResultOk, consumer.acknowledge(receivedMsg)); + } + } + + // Number of messages consumed + ASSERT_EQ(i, numOfMessages / 2); + + // Unsubscribe and resubscribe + // Expecting only one batch message to be resent + + consumer.close(); + client.subscribe(topicName, subName, consumerConfig, consumer); + + i = 0; + while (consumer.receive(receivedMsg, 5000) == ResultOk) { + std::string expectedMessageContent = prefix + boost::lexical_cast < std::string > (i + numOfMessages/2); + LOG_INFO( + "Received Message with [ content - " << receivedMsg.getDataAsString() << "] [ messageID = " << receivedMsg.getMessageId() << "]"); + ASSERT_EQ(receivedMsg.getProperty("msgIndex"), boost::lexical_cast < std::string > (i++ + numOfMessages/2)); + ASSERT_EQ(expectedMessageContent, receivedMsg.getDataAsString()); + // Ack all + ASSERT_EQ(ResultOk, consumer.acknowledge(receivedMsg)); + } + + // Number of messages consumed + ASSERT_EQ(i, numOfMessages / 2); + + // Unsubscribe and resubscribe + // Expecting no batch message to be resent + + consumer.close(); + client.subscribe(topicName, subName, consumerConfig, consumer); + + // Number of messages consumed + ASSERT_NE(ResultOk, consumer.receive(receivedMsg, 5000)); +} + +TEST(BatchMessageTest, testCumulativeAck) { + std::string testName = boost::lexical_cast(epochTime) + "testCumulativeAck"; + + + Client client(lookupUrl); + std::string topicName = "persistent://property/cluster/namespace/" + testName; + std::string subName = "subscription-name"; + Producer producer; + + globalTestBatchMessagesCounter=0; + + // Enable batching on producer side + int batchSize = 5; + int numOfMessages = 15; + ProducerConfiguration conf; + conf.setBatchingMaxMessages(batchSize); + conf.setBatchingEnabled(true); + + Promise < Result, Producer > producerPromise; + client.createProducerAsync(topicName, conf, + WaitForCallbackValue < Producer > (producerPromise)); + Future < Result, Producer > producerFuture = producerPromise.getFuture(); + Result result = producerFuture.get(producer); + ASSERT_EQ(ResultOk, result); + + Consumer consumer; + ConsumerConfiguration consumerConfig; + consumerConfig.setReceiverQueueSize(1); + + Promise < Result, Consumer > consumerPromise; + client.subscribeAsync(topicName, subName, consumerConfig, + WaitForCallbackValue < Consumer > (consumerPromise)); + Future < Result, Consumer > consumerFuture = consumerPromise.getFuture(); + result = consumerFuture.get(consumer); + ASSERT_EQ(ResultOk, result); + + // handling dangling subscriptions + consumer.close(); + client.subscribe(topicName, subName, consumerConfig, consumer); + + std::string temp = producer.getTopic(); + ASSERT_EQ(temp, topicName); + temp = consumer.getTopic(); + ASSERT_EQ(temp, topicName); + ASSERT_EQ(consumer.getSubscriptionName(), subName); + + // Send Asynchronously + std::string prefix = testName; + for (int i = 0; i < numOfMessages; i++) { + std::string messageContent = prefix + boost::lexical_cast < std::string > (i); + Message msg = MessageBuilder().setContent(messageContent).setProperty( + "msgIndex", boost::lexical_cast < std::string > (i)).build(); + producer.sendAsync(msg, &sendCallBack); + LOG_INFO("sending message " << messageContent); + } + + Message receivedMsg; + int i = 0; + while (consumer.receive(receivedMsg, 5000) == ResultOk) { + std::string expectedMessageContent = prefix + boost::lexical_cast < std::string > (i); + LOG_INFO( + "Received Message with [ content - " << receivedMsg.getDataAsString() << "] [ messageID = " << receivedMsg.getMessageId() << "]"); + ASSERT_EQ(receivedMsg.getProperty("msgIndex"), boost::lexical_cast < std::string > (i++)); + ASSERT_EQ(expectedMessageContent, receivedMsg.getDataAsString()); + // Cumm. Ack 7th message + if (i == 7) { + ASSERT_EQ(ResultOk, consumer.acknowledgeCumulative(receivedMsg)); + } + } + // Number of messages produced + ASSERT_EQ(globalTestBatchMessagesCounter, numOfMessages); + + // Number of messages consumed + ASSERT_EQ(i, numOfMessages); + + // Unsubscribe and resubscribe + // Expecting 10 messages to be sent again + + consumer.close(); + client.subscribe(topicName, subName, consumerConfig, consumer); + + i = 0; + while (consumer.receive(receivedMsg, 5000) == ResultOk) { + std::string expectedMessageContent = prefix + boost::lexical_cast < std::string > (i + 5); + LOG_INFO( + "Received Message with [ content - " << receivedMsg.getDataAsString() << "] [ messageID = " << receivedMsg.getMessageId() << "]"); + ASSERT_EQ(receivedMsg.getProperty("msgIndex"), boost::lexical_cast < std::string > (i++ + 5)); + ASSERT_EQ(expectedMessageContent, receivedMsg.getDataAsString()); + // Ack 10th message + if (i == 10) { + ASSERT_EQ(ResultOk, consumer.acknowledgeCumulative(receivedMsg)); + } + } + + // Number of messages consumed + ASSERT_EQ(i, 10); + + // Unsubscribe and resubscribe + // Expecting no batch message to be resent + + consumer.close(); + client.subscribe(topicName, subName, consumerConfig, consumer); + + // Number of messages consumed + ASSERT_NE(ResultOk, consumer.receive(receivedMsg, 5000)); +} + +TEST(BatchMessageTest, testMixedAck) { + std::string testName = boost::lexical_cast(epochTime) + "testMixedAck"; + + + Client client(lookupUrl); + std::string topicName = "persistent://property/cluster/namespace/" + testName; + std::string subName = "subscription-name"; + Producer producer; + + globalTestBatchMessagesCounter=0; + + // Enable batching on producer side + int batchSize = 5; + int numOfMessages = 15; + ProducerConfiguration conf; + conf.setBatchingMaxMessages(batchSize); + conf.setBatchingEnabled(true); + + Promise < Result, Producer > producerPromise; + client.createProducerAsync(topicName, conf, + WaitForCallbackValue < Producer > (producerPromise)); + Future < Result, Producer > producerFuture = producerPromise.getFuture(); + Result result = producerFuture.get(producer); + ASSERT_EQ(ResultOk, result); + + Consumer consumer; + ConsumerConfiguration consumerConfig; + Promise < Result, Consumer > consumerPromise; + client.subscribeAsync(topicName, subName, consumerConfig, + WaitForCallbackValue < Consumer > (consumerPromise)); + Future < Result, Consumer > consumerFuture = consumerPromise.getFuture(); + result = consumerFuture.get(consumer); + ASSERT_EQ(ResultOk, result); + + // handling dangling subscriptions + consumer.close(); + client.subscribe(topicName, subName, consumerConfig, consumer); + + std::string temp = producer.getTopic(); + ASSERT_EQ(temp, topicName); + temp = consumer.getTopic(); + ASSERT_EQ(temp, topicName); + ASSERT_EQ(consumer.getSubscriptionName(), subName); + + // Send Asynchronously + std::string prefix = testName; + for (int i = 0; i < numOfMessages; i++) { + std::string messageContent = prefix + boost::lexical_cast < std::string > (i); + Message msg = MessageBuilder().setContent(messageContent).setProperty( + "msgIndex", boost::lexical_cast < std::string > (i)).build(); + producer.sendAsync(msg, &sendCallBack); + LOG_INFO("sending message " << messageContent); + } + + Message receivedMsg; + int i = 0; + while (consumer.receive(receivedMsg, 5000) == ResultOk) { + std::string expectedMessageContent = prefix + boost::lexical_cast < std::string > (i); + LOG_INFO( + "Received Message with [ content - " << receivedMsg.getDataAsString() << "] [ messageID = " << receivedMsg.getMessageId() << "]"); + ASSERT_EQ(receivedMsg.getProperty("msgIndex"), boost::lexical_cast < std::string > (i++)); + ASSERT_EQ(expectedMessageContent, receivedMsg.getDataAsString()); + // Cumm. Ack 14th message + if (i == 14) { + ASSERT_EQ(ResultOk, consumer.acknowledgeCumulative(receivedMsg)); + } + } + // Number of messages produced + ASSERT_EQ(globalTestBatchMessagesCounter, numOfMessages); + + // Number of messages consumed + ASSERT_EQ(i, numOfMessages); + + // Unsubscribe and resubscribe + // Expecting 5 messages to be sent again + + consumer.close(); + client.subscribe(topicName, subName, consumerConfig, consumer); + + i = 0; + while (consumer.receive(receivedMsg, 5000) == ResultOk) { + std::string expectedMessageContent = prefix + boost::lexical_cast < std::string > (i + 10); + LOG_INFO( + "Received Message with [ content - " << receivedMsg.getDataAsString() << "] [ messageID = " << receivedMsg.getMessageId() << "]"); + ASSERT_EQ(receivedMsg.getProperty("msgIndex"), boost::lexical_cast < std::string > (i++ + 10)); + ASSERT_EQ(expectedMessageContent, receivedMsg.getDataAsString()); + // Cumm Ack 9th message + if (i == 4) { + ASSERT_EQ(ResultOk, consumer.acknowledgeCumulative(receivedMsg)); + } + } + ASSERT_EQ(ResultOk, consumer.acknowledge(receivedMsg)); + + // Number of messages consumed + ASSERT_EQ(i, 5); + + // Unsubscribe and resubscribe + // Expecting no batch message to be resent + + consumer.close(); + client.subscribe(topicName, subName, consumerConfig, consumer); + + // Number of messages consumed + ASSERT_NE(ResultOk, consumer.receive(receivedMsg, 5000)); +} + +// Also testing Cumulative Ack test case where greatestCumulativeAck returns +// MessageId() +TEST(BatchMessageTest, testPermits) { + std::string testName = boost::lexical_cast(epochTime) + "testPermits"; + + + Client client(lookupUrl); + std::string topicName = "persistent://property/cluster/namespace/" + testName; + std::string subName = "subscription-name"; + Producer producer; + + globalTestBatchMessagesCounter=0; + + // Enable batching on producer side + int batchSize = 10; + int numOfMessages = 75; + ProducerConfiguration conf; + conf.setBatchingMaxMessages(batchSize); + conf.setBatchingMaxPublishDelayMs(5); + conf.setBatchingEnabled(true); + + Promise < Result, Producer > producerPromise; + client.createProducerAsync(topicName, conf, + WaitForCallbackValue < Producer > (producerPromise)); + Future < Result, Producer > producerFuture = producerPromise.getFuture(); + Result result = producerFuture.get(producer); + ASSERT_EQ(ResultOk, result); + + Consumer consumer; + ConsumerConfiguration consumerConfig; + consumerConfig.setReceiverQueueSize(5); + + Promise < Result, Consumer > consumerPromise; + client.subscribeAsync(topicName, subName, consumerConfig, + WaitForCallbackValue < Consumer > (consumerPromise)); + Future < Result, Consumer > consumerFuture = consumerPromise.getFuture(); + result = consumerFuture.get(consumer); + ASSERT_EQ(ResultOk, result); + + // handling dangling subscriptions + consumer.close(); + client.subscribe(topicName, subName, consumerConfig, consumer); + + std::string temp = producer.getTopic(); + ASSERT_EQ(temp, topicName); + temp = consumer.getTopic(); + ASSERT_EQ(temp, topicName); + ASSERT_EQ(consumer.getSubscriptionName(), subName); + + // Send Asynchronously + std::string prefix = testName; + for (int i = 0; i < numOfMessages; i++) { + std::string messageContent = prefix + boost::lexical_cast < std::string > (i); + Message msg = MessageBuilder().setContent(messageContent).setProperty( + "msgIndex", boost::lexical_cast < std::string > (i)).build(); + producer.sendAsync(msg, &sendCallBack); + LOG_INFO("sending message " << messageContent); + } + + usleep(5 * 1000 * 1000); + + Message receivedMsg; + int i = 0; + while (consumer.receive(receivedMsg, 5000) == ResultOk) { + std::string expectedMessageContent = prefix + boost::lexical_cast < std::string > (i); + LOG_INFO( + "Received Message with [ content - " << receivedMsg.getDataAsString() << "] [ messageID = " << receivedMsg.getMessageId() << "]"); + ASSERT_EQ(receivedMsg.getProperty("msgIndex"), boost::lexical_cast < std::string > (i++)); + ASSERT_EQ(expectedMessageContent, receivedMsg.getDataAsString()); + ASSERT_EQ(ResultOk, consumer.acknowledgeCumulative(receivedMsg)); + ASSERT_EQ(ResultOk, consumer.acknowledge(receivedMsg)); + } + // Number of messages produced + ASSERT_EQ(globalTestBatchMessagesCounter, numOfMessages); + + // Number of messages consumed + ASSERT_EQ(i, numOfMessages); + + // Since all messages are acked + // Creating 25 new non batched message + conf.setBatchingEnabled(false); + + client.createProducer(topicName, conf, producer); + + globalTestBatchMessagesCounter = 0; + // Send Asynchronously + for (int i = 0; i < numOfMessages; i++) { + std::string messageContent = prefix + boost::lexical_cast < std::string > (i); + Message msg = MessageBuilder().setContent(messageContent).setProperty( + "msgIndex", boost::lexical_cast < std::string > (i)).build(); + producer.sendAsync(msg, &sendCallBack); + LOG_INFO("sending message " << messageContent); + } + usleep(5 * 1000 * 1000); + + ASSERT_LE(ConsumerTest::getNumOfMessagesInQueue(consumer), consumerConfig.getReceiverQueueSize()); + ASSERT_GE(ConsumerTest::getNumOfMessagesInQueue(consumer), consumerConfig.getReceiverQueueSize()/2); + + i = 0; + while (consumer.receive(receivedMsg, 5000) == ResultOk) { + std::string expectedMessageContent = prefix + boost::lexical_cast < std::string > (i); + LOG_INFO( + "Received Message with [ content - " << receivedMsg.getDataAsString() << "] [ messageID = " << receivedMsg.getMessageId() << "]"); + ASSERT_EQ(receivedMsg.getProperty("msgIndex"), boost::lexical_cast < std::string > (i++)); + ASSERT_EQ(expectedMessageContent, receivedMsg.getDataAsString()); + ASSERT_EQ(ResultOk, consumer.acknowledgeCumulative(receivedMsg)); + } + // Number of messages produced + ASSERT_EQ(globalTestBatchMessagesCounter, numOfMessages); + + // Number of messages consumed + ASSERT_EQ(i, numOfMessages); +} + +TEST(BatchMessageTest, testPartitionedTopics) { + Client client(lookupUrl); + std::string topicName = "persistent://property/cluster/namespace/test-partitioned-batch-messages-" + boost::lexical_cast(epochTime) ; + + // call admin api to make it partitioned + std::string url = lookupUrl + "/admin/persistent/prop/unit/ns/test-partitioned-batch-messages-" + + boost::lexical_cast(epochTime) + "/partitions"; + int res = makePutRequest(lookupUrl, "7"); + + if (res != 204 && res != 409) { + LOG_DEBUG("Unable to create partitioned topic."); + return; + } + + usleep(2 * 1000 * 1000); + + Producer producer; + // Enable batching on producer side + int batchSize = 100; + int numOfMessages = 10000; + ProducerConfiguration conf; + + conf.setCompressionType(CompressionZLib); + conf.setBatchingMaxMessages(batchSize); + conf.setBatchingEnabled(true); + conf.setBatchingMaxPublishDelayMs(5); + conf.setBlockIfQueueFull(false); + conf.setMaxPendingMessages(10); + + Promise producerPromise; + client.createProducerAsync(topicName, conf, WaitForCallbackValue(producerPromise)); + Future producerFuture = producerPromise.getFuture(); + Result result = producerFuture.get(producer); + ASSERT_EQ(ResultOk, result); + + std::string subName = "subscription-name"; + Consumer consumer; + Promise consumerPromise; + client.subscribeAsync(topicName, subName, WaitForCallbackValue(consumerPromise)); + Future consumerFuture = consumerPromise.getFuture(); + result = consumerFuture.get(consumer); + ASSERT_EQ(ResultOk, result); + + std::string temp = producer.getTopic(); + ASSERT_EQ(temp, topicName); + temp = consumer.getTopic(); + ASSERT_EQ(temp, topicName); + ASSERT_EQ(consumer.getSubscriptionName(), subName); + + globalPublishCountSuccess = 0; + globalPublishCountQueueFull = 0; + + // Send Asynchronously + std::string prefix = "msg-batch-"; + for (int i = 0; i(i); + Message msg = MessageBuilder().setContent(messageContent).setProperty("msgIndex", boost::lexical_cast(i)).build(); + producer.sendAsync(msg, &sendCallBackExpectingErrors); + LOG_INFO("sending message " << messageContent); + } + + Message receivedMsg; + int i = 0; + while (consumer.receive(receivedMsg, 30000) == ResultOk) { + LOG_INFO("Received Message with [ content - " << receivedMsg.getDataAsString() << "] [ messageID = " << receivedMsg.getMessageId() << "]"); + ASSERT_EQ(ResultOk, consumer.acknowledge(receivedMsg)); + i++; + } + + LOG_DEBUG("globalPublishCountQueueFull = " << globalPublishCountQueueFull); + LOG_DEBUG("globalPublishCountSuccess = " << globalPublishCountSuccess); + LOG_DEBUG("numOfMessages = " << numOfMessages); + + // Number of messages produced + ASSERT_EQ(globalPublishCountSuccess + globalPublishCountQueueFull, numOfMessages); + + // Number of messages consumed + ASSERT_EQ(i, numOfMessages - globalPublishCountQueueFull); + +} diff --git a/pulsar-client-cpp/tests/BinaryLookupServiceTest.cc b/pulsar-client-cpp/tests/BinaryLookupServiceTest.cc new file mode 100644 index 0000000000000..d2ff2c7469e44 --- /dev/null +++ b/pulsar-client-cpp/tests/BinaryLookupServiceTest.cc @@ -0,0 +1,55 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include "ConnectionPool.h" +#include +#include + +using namespace pulsar; + +TEST(BinaryLookupServiceTest, basicLookup) { + ExecutorServiceProviderPtr service = boost::make_shared(1); + AuthenticationPtr authData = Auth::Disabled(); + std::string url = "pulsar://localhost:8885"; + ClientConfiguration conf; + ExecutorServiceProviderPtr ioExecutorProvider_(boost::make_shared(1)); + ConnectionPool pool_(conf, ioExecutorProvider_, authData, true); + BinaryProtoLookupService lookupService(pool_, url); + + std::string topic = "persistent://prop/unit/ns1/destination"; + DestinationNamePtr dn = DestinationName::get(topic); + + Future partitionFuture = lookupService.getPartitionMetadataAsync(dn); + LookupDataResultPtr lookupData; + Result result = partitionFuture.get(lookupData); + ASSERT_TRUE(lookupData != NULL); + ASSERT_EQ(0, lookupData->getPartitions()); + + Future future = lookupService.lookupAsync("persistent://prop/unit/ns1/destination"); + result = future.get(lookupData); + + ASSERT_EQ(ResultOk, result); + ASSERT_TRUE(lookupData != NULL); + ASSERT_EQ(url, lookupData->getBrokerUrl()); +} diff --git a/pulsar-client-cpp/tests/BlockingQueueTest.cc b/pulsar-client-cpp/tests/BlockingQueueTest.cc new file mode 100644 index 0000000000000..5653cad4d419e --- /dev/null +++ b/pulsar-client-cpp/tests/BlockingQueueTest.cc @@ -0,0 +1,232 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include + +#include +#include + +using namespace boost::posix_time; + +class ProducerWorker { + private: + boost::thread producerThread_; + BlockingQueue& queue_; + + public: + ProducerWorker(BlockingQueue& queue) + : queue_(queue) { + + } + + void produce(int number) { + producerThread_ = boost::thread(&ProducerWorker::pushNumbers, this, number); + } + + void pushNumbers(int number) { + for (int i = 1; i <= number; i++) { + queue_.push(i); + } + } + + void join() { + producerThread_.join(); + } +}; + +class ConsumerWorker { + private: + boost::thread consumerThread_; + BlockingQueue& queue_; + + public: + ConsumerWorker(BlockingQueue& queue) + : queue_(queue) { + + } + + void consume(int number) { + consumerThread_ = boost::thread(&ConsumerWorker::popNumbers, this, number); + } + + void popNumbers(int number) { + for (int i = 1; i <= number; i++) { + int poppedElement; + queue_.pop(poppedElement); + } + } + + void join() { + consumerThread_.join(); + } +}; + +TEST(BlockingQueueTest, testBasic) { + size_t size = 5; + BlockingQueue queue(size); + + ProducerWorker producerWorker(queue); + producerWorker.produce(5); + + ConsumerWorker consumerWorker(queue); + consumerWorker.consume(5); + + producerWorker.join(); + consumerWorker.join(); + + size_t zero = 0; + ASSERT_EQ(zero, queue.size()); +} + +TEST(BlockingQueueTest, testQueueOperations) { + size_t size = 5; + BlockingQueue queue(size); + for (size_t i = 1; i <= size; i++) { + queue.push(i); + } + ASSERT_EQ(queue.size(), size); + + int cnt = 1; + for (BlockingQueue::const_iterator it = queue.begin(); it != queue.end(); it++) { + ASSERT_EQ(cnt, *it); + ++cnt; + } + + cnt = 1; + for (BlockingQueue::iterator it = queue.begin(); it != queue.end(); it++) { + ASSERT_EQ(cnt, *it); + ++cnt; + } + + int poppedElement; + for (size_t i = 1; i <= size; i++) { + queue.pop(poppedElement); + } + + ASSERT_FALSE(queue.peek(poppedElement)); +} + +TEST(BlockingQueueTest, testBlockingProducer) { + size_t size = 5; + BlockingQueue queue(size); + + ProducerWorker producerWorker(queue); + producerWorker.produce(8); + + ConsumerWorker consumerWorker(queue); + consumerWorker.consume(5); + + producerWorker.join(); + consumerWorker.join(); + + size_t three = 3; + ASSERT_EQ(three, queue.size()); +} + +TEST(BlockingQueueTest, testBlockingConsumer) { + size_t size = 5; + BlockingQueue queue(size); + + ProducerWorker producerWorker(queue); + producerWorker.produce(5); + + ConsumerWorker consumerWorker(queue); + consumerWorker.consume(8); + + producerWorker.pushNumbers(3); + + producerWorker.join(); + consumerWorker.join(); + + size_t zero = 0; + ASSERT_EQ(zero, queue.size()); +} + +TEST(BlockingQueueTest, testTimeout) { + size_t size = 5; + BlockingQueue queue(size); + int value; + bool popReturn = queue.pop(value, seconds(1)); + boost::this_thread::sleep(seconds(2)); + ASSERT_FALSE(popReturn); +} + +TEST(BlockingQueueTest, testReservedSpot) { + size_t size = 3; + BlockingQueue queue(size); + + ASSERT_TRUE(queue.empty()); + ASSERT_FALSE(queue.full()); + ASSERT_EQ(0, queue.size()); + + queue.push(1); + ASSERT_FALSE(queue.empty()); + ASSERT_FALSE(queue.full()); + ASSERT_EQ(1, queue.size()); + + BlockingQueue::ReservedSpot spot1 = queue.reserve(); + ASSERT_FALSE(queue.empty()); + ASSERT_FALSE(queue.full()); + ASSERT_EQ(1, queue.size()); + + queue.push(2, spot1); + + ASSERT_FALSE(queue.empty()); + ASSERT_FALSE(queue.full()); + ASSERT_EQ(2, queue.size()); + + { + BlockingQueue::ReservedSpot spot2 = queue.reserve(); + + ASSERT_FALSE(queue.empty()); + ASSERT_TRUE(queue.full()); + ASSERT_EQ(2, queue.size()); + } + + ASSERT_FALSE(queue.empty()); + ASSERT_FALSE(queue.full()); + ASSERT_EQ(2, queue.size()); + + BlockingQueue::ReservedSpot spot3 = queue.reserve(); + + int res; + queue.pop(res); + ASSERT_EQ(1, res); + + ASSERT_FALSE(queue.empty()); + ASSERT_FALSE(queue.full()); + ASSERT_EQ(1, queue.size()); + + queue.pop(res); + ASSERT_EQ(2, res); + + ASSERT_TRUE(queue.empty()); + ASSERT_FALSE(queue.full()); + ASSERT_EQ(0, queue.size()); + + spot3.release(); + + { + BlockingQueue::ReservedSpot spot1 = queue.reserve(); + BlockingQueue::ReservedSpot spot2 = queue.reserve(); + BlockingQueue::ReservedSpot spot3 = queue.reserve(); + + ASSERT_TRUE(queue.empty()); + ASSERT_TRUE(queue.full()); + ASSERT_EQ(0, queue.size()); + } +} diff --git a/pulsar-client-cpp/tests/CMakeLists.txt b/pulsar-client-cpp/tests/CMakeLists.txt new file mode 100644 index 0000000000000..b2b542540b5e5 --- /dev/null +++ b/pulsar-client-cpp/tests/CMakeLists.txt @@ -0,0 +1,25 @@ +# +# Copyright 2016 Yahoo Inc. +# +# Licensed 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. +# + +find_library(GTEST_LIBRARY_PATH gtest) + +file(GLOB TEST_SOURCES *.cc) + +add_executable(main ${TEST_SOURCES}) + +target_include_directories(main PRIVATE ${CMAKE_SOURCE_DIR}/lib) + +target_link_libraries(main ${CLIENT_LIBS} ${GTEST_LIBRARY_PATH}) diff --git a/pulsar-client-cpp/tests/ClientTest.cc b/pulsar-client-cpp/tests/ClientTest.cc new file mode 100644 index 0000000000000..71c5c14c8b97f --- /dev/null +++ b/pulsar-client-cpp/tests/ClientTest.cc @@ -0,0 +1,77 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include + +#include +#include "../lib/checksum/ChecksumProvider.h" + +using namespace pulsar; + +static std::string lookupUrl = "pulsar://localhost:8885"; + +TEST(ClientTest, testChecksumComputation) { + + std::string data = "test"; + std::string doubleData = "testtest"; + + // (1) compute checksum of specific chunk of string + int checksum1 = computeChecksum(0, (char *) data.c_str(), data.length()); + int checksum2 = computeChecksum(0, (char *) doubleData.c_str() + 4, 4); + ASSERT_EQ(checksum1, checksum2); + + //(2) compute incremental checksum + // (a) checksum on full data + int doubleChecksum = computeChecksum(0, (char *) doubleData.c_str(), doubleData.length()); + // (b) incremental checksum on multiple partial data + checksum1 = computeChecksum(0, (char *) data.c_str(), data.length()); + int incrementalChecksum = computeChecksum(checksum1, (char *) data.c_str(), data.length()); + ASSERT_EQ(incrementalChecksum, doubleChecksum); + +} + +TEST(ClientTest, testSwHwChecksum) { + + std::string data = "test"; + std::string doubleData = "testtest"; + + // (1) compute checksum of specific chunk of string + // (a) HW + uint32_t hwChecksum1 = crc32cHw(0, (char *) data.c_str(), data.length()); + uint32_t hwChecksum2 = crc32cHw(0, (char *) doubleData.c_str() + 4, 4); + // (b) SW + uint32_t swChecksum1 = crc32cSw(0, (char *) data.c_str(), data.length()); + uint32_t swChecksum2 = crc32cSw(0, (char *) doubleData.c_str() + 4, 4); + ASSERT_EQ(hwChecksum1, hwChecksum2); + ASSERT_EQ(hwChecksum1, swChecksum1); + ASSERT_EQ(hwChecksum2, swChecksum2); + + //(2) compute incremental checksum + // (a.1) hw: checksum on full data + uint32_t hwDoubleChecksum = crc32cHw(0, (char *) doubleData.c_str(), doubleData.length()); + // (a.2) hw: incremental checksum on multiple partial data + hwChecksum1 = crc32cHw(0, (char *) data.c_str(), data.length()); + uint32_t hwIncrementalChecksum = crc32cHw(hwChecksum1, (char *) data.c_str(), data.length()); + // (b.1) sw: checksum on full data + uint32_t swDoubleChecksum = crc32cSw(0, (char *) doubleData.c_str(), doubleData.length()); + // (b.2) sw: incremental checksum on multiple partial data + swChecksum1 = crc32cHw(0, (char *) data.c_str(), data.length()); + uint32_t swIncrementalChecksum = crc32cSw(swChecksum1, (char *) data.c_str(), data.length()); + + ASSERT_EQ(hwIncrementalChecksum, hwDoubleChecksum); + ASSERT_EQ(hwIncrementalChecksum, swIncrementalChecksum); + +} diff --git a/pulsar-client-cpp/tests/ConsumerTest.cc b/pulsar-client-cpp/tests/ConsumerTest.cc new file mode 100644 index 0000000000000..bb384f923274d --- /dev/null +++ b/pulsar-client-cpp/tests/ConsumerTest.cc @@ -0,0 +1,95 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include + +#include "../lib/Future.h" +#include "../lib/Utils.h" + +using namespace pulsar; + +TEST(ConsumerTest, consumerNotInitialized) { + Consumer consumer; + + ASSERT_TRUE(consumer.getTopic().empty()); + ASSERT_TRUE(consumer.getSubscriptionName().empty()); + + Message msg; + ASSERT_EQ(ResultConsumerNotInitialized, consumer.receive(msg)); + ASSERT_EQ(ResultConsumerNotInitialized, consumer.receive(msg, 100)); + + ASSERT_EQ(ResultConsumerNotInitialized, consumer.acknowledge(msg)); + + MessageId msgId; + ASSERT_EQ(ResultConsumerNotInitialized, consumer.acknowledge(msgId)); + + Result result; + { + Promise promise; + consumer.acknowledgeAsync(msg, WaitForCallback(promise)); + promise.getFuture().get(result); + + ASSERT_EQ(ResultConsumerNotInitialized, result); + } + + { + Promise promise; + consumer.acknowledgeAsync(msgId, WaitForCallback(promise)); + promise.getFuture().get(result); + + ASSERT_EQ(ResultConsumerNotInitialized, result); + } + + ASSERT_EQ(ResultConsumerNotInitialized, consumer.acknowledgeCumulative(msg)); + ASSERT_EQ(ResultConsumerNotInitialized, consumer.acknowledgeCumulative(msgId)); + + { + Promise promise; + consumer.acknowledgeCumulativeAsync(msg, WaitForCallback(promise)); + promise.getFuture().get(result); + + ASSERT_EQ(ResultConsumerNotInitialized, result); + } + + { + Promise promise; + consumer.acknowledgeCumulativeAsync(msgId, WaitForCallback(promise)); + promise.getFuture().get(result); + + ASSERT_EQ(ResultConsumerNotInitialized, result); + } + + ASSERT_EQ(ResultConsumerNotInitialized, consumer.close()); + + { + Promise promise; + consumer.closeAsync(WaitForCallback(promise)); + promise.getFuture().get(result); + + ASSERT_EQ(ResultConsumerNotInitialized, result); + } + + ASSERT_EQ(ResultConsumerNotInitialized, consumer.unsubscribe()); + + { + Promise promise; + consumer.unsubscribeAsync(WaitForCallback(promise)); + promise.getFuture().get(result); + + ASSERT_EQ(ResultConsumerNotInitialized, result); + } +} diff --git a/pulsar-client-cpp/tests/ConsumerTest.h b/pulsar-client-cpp/tests/ConsumerTest.h new file mode 100644 index 0000000000000..50299871ff156 --- /dev/null +++ b/pulsar-client-cpp/tests/ConsumerTest.h @@ -0,0 +1,29 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "lib/ConsumerImpl.h" +#include + +using std::string; + +namespace pulsar{ +class ConsumerTest { + public: + static int getNumOfMessagesInQueue(const Consumer& consumer) { + return consumer.impl_->getNumOfPrefetchedMessages(); + } +}; +} diff --git a/pulsar-client-cpp/tests/CustomRoutingPolicy.h b/pulsar-client-cpp/tests/CustomRoutingPolicy.h new file mode 100644 index 0000000000000..135481cf74b37 --- /dev/null +++ b/pulsar-client-cpp/tests/CustomRoutingPolicy.h @@ -0,0 +1,30 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef CUSTOM_ROUTER_POLICY_HEADER_ +#define CUSTOM_ROUTER_POLICY_HEADER_ + +#include // rand() +#include +namespace pulsar { +class CustomRoutingPolicy : public MessageRoutingPolicy { + int getPartition(const Message& msg) { + return 0; + } +}; +} + +#endif // CUSTOM_ROUTER_POLICY_HEADER_ diff --git a/pulsar-client-cpp/tests/DestinationNameTest.cc b/pulsar-client-cpp/tests/DestinationNameTest.cc new file mode 100644 index 0000000000000..262cc00e122dd --- /dev/null +++ b/pulsar-client-cpp/tests/DestinationNameTest.cc @@ -0,0 +1,115 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include + +#include + +using namespace pulsar; + +TEST(DestinationNameTest, testLookup) { + boost::shared_ptr dn = DestinationName::get( + "persistent://pulsar/bf1/TESTNS.0/curveballapps"); + std::string lookup_name = dn->getLookupName(); + ASSERT_EQ(lookup_name, "persistent/pulsar/bf1/TESTNS.0/curveballapps"); +} + +TEST(DestinationNameTest, testDestinationName) { + // Compare getters and setters + boost::shared_ptr dn = DestinationName::get( + "persistent://property/cluster/namespace/destination"); + ASSERT_EQ("property", dn->getProperty()); + ASSERT_EQ("cluster", dn->getCluster()); + ASSERT_EQ("namespace", dn->getNamespacePortion()); + ASSERT_EQ("persistent", dn->getDomain()); + ASSERT_EQ(DestinationName::getEncodedName("destination"), dn->getLocalName()); + + // Compare == operator + boost::shared_ptr dn1 = DestinationName::get("persistent://p/c/n/d"); + boost::shared_ptr dn2 = DestinationName::get("persistent://p/c/n/d"); + ASSERT_TRUE(*dn1 == *dn2); +} + +TEST(DestinationNameTest, testDestinationNameWithSlashes) { + // Compare getters and setters + boost::shared_ptr dn = DestinationName::get( + "persistent://property/cluster/namespace/destination/name/with/slash"); + ASSERT_EQ("property", dn->getProperty()); + ASSERT_EQ("cluster", dn->getCluster()); + ASSERT_EQ("namespace", dn->getNamespacePortion()); + ASSERT_EQ("persistent", dn->getDomain()); + ASSERT_EQ("destination/name/with/slash", dn->getLocalName()); + + dn = DestinationName::get("persistent://property/cluster/namespace/destination/ends/with/slash/"); + ASSERT_TRUE(dn != NULL); + ASSERT_EQ(DestinationName::getEncodedName("destination/ends/with/slash/"), dn->getEncodedLocalName()); + + dn = DestinationName::get("persistent://property/cluster/namespace/`~!@#$%^&*()-_+=[]{}|\\;:'\"<>,./?"); + ASSERT_TRUE(dn != NULL); + ASSERT_EQ(DestinationName::getEncodedName("`~!@#$%^&*()-_+=[]{}|\\;:'\"<>,./?"), dn->getEncodedLocalName()); + + dn = DestinationName::get("persistent://property/cluster/namespace/topic@%*)(&!%$#@#$>getEncodedLocalName()); + + dn = DestinationName::get("persistent://property/cluster/namespace/destination//with//double//slash//"); + ASSERT_TRUE(dn != NULL); + ASSERT_EQ(DestinationName::getEncodedName("destination//with//double//slash//"), dn->getEncodedLocalName()); + + dn = DestinationName::get("persistent://property/cluster/namespace//destination/starts/with/slash/"); + ASSERT_TRUE(dn != NULL); + ASSERT_EQ(DestinationName::getEncodedName("/destination/starts/with/slash/"), dn->getEncodedLocalName()); + +} +TEST(DestinationNameTest, testEmptyClusterName) { + // Compare getters and setters + boost::shared_ptr dn = DestinationName::get( + "persistent://property//namespace/destination"); + + ASSERT_FALSE(dn); +} + +TEST(DestinationNameTest, testExtraSlashes) { + boost::shared_ptr dn = DestinationName::get( + "persistent://property/cluster//namespace/destination"); + ASSERT_FALSE(dn); + dn = DestinationName::get("persistent://property//cluster//namespace//destination"); + ASSERT_FALSE(dn); +} + +TEST(DestinationNameTest, testIllegalCharacters) { + boost::shared_ptr dn = DestinationName::get( + "persistent://prop!!!erty/cluster&)&Name/name%%%space/destination"); + ASSERT_FALSE(dn); +} + +TEST(DestinationNameTest, testIllegalUrl) { + boost::shared_ptr dn = DestinationName::get( + "persistent:::/property/cluster/namespace/destination"); + ASSERT_FALSE(dn); +} + +TEST(DestinationNameTest, testEmptyString) { + boost::shared_ptr dn = DestinationName::get( + ""); + ASSERT_FALSE(dn); +} + +TEST(DestinationNameTest, testExtraArguments) { + boost::shared_ptr dn = DestinationName::get( + "persistent:::/property/cluster/namespace/destination/some/extra/args"); + ASSERT_FALSE(dn); +} diff --git a/pulsar-client-cpp/tests/HttpHelper.cc b/pulsar-client-cpp/tests/HttpHelper.cc new file mode 100644 index 0000000000000..95ae39b373090 --- /dev/null +++ b/pulsar-client-cpp/tests/HttpHelper.cc @@ -0,0 +1,38 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + + #include "HttpHelper.h" + + #include + + + int makePutRequest(const std::string& url, const std::string& body) { + CURL* curl = curl_easy_init(); + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str()); + + int res = curl_easy_perform(curl); + if (res != CURLE_OK) { + return -1; + } + + int httpResult = 0; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpResult); + + curl_easy_cleanup(curl); + return httpResult; + } diff --git a/pulsar-client-cpp/tests/HttpHelper.h b/pulsar-client-cpp/tests/HttpHelper.h new file mode 100644 index 0000000000000..79db65892bfc6 --- /dev/null +++ b/pulsar-client-cpp/tests/HttpHelper.h @@ -0,0 +1,25 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#ifndef HTTP_HELPER +#define HTTP_HELPER + +#include + +int makePutRequest(const std::string& url, const std::string& body); + + +#endif /* end of include guard: HTTP_HELPER */ diff --git a/pulsar-client-cpp/tests/LatchTest.cc b/pulsar-client-cpp/tests/LatchTest.cc new file mode 100644 index 0000000000000..04aa9e347263d --- /dev/null +++ b/pulsar-client-cpp/tests/LatchTest.cc @@ -0,0 +1,89 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include +#include +#include +#include "LogUtils.h" + +DECLARE_LOG_OBJECT() + +using namespace pulsar; +using namespace boost::posix_time; + +class Service { + private: + std::string serviceName_; + time_duration sleepDuration_; + Latch latch_; + boost::thread thread_; + + public: + Service(const std::string& serviceName, time_duration sleepDuration, const Latch& latch) + : serviceName_(serviceName), + sleepDuration_(sleepDuration), + latch_(latch) { + thread_ = boost::thread(&Service::run, this); + } + + void run() { + boost::this_thread::sleep(sleepDuration_); + LOG_INFO("Service " << serviceName_ << " is up"); + latch_.countdown(); + } + + ~Service() { + thread_.join(); + } +}; + +TEST(LatchTest, testCountDown) { + Latch latch(3); + Service service1("service1", millisec(50), latch); + Service service2("service2", millisec(30), latch); + Service service3("service3", millisec(20), latch); + latch.wait(); +} + +TEST(LatchTest, testLatchCount) { + Latch latch(3); + Service service1("service1", millisec(50), latch); + Service service2("service2", millisec(30), latch); + Service service3("service3", millisec(20), latch); + ASSERT_EQ(3, latch.getCount()); + latch.wait(); + ASSERT_EQ(0, latch.getCount()); +} + +TEST(LatchTest, testTimedWait) { + // Wait for 7 seconds which is more than the maximum sleep time (5 seconds) + Latch latch1(3); + Service service1("service1", millisec(50), latch1); + Service service2("service2", millisec(30), latch1); + Service service3("service3", millisec(50), latch1); + ASSERT_TRUE(latch1.wait(millisec(70))); + + // Wait for 3 seconds which is less than the maximum sleep time (5 seconds) + Latch latch2(3); + Service service4("service4", millisec(50), latch2); + Service service5("service5", millisec(30), latch2); + Service service6("service6", millisec(50), latch2); + ASSERT_FALSE(latch2.wait(millisec(30))); + + // After the assert is passed and Service is destroyed because of join, the + // main thread would not exit until service4 thread is returned. +} diff --git a/pulsar-client-cpp/tests/LoggerTest.cc b/pulsar-client-cpp/tests/LoggerTest.cc new file mode 100644 index 0000000000000..413728fe68964 --- /dev/null +++ b/pulsar-client-cpp/tests/LoggerTest.cc @@ -0,0 +1,26 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "LogUtils.h" +#include + +DECLARE_LOG_OBJECT() + +TEST(LoggerTest, testLogger) { + LOG_DEBUG("Testing logger..."); + int a = 5; + LOG_INFO("Testing logger with arguments " << a); +} diff --git a/pulsar-client-cpp/tests/MessageTest.cc b/pulsar-client-cpp/tests/MessageTest.cc new file mode 100644 index 0000000000000..368e3ecb747fc --- /dev/null +++ b/pulsar-client-cpp/tests/MessageTest.cc @@ -0,0 +1,79 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include +#include +#include +#include + +DECLARE_LOG_OBJECT() + +using namespace pulsar; +TEST(MessageTest, testMessageContents) { + MessageBuilder msgBuilder1; + std::string content = "my-content"; + msgBuilder1.setContent(content); + Message msg = msgBuilder1.build(); + ASSERT_EQ(content, msg.getDataAsString()); + ASSERT_EQ(content.length(), msg.getLength()); + ASSERT_EQ(content, std::string((char * ) msg.getData(), msg.getLength())); + + MessageBuilder msgBuilder2; + std::string myContents = "mycontents"; + msgBuilder2.setContent(myContents.c_str(), myContents.length()); + msg = msgBuilder2.build(); + ASSERT_EQ(myContents, std::string((char * ) msg.getData(), msg.getLength())); + ASSERT_NE(myContents.c_str(), (char * ) msg.getData()); + ASSERT_EQ(myContents, msg.getDataAsString()); + ASSERT_EQ(std::string("mycontents").length(), msg.getLength()); +} + +TEST(MessageTest, testAllocatedContents) { + MessageBuilder msgBuilder; + std::string str = "content"; + char *content = new char[str.size()]; + strcpy(content, str.c_str()); + msgBuilder.setAllocatedContent(content, str.length()); + Message msg = msgBuilder.build(); + ASSERT_FALSE(strncmp("content", (char * ) msg.getData(), msg.getLength())); + ASSERT_EQ(content, (char * ) msg.getData()); + delete[] content; +} + +template +bool compareMaps(const Map& lhs, const Map& rhs) { + return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin()); +} + +TEST(MessageTest, testProperties) { + MessageBuilder msgBuilder1; + msgBuilder1.setProperty("property1", "value1"); + Message msg = msgBuilder1.build(); + ASSERT_EQ(msg.getProperty("property1"), "value1"); + + MessageBuilder msgBuilder2; + Message::StringMap stringMap; + stringMap.insert(std::pair("p1", "v1")); + stringMap.insert(std::pair("p2", "v2")); + stringMap.insert(std::pair("p3", "v3")); + msgBuilder2.setProperties(stringMap); + msg = msgBuilder2.build(); + ASSERT_EQ(msg.getProperty("p1"), "v1"); + ASSERT_EQ(msg.getProperty("p2"), "v2"); + ASSERT_EQ(msg.getProperty("p3"), "v3"); + ASSERT_TRUE(compareMaps(msg.getProperties(), stringMap)); +} diff --git a/pulsar-client-cpp/tests/NamespaceNameTest.cc b/pulsar-client-cpp/tests/NamespaceNameTest.cc new file mode 100644 index 0000000000000..d42acb31ab992 --- /dev/null +++ b/pulsar-client-cpp/tests/NamespaceNameTest.cc @@ -0,0 +1,29 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include + +#include + +TEST(NamespaceNameTest, testNamespaceName) { + boost::shared_ptr nn1 = NamespaceName::get("property", "cluster", "namespace"); + ASSERT_EQ("property", nn1->getProperty()); + ASSERT_EQ("cluster", nn1->getCluster()); + ASSERT_EQ("namespace", nn1->getLocalName()); + + boost::shared_ptr nn2 = NamespaceName::get("property", "cluster", "namespace"); + ASSERT_TRUE(*nn1 == *nn2); +} diff --git a/pulsar-client-cpp/tests/ProducerTest.cc b/pulsar-client-cpp/tests/ProducerTest.cc new file mode 100644 index 0000000000000..635316b30cea2 --- /dev/null +++ b/pulsar-client-cpp/tests/ProducerTest.cc @@ -0,0 +1,48 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include + +#include "../lib/Future.h" +#include "../lib/Utils.h" + +using namespace pulsar; + +TEST(ProducerTest, producerNotInitialized) { + Producer producer; + + Message msg = MessageBuilder().setContent("test").build(); + + ASSERT_EQ(ResultProducerNotInitialized, producer.send(msg)); + + Promise promise; + producer.sendAsync(msg, WaitForCallbackValue(promise)); + + Message m; + ASSERT_EQ(ResultProducerNotInitialized, promise.getFuture().get(m)); + + ASSERT_EQ(ResultProducerNotInitialized, producer.close()); + + Promise promiseClose; + producer.closeAsync(WaitForCallback(promiseClose)); + + Result result; + promiseClose.getFuture().get(result); + ASSERT_EQ(ResultProducerNotInitialized, result); + + ASSERT_TRUE(producer.getTopic().empty()); +} diff --git a/pulsar-client-cpp/tests/PulsarFriend.h b/pulsar-client-cpp/tests/PulsarFriend.h new file mode 100644 index 0000000000000..c2e0b57f7995e --- /dev/null +++ b/pulsar-client-cpp/tests/PulsarFriend.h @@ -0,0 +1,29 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include + +using std::string; + +namespace pulsar{ +class PulsarFriend { + public: + static int getBatchIndex(const BatchMessageId& mId) { + return mId.batchIndex_; + } +}; +} diff --git a/pulsar-client-cpp/tests/UrlTest.cc b/pulsar-client-cpp/tests/UrlTest.cc new file mode 100644 index 0000000000000..183b30f9160bf --- /dev/null +++ b/pulsar-client-cpp/tests/UrlTest.cc @@ -0,0 +1,60 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include "Url.h" +#include + +using namespace pulsar; + +TEST(UrlTest, testUrl) { + Url url; + + ASSERT_TRUE(Url::parse("http://example.com", url)); + ASSERT_EQ("http", url.protocol()); + ASSERT_EQ(80, url.port()); + + ASSERT_TRUE(Url::parse("https://example.com", url)); + ASSERT_EQ("https", url.protocol()); + ASSERT_EQ(443, url.port()); + + ASSERT_TRUE(Url::parse("http://example.com:8080", url)); + ASSERT_EQ("http", url.protocol()); + ASSERT_EQ(8080, url.port()); + + ASSERT_TRUE(Url::parse("http://example.com:8080/", url)); + ASSERT_EQ("http", url.protocol()); + ASSERT_EQ(8080, url.port()); + + ASSERT_TRUE(Url::parse("http://example.com", url)); + ASSERT_EQ("http", url.protocol()); + ASSERT_EQ(80, url.port()); + + ASSERT_TRUE(Url::parse("http://example.com:8080/test/my/path", url)); + ASSERT_EQ("http", url.protocol()); + ASSERT_EQ(8080, url.port()); + + ASSERT_TRUE(Url::parse("http://example.com:8080/test/my/path?key=value#adsasda", url)); + ASSERT_EQ("http", url.protocol()); + ASSERT_EQ(8080, url.port()); + + ASSERT_TRUE(Url::parse("pulsar://example.com:8080", url)); + ASSERT_EQ("pulsar", url.protocol()); + ASSERT_EQ(8080, url.port()); + + ASSERT_TRUE(Url::parse("pulsar://example.com", url)); + ASSERT_EQ("pulsar", url.protocol()); + ASSERT_EQ(6650, url.port()); +} diff --git a/pulsar-client-cpp/tests/main.cc b/pulsar-client-cpp/tests/main.cc new file mode 100644 index 0000000000000..d49b70dd1f7d1 --- /dev/null +++ b/pulsar-client-cpp/tests/main.cc @@ -0,0 +1,24 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include + +int main(int argc, char **argv) { + LogUtils::init("log4cxx.conf"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/pulsar-client-cpp/tests/standalone.conf b/pulsar-client-cpp/tests/standalone.conf new file mode 100644 index 0000000000000..05e587ebacbb4 --- /dev/null +++ b/pulsar-client-cpp/tests/standalone.conf @@ -0,0 +1,254 @@ +# +# Copyright 2016 Yahoo Inc. +# +# Licensed 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. +# + +### --- General broker settings --- ### + +# Zookeeper quorum connection string +zookeeperServers= + +# Global Zookeeper quorum connection string +globalZookeeperServers= + +brokerServicePort=8885 + +# Port to use to server HTTP request +webServicePort=8765 + +# Hostname or IP address the service binds on, default is 0.0.0.0. +bindAddress=0.0.0.0 + +# Hostname or IP address the service advertises to the outside world. If not set, the value of InetAddress.getLocalHost().getHostName() is used. +advertisedAddress=localhost + +# Name of the cluster to which this broker belongs to +clusterName=standalone + +# Zookeeper session timeout in milliseconds +zooKeeperSessionTimeoutMillis=30000 + +# Time to wait for broker graceful shutdown. After this time elapses, the process will be killed +brokerShutdownTimeoutMs=3000 + +# Enable backlog quota check. Enforces action on topic when the quota is reached +backlogQuotaCheckEnabled=true + +# How often to check for topics that have reached the quota +backlogQuotaCheckIntervalInSeconds=60 + +# Default per-topic backlog quota limit +backlogQuotaDefaultLimitGB=10 + +# Enable the deletion of inactive topics +brokerDeleteInactiveTopicsEnabled=true + +# How often to check for inactive topics +brokerDeleteInactiveTopicsFrequencySeconds=60 + +# How frequently to proactively check and purge expired messages +messageExpiryCheckIntervalInMinutes=5 + +# Enable check for minimum allowed client library version +clientLibraryVersionCheckEnabled=false + +# Allow client libraries with no version information +clientLibraryVersionCheckAllowUnversioned=true + +# Path for the file used to determine the rotation status for the broker when responding +# to service discovery health checks +statusFilePath=/usr/local/apache/htdocs + +# Max number of unacknowledged messages allowed to receive messages by a consumer on a shared subscription. Broker will stop sending +# messages to consumer once, this limit reaches until consumer starts acknowledging messages back +# Using a value of 0, is disabling unackeMessage limit check and consumer can receive messages without any restriction +maxUnackedMessagesPerConsumer=50000 + +### --- Authentication --- ### + +# Enable authentication +authenticationEnabled=false + +# Autentication provider name list, which is comma separated list of class names +authenticationProviders=false + +# Enforce authorization +authorizationEnabled=false + +# Role names that are treated as "super-user", meaning they will be able to do all admin +# operations and publish/consume from all topics +superUserRoles= + +# Authentication settings of the broker itself. Used when the broker connects to other brokers, +# either in same or other clusters +brokerClientAuthenticationPlugin= +brokerClientAuthenticationParameters= + + +### --- BookKeeper Client --- ### + +# Authentication plugin to use when connecting to bookies +bookkeeperClientAuthenticationPlugin= + +# BookKeeper auth plugin implementatation specifics parameters name and values +bookkeeperClientAuthenticationParametersName= +bookkeeperClientAuthenticationParameters= + +# Timeout for BK add / read operations +bookkeeperClientTimeoutInSeconds=30 + +# Speculative reads are initiated if a read request doesn't complete within a certain time +# Using a value of 0, is disabling the speculative reads +bookkeeperClientSpeculativeReadTimeoutInMillis=0 + +# Enable bookies health check. Bookies that have more than the configured number of failure within +# the interval will be quarantined for some time. During this period, new ledgers won't be created +# on these bookies +bookkeeperClientHealthCheckEnabled=true +bookkeeperClientHealthCheckIntervalSeconds=60 +bookkeeperClientHealthCheckErrorThresholdPerInterval=5 +bookkeeperClientHealthCheckQuarantineTimeInSeconds=1800 + +# Enable rack-aware bookie selection policy. BK will chose bookies from different racks when +# forming a new bookie ensemble +bookkeeperClientRackawarePolicyEnabled=true + +# Enable bookie isolation by specifying a list of bookie groups to choose from. Any bookie +# outside the specified groups will not be used by the broker +bookkeeperClientIsolationGroups= + +### --- Managed Ledger --- ### + +# Number of bookies to use when creating a ledger +managedLedgerDefaultEnsembleSize=1 + +# Number of copies to store for each message +managedLedgerDefaultWriteQuorum=1 + +# Number of guaranteed copies (acks to wait before write is complete) +managedLedgerDefaultAckQuorum=1 + +# Amount of memory to use for caching data payload in managed ledger. This memory +# is allocated from JVM direct memory and it's shared across all the topics +# running in the same broker +managedLedgerCacheSizeMB=1024 + +# Threshold to which bring down the cache level when eviction is triggered +managedLedgerCacheEvictionWatermark=0.9 + +# Rate limit the amount of writes generated by consumer acking the messages +managedLedgerDefaultMarkDeleteRateLimit=0.1 + +# Max number of entries to append to a ledger before triggering a rollover +# A ledger rollover is triggered on these conditions +# * Either the max rollover time has been reached +# * or max entries have been written to the ledged and at least min-time +# has passed +managedLedgerMaxEntriesPerLedger=50000 + +# Minimum time between ledger rollover for a topic +managedLedgerMinLedgerRolloverTimeMinutes=10 + +# Maximum time before forcing a ledger rollover for a topic +managedLedgerMaxLedgerRolloverTimeMinutes=240 + +# Max number of entries to append to a cursor ledger +managedLedgerCursorMaxEntriesPerLedger=50000 + +# Max time before triggering a rollover on a cursor ledger +managedLedgerCursorRolloverTimeInSeconds=14400 + + + +### --- Load balancer --- ### + +# Enable load balancer +loadBalancerEnabled=false + +# Strategy to assign a new bundle +loadBalancerPlacementStrategy=weightedRandomSelection + +# Percentage of change to trigger load report update +loadBalancerReportUpdateThresholdPercentage=10 + +# maximum interval to update load report +loadBalancerReportUpdateMaxIntervalMinutes=15 + +# Frequency of report to collect +loadBalancerHostUsageCheckIntervalMinutes=1 + +# Load shedding interval. Broker periodically checks whether some traffic should be offload from +# some over-loaded broker to other under-loaded brokers +loadBalancerSheddingIntervalMinutes=30 + +# Prevent the same topics to be shed and moved to other broker more that once within this timeframe +loadBalancerSheddingGracePeriodMinutes=30 + +# Usage threshold to determine a broker as under-loaded +loadBalancerBrokerUnderloadedThresholdPercentage=1 + +# Usage threshold to determine a broker as over-loaded +loadBalancerBrokerOverloadedThresholdPercentage=85 + +# Interval to update namespace bundle resource quotat +loadBalancerResourceQuotaUpdateIntervalMinutes=15 + +# Usage threshold to determine a broker is having just right level of load +loadBalancerBrokerComfortLoadLevelPercentage=65 + +# enable/disable namespace bundle auto split +loadBalancerAutoBundleSplitEnabled=false + +# interval to detect & split hot namespace bundle +loadBalancerNamespaceBundleSplitIntervalMinutes=15 + +# maximum topics in a bundle, otherwise bundle split will be triggered +loadBalancerNamespaceBundleMaxTopics=1000 + +# maximum sessions (producers + consumers) in a bundle, otherwise bundle split will be triggered +loadBalancerNamespaceBundleMaxSessions=1000 + +# maximum msgRate (in + out) in a bundle, otherwise bundle split will be triggered +loadBalancerNamespaceBundleMaxMsgRate=1000 + +# maximum bandwidth (in + out) in a bundle, otherwise bundle split will be triggered +loadBalancerNamespaceBundleMaxBandwidthMbytes=100 + +# maximum number of bundles in a namespace +loadBalancerNamespaceMaximumBundles=128 + +### --- Replication --- ### + +# Enable replication metrics +replicationMetricsEnabled=true + +# Max number of connections to open for each broker in a remote cluster +# More connections host-to-host lead to better throughput over high-latency +# links. +replicationConnectionsPerBroker=16 + +# Replicator producer queue size +replicationProducerQueueSize=1000 + +# Default message retention time +defaultRetentionTimeInMinutes=0 + +# Default retention size +defaultRetentionSizeInMB=0 + +# How often to check whether the connections are still alive +keepAliveIntervalSeconds=30 + +# How often broker checks for inactive topics to be deleted (topics with no subscriptions and no one connected) +brokerServicePurgeInactiveFrequencyInSeconds=60 diff --git a/pulsar-client-cpp/travis-build.sh b/pulsar-client-cpp/travis-build.sh new file mode 100755 index 0000000000000..f760afbc80780 --- /dev/null +++ b/pulsar-client-cpp/travis-build.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +# Copyright 2016 Yahoo Inc. +# +# Licensed 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. + +function usage() { + echo "$0: [all|dep|compile]"; + echo " Unpack Location is used to store downloaded dependant packages"; + echo " Build directory is pulsar base folder"; + exit 1; +} + +if [ $# -ne 3 ]; then + usage +fi + +if [ ! -d $1 ]; then + echo "Unpack directory $1 does not exists" + echo "" + usage; +fi + +if [ ! -d $2 ]; then + echo "Build directory $2 does not exists" + echo "" + usage; +fi + +if [ "$3" != "all" -a "$3" != "dep" -a "$3" != "compile" ]; then + echo "Unknown command $3. Supported commands all|dep|compile"; + echo "" + usage; +fi + +exec_cmd() { + eval $* + if [ $? -ne 0 ]; then + echo "Command $* failed" + usage + fi + return $! +} + +if [ "$3" = "all" -o "$3" = "dep" ]; then + # Install dependant packages + exec_cmd "apt-get install -y cmake libssl-dev libcurl4-openssl-dev liblog4cxx10-dev libprotobuf-dev libboost1.55-all-dev libgtest-dev"; + exec_cmd "pushd $1/ && wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz && popd"; + exec_cmd "pushd /usr/src/gtest && cmake . && make && cp *.a /usr/lib && popd"; + exec_cmd "pushd $1/ && tar xvfz $1/protobuf-2.6.1.tar.gz && pushd $1/protobuf-2.6.1 && ./configure && make && make install && popd && popd"; +fi + +if [ "$3" = "all" -o "$3" = "compile" ]; then + # Compile and run unit tests + exec_cmd "pushd $2/pulsar-client-cpp && cmake . && make && popd"; + PULSAR_STANDALONE_CONF=$2/pulsar-client-cpp/tests/standalone.conf $2/bin/pulsar standalone & + pid=$!; + exec_cmd "sleep 10 && pushd $2/pulsar-client-cpp/tests && ./main && popd"; + exec_cmd "kill -SIGTERM $pid"; +fi diff --git a/pulsar-client-cpp/wireshark/moduleinfo.h b/pulsar-client-cpp/wireshark/moduleinfo.h new file mode 100644 index 0000000000000..20ba425f11967 --- /dev/null +++ b/pulsar-client-cpp/wireshark/moduleinfo.h @@ -0,0 +1,32 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +/* Included *after* config.h, in order to re-define these macros */ + +#ifdef PACKAGE +#undef PACKAGE +#endif + +/* Name of package */ +#define PACKAGE "|pulsar|" + + +#ifdef VERSION +#undef VERSION +#endif + +/* Version number of package */ +#define VERSION "0.0.1" diff --git a/pulsar-client-cpp/wireshark/pulsarDissector.cc b/pulsar-client-cpp/wireshark/pulsarDissector.cc new file mode 100644 index 0000000000000..6541278d9648c --- /dev/null +++ b/pulsar-client-cpp/wireshark/pulsarDissector.cc @@ -0,0 +1,958 @@ +/** + * Copyright 2016 Yahoo Inc. + * + * Licensed 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. + */ + +#include +#include "moduleinfo.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PulsarApi.pb.h" + +const static int PULSAR_PORT = 6650; + +static int proto_pulsar = -1; +static int hf_pulsar_error = -1; +static int hf_pulsar_error_message = -1; +static int hf_pulsar_cmd_type = -1; +static int hf_pulsar_frame_size = -1; +static int hf_pulsar_cmd_size = -1; + +static int hf_pulsar_client_version = -1; +static int hf_pulsar_auth_method = -1; +static int hf_pulsar_auth_data = -1; +static int hf_pulsar_protocol_version = -1; +static int hf_pulsar_server_version = -1; + +static int hf_pulsar_topic = -1; +static int hf_pulsar_subscription = -1; +static int hf_pulsar_subType = -1; +static int hf_pulsar_consumer_id = -1; +static int hf_pulsar_producer_id = -1; +static int hf_pulsar_server_error = -1; +static int hf_pulsar_ack_type = -1; +static int hf_pulsar_request_id = -1; +static int hf_pulsar_consumer_name = -1; +static int hf_pulsar_producer_name = -1; + +static int hf_pulsar_publish_time = -1; +static int hf_pulsar_replicated_from = -1; +static int hf_pulsar_partition_key = -1; +static int hf_pulsar_replicate_to = -1; +static int hf_pulsar_property = -1; + +static int hf_pulsar_request_in = -1; +static int hf_pulsar_response_in = -1; +static int hf_pulsar_publish_latency = -1; + +static int hf_pulsar_sequence_id = -1; +static int hf_pulsar_message_id = -1; +static int hf_pulsar_message_permits = -1; + +static int ett_pulsar = -1; + +const static int FRAME_SIZE_LEN = 4; + +static pulsar::proto::BaseCommand command; + +using namespace pulsar::proto; + +static const value_string pulsar_cmd_names[] = { // + { BaseCommand::CONNECT, "Connect" }, // + { BaseCommand::CONNECTED, "Connected" }, // + { BaseCommand::SUBSCRIBE, "Subscribe" }, // + { BaseCommand::PRODUCER, "Producer" }, // + { BaseCommand::SEND, "Send" }, // + { BaseCommand::SEND_RECEIPT, "SendReceipt" }, // + { BaseCommand::SEND_ERROR, "SendError" }, // + { BaseCommand::MESSAGE, "Message" }, // + { BaseCommand::ACK, "Ack" }, // + { BaseCommand::FLOW, "Flow" }, // + { BaseCommand::UNSUBSCRIBE, "Unsubscribe" }, // + { BaseCommand::SUCCESS, "Success" }, // + { BaseCommand::ERROR, "Error" }, // + { BaseCommand::CLOSE_PRODUCER, "CloseProducer" }, // + { BaseCommand::CLOSE_CONSUMER, "CloseConsumer" }, // + { BaseCommand::PRODUCER_SUCCESS, "ProducerSuccess" }, // + { BaseCommand::PING, "Ping" }, // + { BaseCommand::PONG, "Pong" }, // + }; + +static const value_string auth_methods_vs[] = { { AuthMethodNone, "None" }, // + { AuthMethodYcaV1, "YCAv1" }, // + { AuthMethodAthens, "Athens" } // +}; + +static const value_string server_errors_vs[] = { { UnknownError, "UnknownError" }, // + { MetadataError, "MetadataError" }, // + { PersistenceError, "PersistenceError" }, // + { AuthenticationError, "AuthenticationError" }, // + { AuthorizationError, "AuthorizationError" }, // + { ConsumerBusy, "ConsumerBusy" }, // + { ServiceNotReady, "ServiceNotReady" }, // + { ProducerBlockedQuotaExceededError, "ProducerBlockedQuotaExceededError" }, // + { ProducerBlockedQuotaExceededException, "ProducerBlockedQuotaExceededException" } // +}; + +static const value_string ack_type_vs[] = { { CommandAck::Individual, "Individual" }, // + { CommandAck::Cumulative, "Cumulative" } // +}; + +static const value_string protocol_version_vs[] = { { v0, "v0" }, // + { v1, "v1" } // +}; + +static const value_string sub_type_names_vs[] = { // + { CommandSubscribe::Exclusive, "Exclusive" }, // + { CommandSubscribe::Shared, "Shared" }, // + { CommandSubscribe::Failover, "Failover" } // + }; + +static const char* to_str(int value, const value_string* values) { + return val_to_str(value, values, "Unknown (%d)"); +} + +struct MessageIdComparator { + bool operator()(const MessageIdData& a, const MessageIdData& b) const { + if (a.ledgerid() < b.ledgerid()) { + return true; + } else if (a.ledgerid() == b.ledgerid()) { + return a.entryid() < b.entryid(); + } else { + return false; + } + } +}; + +struct RequestData { + uint32_t requestFrame; + nstime_t requestTimestamp; + uint32_t ackFrame; + nstime_t ackTimestamp; + + RequestData() + : requestFrame(UINT32_MAX), + ackFrame(UINT32_MAX) { + } +}; + +struct RequestResponseData : public RequestData { + uint64_t id; // producer / consumer id +}; + +struct ProducerData { + std::string topic; + std::string producerName; + + std::map messages; +}; + +struct ConsumerData { + std::string topic; + std::string subscriptionName; + std::string consumerName; + CommandSubscribe::SubType subType; + + // Link messages to acks for the consumer + std::map messages; +}; + +struct ConnectionState { + std::map producers; + std::map consumers; + std::map requests; +}; + +static void dissect_message_metadata(proto_tree* frame_tree, tvbuff_t *tvb, int offset, + int maxOffset) { + // Decode message metadata + uint32_t metadataSize = (uint32_t) tvb_get_ntohl(tvb, offset); + offset += 4; + + if (offset + metadataSize > maxOffset) { + // Not enough data to dissect metadata + proto_tree_add_debug_text(frame_tree, "[Not enough data to dissect message metadata]"); + return; + } + + static MessageMetadata msgMetadata; + uint8_t* ptr = (uint8_t*) tvb_get_ptr(tvb, offset, metadataSize); + + if (!msgMetadata.ParseFromArray(ptr, metadataSize)) { + proto_tree_add_boolean_format(frame_tree, hf_pulsar_error, tvb, offset, metadataSize, true, + "Error parsing protocol buffer message metadata"); + return; + } + + proto_item* md_tree = proto_tree_add_subtree_format(frame_tree, tvb, offset, metadataSize, + ett_pulsar, + NULL, + "Message / %s / %llu", + msgMetadata.producer_name().c_str(), + msgMetadata.sequence_id()); + proto_tree_add_string(md_tree, hf_pulsar_producer_name, tvb, offset, metadataSize, + msgMetadata.producer_name().c_str()); + proto_tree_add_uint64(md_tree, hf_pulsar_sequence_id, tvb, offset, metadataSize, + msgMetadata.sequence_id()); + proto_tree_add_uint64(md_tree, hf_pulsar_publish_time, tvb, offset, metadataSize, + msgMetadata.publish_time()); + if (msgMetadata.has_replicated_from()) { + proto_tree_add_string(md_tree, hf_pulsar_replicated_from, tvb, offset, metadataSize, + msgMetadata.replicated_from().c_str()); + } + + if (msgMetadata.properties_size() > 0) { + proto_item* properties_tree = proto_tree_add_subtree_format(frame_tree, tvb, offset, + metadataSize, ett_pulsar, + NULL, + "Properties"); + for (int i = 0; i < msgMetadata.properties_size(); i++) { + const KeyValue& kv = msgMetadata.properties(i); + proto_tree_add_string_format(properties_tree, hf_pulsar_property, tvb, offset, + metadataSize, "", "%s : %s", kv.key().c_str(), + kv.value().c_str()); + } + } + + if (msgMetadata.replicate_to_size() > 0) { + proto_item* replicate_tree = proto_tree_add_subtree_format(frame_tree, tvb, offset, + metadataSize, ett_pulsar, + NULL, + "Replicate to"); + for (int i = 0; i < msgMetadata.replicate_to_size(); i++) { + proto_tree_add_string_format(replicate_tree, hf_pulsar_replicated_from, tvb, offset, + metadataSize, "", "%s", + msgMetadata.replicate_to(i).c_str()); + } + } + + if (msgMetadata.has_partition_key()) { + proto_tree_add_string(md_tree, hf_pulsar_partition_key, tvb, offset, metadataSize, + msgMetadata.partition_key().c_str()); + } + + offset += metadataSize; + uint32_t payloadSize = maxOffset - offset; + proto_tree_add_subtree_format(md_tree, tvb, offset, payloadSize, ett_pulsar, NULL, + "Payload / size=%u", payloadSize); +} + +void link_to_request_frame(proto_tree* cmd_tree, tvbuff_t* tvb, int offset, int size, + const RequestData& reqData) { + if (reqData.requestFrame != UINT32_MAX) { + proto_tree* item = proto_tree_add_uint(cmd_tree, hf_pulsar_request_in, tvb, offset, size, + reqData.requestFrame); + PROTO_ITEM_SET_GENERATED(item); + + nstime_t latency; + nstime_delta(&latency, &reqData.ackTimestamp, &reqData.requestTimestamp); + item = proto_tree_add_time(cmd_tree, hf_pulsar_publish_latency, tvb, offset, size, &latency); + PROTO_ITEM_SET_GENERATED(item); + } +} + +void link_to_response_frame(proto_tree* cmd_tree, tvbuff_t* tvb, int offset, int size, + const RequestData& reqData) { + if (reqData.ackFrame != UINT32_MAX) { + proto_tree* item = proto_tree_add_uint(cmd_tree, hf_pulsar_response_in, tvb, offset, size, + reqData.ackFrame); + PROTO_ITEM_SET_GENERATED(item); + + nstime_t latency; + nstime_delta(&latency, &reqData.ackTimestamp, &reqData.requestTimestamp); + item = proto_tree_add_time(cmd_tree, hf_pulsar_publish_latency, tvb, offset, size, &latency); + PROTO_ITEM_SET_GENERATED(item); + } +} + +////////// + +/* This method dissects fully reassembled messages */ +static int dissect_pulsar_message(tvbuff_t *tvb, packet_info* pinfo, proto_tree* tree, + void* data _U_) { + col_set_str(pinfo->cinfo, COL_PROTOCOL, "yahoo-Pulsar"); + + conversation_t* conversation = find_or_create_conversation(pinfo); + ConnectionState* state = (ConnectionState*) conversation_get_proto_data(conversation, + proto_pulsar); + if (state == NULL) { + state = new ConnectionState(); + conversation_add_proto_data(conversation, proto_pulsar, state); + } + + uint32_t offset = FRAME_SIZE_LEN; + int maxOffset = tvb_captured_length(tvb); + + uint32_t cmdSize = (uint32_t) tvb_get_ntohl(tvb, offset); + offset += 4; + + if (offset + cmdSize > maxOffset) { + // Not enough data to dissect + proto_tree_add_debug_text(tree, "[Not enough data to dissect command]"); + return maxOffset; + } + + uint8_t* ptr = (uint8_t*) tvb_get_ptr(tvb, offset, cmdSize); + if (!command.ParseFromArray(ptr, cmdSize)) { + proto_tree_add_boolean_format(tree, hf_pulsar_error, tvb, offset, cmdSize, true, + "Error parsing protocol buffer command"); + return maxOffset; + } + + int cmdOffset = offset; + offset += cmdSize; + + col_add_str(pinfo->cinfo, COL_INFO, + val_to_str_const(command.type(), pulsar_cmd_names, "Unknown (%d)")); + + proto_item* frame_tree = NULL; + proto_item* cmd_tree = NULL; + if (tree) { /* we are being asked for details */ + proto_item *ti = proto_tree_add_item(tree, proto_pulsar, tvb, 0, -1, ENC_NA); + frame_tree = proto_item_add_subtree(ti, ett_pulsar); + proto_tree_add_item(frame_tree, hf_pulsar_frame_size, tvb, 0, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(frame_tree, hf_pulsar_cmd_size, tvb, 4, 4, ENC_BIG_ENDIAN); + cmd_tree = proto_tree_add_subtree_format(frame_tree, tvb, 8, cmdSize, ett_pulsar, + NULL, + "Command %s", + to_str(command.type(), pulsar_cmd_names)); + proto_tree_add_string(cmd_tree, hf_pulsar_cmd_type, tvb, 8, cmdSize, + to_str(command.type(), pulsar_cmd_names)); + } + + proto_tree* item = NULL; + + switch (command.type()) { + case BaseCommand::CONNECT: { + const CommandConnect& connect = command.connect(); + if (tree) { + proto_tree_add_string(cmd_tree, hf_pulsar_client_version, tvb, cmdOffset, cmdSize, + connect.client_version().c_str()); + proto_tree_add_string(cmd_tree, hf_pulsar_protocol_version, tvb, cmdOffset, cmdSize, + to_str(connect.protocol_version(), protocol_version_vs)); + proto_tree_add_string(cmd_tree, hf_pulsar_auth_method, tvb, cmdOffset, cmdSize, + to_str(connect.auth_method(), auth_methods_vs)); + if (connect.has_auth_data()) { + proto_tree_add_string(cmd_tree, hf_pulsar_auth_data, tvb, cmdOffset, cmdSize, + connect.auth_data().c_str()); + } + } + break; + } + case BaseCommand::CONNECTED: { + const CommandConnected& connected = command.connected(); + if (tree) { + proto_tree_add_string(cmd_tree, hf_pulsar_server_version, tvb, cmdOffset, cmdSize, + connected.server_version().c_str()); + proto_tree_add_string(cmd_tree, hf_pulsar_protocol_version, tvb, cmdOffset, cmdSize, + to_str(connected.protocol_version(), protocol_version_vs)); + } + break; + } + case BaseCommand::SUBSCRIBE: { + const CommandSubscribe& subscribe = command.subscribe(); + RequestData& reqData = state->requests[subscribe.request_id()]; + reqData.requestFrame = pinfo->fd->num; + reqData.requestTimestamp.secs = pinfo->fd->abs_ts.secs; + reqData.requestTimestamp.nsecs = pinfo->fd->abs_ts.nsecs; + + ConsumerData& consumerData = state->consumers[subscribe.consumer_id()]; + consumerData.topic = subscribe.topic(); + consumerData.subscriptionName = subscribe.subscription(); + consumerData.consumerName = subscribe.consumer_name(); + consumerData.subType = subscribe.subtype(); + + col_append_fstr(pinfo->cinfo, COL_INFO, " / %s / %s / %s / %s", + to_str(subscribe.subtype(), sub_type_names_vs), + subscribe.topic().c_str(), subscribe.subscription().c_str(), + subscribe.consumer_name().c_str()); + + if (tree) { + proto_tree_add_string(cmd_tree, hf_pulsar_topic, tvb, cmdOffset, cmdSize, + subscribe.topic().c_str()); + proto_tree_add_string(cmd_tree, hf_pulsar_subscription, tvb, cmdOffset, cmdSize, + subscribe.subscription().c_str()); + proto_tree_add_string(cmd_tree, hf_pulsar_subType, tvb, cmdOffset, cmdSize, + to_str(subscribe.subtype(), sub_type_names_vs)); + proto_tree_add_uint64(cmd_tree, hf_pulsar_consumer_id, tvb, cmdOffset, cmdSize, + subscribe.consumer_id()); + proto_tree_add_uint64(cmd_tree, hf_pulsar_request_id, tvb, cmdOffset, cmdSize, + subscribe.request_id()); + proto_tree_add_string( + cmd_tree, + hf_pulsar_consumer_name, + tvb, + cmdOffset, + cmdSize, + subscribe.has_consumer_name() ? + subscribe.consumer_name().c_str() : ""); + } + break; + } + case BaseCommand::PRODUCER: { + const CommandProducer& producer = command.producer(); + RequestResponseData& reqData = state->requests[producer.request_id()]; + reqData.requestFrame = pinfo->fd->num; + reqData.requestTimestamp.secs = pinfo->fd->abs_ts.secs; + reqData.requestTimestamp.nsecs = pinfo->fd->abs_ts.nsecs; + reqData.id = producer.producer_id(); + + state->producers[producer.producer_id()].topic = producer.topic(); + + col_append_fstr(pinfo->cinfo, COL_INFO, " / %s", producer.topic().c_str()); + + if (tree) { + proto_tree_add_string(cmd_tree, hf_pulsar_topic, tvb, cmdOffset, cmdSize, + producer.topic().c_str()); + proto_tree_add_uint64(cmd_tree, hf_pulsar_producer_id, tvb, cmdOffset, cmdSize, + producer.producer_id()); + proto_tree_add_uint64(cmd_tree, hf_pulsar_request_id, tvb, cmdOffset, cmdSize, + producer.request_id()); + proto_tree_add_string( + cmd_tree, hf_pulsar_producer_name, tvb, cmdOffset, cmdSize, + producer.has_producer_name() ? producer.producer_name().c_str() : ""); + + link_to_response_frame(cmd_tree, tvb, cmdOffset, cmdSize, reqData); + } + break; + } + case BaseCommand::SEND: { + const CommandSend& send = command.send(); + RequestData& data = state->producers[send.producer_id()].messages[send.sequence_id()]; + data.requestFrame = pinfo->fd->num; + data.requestTimestamp.secs = pinfo->fd->abs_ts.secs; + data.requestTimestamp.nsecs = pinfo->fd->abs_ts.nsecs; + + ProducerData& producerData = state->producers[send.producer_id()]; + + col_append_fstr(pinfo->cinfo, COL_INFO, " / %s / %llu", + producerData.producerName.c_str(), send.sequence_id()); + + if (tree) { + proto_tree_add_uint64(cmd_tree, hf_pulsar_producer_id, tvb, cmdOffset, cmdSize, + send.producer_id()); + proto_tree_add_uint64(cmd_tree, hf_pulsar_sequence_id, tvb, cmdOffset, cmdSize, + send.sequence_id()); + + // Decode message metadata + dissect_message_metadata(cmd_tree, tvb, offset, maxOffset); + + item = proto_tree_add_string(cmd_tree, hf_pulsar_producer_name, tvb, cmdOffset, + cmdSize, producerData.producerName.c_str()); + PROTO_ITEM_SET_GENERATED(item); + + item = proto_tree_add_string(cmd_tree, hf_pulsar_topic, tvb, cmdOffset, cmdSize, + producerData.topic.c_str()); + PROTO_ITEM_SET_GENERATED(item); + + // Pair with frame information + link_to_response_frame(cmd_tree, tvb, cmdOffset, cmdSize, data); + } + break; + } + case BaseCommand::SEND_RECEIPT: { + const CommandSendReceipt& send_receipt = command.send_receipt(); + RequestData & data = state->producers[send_receipt.producer_id()].messages[send_receipt + .sequence_id()]; + data.ackFrame = pinfo->fd->num; + data.ackTimestamp.secs = pinfo->fd->abs_ts.secs; + data.ackTimestamp.nsecs = pinfo->fd->abs_ts.nsecs; + + ProducerData& producerData = state->producers[send_receipt.producer_id()]; + col_append_fstr(pinfo->cinfo, COL_INFO, " / %s / %llu", + producerData.producerName.c_str(), send_receipt.sequence_id()); + + if (tree) { + proto_tree_add_uint64(cmd_tree, hf_pulsar_producer_id, tvb, cmdOffset, cmdSize, + send_receipt.producer_id()); + proto_tree_add_uint64(cmd_tree, hf_pulsar_sequence_id, tvb, cmdOffset, cmdSize, + send_receipt.sequence_id()); + if (send_receipt.has_message_id()) { + const MessageIdData& messageId = send_receipt.message_id(); + proto_tree_add_string_format(cmd_tree, hf_pulsar_message_id, tvb, cmdOffset, + cmdSize, "", "Message Id: %llu:%llu", + messageId.ledgerid(), messageId.entryid()); + } + + item = proto_tree_add_string(cmd_tree, hf_pulsar_producer_name, tvb, cmdOffset, + cmdSize, producerData.producerName.c_str()); + PROTO_ITEM_SET_GENERATED(item); + + item = proto_tree_add_string(cmd_tree, hf_pulsar_topic, tvb, cmdOffset, cmdSize, + producerData.topic.c_str()); + PROTO_ITEM_SET_GENERATED(item); + + link_to_request_frame(cmd_tree, tvb, cmdOffset, cmdSize, data); + } + break; + } + case BaseCommand::SEND_ERROR: { + const CommandSendError& send_error = command.send_error(); + RequestData & reqData = state->producers[send_error.producer_id()].messages[send_error + .sequence_id()]; + reqData.ackFrame = pinfo->fd->num; + reqData.ackTimestamp.secs = pinfo->fd->abs_ts.secs; + reqData.ackTimestamp.nsecs = pinfo->fd->abs_ts.nsecs; + + ProducerData& producerData = state->producers[send_error.producer_id()]; + col_append_fstr(pinfo->cinfo, COL_INFO, " / %s / %llu", + producerData.producerName.c_str(), send_error.sequence_id()); + + if (tree) { + proto_tree_add_boolean_format(frame_tree, hf_pulsar_error, tvb, cmdOffset, cmdSize, + true, "Error in sending operation"); + proto_tree_add_uint64(cmd_tree, hf_pulsar_producer_id, tvb, cmdOffset, cmdSize, + send_error.producer_id()); + proto_tree_add_uint64(cmd_tree, hf_pulsar_sequence_id, tvb, cmdOffset, cmdSize, + send_error.sequence_id()); + + item = proto_tree_add_string(cmd_tree, hf_pulsar_server_error, tvb, cmdOffset, cmdSize, + to_str(send_error.error(), server_errors_vs)); + + item = proto_tree_add_string(cmd_tree, hf_pulsar_producer_name, tvb, cmdOffset, + cmdSize, producerData.producerName.c_str()); + PROTO_ITEM_SET_GENERATED(item); + + item = proto_tree_add_string(cmd_tree, hf_pulsar_topic, tvb, cmdOffset, cmdSize, + producerData.topic.c_str()); + PROTO_ITEM_SET_GENERATED(item); + + // Pair with frame information + link_to_request_frame(cmd_tree, tvb, cmdOffset, cmdSize, reqData); + } + break; + } + case BaseCommand::MESSAGE: { + const CommandMessage& message = command.message(); + RequestData& data = + state->consumers[message.consumer_id()].messages[message.message_id()]; + data.requestFrame = pinfo->fd->num; + data.requestTimestamp.secs = pinfo->fd->abs_ts.secs; + data.requestTimestamp.nsecs = pinfo->fd->abs_ts.nsecs; + + const ConsumerData& consumerData = state->consumers[message.consumer_id()]; + + col_append_fstr(pinfo->cinfo, COL_INFO, " / %s / %llu:%llu", + consumerData.consumerName.c_str(), message.message_id().ledgerid(), + message.message_id().entryid()); + + if (tree) { + proto_tree_add_uint64(cmd_tree, hf_pulsar_consumer_id, tvb, cmdOffset, cmdSize, + message.consumer_id()); + + dissect_message_metadata(cmd_tree, tvb, offset, maxOffset); + + item = proto_tree_add_string(cmd_tree, hf_pulsar_consumer_name, tvb, cmdOffset, + cmdSize, consumerData.consumerName.c_str()); + PROTO_ITEM_SET_GENERATED(item); + + item = proto_tree_add_string(cmd_tree, hf_pulsar_topic, tvb, cmdOffset, cmdSize, + consumerData.topic.c_str()); + PROTO_ITEM_SET_GENERATED(item); + + // Pair with frame information + link_to_response_frame(cmd_tree, tvb, cmdOffset, cmdSize, data); + } + break; + } + case BaseCommand::ACK: { + const CommandAck& ack = command.ack(); + RequestData& data = state->consumers[ack.consumer_id()].messages[ack.message_id()]; + data.ackFrame = pinfo->fd->num; + data.ackTimestamp.secs = pinfo->fd->abs_ts.secs; + data.ackTimestamp.nsecs = pinfo->fd->abs_ts.nsecs; + + const ConsumerData& consumerData = state->consumers[ack.consumer_id()]; + + col_append_fstr(pinfo->cinfo, COL_INFO, " / %s / %llu:%llu", + consumerData.consumerName.c_str(), ack.message_id().ledgerid(), + ack.message_id().entryid()); + + if (tree) { + proto_tree_add_uint64(cmd_tree, hf_pulsar_consumer_id, tvb, cmdOffset, cmdSize, + ack.consumer_id()); + proto_tree_add_string(cmd_tree, hf_pulsar_ack_type, tvb, cmdOffset, cmdSize, + to_str(ack.ack_type(), ack_type_vs)); + + item = proto_tree_add_string(cmd_tree, hf_pulsar_consumer_name, tvb, cmdOffset, + cmdSize, consumerData.consumerName.c_str()); + PROTO_ITEM_SET_GENERATED(item); + + item = proto_tree_add_string(cmd_tree, hf_pulsar_topic, tvb, cmdOffset, cmdSize, + consumerData.topic.c_str()); + PROTO_ITEM_SET_GENERATED(item); + + // Pair with frame information + link_to_request_frame(cmd_tree, tvb, cmdOffset, cmdSize, data); + } + break; + } + case BaseCommand::FLOW: { + const CommandFlow& flow = command.flow(); + const ConsumerData& consumerData = state->consumers[flow.consumer_id()]; + + col_append_fstr(pinfo->cinfo, COL_INFO, " / %s / %d", consumerData.consumerName.c_str(), + flow.messagepermits()); + + if (tree) { + proto_tree_add_uint64(cmd_tree, hf_pulsar_consumer_id, tvb, cmdOffset, cmdSize, + flow.consumer_id()); + proto_tree_add_uint(cmd_tree, hf_pulsar_message_permits, tvb, cmdOffset, cmdSize, + flow.messagepermits()); + + item = proto_tree_add_string(cmd_tree, hf_pulsar_consumer_name, tvb, cmdOffset, + cmdSize, consumerData.consumerName.c_str()); + PROTO_ITEM_SET_GENERATED(item); + + item = proto_tree_add_string(cmd_tree, hf_pulsar_topic, tvb, cmdOffset, cmdSize, + consumerData.topic.c_str()); + PROTO_ITEM_SET_GENERATED(item); + } + break; + } + case BaseCommand::UNSUBSCRIBE: { + const CommandUnsubscribe& unsubscribe = command.unsubscribe(); + RequestData& reqData = state->requests[unsubscribe.request_id()]; + reqData.requestFrame = pinfo->fd->num; + reqData.requestTimestamp.secs = pinfo->fd->abs_ts.secs; + reqData.requestTimestamp.nsecs = pinfo->fd->abs_ts.nsecs; + + ConsumerData& consumerData = state->consumers[unsubscribe.consumer_id()]; + + col_append_fstr(pinfo->cinfo, COL_INFO, " / %s / %s / %s / %s", + to_str(consumerData.subType, sub_type_names_vs), + consumerData.topic.c_str(), consumerData.subscriptionName.c_str(), + consumerData.consumerName.c_str()); + + if (tree) { + proto_tree_add_uint64(cmd_tree, hf_pulsar_consumer_id, tvb, cmdOffset, cmdSize, + unsubscribe.consumer_id()); + proto_tree_add_uint64(cmd_tree, hf_pulsar_request_id, tvb, cmdOffset, cmdSize, + unsubscribe.request_id()); + item = proto_tree_add_string(cmd_tree, hf_pulsar_topic, tvb, cmdOffset, cmdSize, + consumerData.topic.c_str()); + PROTO_ITEM_IS_GENERATED(item); + item = proto_tree_add_string(cmd_tree, hf_pulsar_subscription, tvb, cmdOffset, cmdSize, + consumerData.subscriptionName.c_str()); + PROTO_ITEM_IS_GENERATED(item); + proto_tree_add_string(cmd_tree, hf_pulsar_subType, tvb, cmdOffset, cmdSize, + to_str(consumerData.subType, sub_type_names_vs)); + PROTO_ITEM_IS_GENERATED(item); + + proto_tree_add_string(cmd_tree, hf_pulsar_consumer_name, tvb, cmdOffset, cmdSize, + consumerData.consumerName.c_str()); + PROTO_ITEM_IS_GENERATED(item); + + link_to_response_frame(cmd_tree, tvb, cmdOffset, cmdSize, reqData); + } + break; + } + + case BaseCommand::SUCCESS: { + const CommandSuccess& success = command.success(); + RequestResponseData & reqData = state->requests[success.request_id()]; + reqData.ackFrame = pinfo->fd->num; + reqData.ackTimestamp.secs = pinfo->fd->abs_ts.secs; + reqData.ackTimestamp.nsecs = pinfo->fd->abs_ts.nsecs; + + if (tree) { + proto_tree_add_uint64(cmd_tree, hf_pulsar_request_id, tvb, cmdOffset, cmdSize, + success.request_id()); + + link_to_request_frame(cmd_tree, tvb, cmdOffset, cmdSize, reqData); + } + break; + } + case BaseCommand::ERROR: { + const CommandError& error = command.error(); + RequestResponseData & reqData = state->requests[error.request_id()]; + reqData.ackFrame = pinfo->fd->num; + reqData.ackTimestamp.secs = pinfo->fd->abs_ts.secs; + reqData.ackTimestamp.nsecs = pinfo->fd->abs_ts.nsecs; + + if (tree) { + proto_tree_add_boolean_format(frame_tree, hf_pulsar_error, tvb, cmdOffset, cmdSize, + true, "Request failed"); + proto_tree_add_uint64(cmd_tree, hf_pulsar_request_id, tvb, cmdOffset, cmdSize, + error.request_id()); + proto_tree_add_string(cmd_tree, hf_pulsar_server_error, tvb, cmdOffset, cmdSize, + to_str(error.error(), server_errors_vs)); + proto_tree_add_string(cmd_tree, hf_pulsar_error_message, tvb, cmdOffset, cmdSize, + error.message().c_str()); + + link_to_request_frame(cmd_tree, tvb, cmdOffset, cmdSize, reqData); + } + break; + } + case BaseCommand::CLOSE_PRODUCER: { + const CommandCloseProducer& close_producer = command.close_producer(); + RequestData& reqData = state->requests[close_producer.request_id()]; + reqData.requestFrame = pinfo->fd->num; + reqData.requestTimestamp.secs = pinfo->fd->abs_ts.secs; + reqData.requestTimestamp.nsecs = pinfo->fd->abs_ts.nsecs; + + ProducerData& producerData = state->producers[close_producer.producer_id()]; + + col_append_fstr(pinfo->cinfo, COL_INFO, " / %s", producerData.topic.c_str()); + + if (tree) { + proto_tree_add_uint64(cmd_tree, hf_pulsar_producer_id, tvb, cmdOffset, cmdSize, + close_producer.producer_id()); + proto_tree_add_uint64(cmd_tree, hf_pulsar_request_id, tvb, cmdOffset, cmdSize, + close_producer.request_id()); + item = proto_tree_add_string(cmd_tree, hf_pulsar_topic, tvb, cmdOffset, cmdSize, + producerData.topic.c_str()); + PROTO_ITEM_IS_GENERATED(item); + + proto_tree_add_string(cmd_tree, hf_pulsar_producer_name, tvb, cmdOffset, cmdSize, + producerData.producerName.c_str()); + PROTO_ITEM_IS_GENERATED(item); + + link_to_response_frame(cmd_tree, tvb, cmdOffset, cmdSize, reqData); + } + break; + } + + case BaseCommand::CLOSE_CONSUMER: { + const CommandCloseConsumer& close_consumer = command.close_consumer(); + RequestData& reqData = state->requests[close_consumer.request_id()]; + reqData.requestFrame = pinfo->fd->num; + reqData.requestTimestamp.secs = pinfo->fd->abs_ts.secs; + reqData.requestTimestamp.nsecs = pinfo->fd->abs_ts.nsecs; + + ConsumerData& consumerData = state->consumers[close_consumer.consumer_id()]; + + col_append_fstr(pinfo->cinfo, COL_INFO, " / %s / %s / %s / %s", + to_str(consumerData.subType, sub_type_names_vs), + consumerData.topic.c_str(), consumerData.subscriptionName.c_str(), + consumerData.consumerName.c_str()); + + if (tree) { + proto_tree_add_uint64(cmd_tree, hf_pulsar_consumer_id, tvb, cmdOffset, cmdSize, + close_consumer.consumer_id()); + proto_tree_add_uint64(cmd_tree, hf_pulsar_request_id, tvb, cmdOffset, cmdSize, + close_consumer.request_id()); + item = proto_tree_add_string(cmd_tree, hf_pulsar_topic, tvb, cmdOffset, cmdSize, + consumerData.topic.c_str()); + PROTO_ITEM_IS_GENERATED(item); + item = proto_tree_add_string(cmd_tree, hf_pulsar_subscription, tvb, cmdOffset, cmdSize, + consumerData.subscriptionName.c_str()); + PROTO_ITEM_IS_GENERATED(item); + proto_tree_add_string(cmd_tree, hf_pulsar_subType, tvb, cmdOffset, cmdSize, + to_str(consumerData.subType, sub_type_names_vs)); + PROTO_ITEM_IS_GENERATED(item); + + proto_tree_add_string(cmd_tree, hf_pulsar_consumer_name, tvb, cmdOffset, cmdSize, + consumerData.consumerName.c_str()); + PROTO_ITEM_IS_GENERATED(item); + + link_to_response_frame(cmd_tree, tvb, cmdOffset, cmdSize, reqData); + } + break; + } + + case BaseCommand::PRODUCER_SUCCESS: { + const CommandProducerSuccess& success = command.producer_success(); + RequestResponseData & reqData = state->requests[success.request_id()]; + reqData.ackFrame = pinfo->fd->num; + reqData.ackTimestamp.secs = pinfo->fd->abs_ts.secs; + reqData.ackTimestamp.nsecs = pinfo->fd->abs_ts.nsecs; + uint64_t producerId = reqData.id; + ProducerData& producerData = state->producers[producerId]; + producerData.producerName = success.producer_name(); + + if (tree) { + proto_tree_add_uint64(cmd_tree, hf_pulsar_request_id, tvb, cmdOffset, cmdSize, + success.request_id()); + proto_tree_add_string(cmd_tree, hf_pulsar_producer_name, tvb, cmdOffset, cmdSize, + success.producer_name().c_str()); + + proto_tree* item = proto_tree_add_uint64(cmd_tree, hf_pulsar_producer_id, tvb, + cmdOffset, cmdSize, producerId); + PROTO_ITEM_SET_GENERATED(item); + + item = proto_tree_add_string(cmd_tree, hf_pulsar_topic, tvb, cmdOffset, cmdSize, + producerData.topic.c_str()); + PROTO_ITEM_SET_GENERATED(item); + + link_to_request_frame(cmd_tree, tvb, cmdOffset, cmdSize, reqData); + } + break; + } + case BaseCommand::PING: + break; + case BaseCommand::PONG: + break; + } + + return maxOffset; +} + +/* determine PDU length of protocol Pulsar */ +static uint32_t get_pulsar_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, + void *data _U_) { + uint32_t len = (uint32_t) tvb_get_ntohl(tvb, offset); + return FRAME_SIZE_LEN + len; +} + +static int dissect_pulsar(tvbuff_t *tvb, packet_info* pinfo, proto_tree* tree, void* data _U_) { + tcp_dissect_pdus(tvb, pinfo, tree, 1, FRAME_SIZE_LEN, get_pulsar_message_len, dissect_pulsar_message, + data); + return tvb_captured_length(tvb); +} + +static hf_register_info hf[] = { // + { &hf_pulsar_error, { "Error", "yahoo.pulsar.error", FT_BOOLEAN, BASE_DEC, + NULL, 0x0, NULL, HFILL } }, // + { &hf_pulsar_error_message, { "Message", "yahoo.pulsar.error_message", FT_STRING, 0, + NULL, 0x0, + NULL, HFILL } }, // + { &hf_pulsar_cmd_type, { "Command Type", "yahoo.pulsar.cmd.type", FT_STRING, 0, + NULL, 0x0, + NULL, HFILL } }, // + { &hf_pulsar_frame_size, { "Frame size", "yahoo.pulsar.frame_size", FT_UINT32, BASE_DEC, + NULL, 0x0, NULL, HFILL } }, // + { &hf_pulsar_cmd_size, { "Command size", "yahoo.pulsar.cmd_size", FT_UINT32, BASE_DEC, + NULL, 0x0, + NULL, HFILL } }, // + + { &hf_pulsar_client_version, { "Client version", "yahoo.pulsar.client_version", FT_STRING, + 0, + NULL, 0x0, NULL, HFILL } }, // + { &hf_pulsar_auth_method, { "Auth method", "yahoo.pulsar.auth_method", FT_STRING, 0, NULL, + 0x0, + NULL, HFILL } }, // + { &hf_pulsar_auth_data, { "Auth data", "yahoo.pulsar.auth_data", FT_STRING, 0, + NULL, 0x0, NULL, HFILL } }, // + { &hf_pulsar_protocol_version, { "Protocol version", "yahoo.pulsar.protocol_version", + FT_STRING, 0, + NULL, 0x0, NULL, HFILL } }, + + { &hf_pulsar_server_version, { "Server version", "yahoo.pulsar.server_version", FT_STRING, + 0, + NULL, 0x0, NULL, HFILL } }, // + { &hf_pulsar_topic, { "Topic", "yahoo.pulsar.topic", FT_STRING, 0, NULL, 0x0, + NULL, HFILL } }, // + { &hf_pulsar_subscription, { "Subscription", "yahoo.pulsar.subscription", FT_STRING, 0, + NULL, 0x0, NULL, HFILL } }, // + { &hf_pulsar_subType, { "Subscription type:", "yahoo.pulsar.sub_type", FT_STRING, 0, NULL, + 0x0, + NULL, HFILL } }, // + { &hf_pulsar_consumer_id, { "Consumer Id", "yahoo.pulsar.consumer_id", FT_UINT64, + BASE_DEC, + NULL, 0x0, NULL, HFILL } }, // + { &hf_pulsar_producer_id, { "Producer Id", "yahoo.pulsar.producer_id", FT_UINT64, + BASE_DEC, + NULL, 0x0, NULL, HFILL } }, // + + { &hf_pulsar_server_error, { "Server error", "yahoo.pulsar.server_error", FT_STRING, 0, + NULL, 0x0, NULL, HFILL } }, // + { &hf_pulsar_ack_type, { "Ack type", "yahoo.pulsar.ack_type", FT_STRING, 0, + NULL, 0x0, NULL, HFILL } }, // + + { &hf_pulsar_request_id, { "Request Id", "yahoo.pulsar.request_id", FT_UINT64, BASE_DEC, + NULL, 0x0, NULL, HFILL } }, // + { &hf_pulsar_consumer_name, { "Consumer Name", "yahoo.pulsar.consumer_name", FT_STRING, + BASE_NONE, + NULL, 0x0, NULL, HFILL } }, // + { &hf_pulsar_producer_name, { "Producer Name", "yahoo.pulsar.producer_name", FT_STRING, + BASE_NONE, + NULL, 0x0, NULL, HFILL } }, // + + { &hf_pulsar_sequence_id, { "Sequence Id", "yahoo.pulsar.sequence_id", FT_UINT64, + BASE_DEC, + NULL, 0x0, NULL, HFILL } }, // + { &hf_pulsar_message_id, { "Message Id", "yahoo.pulsar.message_id", FT_STRING, BASE_NONE, + NULL, 0x0, NULL, HFILL } }, // + { &hf_pulsar_message_permits, { "Message Permits", "yahoo.pulsar.message_permits", + FT_UINT32, BASE_DEC, + NULL, 0x0, NULL, HFILL } }, // + + { &hf_pulsar_publish_time, { "Publish time", "yahoo.pulsar.publish_time", FT_UINT64, + BASE_DEC, + NULL, 0x0, NULL, HFILL } }, // + + { &hf_pulsar_replicated_from, { "Replicated from", "yahoo.pulsar.replicated_from", + FT_STRING, BASE_NONE, + NULL, 0x0, NULL, HFILL } }, // + { &hf_pulsar_partition_key, { "Partition key", "yahoo.pulsar.partition_key", FT_STRING, + BASE_NONE, + NULL, 0x0, NULL, HFILL } }, // + { &hf_pulsar_replicate_to, { "Replicate to", "yahoo.pulsar.replicate_to", FT_STRING, + BASE_NONE, + NULL, 0x0, NULL, HFILL } }, // + { &hf_pulsar_property, { "Property", "yahoo.pulsar.property", FT_STRING, BASE_NONE, + NULL, 0x0, NULL, HFILL } }, // + + { &hf_pulsar_request_in, { "Request in frame", "yahoo.pulsar.request_in", FT_FRAMENUM, + BASE_NONE, + NULL, 0, "This packet is a response to the packet with this number", + HFILL } }, // + { &hf_pulsar_response_in, { "Response in frame", "yahoo.pulsar.response_in", FT_FRAMENUM, + BASE_NONE, + NULL, 0, "This packet will be responded in the packet with this number", + HFILL } }, // + { &hf_pulsar_publish_latency, { "Latency", "yahoo.pulsar.publish_latency", + FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0, + "How long time it took to ACK message", HFILL } }, }; + +//////////////// +/// +void proto_register_pulsar() { + // register the new protocol, protocol fields, and subtrees + + proto_pulsar = proto_register_protocol("Pulsar Wire Protocol", /* name */ + "Yahoo Pulsar", /* short name */ + "yahoo.pulsar" /* abbrev */ + ); + + /* Setup protocol subtree array */ + static int *ett[] = { &ett_pulsar }; + + proto_register_field_array(proto_pulsar, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +void proto_reg_handoff_pulsar() { + static dissector_handle_t pulsar_handle; + + pulsar_handle = create_dissector_handle(&dissect_pulsar, proto_pulsar); + dissector_add_uint("tcp.port", PULSAR_PORT, pulsar_handle); +} + +extern "C" { + +G_MODULE_EXPORT const char* version = VERSION; + +/* Start the functions we need for the plugin stuff */ +G_MODULE_EXPORT void plugin_register(void) { + if (proto_pulsar == -1) { + proto_register_pulsar(); + } +} + +G_MODULE_EXPORT void plugin_reg_handoff(void) { + proto_reg_handoff_pulsar(); +} + +}