Skip to content

gRPC: add gRPC wrapper classes to CMake build #2015

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 82 commits into from
Nov 5, 2018
Merged
Show file tree
Hide file tree
Changes from 75 commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
ce6949c
lint
var-const Oct 9, 2018
f6f3f84
small fixes
var-const Oct 9, 2018
282009c
Add grpc_connection_test
var-const Oct 9, 2018
635c473
Missed test cases
var-const Oct 9, 2018
59f070c
Review feedback
var-const Oct 10, 2018
3139cb4
Forgotten files
var-const Oct 11, 2018
7170b70
linter
var-const Oct 11, 2018
a0f061f
Remove unnecessary split
var-const Oct 11, 2018
5bfc05b
quick fix
var-const Oct 11, 2018
1d38fb1
Initial
var-const Oct 11, 2018
dd3d10c
Delete some of the more excessive tests
var-const Oct 12, 2018
23070bb
Fix bug in WriteAndFinish
var-const Oct 12, 2018
9dca0f9
Merge branch 'varconst/grpc-unit-tests-wrappers' into varconst/grpc-u…
var-const Oct 12, 2018
928953a
compiles
var-const Oct 12, 2018
29e726c
Merge branch 'master' into varconst/grpc-unit-tests-domain
var-const Oct 12, 2018
40b6260
linter
var-const Oct 12, 2018
7a86c73
Merge branch 'master' into varconst/grpc-unit-tests-domain
var-const Oct 12, 2018
4c57926
Simple test fixes
var-const Oct 12, 2018
c4e01a6
Initial -- does not work yet
var-const Oct 13, 2018
289df14
forgotten file
var-const Oct 15, 2018
63f5146
proof of concept -- does not work
var-const Oct 15, 2018
805b673
gRPC: add support for SSL disabled to `GrpcConnection`.
var-const Oct 18, 2018
839f408
gRPC: make gRPC calls using the C++ implementation:
var-const Oct 18, 2018
a93b783
C++: port `MockWatchStream` and `MockWriteStream` to C++.
var-const Oct 18, 2018
4fe32a1
No longer generate Objective-C gRPC service definitions from protos.
var-const Oct 18, 2018
0ea6fcc
Remove all references to Objective-C gRPC client.
var-const Oct 18, 2018
21d30b6
Use local certificate for now
var-const Oct 22, 2018
7f60ad0
Fix/improve ASCII conversion
var-const Oct 22, 2018
feb0285
Review feedback
var-const Oct 22, 2018
8332a5f
style.sh
var-const Oct 22, 2018
ab6df2e
Appease linter
var-const Oct 22, 2018
9f9d94d
Undo accidental change
var-const Oct 22, 2018
555e1d8
missing word
var-const Oct 22, 2018
6f0d4e6
add comment
var-const Oct 22, 2018
84e454b
Remove leftover reference to Objective-C gRPC
var-const Oct 22, 2018
c96f670
More using declarations
var-const Oct 22, 2018
e2e53b0
typo
var-const Oct 22, 2018
1bcfc0f
Use Path instead of plain string
var-const Oct 22, 2018
2d68f12
Missed include
var-const Oct 22, 2018
80a938e
Remove redundant word
var-const Oct 22, 2018
85b6570
Merge branch 'varconst/grpc-integr82' into varconst/grpc-cmake
var-const Oct 22, 2018
1cd2950
External depends
var-const Oct 23, 2018
9ede2b0
remove test func
var-const Oct 23, 2018
0cbae74
Add src files to CMake
var-const Oct 23, 2018
761b26d
Tests wip
var-const Oct 23, 2018
25a4130
test wip
var-const Oct 24, 2018
2786250
fix dependency name
var-const Oct 24, 2018
8934b7a
foreach
var-const Oct 24, 2018
3dd4c4a
Hacks to make it compile
var-const Oct 24, 2018
21d95ee
wip
var-const Oct 24, 2018
4fbfcd3
forgotten file
var-const Oct 24, 2018
b8edd81
very wip, but works
var-const Oct 25, 2018
aeb4e57
Remove problematic test
var-const Oct 25, 2018
116b95e
wip
var-const Oct 25, 2018
97a5ef6
stash
var-const Oct 26, 2018
87ae3ae
Sort of works
var-const Oct 26, 2018
5ee93e8
comment
var-const Oct 26, 2018
22efcfd
Merge branch 'master' into varconst/grpc-cmake
var-const Oct 26, 2018
de56f42
remove extra file
var-const Oct 26, 2018
2c0b555
cleanup wip
var-const Oct 26, 2018
3d4356f
Cleanup wip
var-const Oct 26, 2018
a1883c6
Restore how version is defined
var-const Oct 26, 2018
9c9988b
move comment
var-const Oct 26, 2018
3d5af99
Appease linter
var-const Oct 26, 2018
48a2eb7
Appease linter
var-const Oct 26, 2018
3b789d5
Review feedback wip
var-const Oct 28, 2018
00af67c
Review feedback
var-const Oct 28, 2018
8120e41
wip
var-const Oct 30, 2018
f76027a
wip
var-const Oct 31, 2018
5c07da4
Fix variable problem
var-const Oct 31, 2018
640284e
wip
var-const Oct 31, 2018
090bd08
Initial
var-const Nov 1, 2018
9408698
Comment
var-const Nov 1, 2018
45a8826
Quick fix
var-const Nov 2, 2018
3e4e9a2
Newline
var-const Nov 2, 2018
80fd42c
Fix XCode build
var-const Nov 2, 2018
9c33561
style.sh
var-const Nov 2, 2018
5a1324d
Review feedback
var-const Nov 2, 2018
69db1e0
Fix unit tests which relied on the old finish logic
var-const Nov 5, 2018
8a54cc7
Refix
var-const Nov 5, 2018
45ff81c
Merge branch 'varconst/grpc-master' into varconst/grpc-cmake
var-const Nov 5, 2018
64e9b59
Merge branch 'grpc-master' into varconst/grpc-cmake
var-const Nov 5, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ set(
CACHE PATH "Where to store downloaded files"
)

