diff --git a/native/cpp/CommonCpp/grpc/_generated/blob.grpc.pb.h b/native/cpp/CommonCpp/grpc/_generated/blob.grpc.pb.h
--- a/native/cpp/CommonCpp/grpc/_generated/blob.grpc.pb.h
+++ b/native/cpp/CommonCpp/grpc/_generated/blob.grpc.pb.h
@@ -60,6 +60,13 @@
     std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>> PrepareAsyncRemove(::grpc::ClientContext* context, const ::blob::RemoveRequest& request, ::grpc::CompletionQueue* cq) {
       return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>>(PrepareAsyncRemoveRaw(context, request, cq));
     }
+    virtual ::grpc::Status AppendHolder(::grpc::ClientContext* context, const ::blob::AppendHolderRequest& request, ::google::protobuf::Empty* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>> AsyncAppendHolder(::grpc::ClientContext* context, const ::blob::AppendHolderRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>>(AsyncAppendHolderRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>> PrepareAsyncAppendHolder(::grpc::ClientContext* context, const ::blob::AppendHolderRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>>(PrepareAsyncAppendHolderRaw(context, request, cq));
+    }
     class async_interface {
      public:
       virtual ~async_interface() {}
@@ -67,6 +74,8 @@
       virtual void Get(::grpc::ClientContext* context, const ::blob::GetRequest* request, ::grpc::ClientReadReactor< ::blob::GetResponse>* reactor) = 0;
       virtual void Remove(::grpc::ClientContext* context, const ::blob::RemoveRequest* request, ::google::protobuf::Empty* response, std::function<void(::grpc::Status)>) = 0;
       virtual void Remove(::grpc::ClientContext* context, const ::blob::RemoveRequest* request, ::google::protobuf::Empty* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      virtual void AppendHolder(::grpc::ClientContext* context, const ::blob::AppendHolderRequest* request, ::google::protobuf::Empty* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void AppendHolder(::grpc::ClientContext* context, const ::blob::AppendHolderRequest* request, ::google::protobuf::Empty* response, ::grpc::ClientUnaryReactor* reactor) = 0;
     };
     typedef class async_interface experimental_async_interface;
     virtual class async_interface* async() { return nullptr; }
@@ -80,6 +89,8 @@
     virtual ::grpc::ClientAsyncReaderInterface< ::blob::GetResponse>* PrepareAsyncGetRaw(::grpc::ClientContext* context, const ::blob::GetRequest& request, ::grpc::CompletionQueue* cq) = 0;
     virtual ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>* AsyncRemoveRaw(::grpc::ClientContext* context, const ::blob::RemoveRequest& request, ::grpc::CompletionQueue* cq) = 0;
     virtual ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>* PrepareAsyncRemoveRaw(::grpc::ClientContext* context, const ::blob::RemoveRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>* AsyncAppendHolderRaw(::grpc::ClientContext* context, const ::blob::AppendHolderRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>* PrepareAsyncAppendHolderRaw(::grpc::ClientContext* context, const ::blob::AppendHolderRequest& request, ::grpc::CompletionQueue* cq) = 0;
   };
   class Stub final : public StubInterface {
    public:
@@ -109,6 +120,13 @@
     std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>> PrepareAsyncRemove(::grpc::ClientContext* context, const ::blob::RemoveRequest& request, ::grpc::CompletionQueue* cq) {
       return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>>(PrepareAsyncRemoveRaw(context, request, cq));
     }
+    ::grpc::Status AppendHolder(::grpc::ClientContext* context, const ::blob::AppendHolderRequest& request, ::google::protobuf::Empty* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>> AsyncAppendHolder(::grpc::ClientContext* context, const ::blob::AppendHolderRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>>(AsyncAppendHolderRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>> PrepareAsyncAppendHolder(::grpc::ClientContext* context, const ::blob::AppendHolderRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>>(PrepareAsyncAppendHolderRaw(context, request, cq));
+    }
     class async final :
       public StubInterface::async_interface {
      public:
@@ -116,6 +134,8 @@
       void Get(::grpc::ClientContext* context, const ::blob::GetRequest* request, ::grpc::ClientReadReactor< ::blob::GetResponse>* reactor) override;
       void Remove(::grpc::ClientContext* context, const ::blob::RemoveRequest* request, ::google::protobuf::Empty* response, std::function<void(::grpc::Status)>) override;
       void Remove(::grpc::ClientContext* context, const ::blob::RemoveRequest* request, ::google::protobuf::Empty* response, ::grpc::ClientUnaryReactor* reactor) override;
+      void AppendHolder(::grpc::ClientContext* context, const ::blob::AppendHolderRequest* request, ::google::protobuf::Empty* response, std::function<void(::grpc::Status)>) override;
+      void AppendHolder(::grpc::ClientContext* context, const ::blob::AppendHolderRequest* request, ::google::protobuf::Empty* response, ::grpc::ClientUnaryReactor* reactor) override;
      private:
       friend class Stub;
       explicit async(Stub* stub): stub_(stub) { }
@@ -135,9 +155,12 @@
     ::grpc::ClientAsyncReader< ::blob::GetResponse>* PrepareAsyncGetRaw(::grpc::ClientContext* context, const ::blob::GetRequest& request, ::grpc::CompletionQueue* cq) override;
     ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>* AsyncRemoveRaw(::grpc::ClientContext* context, const ::blob::RemoveRequest& request, ::grpc::CompletionQueue* cq) override;
     ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>* PrepareAsyncRemoveRaw(::grpc::ClientContext* context, const ::blob::RemoveRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>* AsyncAppendHolderRaw(::grpc::ClientContext* context, const ::blob::AppendHolderRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>* PrepareAsyncAppendHolderRaw(::grpc::ClientContext* context, const ::blob::AppendHolderRequest& request, ::grpc::CompletionQueue* cq) override;
     const ::grpc::internal::RpcMethod rpcmethod_Put_;
     const ::grpc::internal::RpcMethod rpcmethod_Get_;
     const ::grpc::internal::RpcMethod rpcmethod_Remove_;
+    const ::grpc::internal::RpcMethod rpcmethod_AppendHolder_;
   };
   static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
 
@@ -148,6 +171,7 @@
     virtual ::grpc::Status Put(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::blob::PutResponse, ::blob::PutRequest>* stream);
     virtual ::grpc::Status Get(::grpc::ServerContext* context, const ::blob::GetRequest* request, ::grpc::ServerWriter< ::blob::GetResponse>* writer);
     virtual ::grpc::Status Remove(::grpc::ServerContext* context, const ::blob::RemoveRequest* request, ::google::protobuf::Empty* response);
+    virtual ::grpc::Status AppendHolder(::grpc::ServerContext* context, const ::blob::AppendHolderRequest* request, ::google::protobuf::Empty* response);
   };
   template <class BaseClass>
   class WithAsyncMethod_Put : public BaseClass {
@@ -209,7 +233,27 @@
       ::grpc::Service::RequestAsyncUnary(2, context, request, response, new_call_cq, notification_cq, tag);
     }
   };
-  typedef WithAsyncMethod_Put<WithAsyncMethod_Get<WithAsyncMethod_Remove<Service > > > AsyncService;
+  template <class BaseClass>
+  class WithAsyncMethod_AppendHolder : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_AppendHolder() {
+      ::grpc::Service::MarkMethodAsync(3);
+    }
+    ~WithAsyncMethod_AppendHolder() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status AppendHolder(::grpc::ServerContext* /*context*/, const ::blob::AppendHolderRequest* /*request*/, ::google::protobuf::Empty* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestAppendHolder(::grpc::ServerContext* context, ::blob::AppendHolderRequest* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(3, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  typedef WithAsyncMethod_Put<WithAsyncMethod_Get<WithAsyncMethod_Remove<WithAsyncMethod_AppendHolder<Service > > > > AsyncService;
   template <class BaseClass>
   class WithCallbackMethod_Put : public BaseClass {
    private:
@@ -282,7 +326,34 @@
     virtual ::grpc::ServerUnaryReactor* Remove(
       ::grpc::CallbackServerContext* /*context*/, const ::blob::RemoveRequest* /*request*/, ::google::protobuf::Empty* /*response*/)  { return nullptr; }
   };
-  typedef WithCallbackMethod_Put<WithCallbackMethod_Get<WithCallbackMethod_Remove<Service > > > CallbackService;
+  template <class BaseClass>
+  class WithCallbackMethod_AppendHolder : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithCallbackMethod_AppendHolder() {
+      ::grpc::Service::MarkMethodCallback(3,
+          new ::grpc::internal::CallbackUnaryHandler< ::blob::AppendHolderRequest, ::google::protobuf::Empty>(
+            [this](
+                   ::grpc::CallbackServerContext* context, const ::blob::AppendHolderRequest* request, ::google::protobuf::Empty* response) { return this->AppendHolder(context, request, response); }));}
+    void SetMessageAllocatorFor_AppendHolder(
+        ::grpc::MessageAllocator< ::blob::AppendHolderRequest, ::google::protobuf::Empty>* allocator) {
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(3);
+      static_cast<::grpc::internal::CallbackUnaryHandler< ::blob::AppendHolderRequest, ::google::protobuf::Empty>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~WithCallbackMethod_AppendHolder() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status AppendHolder(::grpc::ServerContext* /*context*/, const ::blob::AppendHolderRequest* /*request*/, ::google::protobuf::Empty* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    virtual ::grpc::ServerUnaryReactor* AppendHolder(
+      ::grpc::CallbackServerContext* /*context*/, const ::blob::AppendHolderRequest* /*request*/, ::google::protobuf::Empty* /*response*/)  { return nullptr; }
+  };
+  typedef WithCallbackMethod_Put<WithCallbackMethod_Get<WithCallbackMethod_Remove<WithCallbackMethod_AppendHolder<Service > > > > CallbackService;
   typedef CallbackService ExperimentalCallbackService;
   template <class BaseClass>
   class WithGenericMethod_Put : public BaseClass {
@@ -336,6 +407,23 @@
     }
   };
   template <class BaseClass>
+  class WithGenericMethod_AppendHolder : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_AppendHolder() {
+      ::grpc::Service::MarkMethodGeneric(3);
+    }
+    ~WithGenericMethod_AppendHolder() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status AppendHolder(::grpc::ServerContext* /*context*/, const ::blob::AppendHolderRequest* /*request*/, ::google::protobuf::Empty* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
   class WithRawMethod_Put : public BaseClass {
    private:
     void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
@@ -396,6 +484,26 @@
     }
   };
   template <class BaseClass>
+  class WithRawMethod_AppendHolder : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_AppendHolder() {
+      ::grpc::Service::MarkMethodRaw(3);
+    }
+    ~WithRawMethod_AppendHolder() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status AppendHolder(::grpc::ServerContext* /*context*/, const ::blob::AppendHolderRequest* /*request*/, ::google::protobuf::Empty* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestAppendHolder(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(3, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
   class WithRawCallbackMethod_Put : public BaseClass {
    private:
     void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
@@ -463,6 +571,28 @@
       ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)  { return nullptr; }
   };
   template <class BaseClass>
+  class WithRawCallbackMethod_AppendHolder : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawCallbackMethod_AppendHolder() {
+      ::grpc::Service::MarkMethodRawCallback(3,
+          new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+                   ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->AppendHolder(context, request, response); }));
+    }
+    ~WithRawCallbackMethod_AppendHolder() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status AppendHolder(::grpc::ServerContext* /*context*/, const ::blob::AppendHolderRequest* /*request*/, ::google::protobuf::Empty* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    virtual ::grpc::ServerUnaryReactor* AppendHolder(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)  { return nullptr; }
+  };
+  template <class BaseClass>
   class WithStreamedUnaryMethod_Remove : public BaseClass {
    private:
     void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
@@ -489,7 +619,34 @@
     // replace default version of method with streamed unary
     virtual ::grpc::Status StreamedRemove(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::blob::RemoveRequest,::google::protobuf::Empty>* server_unary_streamer) = 0;
   };
-  typedef WithStreamedUnaryMethod_Remove<Service > StreamedUnaryService;
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_AppendHolder : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_AppendHolder() {
+      ::grpc::Service::MarkMethodStreamed(3,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::blob::AppendHolderRequest, ::google::protobuf::Empty>(
+            [this](::grpc::ServerContext* context,
+                   ::grpc::ServerUnaryStreamer<
+                     ::blob::AppendHolderRequest, ::google::protobuf::Empty>* streamer) {
+                       return this->StreamedAppendHolder(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_AppendHolder() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status AppendHolder(::grpc::ServerContext* /*context*/, const ::blob::AppendHolderRequest* /*request*/, ::google::protobuf::Empty* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedAppendHolder(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::blob::AppendHolderRequest,::google::protobuf::Empty>* server_unary_streamer) = 0;
+  };
+  typedef WithStreamedUnaryMethod_Remove<WithStreamedUnaryMethod_AppendHolder<Service > > StreamedUnaryService;
   template <class BaseClass>
   class WithSplitStreamingMethod_Get : public BaseClass {
    private:
@@ -518,7 +675,7 @@
     virtual ::grpc::Status StreamedGet(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::blob::GetRequest,::blob::GetResponse>* server_split_streamer) = 0;
   };
   typedef WithSplitStreamingMethod_Get<Service > SplitStreamedService;
-  typedef WithSplitStreamingMethod_Get<WithStreamedUnaryMethod_Remove<Service > > StreamedService;
+  typedef WithSplitStreamingMethod_Get<WithStreamedUnaryMethod_Remove<WithStreamedUnaryMethod_AppendHolder<Service > > > StreamedService;
 };
 
 }  // namespace blob
diff --git a/native/cpp/CommonCpp/grpc/_generated/blob.grpc.pb.cc b/native/cpp/CommonCpp/grpc/_generated/blob.grpc.pb.cc
--- a/native/cpp/CommonCpp/grpc/_generated/blob.grpc.pb.cc
+++ b/native/cpp/CommonCpp/grpc/_generated/blob.grpc.pb.cc
@@ -25,6 +25,7 @@
   "/blob.BlobService/Put",
   "/blob.BlobService/Get",
   "/blob.BlobService/Remove",
+  "/blob.BlobService/AppendHolder",
 };
 
 std::unique_ptr< BlobService::Stub> BlobService::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
@@ -37,6 +38,7 @@
   : channel_(channel), rpcmethod_Put_(BlobService_method_names[0], options.suffix_for_stats(),::grpc::internal::RpcMethod::BIDI_STREAMING, channel)
   , rpcmethod_Get_(BlobService_method_names[1], options.suffix_for_stats(),::grpc::internal::RpcMethod::SERVER_STREAMING, channel)
   , rpcmethod_Remove_(BlobService_method_names[2], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_AppendHolder_(BlobService_method_names[3], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel)
   {}
 
 ::grpc::ClientReaderWriter< ::blob::PutRequest, ::blob::PutResponse>* BlobService::Stub::PutRaw(::grpc::ClientContext* context) {
@@ -94,6 +96,29 @@
   return result;
 }
 
+::grpc::Status BlobService::Stub::AppendHolder(::grpc::ClientContext* context, const ::blob::AppendHolderRequest& request, ::google::protobuf::Empty* response) {
+  return ::grpc::internal::BlockingUnaryCall< ::blob::AppendHolderRequest, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_AppendHolder_, context, request, response);
+}
+
+void BlobService::Stub::async::AppendHolder(::grpc::ClientContext* context, const ::blob::AppendHolderRequest* request, ::google::protobuf::Empty* response, std::function<void(::grpc::Status)> f) {
+  ::grpc::internal::CallbackUnaryCall< ::blob::AppendHolderRequest, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_AppendHolder_, context, request, response, std::move(f));
+}
+
+void BlobService::Stub::async::AppendHolder(::grpc::ClientContext* context, const ::blob::AppendHolderRequest* request, ::google::protobuf::Empty* response, ::grpc::ClientUnaryReactor* reactor) {
+  ::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_AppendHolder_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>* BlobService::Stub::PrepareAsyncAppendHolderRaw(::grpc::ClientContext* context, const ::blob::AppendHolderRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::google::protobuf::Empty, ::blob::AppendHolderRequest, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_AppendHolder_, context, request);
+}
+
+::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>* BlobService::Stub::AsyncAppendHolderRaw(::grpc::ClientContext* context, const ::blob::AppendHolderRequest& request, ::grpc::CompletionQueue* cq) {
+  auto* result =
+    this->PrepareAsyncAppendHolderRaw(context, request, cq);
+  result->StartCall();
+  return result;
+}
+
 BlobService::Service::Service() {
   AddMethod(new ::grpc::internal::RpcServiceMethod(
       BlobService_method_names[0],
@@ -125,6 +150,16 @@
              ::google::protobuf::Empty* resp) {
                return service->Remove(ctx, req, resp);
              }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      BlobService_method_names[3],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< BlobService::Service, ::blob::AppendHolderRequest, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
+          [](BlobService::Service* service,
+             ::grpc::ServerContext* ctx,
+             const ::blob::AppendHolderRequest* req,
+             ::google::protobuf::Empty* resp) {
+               return service->AppendHolder(ctx, req, resp);
+             }, this)));
 }
 
 BlobService::Service::~Service() {
@@ -150,6 +185,13 @@
   return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
 }
 
+::grpc::Status BlobService::Service::AppendHolder(::grpc::ServerContext* context, const ::blob::AppendHolderRequest* request, ::google::protobuf::Empty* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
 
 }  // namespace blob
 
diff --git a/native/cpp/CommonCpp/grpc/_generated/blob.pb.h b/native/cpp/CommonCpp/grpc/_generated/blob.pb.h
--- a/native/cpp/CommonCpp/grpc/_generated/blob.pb.h
+++ b/native/cpp/CommonCpp/grpc/_generated/blob.pb.h
@@ -47,7 +47,7 @@
     PROTOBUF_SECTION_VARIABLE(protodesc_cold);
   static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
     PROTOBUF_SECTION_VARIABLE(protodesc_cold);
-  static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[5]
+  static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[6]
     PROTOBUF_SECTION_VARIABLE(protodesc_cold);
   static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
   static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
@@ -56,6 +56,9 @@
 extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_blob_2eproto;
 ::PROTOBUF_NAMESPACE_ID::Metadata descriptor_table_blob_2eproto_metadata_getter(int index);
 namespace blob {
+class AppendHolderRequest;
+struct AppendHolderRequestDefaultTypeInternal;
+extern AppendHolderRequestDefaultTypeInternal _AppendHolderRequest_default_instance_;
 class GetRequest;
 struct GetRequestDefaultTypeInternal;
 extern GetRequestDefaultTypeInternal _GetRequest_default_instance_;
@@ -73,6 +76,7 @@
 extern RemoveRequestDefaultTypeInternal _RemoveRequest_default_instance_;
 }  // namespace blob
 PROTOBUF_NAMESPACE_OPEN
+template<> ::blob::AppendHolderRequest* Arena::CreateMaybeMessage<::blob::AppendHolderRequest>(Arena*);
 template<> ::blob::GetRequest* Arena::CreateMaybeMessage<::blob::GetRequest>(Arena*);
 template<> ::blob::GetResponse* Arena::CreateMaybeMessage<::blob::GetResponse>(Arena*);
 template<> ::blob::PutRequest* Arena::CreateMaybeMessage<::blob::PutRequest>(Arena*);
@@ -863,6 +867,168 @@
   mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
   friend struct ::TableStruct_blob_2eproto;
 };
+// -------------------------------------------------------------------
+
+class AppendHolderRequest PROTOBUF_FINAL :
+    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:blob.AppendHolderRequest) */ {
+ public:
+  inline AppendHolderRequest() : AppendHolderRequest(nullptr) {}
+  virtual ~AppendHolderRequest();
+  explicit constexpr AppendHolderRequest(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+  AppendHolderRequest(const AppendHolderRequest& from);
+  AppendHolderRequest(AppendHolderRequest&& from) noexcept
+    : AppendHolderRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline AppendHolderRequest& operator=(const AppendHolderRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  inline AppendHolderRequest& operator=(AppendHolderRequest&& from) noexcept {
+    if (GetArena() == from.GetArena()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+
+  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+    return GetDescriptor();
+  }
+  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+    return GetMetadataStatic().descriptor;
+  }
+  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+    return GetMetadataStatic().reflection;
+  }
+  static const AppendHolderRequest& default_instance() {
+    return *internal_default_instance();
+  }
+  static inline const AppendHolderRequest* internal_default_instance() {
+    return reinterpret_cast<const AppendHolderRequest*>(
+               &_AppendHolderRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    5;
+
+  friend void swap(AppendHolderRequest& a, AppendHolderRequest& b) {
+    a.Swap(&b);
+  }
+  inline void Swap(AppendHolderRequest* other) {
+    if (other == this) return;
+    if (GetArena() == other->GetArena()) {
+      InternalSwap(other);
+    } else {
+      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+    }
+  }
+  void UnsafeArenaSwap(AppendHolderRequest* other) {
+    if (other == this) return;
+    GOOGLE_DCHECK(GetArena() == other->GetArena());
+    InternalSwap(other);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline AppendHolderRequest* New() const final {
+    return CreateMaybeMessage<AppendHolderRequest>(nullptr);
+  }
+
+  AppendHolderRequest* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
+    return CreateMaybeMessage<AppendHolderRequest>(arena);
+  }
+  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
+  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
+  void CopyFrom(const AppendHolderRequest& from);
+  void MergeFrom(const AppendHolderRequest& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
+      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  inline void SharedCtor();
+  inline void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(AppendHolderRequest* other);
+  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+    return "blob.AppendHolderRequest";
+  }
+  protected:
+  explicit AppendHolderRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+  private:
+  static void ArenaDtor(void* object);
+  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+  public:
+
+  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+  private:
+  static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() {
+    return ::descriptor_table_blob_2eproto_metadata_getter(kIndexInFileMessages);
+  }
+
+  public:
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  enum : int {
+    kHolderFieldNumber = 1,
+    kBlobHashFieldNumber = 2,
+  };
+  // string holder = 1;
+  void clear_holder();
+  const std::string& holder() const;
+  void set_holder(const std::string& value);
+  void set_holder(std::string&& value);
+  void set_holder(const char* value);
+  void set_holder(const char* value, size_t size);
+  std::string* mutable_holder();
+  std::string* release_holder();
+  void set_allocated_holder(std::string* holder);
+  private:
+  const std::string& _internal_holder() const;
+  void _internal_set_holder(const std::string& value);
+  std::string* _internal_mutable_holder();
+  public:
+
+  // string blobHash = 2;
+  void clear_blobhash();
+  const std::string& blobhash() const;
+  void set_blobhash(const std::string& value);
+  void set_blobhash(std::string&& value);
+  void set_blobhash(const char* value);
+  void set_blobhash(const char* value, size_t size);
+  std::string* mutable_blobhash();
+  std::string* release_blobhash();
+  void set_allocated_blobhash(std::string* blobhash);
+  private:
+  const std::string& _internal_blobhash() const;
+  void _internal_set_blobhash(const std::string& value);
+  std::string* _internal_mutable_blobhash();
+  public:
+
+  // @@protoc_insertion_point(class_scope:blob.AppendHolderRequest)
+ private:
+  class _Internal;
+
+  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+  typedef void InternalArenaConstructable_;
+  typedef void DestructorSkippable_;
+  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr holder_;
+  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr blobhash_;
+  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_blob_2eproto;
+};
 // ===================================================================
 
 
@@ -1432,6 +1598,132 @@
   // @@protoc_insertion_point(field_set_allocated:blob.RemoveRequest.holder)
 }
 
+// -------------------------------------------------------------------
+
+// AppendHolderRequest
+
+// string holder = 1;
+inline void AppendHolderRequest::clear_holder() {
+  holder_.ClearToEmpty();
+}
+inline const std::string& AppendHolderRequest::holder() const {
+  // @@protoc_insertion_point(field_get:blob.AppendHolderRequest.holder)
+  return _internal_holder();
+}
+inline void AppendHolderRequest::set_holder(const std::string& value) {
+  _internal_set_holder(value);
+  // @@protoc_insertion_point(field_set:blob.AppendHolderRequest.holder)
+}
+inline std::string* AppendHolderRequest::mutable_holder() {
+  // @@protoc_insertion_point(field_mutable:blob.AppendHolderRequest.holder)
+  return _internal_mutable_holder();
+}
+inline const std::string& AppendHolderRequest::_internal_holder() const {
+  return holder_.Get();
+}
+inline void AppendHolderRequest::_internal_set_holder(const std::string& value) {
+  
+  holder_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
+}
+inline void AppendHolderRequest::set_holder(std::string&& value) {
+  
+  holder_.Set(
+    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena());
+  // @@protoc_insertion_point(field_set_rvalue:blob.AppendHolderRequest.holder)
+}
+inline void AppendHolderRequest::set_holder(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  holder_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena());
+  // @@protoc_insertion_point(field_set_char:blob.AppendHolderRequest.holder)
+}
+inline void AppendHolderRequest::set_holder(const char* value,
+    size_t size) {
+  
+  holder_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(
+      reinterpret_cast<const char*>(value), size), GetArena());
+  // @@protoc_insertion_point(field_set_pointer:blob.AppendHolderRequest.holder)
+}
+inline std::string* AppendHolderRequest::_internal_mutable_holder() {
+  
+  return holder_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
+}
+inline std::string* AppendHolderRequest::release_holder() {
+  // @@protoc_insertion_point(field_release:blob.AppendHolderRequest.holder)
+  return holder_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
+}
+inline void AppendHolderRequest::set_allocated_holder(std::string* holder) {
+  if (holder != nullptr) {
+    
+  } else {
+    
+  }
+  holder_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), holder,
+      GetArena());
+  // @@protoc_insertion_point(field_set_allocated:blob.AppendHolderRequest.holder)
+}
+
+// string blobHash = 2;
+inline void AppendHolderRequest::clear_blobhash() {
+  blobhash_.ClearToEmpty();
+}
+inline const std::string& AppendHolderRequest::blobhash() const {
+  // @@protoc_insertion_point(field_get:blob.AppendHolderRequest.blobHash)
+  return _internal_blobhash();
+}
+inline void AppendHolderRequest::set_blobhash(const std::string& value) {
+  _internal_set_blobhash(value);
+  // @@protoc_insertion_point(field_set:blob.AppendHolderRequest.blobHash)
+}
+inline std::string* AppendHolderRequest::mutable_blobhash() {
+  // @@protoc_insertion_point(field_mutable:blob.AppendHolderRequest.blobHash)
+  return _internal_mutable_blobhash();
+}
+inline const std::string& AppendHolderRequest::_internal_blobhash() const {
+  return blobhash_.Get();
+}
+inline void AppendHolderRequest::_internal_set_blobhash(const std::string& value) {
+  
+  blobhash_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
+}
+inline void AppendHolderRequest::set_blobhash(std::string&& value) {
+  
+  blobhash_.Set(
+    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena());
+  // @@protoc_insertion_point(field_set_rvalue:blob.AppendHolderRequest.blobHash)
+}
+inline void AppendHolderRequest::set_blobhash(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  blobhash_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena());
+  // @@protoc_insertion_point(field_set_char:blob.AppendHolderRequest.blobHash)
+}
+inline void AppendHolderRequest::set_blobhash(const char* value,
+    size_t size) {
+  
+  blobhash_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(
+      reinterpret_cast<const char*>(value), size), GetArena());
+  // @@protoc_insertion_point(field_set_pointer:blob.AppendHolderRequest.blobHash)
+}
+inline std::string* AppendHolderRequest::_internal_mutable_blobhash() {
+  
+  return blobhash_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
+}
+inline std::string* AppendHolderRequest::release_blobhash() {
+  // @@protoc_insertion_point(field_release:blob.AppendHolderRequest.blobHash)
+  return blobhash_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
+}
+inline void AppendHolderRequest::set_allocated_blobhash(std::string* blobhash) {
+  if (blobhash != nullptr) {
+    
+  } else {
+    
+  }
+  blobhash_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), blobhash,
+      GetArena());
+  // @@protoc_insertion_point(field_set_allocated:blob.AppendHolderRequest.blobHash)
+}
+
 #ifdef __GNUC__
   #pragma GCC diagnostic pop
 #endif  // __GNUC__
@@ -1443,6 +1735,8 @@
 
 // -------------------------------------------------------------------
 
+// -------------------------------------------------------------------
+
 
 // @@protoc_insertion_point(namespace_scope)
 
diff --git a/native/cpp/CommonCpp/grpc/_generated/blob.pb.cc b/native/cpp/CommonCpp/grpc/_generated/blob.pb.cc
--- a/native/cpp/CommonCpp/grpc/_generated/blob.pb.cc
+++ b/native/cpp/CommonCpp/grpc/_generated/blob.pb.cc
@@ -77,8 +77,21 @@
   };
 };
 PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT RemoveRequestDefaultTypeInternal _RemoveRequest_default_instance_;
+constexpr AppendHolderRequest::AppendHolderRequest(
+  ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+  : holder_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+  , blobhash_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string){}
+struct AppendHolderRequestDefaultTypeInternal {
+  constexpr AppendHolderRequestDefaultTypeInternal()
+    : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+  ~AppendHolderRequestDefaultTypeInternal() {}
+  union {
+    AppendHolderRequest _instance;
+  };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT AppendHolderRequestDefaultTypeInternal _AppendHolderRequest_default_instance_;
 }  // namespace blob
-static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_blob_2eproto[5];
+static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_blob_2eproto[6];
 static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_blob_2eproto = nullptr;
 static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_blob_2eproto = nullptr;
 
@@ -116,6 +129,13 @@
   ~0u,  // no _oneof_case_
   ~0u,  // no _weak_field_map_
   PROTOBUF_FIELD_OFFSET(::blob::RemoveRequest, holder_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::blob::AppendHolderRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::blob::AppendHolderRequest, holder_),
+  PROTOBUF_FIELD_OFFSET(::blob::AppendHolderRequest, blobhash_),
 };
 static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
   { 0, -1, sizeof(::blob::PutRequest)},
@@ -123,6 +143,7 @@
   { 15, -1, sizeof(::blob::GetRequest)},
   { 21, -1, sizeof(::blob::GetResponse)},
   { 27, -1, sizeof(::blob::RemoveRequest)},
+  { 33, -1, sizeof(::blob::AppendHolderRequest)},
 };
 
 static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = {
@@ -131,6 +152,7 @@
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::blob::_GetRequest_default_instance_),
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::blob::_GetResponse_default_instance_),
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::blob::_RemoveRequest_default_instance_),
+  reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::blob::_AppendHolderRequest_default_instance_),
 };
 
 const char descriptor_table_protodef_blob_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
