Skip to content

Commit

Permalink
feat(bigtable): instance name as a class
Browse files Browse the repository at this point in the history
  • Loading branch information
dbolduc committed Jun 28, 2022
1 parent f91081c commit ea68ba1
Show file tree
Hide file tree
Showing 6 changed files with 234 additions and 0 deletions.
3 changes: 3 additions & 0 deletions google/cloud/bigtable/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ add_library(
instance_config.cc
instance_config.h
instance_list_responses.h
instance_resource.cc
instance_resource.h
instance_update_config.cc
instance_update_config.h
internal/admin_client_params.cc
Expand Down Expand Up @@ -334,6 +336,7 @@ if (BUILD_TESTING)
instance_admin_client_test.cc
instance_admin_test.cc
instance_config_test.cc
instance_resource_test.cc
instance_update_config_test.cc
internal/admin_client_params_test.cc
internal/async_bulk_apply_test.cc
Expand Down
1 change: 1 addition & 0 deletions google/cloud/bigtable/bigtable_client_unit_tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ bigtable_client_unit_tests = [
"iam_binding_test.cc",
"iam_policy_test.cc",
"idempotent_mutation_policy_test.cc",
"instance_resource_test.cc",
"instance_admin_client_test.cc",
"instance_admin_test.cc",
"instance_config_test.cc",
Expand Down
2 changes: 2 additions & 0 deletions google/cloud/bigtable/google_cloud_cpp_bigtable.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ google_cloud_cpp_bigtable_hdrs = [
"iam_binding.h",
"iam_policy.h",
"idempotent_mutation_policy.h",
"instance_resource.h",
"instance_admin.h",
"instance_admin_client.h",
"instance_config.h",
Expand Down Expand Up @@ -150,6 +151,7 @@ google_cloud_cpp_bigtable_srcs = [
"iam_binding.cc",
"iam_policy.cc",
"idempotent_mutation_policy.cc",
"instance_resource.cc",
"instance_admin.cc",
"instance_admin_client.cc",
"instance_config.cc",
Expand Down
57 changes: 57 additions & 0 deletions google/cloud/bigtable/instance_resource.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// 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 "google/cloud/bigtable/instance_resource.h"
#include <ostream>
#include <regex>

namespace google {
namespace cloud {
namespace bigtable {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN

InstanceResource::InstanceResource(Project project, std::string instance_id)
: project_(std::move(project)), instance_id_(std::move(instance_id)) {}

std::string InstanceResource::FullName() const {
return project_.FullName() + "/instances/" + instance_id_;
}

bool operator==(InstanceResource const& a, InstanceResource const& b) {
return a.project_ == b.project_ && a.instance_id_ == b.instance_id_;
}

bool operator!=(InstanceResource const& a, InstanceResource const& b) {
return !(a == b);
}

std::ostream& operator<<(std::ostream& os, InstanceResource const& in) {
return os << in.FullName();
}

StatusOr<InstanceResource> MakeInstanceResource(std::string const& full_name) {
std::regex re("projects/([^/]+)/instances/([^/]+)");
std::smatch matches;
if (!std::regex_match(full_name, matches, re)) {
return Status(StatusCode::kInvalidArgument,
"Improperly formatted InstanceResource: " + full_name);
}
return InstanceResource(Project(std::move(matches[1])),
std::move(matches[2]));
}

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace bigtable
} // namespace cloud
} // namespace google
86 changes: 86 additions & 0 deletions google/cloud/bigtable/instance_resource.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// 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 GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_INSTANCE_RESOURCE_H
#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_INSTANCE_RESOURCE_H

#include "google/cloud/bigtable/version.h"
#include "google/cloud/project.h"
#include "google/cloud/status_or.h"
#include <iosfwd>
#include <string>

namespace google {
namespace cloud {
namespace bigtable {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN

/**
* This class identifies a Cloud Bigtable Instance.
*
* A Cloud Bigtable instance is identified by its `project_id` and
* `instance_id`.
*
* @note This class makes no effort to validate the components of the
* database name. It is the application's responsibility to provide valid
* project, and instance ids. Passing invalid values will not be checked
* until the instance name is used in an RPC to Bigtable.
*/
class InstanceResource {
public:
/**
* Constructs an InstanceResource object identified by the given @p project
* and @p instance_id.
*/
InstanceResource(Project project, std::string instance_id);

/// Returns the `Project` containing this instance.
Project const& project() const { return project_; }
std::string const& project_id() const { return project_.project_id(); }

/// Returns the Instance ID.
std::string const& instance_id() const { return instance_id_; }

/**
* Returns the fully qualified instance name as a string of the form:
* "projects/<project-id>/instances/<instance-id>"
*/
std::string FullName() const;

/// @name Equality operators
//@{
friend bool operator==(InstanceResource const& a, InstanceResource const& b);
friend bool operator!=(InstanceResource const& a, InstanceResource const& b);
//@}

/// Output the `FullName()` format.
friend std::ostream& operator<<(std::ostream&, InstanceResource const&);

private:
Project project_;
std::string instance_id_;
};

/**
* Constructs an `InstanceResource` from the given @p full_name.
* Returns a non-OK Status if `full_name` is improperly formed.
*/
StatusOr<InstanceResource> MakeInstanceResource(std::string const& full_name);

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace bigtable
} // namespace cloud
} // namespace google

#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_INSTANCE_RESOURCE_H
85 changes: 85 additions & 0 deletions google/cloud/bigtable/instance_resource_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// 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 "google/cloud/bigtable/instance_resource.h"
#include "google/cloud/testing_util/status_matchers.h"
#include <gmock/gmock.h>
#include <sstream>
#include <string>

namespace google {
namespace cloud {
namespace bigtable {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
namespace {

using ::google::cloud::testing_util::StatusIs;

TEST(InstanceResource, Basics) {
InstanceResource in(Project("p1"), "i1");
EXPECT_EQ("p1", in.project_id());
EXPECT_EQ("i1", in.instance_id());
EXPECT_EQ("projects/p1/instances/i1", in.FullName());

auto copy = in;
EXPECT_EQ(copy, in);
EXPECT_EQ("p1", copy.project_id());
EXPECT_EQ("i1", copy.instance_id());
EXPECT_EQ("projects/p1/instances/i1", copy.FullName());

auto moved = std::move(copy);
EXPECT_EQ(moved, in);
EXPECT_EQ("p1", moved.project_id());
EXPECT_EQ("i1", moved.instance_id());
EXPECT_EQ("projects/p1/instances/i1", moved.FullName());

InstanceResource in2(Project("p2"), "i2");
EXPECT_NE(in2, in);
EXPECT_EQ("p2", in2.project_id());
EXPECT_EQ("i2", in2.instance_id());
EXPECT_EQ("projects/p2/instances/i2", in2.FullName());
}

TEST(InstanceResource, OutputStream) {
InstanceResource in(Project("p1"), "i1");
std::ostringstream os;
os << in;
EXPECT_EQ("projects/p1/instances/i1", os.str());
}

TEST(InstanceResource, MakeInstanceResource) {
auto in = InstanceResource(Project("p1"), "i1");
EXPECT_EQ(in, MakeInstanceResource(in.FullName()).value());

for (std::string invalid : {
"",
"projects/",
"projects/p1",
"projects/p1/instances/",
"/projects/p1/instances/i1",
"projects/p1/instances/i1/",
"projects/p1/instances/i1/etc",
}) {
auto in = MakeInstanceResource(invalid);
EXPECT_THAT(in,
StatusIs(StatusCode::kInvalidArgument,
"Improperly formatted InstanceResource: " + invalid));
}
}

} // namespace
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace bigtable
} // namespace cloud
} // namespace google

0 comments on commit ea68ba1

Please sign in to comment.