set(
FIREBASE_EXTERNAL_SOURCE_DIR
${FIREBASE_BINARY_DIR}/external/src
CACHE PATH "Root directory of source code of the external dependencies"
)

download_external_sources()


Expand Down Expand Up @@ -103,8 +109,6 @@ set(gRPC_BUILD_TESTS OFF CACHE BOOL "Disable gRPC tests")
add_external_subdirectory(grpc)

# Fix up targets included by gRPC's build
set(external_src_dir ${FIREBASE_BINARY_DIR}/external/src)

if(OPENSSL_FOUND)
# gRPC's CMakeLists.txt does not account for finding OpenSSL in a directory
# that's not in the default search path.
Expand All @@ -127,14 +131,14 @@ else()
target_include_directories(
crypto
INTERFACE
$<BUILD_INTERFACE:${external_src_dir}/grpc/third_party/boringssl/include>
$<BUILD_INTERFACE:${FIREBASE_EXTERNAL_SOURCE_DIR}/grpc/third_party/boringssl/include>
)

add_alias(OpenSSL::SSL ssl)
target_include_directories(
ssl
INTERFACE
$<BUILD_INTERFACE:${external_src_dir}/grpc/third_party/boringssl/include>
$<BUILD_INTERFACE:${FIREBASE_EXTERNAL_SOURCE_DIR}/grpc/third_party/boringssl/include>
)
endif()

Expand All @@ -156,7 +160,7 @@ endif()
if(NOT ZLIB_FOUND)
target_include_directories(
zlibstatic
INTERFACE $<BUILD_INTERFACE:${external_src_dir}/grpc/third_party/zlib>
INTERFACE $<BUILD_INTERFACE:${FIREBASE_EXTERNAL_SOURCE_DIR}/grpc/third_party/zlib>
)
endif()

