diff --git a/examples/push_notification_config_client.cpp b/examples/push_notification_config_client.cpp index 95257ee..be2a18c 100644 --- a/examples/push_notification_config_client.cpp +++ b/examples/push_notification_config_client.cpp @@ -38,7 +38,7 @@ int main() { cfg.set_id("cfg-1"); cfg.set_task_id("task-1"); cfg.set_endpoint("https://callback.example/notify"); - const auto set_result = client.SetTaskPushNotificationConfig(cfg); + const auto set_result = client.CreateTaskPushNotificationConfig(cfg); if (!set_result.ok()) { std::cerr << "set failed: " << set_result.error().message() << '\n'; return 1; diff --git a/include/a2a/client/client.h b/include/a2a/client/client.h index f84f9ad..db331c7 100644 --- a/include/a2a/client/client.h +++ b/include/a2a/client/client.h @@ -116,7 +116,7 @@ class ClientTransport { const lf::a2a::v1::CancelTaskRequest& request, const CallOptions& options) = 0; [[nodiscard]] virtual core::Result - SetTaskPushNotificationConfig(const lf::a2a::v1::TaskPushNotificationConfig& request, + CreateTaskPushNotificationConfig(const lf::a2a::v1::TaskPushNotificationConfig& request, const CallOptions& options) = 0; [[nodiscard]] virtual core::Result @@ -161,7 +161,7 @@ class A2AClient final { [[nodiscard]] core::Result CancelTask( const lf::a2a::v1::CancelTaskRequest& request, const CallOptions& options = {}); - [[nodiscard]] core::Result SetTaskPushNotificationConfig( + [[nodiscard]] core::Result CreateTaskPushNotificationConfig( const lf::a2a::v1::TaskPushNotificationConfig& request, const CallOptions& options = {}); [[nodiscard]] core::Result GetTaskPushNotificationConfig( diff --git a/include/a2a/client/grpc_transport.h b/include/a2a/client/grpc_transport.h index 2f24d39..31f5b04 100644 --- a/include/a2a/client/grpc_transport.h +++ b/include/a2a/client/grpc_transport.h @@ -49,7 +49,7 @@ class GrpcTransport final : public ClientTransport { const lf::a2a::v1::CancelTaskRequest& request, lf::a2a::v1::Task* response) = 0; - [[nodiscard]] virtual ::grpc::Status SetTaskPushNotificationConfig( + [[nodiscard]] virtual ::grpc::Status CreateTaskPushNotificationConfig( ::grpc::ClientContext* context, const lf::a2a::v1::TaskPushNotificationConfig& request, lf::a2a::v1::TaskPushNotificationConfig* response) = 0; @@ -86,7 +86,7 @@ class GrpcTransport final : public ClientTransport { [[nodiscard]] core::Result CancelTask( const lf::a2a::v1::CancelTaskRequest& request, const CallOptions& options) override; - [[nodiscard]] core::Result SetTaskPushNotificationConfig( + [[nodiscard]] core::Result CreateTaskPushNotificationConfig( const lf::a2a::v1::TaskPushNotificationConfig& request, const CallOptions& options) override; [[nodiscard]] core::Result GetTaskPushNotificationConfig( diff --git a/include/a2a/client/http_json_transport.h b/include/a2a/client/http_json_transport.h index b99f553..adbb979 100644 --- a/include/a2a/client/http_json_transport.h +++ b/include/a2a/client/http_json_transport.h @@ -60,7 +60,7 @@ class HttpJsonTransport final : public ClientTransport { [[nodiscard]] core::Result CancelTask( const lf::a2a::v1::CancelTaskRequest& request, const CallOptions& options) override; - [[nodiscard]] core::Result SetTaskPushNotificationConfig( + [[nodiscard]] core::Result CreateTaskPushNotificationConfig( const lf::a2a::v1::TaskPushNotificationConfig& request, const CallOptions& options) override; [[nodiscard]] core::Result GetTaskPushNotificationConfig( diff --git a/include/a2a/client/json_rpc_transport.h b/include/a2a/client/json_rpc_transport.h index 7e4c09e..d2c9957 100644 --- a/include/a2a/client/json_rpc_transport.h +++ b/include/a2a/client/json_rpc_transport.h @@ -31,7 +31,7 @@ class JsonRpcTransport final : public ClientTransport { [[nodiscard]] core::Result CancelTask( const lf::a2a::v1::CancelTaskRequest& request, const CallOptions& options) override; - [[nodiscard]] core::Result SetTaskPushNotificationConfig( + [[nodiscard]] core::Result CreateTaskPushNotificationConfig( const lf::a2a::v1::TaskPushNotificationConfig& request, const CallOptions& options) override; [[nodiscard]] core::Result GetTaskPushNotificationConfig( diff --git a/include/a2a/core/json_rpc.h b/include/a2a/core/json_rpc.h index e14073e..76b27de 100644 --- a/include/a2a/core/json_rpc.h +++ b/include/a2a/core/json_rpc.h @@ -10,7 +10,7 @@ struct MethodNames final { static constexpr std::string_view kSendMessage = "a2a.sendMessage"; static constexpr std::string_view kGetTask = "a2a.getTask"; static constexpr std::string_view kCancelTask = "a2a.cancelTask"; - static constexpr std::string_view kSetTaskPushNotificationConfig = + static constexpr std::string_view kCreateTaskPushNotificationConfig = "a2a.setTaskPushNotificationConfig"; static constexpr std::string_view kGetTaskPushNotificationConfig = "a2a.getTaskPushNotificationConfig"; diff --git a/include/a2a/server/grpc_server_transport.h b/include/a2a/server/grpc_server_transport.h index d41b21a..c4ccb41 100644 --- a/include/a2a/server/grpc_server_transport.h +++ b/include/a2a/server/grpc_server_transport.h @@ -36,7 +36,7 @@ class GrpcServerTransport final : public lf::a2a::v1::A2AService::Service { [[nodiscard]] static ::grpc::Status ToGrpcStatus(const core::Error& error, ::grpc::ServerContext* context); - ::grpc::Status SetTaskPushNotificationConfig( + ::grpc::Status CreateTaskPushNotificationConfig( ::grpc::ServerContext* context, const lf::a2a::v1::TaskPushNotificationConfig* request, lf::a2a::v1::TaskPushNotificationConfig* response) override; diff --git a/proto/CMakeLists.txt b/proto/CMakeLists.txt index 2a7e906..b52c65b 100644 --- a/proto/CMakeLists.txt +++ b/proto/CMakeLists.txt @@ -2,19 +2,57 @@ set(A2A_PROTO_ROOT "${CMAKE_CURRENT_SOURCE_DIR}") set(A2A_GENERATED_DIR "${CMAKE_BINARY_DIR}/generated") file(MAKE_DIRECTORY "${A2A_GENERATED_DIR}") +set(A2A_GOOGLEAPIS_PROTO_ROOT "${CMAKE_SOURCE_DIR}/third_party/googleapis") set(A2A_PROTO_FILE "${A2A_PROTO_ROOT}/a2a/v1/a2a.proto") -set(A2A_PROTO_SRCS "${A2A_GENERATED_DIR}/a2a/v1/a2a.pb.cc") -set(A2A_PROTO_HDRS "${A2A_GENERATED_DIR}/a2a/v1/a2a.pb.h") +set(A2A_GOOGLE_API_PROTO_FILES + "${A2A_GOOGLEAPIS_PROTO_ROOT}/google/api/annotations.proto" + "${A2A_GOOGLEAPIS_PROTO_ROOT}/google/api/client.proto" + "${A2A_GOOGLEAPIS_PROTO_ROOT}/google/api/field_behavior.proto" + "${A2A_GOOGLEAPIS_PROTO_ROOT}/google/api/http.proto" +) + +set(A2A_PROTO_SRCS + "${A2A_GENERATED_DIR}/a2a/v1/a2a.pb.cc" + "${A2A_GENERATED_DIR}/google/api/annotations.pb.cc" + "${A2A_GENERATED_DIR}/google/api/client.pb.cc" + "${A2A_GENERATED_DIR}/google/api/field_behavior.pb.cc" + "${A2A_GENERATED_DIR}/google/api/http.pb.cc" +) +set(A2A_PROTO_HDRS + "${A2A_GENERATED_DIR}/a2a/v1/a2a.pb.h" + "${A2A_GENERATED_DIR}/google/api/annotations.pb.h" + "${A2A_GENERATED_DIR}/google/api/client.pb.h" + "${A2A_GENERATED_DIR}/google/api/field_behavior.pb.h" + "${A2A_GENERATED_DIR}/google/api/http.pb.h" +) set(A2A_GRPC_SRCS "${A2A_GENERATED_DIR}/a2a/v1/a2a.grpc.pb.cc") set(A2A_GRPC_HDRS "${A2A_GENERATED_DIR}/a2a/v1/a2a.grpc.pb.h") add_custom_command( - OUTPUT ${A2A_PROTO_SRCS} ${A2A_PROTO_HDRS} ${A2A_GRPC_SRCS} ${A2A_GRPC_HDRS} + OUTPUT ${A2A_PROTO_SRCS} ${A2A_PROTO_HDRS} COMMAND protobuf::protoc ARGS --proto_path=${A2A_PROTO_ROOT} + --proto_path=${A2A_GOOGLEAPIS_PROTO_ROOT} --proto_path=${Protobuf_INCLUDE_DIRS} --cpp_out=${A2A_GENERATED_DIR} + ${A2A_PROTO_FILE} + ${A2A_GOOGLE_API_PROTO_FILES} + DEPENDS + ${A2A_PROTO_FILE} + ${A2A_GOOGLE_API_PROTO_FILES} + protobuf::protoc + COMMENT "Generating protobuf C++ sources" + VERBATIM +) + +add_custom_command( + OUTPUT ${A2A_GRPC_SRCS} ${A2A_GRPC_HDRS} + COMMAND protobuf::protoc + ARGS + --proto_path=${A2A_PROTO_ROOT} + --proto_path=${A2A_GOOGLEAPIS_PROTO_ROOT} + --proto_path=${Protobuf_INCLUDE_DIRS} --grpc_out=${A2A_GENERATED_DIR} --plugin=protoc-gen-grpc=$ ${A2A_PROTO_FILE} @@ -22,7 +60,8 @@ add_custom_command( ${A2A_PROTO_FILE} protobuf::protoc gRPC::grpc_cpp_plugin - COMMENT "Generating C++ sources from ${A2A_PROTO_FILE}" + ${A2A_PROTO_SRCS} + COMMENT "Generating gRPC C++ sources from ${A2A_PROTO_FILE}" VERBATIM ) diff --git a/src/client/client.cpp b/src/client/client.cpp index bc6d665..227f539 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -93,15 +93,15 @@ core::Result A2AClient::CancelTask(const lf::a2a::v1::CancelT return result; } -core::Result A2AClient::SetTaskPushNotificationConfig( +core::Result A2AClient::CreateTaskPushNotificationConfig( const lf::a2a::v1::TaskPushNotificationConfig& request, const CallOptions& options) { if (transport_ == nullptr) { return core::Error::Internal("Client transport is not configured"); } - const ClientCallContext context{.operation = "SetTaskPushNotificationConfig", + const ClientCallContext context{.operation = "CreateTaskPushNotificationConfig", .options = &options}; RunBeforeInterceptors(context); - const auto result = transport_->SetTaskPushNotificationConfig(request, options); + const auto result = transport_->CreateTaskPushNotificationConfig(request, options); RunAfterInterceptors(context, result.ok() ? ClientCallResult{} : ClientCallResult{.ok = false, .error = result.error()}); diff --git a/src/client/grpc_transport.cpp b/src/client/grpc_transport.cpp index 2f99420..fd628e3 100644 --- a/src/client/grpc_transport.cpp +++ b/src/client/grpc_transport.cpp @@ -59,10 +59,10 @@ class StubRpcClient final : public GrpcTransport::RpcClient { return stub_->CancelTask(context, request, response); } - [[nodiscard]] ::grpc::Status SetTaskPushNotificationConfig( + [[nodiscard]] ::grpc::Status CreateTaskPushNotificationConfig( ::grpc::ClientContext* context, const lf::a2a::v1::TaskPushNotificationConfig& request, lf::a2a::v1::TaskPushNotificationConfig* response) override { - return stub_->SetTaskPushNotificationConfig(context, request, response); + return stub_->CreateTaskPushNotificationConfig(context, request, response); } [[nodiscard]] ::grpc::Status GetTaskPushNotificationConfig( @@ -217,7 +217,7 @@ core::Result GrpcTransport::CancelTask( return response; } -core::Result GrpcTransport::SetTaskPushNotificationConfig( +core::Result GrpcTransport::CreateTaskPushNotificationConfig( const lf::a2a::v1::TaskPushNotificationConfig& request, const CallOptions& options) { auto context_result = BuildContext(options); if (!context_result.ok()) { @@ -225,7 +225,7 @@ core::Result GrpcTransport::SetTaskPush } auto context = std::move(context_result.value()); lf::a2a::v1::TaskPushNotificationConfig response; - const auto status = rpc_client_->SetTaskPushNotificationConfig(context.get(), request, &response); + const auto status = rpc_client_->CreateTaskPushNotificationConfig(context.get(), request, &response); if (!status.ok()) { return BuildGrpcError(status); } diff --git a/src/client/http_json_transport.cpp b/src/client/http_json_transport.cpp index 3eb4d95..35c6381 100644 --- a/src/client/http_json_transport.cpp +++ b/src/client/http_json_transport.cpp @@ -409,7 +409,7 @@ core::Result HttpJsonTransport::CancelTask( } core::Result -HttpJsonTransport::SetTaskPushNotificationConfig( +HttpJsonTransport::CreateTaskPushNotificationConfig( const lf::a2a::v1::TaskPushNotificationConfig& request, const CallOptions& options) { const auto body = core::MessageToJson(request); if (!body.ok()) { diff --git a/src/client/json_rpc_transport.cpp b/src/client/json_rpc_transport.cpp index 486e1c6..a7e8a56 100644 --- a/src/client/json_rpc_transport.cpp +++ b/src/client/json_rpc_transport.cpp @@ -401,10 +401,10 @@ core::Result JsonRpcTransport::CancelTask( } core::Result -JsonRpcTransport::SetTaskPushNotificationConfig( +JsonRpcTransport::CreateTaskPushNotificationConfig( const lf::a2a::v1::TaskPushNotificationConfig& request, const CallOptions& options) { const auto result = InvokeForResultValue( - core::json_rpc::MethodNames::kSetTaskPushNotificationConfig, request, options); + core::json_rpc::MethodNames::kCreateTaskPushNotificationConfig, request, options); if (!result.ok()) { return result.error(); } diff --git a/src/server/grpc_server_transport.cpp b/src/server/grpc_server_transport.cpp index f0c240a..d5a59f3 100644 --- a/src/server/grpc_server_transport.cpp +++ b/src/server/grpc_server_transport.cpp @@ -204,7 +204,7 @@ ::grpc::Status GrpcServerTransport::CancelTask(::grpc::ServerContext* context, return ::grpc::Status::OK; } -::grpc::Status GrpcServerTransport::SetTaskPushNotificationConfig( +::grpc::Status GrpcServerTransport::CreateTaskPushNotificationConfig( ::grpc::ServerContext* context, const lf::a2a::v1::TaskPushNotificationConfig* request, lf::a2a::v1::TaskPushNotificationConfig* response) { (void)context; diff --git a/tests/functional/grpc_client_functional_test.cpp b/tests/functional/grpc_client_functional_test.cpp index 4be3b0e..b85300b 100644 --- a/tests/functional/grpc_client_functional_test.cpp +++ b/tests/functional/grpc_client_functional_test.cpp @@ -42,7 +42,7 @@ class ContractRpcClient final : public a2a::client::GrpcTransport::RpcClient { return grpc::Status::OK; } - grpc::Status SetTaskPushNotificationConfig( + grpc::Status CreateTaskPushNotificationConfig( grpc::ClientContext* context, const lf::a2a::v1::TaskPushNotificationConfig& request, lf::a2a::v1::TaskPushNotificationConfig* response) override { (void)context; diff --git a/tests/integration/http_json_client_integration_test.cpp b/tests/integration/http_json_client_integration_test.cpp index b10662c..25573bc 100644 --- a/tests/integration/http_json_client_integration_test.cpp +++ b/tests/integration/http_json_client_integration_test.cpp @@ -166,7 +166,7 @@ TEST(HttpJsonClientIntegrationTest, SupportsPushNotificationConfigCrudAndList) { lf::a2a::v1::TaskPushNotificationConfig set_request; set_request.set_task_id("t-1"); set_request.set_endpoint("https://cb"); - const auto set_response = client.SetTaskPushNotificationConfig(set_request); + const auto set_response = client.CreateTaskPushNotificationConfig(set_request); ASSERT_TRUE(set_response.ok()) << set_response.error().message(); EXPECT_EQ(set_response.value().id(), "pn-1"); diff --git a/tests/unit/client_test.cpp b/tests/unit/client_test.cpp index 19805cc..2c14c68 100644 --- a/tests/unit/client_test.cpp +++ b/tests/unit/client_test.cpp @@ -50,7 +50,7 @@ class FakeClientTransport final : public a2a::client::ClientTransport { return task; } - a2a::core::Result SetTaskPushNotificationConfig( + a2a::core::Result CreateTaskPushNotificationConfig( const lf::a2a::v1::TaskPushNotificationConfig& request, const a2a::client::CallOptions& options) override { (void)options; diff --git a/tests/unit/grpc_transport_test.cpp b/tests/unit/grpc_transport_test.cpp index 66a0487..aa35b67 100644 --- a/tests/unit/grpc_transport_test.cpp +++ b/tests/unit/grpc_transport_test.cpp @@ -72,7 +72,7 @@ class FakeRpcClient final : public a2a::client::GrpcTransport::RpcClient { return cancel_status; } - grpc::Status SetTaskPushNotificationConfig( + grpc::Status CreateTaskPushNotificationConfig( grpc::ClientContext* context, const lf::a2a::v1::TaskPushNotificationConfig& request, lf::a2a::v1::TaskPushNotificationConfig* response) override { (void)context; diff --git a/third_party/googleapis/google/api/annotations.proto b/third_party/googleapis/google/api/annotations.proto new file mode 100644 index 0000000..e008674 --- /dev/null +++ b/third_party/googleapis/google/api/annotations.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package google.api; + +import "google/api/http.proto"; +import "google/protobuf/descriptor.proto"; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "AnnotationsProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + + +extend google.protobuf.MethodOptions { + HttpRule http = 72295728; +} diff --git a/third_party/googleapis/google/api/client.proto b/third_party/googleapis/google/api/client.proto new file mode 100644 index 0000000..bfc7587 --- /dev/null +++ b/third_party/googleapis/google/api/client.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package google.api; + +import "google/protobuf/descriptor.proto"; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "ClientProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.MethodOptions { + repeated string method_signature = 1051; +} diff --git a/third_party/googleapis/google/api/field_behavior.proto b/third_party/googleapis/google/api/field_behavior.proto new file mode 100644 index 0000000..7f102e2 --- /dev/null +++ b/third_party/googleapis/google/api/field_behavior.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package google.api; + +import "google/protobuf/descriptor.proto"; + +enum FieldBehavior { + FIELD_BEHAVIOR_UNSPECIFIED = 0; + OPTIONAL = 1; + REQUIRED = 2; + OUTPUT_ONLY = 3; + INPUT_ONLY = 4; + IMMUTABLE = 5; + UNORDERED_LIST = 6; + NON_EMPTY_DEFAULT = 7; + IDENTIFIER = 8; +} + +extend google.protobuf.FieldOptions { + repeated FieldBehavior field_behavior = 1052; +} diff --git a/third_party/googleapis/google/api/http.proto b/third_party/googleapis/google/api/http.proto new file mode 100644 index 0000000..5fdb165 --- /dev/null +++ b/third_party/googleapis/google/api/http.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; + +package google.api; + +import "google/protobuf/descriptor.proto"; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "HttpProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +message Http { + repeated HttpRule rules = 1; + bool fully_decode_reserved_expansion = 2; +} + +message HttpRule { + string selector = 1; + oneof pattern { + string get = 2; + string put = 3; + string post = 4; + string delete = 5; + string patch = 6; + CustomHttpPattern custom = 8; + } + string body = 7; + string response_body = 12; + repeated HttpRule additional_bindings = 11; +} + +message CustomHttpPattern { + string kind = 1; + string path = 2; +} +