@@ -140,19 +162,23 @@
   "B\006\n\004data\"!\n\013PutResponse\022\022\n\ndataExists\030\001 "
   "\001(\010\"\034\n\nGetRequest\022\016\n\006holder\030\001 \001(\t\" \n\013Get"
   "Response\022\021\n\tdataChunk\030\001 \001(\014\"\037\n\rRemoveReq"
-  "uest\022\016\n\006holder\030\001 \001(\t2\250\001\n\013BlobService\0220\n\003"
-  "Put\022\020.blob.PutRequest\032\021.blob.PutResponse"
-  "\"\000(\0010\001\022.\n\003Get\022\020.blob.GetRequest\032\021.blob.G"
-  "etResponse\"\0000\001\0227\n\006Remove\022\023.blob.RemoveRe"
-  "quest\032\026.google.protobuf.Empty\"\000b\006proto3"
+  "uest\022\016\n\006holder\030\001 \001(\t\"7\n\023AppendHolderRequ"
+  "est\022\016\n\006holder\030\001 \001(\t\022\020\n\010blobHash\030\002 \001(\t2\355\001"
+  "\n\013BlobService\0220\n\003Put\022\020.blob.PutRequest\032\021"
+  ".blob.PutResponse\"\000(\0010\001\022.\n\003Get\022\020.blob.Ge"
+  "tRequest\032\021.blob.GetResponse\"\0000\001\0227\n\006Remov"
+  "e\022\023.blob.RemoveRequest\032\026.google.protobuf"
+  ".Empty\"\000\022C\n\014AppendHolder\022\031.blob.AppendHo"
+  "lderRequest\032\026.google.protobuf.Empty\"\000b\006p"
+  "roto3"
   ;
 static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_blob_2eproto_deps[1] = {
   &::descriptor_table_google_2fprotobuf_2fempty_2eproto,
 };
 static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_blob_2eproto_once;
 const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_blob_2eproto = {
-  false, false, 439, descriptor_table_protodef_blob_2eproto, "blob.proto", 
-  &descriptor_table_blob_2eproto_once, descriptor_table_blob_2eproto_deps, 1, 5,
+  false, false, 565, descriptor_table_protodef_blob_2eproto, "blob.proto", 
+  &descriptor_table_blob_2eproto_once, descriptor_table_blob_2eproto_deps, 1, 6,
   schemas, file_default_instances, TableStruct_blob_2eproto::offsets,
   file_level_metadata_blob_2eproto, file_level_enum_descriptors_blob_2eproto, file_level_service_descriptors_blob_2eproto,
 };