Expand Down Expand Up @@ -186,7 +190,7 @@ target_compile_definitions(

target_include_directories(
protobuf-nanopb
INTERFACE $<BUILD_INTERFACE:${external_src_dir}/nanopb>
INTERFACE $<BUILD_INTERFACE:${FIREBASE_EXTERNAL_SOURCE_DIR}/nanopb>
)


Expand Down
1 change: 1 addition & 0 deletions FirebaseFirestore.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Google Cloud Firestore is a NoSQL document database built for automatic scaling,

# Exclude alternate implementations for other platforms
'Firestore/core/src/firebase/firestore/remote/connectivity_monitor_noop.cc',
'Firestore/core/src/firebase/firestore/remote/grpc_root_certificate_finder_generated.cc',
'Firestore/core/src/firebase/firestore/util/filesystem_win.cc',
'Firestore/core/src/firebase/firestore/util/hard_assert_stdio.cc',
'Firestore/core/src/firebase/firestore/util/log_stdio.cc',
Expand Down
15 changes: 5 additions & 10 deletions Firestore/Source/API/FIRFirestoreVersion.mm
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,11 @@

#import "Firestore/Source/API/FIRFirestoreVersion.h"

#ifndef FIRFirestore_VERSION
#error "FIRFirestore_VERSION is not defined: add -DFIRFirestore_VERSION=... to the build invocation"
#endif
#include "Firestore/core/include/firebase/firestore/firestore_version.h"

// The following two macros supply the incantation so that the C
// preprocessor does not try to parse the version as a floating
// point number. See
// https://www.guyrutenberg.com/2008/12/20/expanding-macros-into-string-constants-in-c/
#define STR(x) STR_EXPAND(x)
#define STR_EXPAND(x) #x
using firebase::firestore::kFirestoreVersionString;

// Because `kFirestoreVersionString` is subject to constant initialization, this
// is not affected by static initialization order fiasco.
extern "C" const unsigned char *const FIRFirestoreVersionString =
(const unsigned char *const)STR(FIRFirestore_VERSION);
(const unsigned char *const)kFirestoreVersionString;
31 changes: 31 additions & 0 deletions Firestore/core/include/firebase/firestore/firestore_version.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2018 Google
*
* 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 FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_FIRESTORE_VERSION_H_
#define FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_FIRESTORE_VERSION_H_

/** Version for Firestore. */

namespace firebase {
namespace firestore {

/** Version string for the Firebase Firestore SDK. */
extern const char* const kFirestoreVersionString;

} // namespace firestore
} // namespace firebase

#endif // FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_FIRESTORE_VERSION_H_
12 changes: 12 additions & 0 deletions Firestore/core/src/firebase/firestore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ cc_library(
firebase_firestore_util
)

cc_library(
firebase_firestore_version
SOURCES
firestore_version.cc
)

target_compile_definitions(
firebase_firestore_version
PRIVATE
FIRFirestore_VERSION=0.13.6
)

# Include the folder with public headers.
target_include_directories(
firebase_firestore_types
Expand Down
37 changes: 37 additions & 0 deletions Firestore/core/src/firebase/firestore/firestore_version.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2018 Google
*
* 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 "Firestore/core/include/firebase/firestore/firestore_version.h"

#ifndef FIRFirestore_VERSION
#error \
"FIRFirestore_VERSION is not defined: add -DFIRFirestore_VERSION=... to the build invocation" // NOLINT(whitespace/line_length)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively to the // NOLINT at the end of an already long line, you could instead use // NOLINTNEXTLINE on the previous line instead. (https://engdoc.corp.google.com/eng/doc/devguide/cpp/styleguide.md#cpplint)

Optional.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The combination fo the comment with line continuation confuses clang-format (tried both // and /**/ comment styles).

#endif

namespace firebase {
namespace firestore {

// The following two macros supply the incantation so that the C
// preprocessor does not try to parse the version as a floating
// point number. See
// https://www.guyrutenberg.com/2008/12/20/expanding-macros-into-string-constants-in-c/
#define STR(x) STR_EXPAND(x)
#define STR_EXPAND(x) #x

const char* const kFirestoreVersionString = STR(FIRFirestore_VERSION);

} // namespace firestore
} // namespace firebase
57 changes: 53 additions & 4 deletions Firestore/core/src/firebase/firestore/remote/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,62 @@ cc_select(
DEFAULT firebase_firestore_remote_connectivity_monitor_noop
)

# `roots.pem` is a file containing root certificates that is distributed
# alongside gRPC and is necessary to establish SSL connections. Embed this file
# into the binary by converting it to a char array.
add_custom_command(
OUTPUT grpc_root_certificates_generated.h grpc_root_certificates_generated.cc
COMMAND ${FIREBASE_SOURCE_DIR}/scripts/binary_to_array.py
--output_header=grpc_root_certificates_generated.h
--output_source=grpc_root_certificates_generated.cc
--cpp_namespace=firebase::firestore::remote
--array=grpc_root_certificates
--array_size=grpc_root_certificates_size
${FIREBASE_EXTERNAL_SOURCE_DIR}/grpc/etc/roots.pem
DEPENDS
${FIREBASE_EXTERNAL_SOURCE_DIR}/grpc/etc/roots.pem
)

cc_library(
firebase_firestore_remote
SOURCES
grpc_util.h
grpc_util.cc
exponential_backoff.h
exponential_backoff.cc
exponential_backoff.h
grpc_call.h
grpc_completion.cc
grpc_completion.h
grpc_connection.cc
grpc_connection.h
grpc_root_certificate_finder.h
grpc_root_certificate_finder_generated.cc
grpc_root_certificates_generated.cc
grpc_root_certificates_generated.h
grpc_stream.cc
grpc_stream.h
grpc_stream_observer.h
grpc_streaming_reader.cc
grpc_streaming_reader.h
grpc_unary_call.cc
grpc_unary_call.h
grpc_util.cc
grpc_util.cc
grpc_util.h
serializer.h
serializer.cc

# TODO(varconst): add these files once they no longer depend on Objective-C
# serializer.
# datastore.h
# datastore.mm
# remote_objc_bridge.h
# remote_objc_bridge.mm
# stream.h
# stream.mm
# watch_stream.h
# watch_stream.mm
# write_stream.h
# write_stream.mm

DEPENDS
# TODO(b/111328563) Force nanopb first to work around ODR violations
protobuf-nanopb
Expand All @@ -60,5 +107,7 @@ cc_library(
firebase_firestore_protos_nanopb
firebase_firestore_remote_connectivity_monitor
firebase_firestore_util
grpc
firebase_firestore_version

grpc++
)
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,21 @@
#include "Firestore/core/src/firebase/firestore/remote/grpc_connection.h"

#include <algorithm>
#include <fstream>
#include <sstream>
#include <string>
#include <utility>

#include "Firestore/core/include/firebase/firestore/firestore_errors.h"
#include "Firestore/core/include/firebase/firestore/firestore_version.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect you can drop the fstream/sstream includes now.

#include "Firestore/core/src/firebase/firestore/auth/token.h"
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
#include "Firestore/core/src/firebase/firestore/remote/grpc_root_certificate_finder.h"
#include "Firestore/core/src/firebase/firestore/util/filesystem.h"
#include "Firestore/core/src/firebase/firestore/util/hard_assert.h"
#include "Firestore/core/src/firebase/firestore/util/log.h"
#include "Firestore/core/src/firebase/firestore/util/string_format.h"
#include "absl/memory/memory.h"
#include "grpcpp/create_channel.h"

#import "Firestore/Source/API/FIRFirestoreVersion.h"

namespace firebase {
namespace firestore {
namespace remote {
Expand All @@ -43,6 +41,7 @@
using model::DatabaseId;
using util::Path;
using util::Status;
using util::StatusOr;
using util::StringFormat;

namespace {
Expand All @@ -54,22 +53,10 @@
return view.data() ? std::string{view.data(), view.size()} : std::string{};
}

std::string LoadCertificate(const Path& path) {
std::ifstream certificate_file{path.native_value()};
HARD_ASSERT(certificate_file.good(),
StringFormat("Unable to open root certificates at file path %s",
path.ToUtf8String())
.c_str());

std::stringstream buffer;
buffer << certificate_file.rdbuf();
return buffer.str();
}

std::shared_ptr<grpc::ChannelCredentials> CreateSslCredentials(
const Path& certificate_path) {
const std::string& certificate) {
grpc::SslCredentialsOptions options;
options.pem_root_certs = LoadCertificate(certificate_path);
options.pem_root_certs = certificate;
return grpc::SslCredentials(options);
}

Expand Down Expand Up @@ -132,8 +119,7 @@ bool HasSpecialConfig(const std::string& host) {
// C++ SDK, etc.).
context->AddMetadata(
kXGoogAPIClientHeader,
StringFormat("gl-objc/ fire/%s grpc/",
reinterpret_cast<const char*>(FIRFirestoreVersionString)));
StringFormat("gl-objc/ fire/%s grpc/", kFirestoreVersionString));

// This header is used to improve routing and project isolation by the
// backend.
Expand All @@ -159,9 +145,8 @@ bool HasSpecialConfig(const std::string& host) {
const std::string& host = database_info_->host();

if (!HasSpecialConfig(host)) {
Path root_certificate_path = FindGrpcRootCertificate();
return grpc::CreateChannel(host,
CreateSslCredentials(root_certificate_path));
std::string root_certificate = LoadGrpcRootCertificate();
return grpc::CreateChannel(host, CreateSslCredentials(root_certificate));
}

const HostConfig& host_config = Config()[host];
Expand All @@ -174,8 +159,15 @@ bool HasSpecialConfig(const std::string& host) {
// For tests only
grpc::ChannelArguments args;
args.SetSslTargetNameOverride(host_config.target_name);
Path path = host_config.certificate_path;
StatusOr<std::string> test_certificate = ReadFile(path);
HARD_ASSERT(test_certificate.ok(),
StringFormat("Unable to open root certificates at file path %s",
path.ToUtf8String())
.c_str());

return grpc::CreateCustomChannel(
host, CreateSslCredentials(host_config.certificate_path), args);
host, CreateSslCredentials(test_certificate.ValueOrDie()), args);
}

std::unique_ptr<GrpcStream> GrpcConnection::CreateStream(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ namespace firestore {
namespace remote {

/**
* Finds the file containing gRPC root certificates (`roots.pem`, must be among
* resources accessible by Firestore) and returns its path. Will trigger
* assertion failure if the file cannot be found.
* Finds the file containing gRPC root certificates (how it is stored differs by
* platform) and returns its contents as a string. Will trigger assertion
* failure if the file cannot be found or open.
*/
util::Path FindGrpcRootCertificate();
std::string LoadGrpcRootCertificate();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the assumption made by the previous interface that roots.pem must exist as a file was too restrictive.


} // namespace remote
} // namespace firestore
Expand Down
Loading