[BinderTransport] Create client channel instead of direct channel (#27790)
* [BinderTransport] Create client channel instead of direct channel In this commit we create a client channel instead of direct channel. BinderConnector is added to connect subchannel when the user actually make RPC call using the channel. BindToOnDeviceServerService() is not required anymore since now the actual connection is delay until the channel is used. * Regenerate projects.pull/27852/head
parent
09658682c9
commit
dcabe420cc
13 changed files with 423 additions and 88 deletions
@ -0,0 +1,121 @@ |
||||
// Copyright 2021 gRPC authors.
|
||||
//
|
||||
// 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 <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/ext/transport/binder/client/binder_connector.h" |
||||
|
||||
#include "src/core/lib/iomgr/port.h" |
||||
|
||||
#ifdef GRPC_HAVE_UNIX_SOCKET |
||||
#include <sys/un.h> |
||||
#endif |
||||
|
||||
#include <functional> |
||||
#include <map> |
||||
|
||||
#include "src/core/ext/filters/client_channel/connector.h" |
||||
#include "src/core/ext/filters/client_channel/subchannel.h" |
||||
#include "src/core/ext/transport/binder/client/endpoint_binder_pool.h" |
||||
#include "src/core/ext/transport/binder/client/security_policy_setting.h" |
||||
#include "src/core/ext/transport/binder/security_policy/untrusted_security_policy.h" |
||||
#include "src/core/ext/transport/binder/transport/binder_transport.h" |
||||
#include "src/core/ext/transport/binder/wire_format/binder.h" |
||||
|
||||
namespace { |
||||
|
||||
// TODO(mingcl): Currently this does no error handling and assumes the
|
||||
// connection always succeeds in reasonable amount of time.
|
||||
class BinderConnector : public grpc_core::SubchannelConnector { |
||||
public: |
||||
BinderConnector() {} |
||||
~BinderConnector() override {} |
||||
void Connect(const Args& args, Result* result, |
||||
grpc_closure* notify) override { |
||||
#ifdef GRPC_HAVE_UNIX_SOCKET |
||||
{ |
||||
struct sockaddr_un* un = |
||||
reinterpret_cast<struct sockaddr_un*>(args.address->addr); |
||||
// length of identifier, including null terminator
|
||||
size_t id_length = args.address->len - sizeof(un->sun_family); |
||||
// The c-style string at least will have a null terminator, and the
|
||||
// connection id itself should not be empty
|
||||
GPR_ASSERT(id_length >= 2); |
||||
// Make sure there is null terminator at the expected location before
|
||||
// reading from it
|
||||
GPR_ASSERT(un->sun_path[id_length - 1] == '\0'); |
||||
conn_id_ = un->sun_path; |
||||
} |
||||
#else |
||||
GPR_ASSERT(0); |
||||
#endif |
||||
gpr_log(GPR_ERROR, "conn_id_ = %s", conn_id_.c_str()); |
||||
|
||||
args_ = args; |
||||
GPR_ASSERT(notify_ == nullptr); |
||||
notify_ = notify; |
||||
result_ = result; |
||||
|
||||
Ref().release(); // Ref held by the following callback
|
||||
|
||||
grpc_binder::GetEndpointBinderPool()->GetEndpointBinder( |
||||
conn_id_, |
||||
std::bind(&BinderConnector::OnConnected, this, std::placeholders::_1)); |
||||
} |
||||
|
||||
void OnConnected(std::unique_ptr<grpc_binder::Binder> endpoint_binder) { |
||||
GPR_ASSERT(endpoint_binder != nullptr); |
||||
grpc_transport* transport = grpc_create_binder_transport_client( |
||||
std::move(endpoint_binder), |
||||
grpc_binder::GetSecurityPolicySetting()->Get(conn_id_)); |
||||
GPR_ASSERT(transport != nullptr); |
||||
result_->channel_args = grpc_channel_args_copy(args_.channel_args); |
||||
result_->transport = transport; |
||||
|
||||
grpc_core::ExecCtx::Run(DEBUG_LOCATION, notify_, GRPC_ERROR_NONE); |
||||
|
||||
Unref(); // Was referenced in BinderConnector::Connect
|
||||
} |
||||
void Shutdown(grpc_error_handle error) override { (void)error; } |
||||
|
||||
private: |
||||
Args args_; |
||||
grpc_closure* notify_ = nullptr; |
||||
Result* result_ = nullptr; |
||||
|
||||
std::string conn_id_; |
||||
}; |
||||
|
||||
} // namespace
|
||||
|
||||
namespace grpc_core { |
||||
|
||||
grpc_core::RefCountedPtr<grpc_core::Subchannel> |
||||
BinderClientChannelFactory::CreateSubchannel( |
||||
const grpc_resolved_address& address, const grpc_channel_args* args) { |
||||
gpr_log(GPR_ERROR, "BinderClientChannelFactory::CreateSubchannel called"); |
||||
grpc_arg default_authority_arg = grpc_channel_arg_string_create( |
||||
const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY), |
||||
const_cast<char*>("binder.authority")); |
||||
grpc_channel_args* new_args = |
||||
grpc_channel_args_copy_and_add(args, &default_authority_arg, 1); |
||||
|
||||
grpc_core::RefCountedPtr<grpc_core::Subchannel> s = |
||||
grpc_core::Subchannel::Create( |
||||
grpc_core::MakeOrphanable<BinderConnector>(), address, new_args); |
||||
|
||||
return s; |
||||
} |
||||
|
||||
} // namespace grpc_core
|
@ -0,0 +1,44 @@ |
||||
// Copyright 2021 gRPC authors.
|
||||
//
|
||||
// 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 GRPC_CORE_EXT_TRANSPORT_BINDER_CLIENT_BINDER_CONNECTOR_H |
||||
#define GRPC_CORE_EXT_TRANSPORT_BINDER_CLIENT_BINDER_CONNECTOR_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <memory> |
||||
#include <utility> |
||||
|
||||
#include "absl/strings/string_view.h" |
||||
#include "absl/strings/strip.h" |
||||
|
||||
#include <grpc/impl/codegen/grpc_types.h> |
||||
#include <grpcpp/channel.h> |
||||
#include <grpcpp/support/channel_arguments.h> |
||||
|
||||
#include "src/core/ext/filters/client_channel/client_channel.h" |
||||
#include "src/core/ext/filters/client_channel/client_channel_factory.h" |
||||
|
||||
namespace grpc_core { |
||||
|
||||
class BinderClientChannelFactory : public grpc_core::ClientChannelFactory { |
||||
public: |
||||
grpc_core::RefCountedPtr<grpc_core::Subchannel> CreateSubchannel( |
||||
const grpc_resolved_address& address, |
||||
const grpc_channel_args* args) override; |
||||
}; |
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
#endif // GRPC_CORE_EXT_TRANSPORT_BINDER_CLIENT_BINDER_CONNECTOR_H
|
@ -0,0 +1,42 @@ |
||||
// Copyright 2021 gRPC authors.
|
||||
//
|
||||
// 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 <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/ext/transport/binder/client/security_policy_setting.h" |
||||
|
||||
namespace grpc_binder { |
||||
|
||||
void SecurityPolicySetting::Set( |
||||
absl::string_view connection_id, |
||||
std::shared_ptr<grpc::experimental::binder::SecurityPolicy> |
||||
security_policy) { |
||||
grpc_core::MutexLock l(&m_); |
||||
GPR_ASSERT(security_policy_map_.count(std::string(connection_id)) == 0); |
||||
security_policy_map_[std::string(connection_id)] = security_policy; |
||||
} |
||||
|
||||
std::shared_ptr<grpc::experimental::binder::SecurityPolicy> |
||||
SecurityPolicySetting::Get(absl::string_view connection_id) { |
||||
grpc_core::MutexLock l(&m_); |
||||
GPR_ASSERT(security_policy_map_.count(std::string(connection_id)) != 0); |
||||
return security_policy_map_[std::string(connection_id)]; |
||||
} |
||||
|
||||
SecurityPolicySetting* GetSecurityPolicySetting() { |
||||
static SecurityPolicySetting* s = new SecurityPolicySetting(); |
||||
return s; |
||||
} |
||||
|
||||
} // namespace grpc_binder
|
@ -0,0 +1,50 @@ |
||||
// Copyright 2021 gRPC authors.
|
||||
//
|
||||
// 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 GRPC_CORE_EXT_TRANSPORT_BINDER_CLIENT_SECURITY_POLICY_SETTING_H |
||||
#define GRPC_CORE_EXT_TRANSPORT_BINDER_CLIENT_SECURITY_POLICY_SETTING_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "absl/container/flat_hash_map.h" |
||||
#include "absl/strings/string_view.h" |
||||
|
||||
#include "src/core/ext/transport/binder/security_policy/security_policy.h" |
||||
#include "src/core/lib/gprpp/sync.h" |
||||
|
||||
namespace grpc_binder { |
||||
|
||||
// A singleton class for setting security setting for each connection. This is
|
||||
// required because we cannot pass security policy shared pointers around using
|
||||
// gRPC arguments, we can only pass connection_id around as part of URI
|
||||
class SecurityPolicySetting { |
||||
public: |
||||
void Set(absl::string_view connection_id, |
||||
std::shared_ptr<grpc::experimental::binder::SecurityPolicy> |
||||
security_policy); |
||||
std::shared_ptr<grpc::experimental::binder::SecurityPolicy> Get( |
||||
absl::string_view connection_id); |
||||
|
||||
private: |
||||
grpc_core::Mutex m_; |
||||
absl::flat_hash_map< |
||||
std::string, std::shared_ptr<grpc::experimental::binder::SecurityPolicy>> |
||||
security_policy_map_ ABSL_GUARDED_BY(m_); |
||||
}; |
||||
|
||||
SecurityPolicySetting* GetSecurityPolicySetting(); |
||||
|
||||
} // namespace grpc_binder
|
||||
|
||||
#endif // GRPC_CORE_EXT_TRANSPORT_BINDER_CLIENT_SECURITY_POLICY_SETTING_H
|
Loading…
Reference in new issue