@@ -1253,6 +1279,244 @@
 }
 
 
+// ===================================================================
+
+class AppendHolderRequest::_Internal {
+ public:
+};
+
+AppendHolderRequest::AppendHolderRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena)
+  : ::PROTOBUF_NAMESPACE_ID::Message(arena) {
+  SharedCtor();
+  RegisterArenaDtor(arena);
+  // @@protoc_insertion_point(arena_constructor:blob.AppendHolderRequest)
+}
+AppendHolderRequest::AppendHolderRequest(const AppendHolderRequest& from)
+  : ::PROTOBUF_NAMESPACE_ID::Message() {
+  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+  holder_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+  if (!from._internal_holder().empty()) {
+    holder_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_holder(), 
+      GetArena());
+  }
+  blobhash_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+  if (!from._internal_blobhash().empty()) {
+    blobhash_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_blobhash(), 
+      GetArena());
+  }
+  // @@protoc_insertion_point(copy_constructor:blob.AppendHolderRequest)
+}
+
+void AppendHolderRequest::SharedCtor() {
+holder_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+blobhash_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+}
+
+AppendHolderRequest::~AppendHolderRequest() {
+  // @@protoc_insertion_point(destructor:blob.AppendHolderRequest)
+  SharedDtor();
+  _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+void AppendHolderRequest::SharedDtor() {
+  GOOGLE_DCHECK(GetArena() == nullptr);
+  holder_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+  blobhash_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+}
+
+void AppendHolderRequest::ArenaDtor(void* object) {
+  AppendHolderRequest* _this = reinterpret_cast< AppendHolderRequest* >(object);
+  (void)_this;
+}
+void AppendHolderRequest::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void AppendHolderRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+
+void AppendHolderRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:blob.AppendHolderRequest)
+  ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  holder_.ClearToEmpty();
+  blobhash_.ClearToEmpty();
+  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* AppendHolderRequest::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+  while (!ctx->Done(&ptr)) {
+    ::PROTOBUF_NAMESPACE_ID::uint32 tag;
+    ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+    CHK_(ptr);
+    switch (tag >> 3) {
+      // string holder = 1;
+      case 1:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10)) {
+          auto str = _internal_mutable_holder();
+          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+          CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "blob.AppendHolderRequest.holder"));
+          CHK_(ptr);
+        } else goto handle_unusual;
+        continue;
+      // string blobHash = 2;
+      case 2:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 18)) {
+          auto str = _internal_mutable_blobhash();
+          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+          CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "blob.AppendHolderRequest.blobHash"));
+          CHK_(ptr);
+        } else goto handle_unusual;
+        continue;
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->SetLastTag(tag);
+          goto success;
+        }
+        ptr = UnknownFieldParse(tag,
+            _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+            ptr, ctx);
+        CHK_(ptr != nullptr);
+        continue;
+      }
+    }  // switch
+  }  // while
+success:
+  return ptr;
+failure:
+  ptr = nullptr;
+  goto success;
+#undef CHK_
+}
+
+::PROTOBUF_NAMESPACE_ID::uint8* AppendHolderRequest::_InternalSerialize(
+    ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+  // @@protoc_insertion_point(serialize_to_array_start:blob.AppendHolderRequest)
+  ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string holder = 1;
+  if (this->holder().size() > 0) {
+    ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
+      this->_internal_holder().data(), static_cast<int>(this->_internal_holder().length()),
+      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
+      "blob.AppendHolderRequest.holder");
+    target = stream->WriteStringMaybeAliased(
+        1, this->_internal_holder(), target);
+  }
+
+  // string blobHash = 2;
+  if (this->blobhash().size() > 0) {
+    ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
+      this->_internal_blobhash().data(), static_cast<int>(this->_internal_blobhash().length()),
+      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
+      "blob.AppendHolderRequest.blobHash");
+    target = stream->WriteStringMaybeAliased(
+        2, this->_internal_blobhash(), target);
+  }
+
+  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:blob.AppendHolderRequest)
+  return target;
+}
+
+size_t AppendHolderRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:blob.AppendHolderRequest)
+  size_t total_size = 0;
+
+  ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string holder = 1;
+  if (this->holder().size() > 0) {
+    total_size += 1 +
+      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+        this->_internal_holder());
+  }
+
+  // string blobHash = 2;
+  if (this->blobhash().size() > 0) {
+    total_size += 1 +
+      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+        this->_internal_blobhash());
+  }
+
+  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+    return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize(
+        _internal_metadata_, total_size, &_cached_size_);
+  }
+  int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void AppendHolderRequest::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:blob.AppendHolderRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const AppendHolderRequest* source =
+      ::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated<AppendHolderRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:blob.AppendHolderRequest)
+    ::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:blob.AppendHolderRequest)
+    MergeFrom(*source);
+  }
+}
+
+void AppendHolderRequest::MergeFrom(const AppendHolderRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:blob.AppendHolderRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+  ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.holder().size() > 0) {
+    _internal_set_holder(from._internal_holder());
+  }
+  if (from.blobhash().size() > 0) {
+    _internal_set_blobhash(from._internal_blobhash());
+  }
+}
+
+void AppendHolderRequest::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:blob.AppendHolderRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void AppendHolderRequest::CopyFrom(const AppendHolderRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:blob.AppendHolderRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool AppendHolderRequest::IsInitialized() const {
+  return true;
+}
+
+void AppendHolderRequest::InternalSwap(AppendHolderRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_);
+  holder_.Swap(&other->holder_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
+  blobhash_.Swap(&other->blobhash_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata AppendHolderRequest::GetMetadata() const {
+  return GetMetadataStatic();
+}
+
+
 // @@protoc_insertion_point(namespace_scope)
 }  // namespace blob
 PROTOBUF_NAMESPACE_OPEN
@@ -1271,6 +1535,9 @@
 template<> PROTOBUF_NOINLINE ::blob::RemoveRequest* Arena::CreateMaybeMessage< ::blob::RemoveRequest >(Arena* arena) {
   return Arena::CreateMessageInternal< ::blob::RemoveRequest >(arena);
 }
+template<> PROTOBUF_NOINLINE ::blob::AppendHolderRequest* Arena::CreateMaybeMessage< ::blob::AppendHolderRequest >(Arena* arena) {
+  return Arena::CreateMessageInternal< ::blob::AppendHolderRequest >(arena);
+}
 PROTOBUF_NAMESPACE_CLOSE
 
 // @@protoc_insertion_point(global_scope)
diff --git a/native/cpp/CommonCpp/grpc/protos/blob.proto b/native/cpp/CommonCpp/grpc/protos/blob.proto
--- a/native/cpp/CommonCpp/grpc/protos/blob.proto
+++ b/native/cpp/CommonCpp/grpc/protos/blob.proto
@@ -8,6 +8,7 @@
   rpc Put(stream PutRequest) returns (stream PutResponse) {}
   rpc Get(GetRequest) returns (stream GetResponse) {}
   rpc Remove(RemoveRequest) returns (google.protobuf.Empty) {}
+  rpc AppendHolder(AppendHolderRequest) returns (google.protobuf.Empty) {}
 }
 
 // Put
@@ -39,3 +40,10 @@
 message RemoveRequest {
   string holder = 1;
 }
+
+// AppendHolder
+
+message AppendHolderRequest {
+  string holder = 1;
+  string blobHash = 2;
+}