Interface for passing HTTP Responses/Requests to observers

PiperOrigin-RevId: 542402792
This commit is contained in:
Qin Wang
2023-06-21 17:06:23 -07:00
committed by Copybara-Service
parent 4d85bde8ce
commit e4b12dbd80
7 changed files with 646 additions and 0 deletions
+19
View File
@@ -23,3 +23,22 @@ cc_proto_library(
],
deps = [":fastpair_proto"],
)
cc_library(
name = "util",
srcs = [
"proto_to_json.cc",
],
hdrs = [
"proto_to_json.h",
],
compatible_with = ["//buildenv/target:non_prod"],
visibility = ["//visibility:public"],
deps = [
":fastpair_cc_proto",
"//fastpair/common",
"//internal/platform:logging",
"@com_google_absl//absl/strings",
"@nlohmann_json//:json",
],
)
+149
View File
@@ -0,0 +1,149 @@
// Copyright 2023 Google LLC
//
// 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
//
// https://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 "fastpair/proto/proto_to_json.h"
#include <string>
#include <utility>
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"
#include "internal/platform/logging.h"
namespace nearby {
namespace fastpair {
namespace {
using json = ::nlohmann::json;
std::string Encode(absl::string_view str) {
return absl::WebSafeBase64Escape(str);
}
std::string TruncateString(absl::string_view str) {
if (str.length() <= 10) return std::string(str);
return absl::StrCat(str.substr(0, 5), "...",
str.substr(str.length() - 5, str.length()));
}
} // namespace
// GetObservedDeviceRequest/Response
json FastPairProtoToJson(
const nearby::fastpair::proto::GetObservedDeviceRequest& request) {
json dict = json::object();
dict["device_id"] = request.device_id();
dict["mode"] = request.mode();
dict["locale"] = request.locale();
dict["hex_device_id"] = request.hex_device_id();
dict["max_icon_size_pixels"] = request.max_icon_size_pixels();
return dict;
}
json FastPairProtoToJson(
const nearby::fastpair::proto::GetObservedDeviceResponse& response) {
json dict = json::object();
dict["device"] = FastPairProtoToJson(response.device());
dict["observed_device_strings "] = FastPairProtoToJson(response.strings());
return dict;
}
// UserReadDevicesRequest/Response
json FastPairProtoToJson(
const nearby::fastpair::proto::UserReadDevicesRequest& request) {
json dict = json::object();
dict["secondary_id"] = request.secondary_id();
return dict;
}
json FastPairProtoToJson(
const nearby::fastpair::proto::UserReadDevicesResponse& response) {
json dict = json::object();
json fast_pair_info_list = json::array();
for (const auto& fast_pair_info : response.fast_pair_info()) {
fast_pair_info_list.push_back(FastPairProtoToJson(fast_pair_info));
}
dict["fast_pair_info"] = std::move(fast_pair_info_list);
return dict;
}
// UserWriteDeviceRequest
json FastPairProtoToJson(
const nearby::fastpair::proto::UserWriteDeviceRequest& request) {
json dict = json::object();
dict["fast_pair_info"] = FastPairProtoToJson(request.fast_pair_info());
return dict;
}
// UserDeleteDeviceRequest/Response
json FastPairProtoToJson(
const nearby::fastpair::proto::UserDeleteDeviceRequest& request) {
json dict = json::object();
dict["hex_account_key"] = TruncateString(Encode(request.hex_account_key()));
return dict;
}
json FastPairProtoToJson(
const nearby::fastpair::proto::UserDeleteDeviceResponse& response) {
json dict = json::object();
dict["success"] = response.success();
json error_messages = json::array();
for (const auto& error_message : response.error_messages()) {
error_messages.push_back(error_message);
}
dict["error_messages"] = std::move(error_messages);
return dict;
}
json FastPairProtoToJson(
const nearby::fastpair::proto::FastPairInfo& fast_pair_info) {
json dict = json::object();
if (fast_pair_info.has_device()) {
dict["device"] = FastPairProtoToJson(fast_pair_info.device());
} else if (fast_pair_info.has_opt_in_status()) {
dict["opt_in_status"] = fast_pair_info.opt_in_status();
}
return dict;
}
json FastPairProtoToJson(
const nearby::fastpair::proto::FastPairDevice& fast_pair_device) {
json dict = json::object();
dict["account_key"] = TruncateString(Encode(fast_pair_device.account_key()));
return dict;
}
json FastPairProtoToJson(
const nearby::fastpair::proto::ObservedDeviceStrings& strings) {
json dict = json::object();
dict["locale"] = strings.locale();
return dict;
}
json FastPairProtoToJson(const nearby::fastpair::proto::Device& device) {
json dict = json::object();
dict["id"] = device.id();
dict["project_number"] = device.project_number();
dict["notification_type"] = device.notification_type();
dict["image_url"] = device.image_url();
dict["name"] = device.name();
dict["intent_uri"] = device.intent_uri();
dict["ble_tx_power"] = device.ble_tx_power();
dict["trigger_distance"] = device.trigger_distance();
dict["device_type"] = device.device_type();
dict["display_name"] = device.display_name();
return dict;
}
} // namespace fastpair
} // namespace nearby
+62
View File
@@ -0,0 +1,62 @@
// Copyright 2023 Google LLC
//
// 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
//
// https://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 THIRD_PARTY_NEARBY_FASTPAIR_PROTO_PROTO_TO_JSON_H_
#define THIRD_PARTY_NEARBY_FASTPAIR_PROTO_PROTO_TO_JSON_H_
#include "nlohmann/json_fwd.hpp"
#include "fastpair/proto/data.proto.h"
#include "fastpair/proto/fastpair_rpcs.proto.h"
namespace nearby {
namespace fastpair {
// Converts Fast Pair protos to readable, JSON-style dictionaries.
// GetObservedDeviceRequest/Response
nlohmann::json FastPairProtoToJson(
const nearby::fastpair::proto::GetObservedDeviceRequest& request);
nlohmann::json FastPairProtoToJson(
const nearby::fastpair::proto::GetObservedDeviceResponse& response);
// UserReadDevicesRequest/Response
nlohmann::json FastPairProtoToJson(
const nearby::fastpair::proto::UserReadDevicesRequest& request);
nlohmann::json FastPairProtoToJson(
const nearby::fastpair::proto::UserReadDevicesResponse& response);
// UserWriteDeviceRequest
nlohmann::json FastPairProtoToJson(
const nearby::fastpair::proto::UserWriteDeviceRequest& request);
// UserDeleteDeviceRequest/Response
nlohmann::json FastPairProtoToJson(
const nearby::fastpair::proto::UserDeleteDeviceRequest& request);
nlohmann::json FastPairProtoToJson(
const nearby::fastpair::proto::UserDeleteDeviceResponse& response);
nlohmann::json FastPairProtoToJson(
const nearby::fastpair::proto::FastPairInfo& fast_pair_info);
nlohmann::json FastPairProtoToJson(
const nearby::fastpair::proto::FastPairDevice& fast_pair_device);
nlohmann::json FastPairProtoToJson(
const nearby::fastpair::proto::ObservedDeviceStrings& strings);
nlohmann::json FastPairProtoToJson(
const nearby::fastpair::proto::Device& device);
} // namespace fastpair
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_FASTPAIR_PROTO_PROTO_TO_JSON_H_
+22
View File
@@ -17,12 +17,14 @@ licenses(["notice"])
cc_library(
name = "server_access",
srcs = [
"fast_pair_http_notifier.cc",
"fast_pair_metadata_downloader.cc",
"fast_pair_metadata_downloader_impl.cc",
"fast_pair_repository.cc",
"fast_pair_repository_impl.cc",
],
hdrs = [
"fast_pair_http_notifier.h",
"fast_pair_metadata_downloader.h",
"fast_pair_metadata_downloader_impl.h",
"fast_pair_repository.h",
@@ -34,12 +36,15 @@ cc_library(
deps = [
"//fastpair/common",
"//fastpair/proto:fastpair_cc_proto",
"//fastpair/proto:util",
"//fastpair/repository",
"//internal/base",
"//internal/network:nearby_http_client",
"//internal/network:types",
"//internal/platform:logging",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/strings",
"@nlohmann_json//:json",
],
)
@@ -100,3 +105,20 @@ cc_test(
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "fast_pair_http_notifier_test",
srcs = [
"fast_pair_http_notifier_test.cc",
],
copts = [
"-Ithird_party",
],
deps = [
":server_access",
"//internal/platform:types",
"//internal/platform/implementation/g3", # build_cleaner: keep
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_googletest//:gtest_main",
],
)
@@ -0,0 +1,98 @@
// Copyright 2022 Google LLC
//
// 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
//
// https://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 "fastpair/server_access/fast_pair_http_notifier.h"
#include "nlohmann/json.hpp"
#include "fastpair/proto/proto_to_json.h"
#include "internal/platform/logging.h"
namespace nearby {
namespace fastpair {
void FastPairHttpNotifier::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
void FastPairHttpNotifier::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
// Notifies all observers of GetObservedDeviceRequest/Response
void FastPairHttpNotifier::NotifyOfRequest(
const proto::GetObservedDeviceRequest& request) {
NEARBY_LOGS(VERBOSE) << ": GetObservedDeviceRequest="
<< FastPairProtoToJson(request).dump();
for (auto& observer : observers_.GetObservers())
observer->OnGetObservedDeviceRequest(request);
}
void FastPairHttpNotifier::NotifyOfResponse(
const proto::GetObservedDeviceResponse& response) {
NEARBY_LOGS(VERBOSE) << ": GetObservedDeviceResponse="
<< FastPairProtoToJson(response).dump();
for (auto& observer : observers_.GetObservers())
observer->OnGetObservedDeviceResponse(response);
}
// Notifies all observers of UserReadDevicesRequest/Response
void FastPairHttpNotifier::NotifyOfRequest(
const proto::UserReadDevicesRequest& request) {
NEARBY_LOGS(VERBOSE) << ": UserReadDevicesRequest="
<< FastPairProtoToJson(request).dump();
for (auto& observer : observers_.GetObservers())
observer->OnUserReadDevicesRequest(request);
}
void FastPairHttpNotifier::NotifyOfResponse(
const proto::UserReadDevicesResponse& response) {
NEARBY_LOGS(VERBOSE) << ": UserReadDevicesResponse="
<< FastPairProtoToJson(response).dump();
for (auto& observer : observers_.GetObservers())
observer->OnUserReadDevicesResponse(response);
}
// Notifies all observers of UserWriteDeviceRequest/Response
void FastPairHttpNotifier::NotifyOfRequest(
const proto::UserWriteDeviceRequest& request) {
NEARBY_LOGS(VERBOSE) << ": UserWriteDeviceRequest="
<< FastPairProtoToJson(request).dump();
for (auto& observer : observers_.GetObservers())
observer->OnUserWriteDeviceRequest(request);
}
void FastPairHttpNotifier::NotifyOfResponse(
const proto::UserWriteDeviceResponse& response) {
for (auto& observer : observers_.GetObservers())
observer->OnUserWriteDeviceResponse(response);
}
// Notifies all observers of UserDeleteDeviceRequest/Response
void FastPairHttpNotifier::NotifyOfRequest(
const proto::UserDeleteDeviceRequest& request) {
NEARBY_LOGS(VERBOSE) << ": UserDeleteDeviceRequest="
<< FastPairProtoToJson(request).dump();
for (auto& observer : observers_.GetObservers())
observer->OnUserDeleteDeviceRequest(request);
}
void FastPairHttpNotifier::NotifyOfResponse(
const proto::UserDeleteDeviceResponse& response) {
NEARBY_LOGS(VERBOSE) << ": UserDeleteDeviceResponse="
<< FastPairProtoToJson(response).dump();
for (auto& observer : observers_.GetObservers())
observer->OnUserDeleteDeviceResponse(response);
}
} // namespace fastpair
} // namespace nearby
@@ -0,0 +1,87 @@
// Copyright 2022 Google LLC
//
// 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
//
// https://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 THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAST_PAIR_HTTP_NOTIFIER_H_
#define THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAST_PAIR_HTTP_NOTIFIER_H_
#include "fastpair/proto/fastpair_rpcs.proto.h"
#include "internal/base/observer_list.h"
namespace nearby {
namespace fastpair {
// Interface for passing HTTP Responses/Requests to observers, by passing
// instances of this class to each HTTP Client.
class FastPairHttpNotifier {
public:
class Observer {
public:
virtual ~Observer() = default;
// Called when HTTP RPC is made for GetObservedDeviceRequest/Response
virtual void OnGetObservedDeviceRequest(
const proto::GetObservedDeviceRequest& request) = 0;
virtual void OnGetObservedDeviceResponse(
const proto::GetObservedDeviceResponse& response) = 0;
// Called when HTTP RPC is made for UserReadDevicesRequest/Response
virtual void OnUserReadDevicesRequest(
const proto::UserReadDevicesRequest& request) = 0;
virtual void OnUserReadDevicesResponse(
const proto::UserReadDevicesResponse& response) = 0;
// Called when HTTP RPC is made for UserWriteDeviceRequest/Response
virtual void OnUserWriteDeviceRequest(
const proto::UserWriteDeviceRequest& request) = 0;
virtual void OnUserWriteDeviceResponse(
const proto::UserWriteDeviceResponse& response) = 0;
// Called when HTTP RPC is made for UserDeleteDeviceRequest/Response
virtual void OnUserDeleteDeviceRequest(
const proto::UserDeleteDeviceRequest& request) = 0;
virtual void OnUserDeleteDeviceResponse(
const proto::UserDeleteDeviceResponse& response) = 0;
};
FastPairHttpNotifier() = default;
FastPairHttpNotifier(const FastPairHttpNotifier&) = delete;
FastPairHttpNotifier& operator=(const FastPairHttpNotifier&) = delete;
~FastPairHttpNotifier() = default;
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// Notifies all observers of GetObservedDeviceRequest/Response
void NotifyOfRequest(const proto::GetObservedDeviceRequest& request);
void NotifyOfResponse(const proto::GetObservedDeviceResponse& response);
// Notifies all observers of UserReadDevicesRequest/Response
void NotifyOfRequest(const proto::UserReadDevicesRequest& request);
void NotifyOfResponse(const proto::UserReadDevicesResponse& response);
// Notifies all observers of UserWriteDeviceRequest/Response
void NotifyOfRequest(const proto::UserWriteDeviceRequest& request);
void NotifyOfResponse(const proto::UserWriteDeviceResponse& response);
// Notifies all observers of UserDeleteDeviceRequest/Response
void NotifyOfRequest(const proto::UserDeleteDeviceRequest& request);
void NotifyOfResponse(const proto::UserDeleteDeviceResponse& response);
private:
ObserverList<Observer> observers_;
};
} // namespace fastpair
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAST_PAIR_HTTP_NOTIFIER_H_
@@ -0,0 +1,209 @@
// Copyright 2022 Google LLC
//
// 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
//
// https://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 "fastpair/server_access/fast_pair_http_notifier.h"
#include "gtest/gtest.h"
#include "internal/platform/count_down_latch.h"
namespace nearby {
namespace fastpair {
namespace {
class FastPairHttpNotifierObserver : public FastPairHttpNotifier::Observer {
public:
explicit FastPairHttpNotifierObserver(CountDownLatch* latch) {
latch_ = latch;
}
void OnGetObservedDeviceRequest(
const proto::GetObservedDeviceRequest& request) override {
latch_->CountDown();
get_observer_device_request_ =
&const_cast<proto::GetObservedDeviceRequest&>(request);
}
void OnGetObservedDeviceResponse(
const proto::GetObservedDeviceResponse& response) override {
latch_->CountDown();
get_observer_device_response_ =
&const_cast<proto::GetObservedDeviceResponse&>(response);
}
// Called when HTTP RPC is made for UserReadDevicesRequest/Response
void OnUserReadDevicesRequest(
const proto::UserReadDevicesRequest& request) override {
latch_->CountDown();
read_devices_request_ =
&const_cast<proto::UserReadDevicesRequest&>(request);
}
void OnUserReadDevicesResponse(
const proto::UserReadDevicesResponse& response) override {
latch_->CountDown();
read_devices_response_ =
&const_cast<proto::UserReadDevicesResponse&>(response);
}
// Called when HTTP RPC is made for UserWriteDeviceRequest/Response
void OnUserWriteDeviceRequest(
const proto::UserWriteDeviceRequest& request) override {
latch_->CountDown();
write_device_request_ =
&const_cast<proto::UserWriteDeviceRequest&>(request);
}
void OnUserWriteDeviceResponse(
const proto::UserWriteDeviceResponse& response) override {
latch_->CountDown();
write_device_response_ =
&const_cast<proto::UserWriteDeviceResponse&>(response);
}
// Called when HTTP RPC is made for UserDeleteDeviceRequest/Response
void OnUserDeleteDeviceRequest(
const proto::UserDeleteDeviceRequest& request) override {
latch_->CountDown();
delete_device_request_ =
&const_cast<proto::UserDeleteDeviceRequest&>(request);
}
void OnUserDeleteDeviceResponse(
const proto::UserDeleteDeviceResponse& response) override {
latch_->CountDown();
delete_device_response_ =
&const_cast<proto::UserDeleteDeviceResponse&>(response);
}
CountDownLatch* latch_;
proto::GetObservedDeviceRequest* get_observer_device_request_;
proto::GetObservedDeviceResponse* get_observer_device_response_;
proto::UserReadDevicesRequest* read_devices_request_;
proto::UserReadDevicesResponse* read_devices_response_;
proto::UserWriteDeviceRequest* write_device_request_;
proto::UserWriteDeviceResponse* write_device_response_;
proto::UserDeleteDeviceRequest* delete_device_request_;
proto::UserDeleteDeviceResponse* delete_device_response_;
};
TEST(FastPairHttpNotifierTest, TestNotifyGetObservedDeviceRequest) {
proto::GetObservedDeviceRequest request;
int64_t device_id;
CHECK(absl::SimpleHexAtoi("718C17", &device_id));
request.set_device_id(device_id);
request.set_mode(proto::GetObservedDeviceRequest::MODE_RELEASE);
CountDownLatch latch(1);
FastPairHttpNotifierObserver observer(&latch);
FastPairHttpNotifier notifier;
notifier.AddObserver(&observer);
notifier.NotifyOfRequest(request);
latch.Await();
EXPECT_EQ(observer.get_observer_device_request_, &request);
EXPECT_EQ(observer.get_observer_device_request_->device_id(), device_id);
EXPECT_EQ(observer.get_observer_device_request_->mode(),
proto::GetObservedDeviceRequest::MODE_RELEASE);
}
TEST(FastPairHttpNotifierTest, TestNotifyGetObservedDeviceResponse) {
proto::GetObservedDeviceResponse response;
CountDownLatch latch(1);
FastPairHttpNotifierObserver observer(&latch);
FastPairHttpNotifier notifier;
notifier.AddObserver(&observer);
notifier.NotifyOfResponse(response);
latch.Await();
EXPECT_EQ(observer.get_observer_device_response_, &response);
}
TEST(FastPairHttpNotifierTest, TestNotifyUserReadDevicesRequest) {
proto::UserReadDevicesRequest request;
CountDownLatch latch(1);
FastPairHttpNotifierObserver observer(&latch);
FastPairHttpNotifier notifier;
notifier.AddObserver(&observer);
notifier.NotifyOfRequest(request);
latch.Await();
EXPECT_EQ(observer.read_devices_request_, &request);
}
TEST(FastPairHttpNotifierTest, TestNotifyUserReadDevicesResponse) {
proto::UserReadDevicesResponse response;
CountDownLatch latch(1);
FastPairHttpNotifierObserver observer(&latch);
FastPairHttpNotifier notifier;
notifier.AddObserver(&observer);
notifier.NotifyOfResponse(response);
latch.Await();
EXPECT_EQ(observer.read_devices_response_, &response);
}
TEST(FastPairHttpNotifierTest, TestNotifyUserWritedeviceRequest) {
proto::UserWriteDeviceRequest request;
CountDownLatch latch(1);
FastPairHttpNotifierObserver observer(&latch);
FastPairHttpNotifier notifier;
notifier.AddObserver(&observer);
notifier.NotifyOfRequest(request);
latch.Await();
EXPECT_EQ(observer.write_device_request_, &request);
}
TEST(FastPairHttpNotifierTest, TestNotifyUserWriteDeviceResponse) {
proto::UserWriteDeviceResponse response;
CountDownLatch latch(1);
FastPairHttpNotifierObserver observer(&latch);
FastPairHttpNotifier notifier;
notifier.AddObserver(&observer);
notifier.NotifyOfResponse(response);
latch.Await();
EXPECT_EQ(observer.write_device_response_, &response);
}
TEST(FastPairHttpNotifierTest, TestNotifyUserDeleteDeviceRequest) {
proto::UserDeleteDeviceRequest request;
CountDownLatch latch(1);
FastPairHttpNotifierObserver observer(&latch);
FastPairHttpNotifier notifier;
notifier.AddObserver(&observer);
notifier.NotifyOfRequest(request);
latch.Await();
EXPECT_EQ(observer.delete_device_request_, &request);
}
TEST(FastPairHttpNotifierTest, TestNotifyUserDeleteDeviceResponse) {
proto::UserDeleteDeviceResponse response;
CountDownLatch latch(1);
FastPairHttpNotifierObserver observer(&latch);
FastPairHttpNotifier notifier;
notifier.AddObserver(&observer);
notifier.NotifyOfResponse(response);
latch.Await();
EXPECT_EQ(observer.delete_device_response_, &response);
}
} // namespace
} // namespace fastpair
} // namespace nearby