Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0564462
Point to googleapi in service control client. (#91)
chowchow316 Feb 14, 2017
7c86530
Merge latest changes from master (#104)
mangchiandjjoe Feb 16, 2017
2f7b296
Extract quota config from service config. (#101)
chowchow316 Feb 17, 2017
577dbd7
Update latest update from master branch (#106)
mangchiandjjoe Feb 17, 2017
c5b9b81
Added quota contoll without the service control client library (#93)
mangchiandjjoe Feb 17, 2017
6c3014d
Add unit test for quota config. (#108)
chowchow316 Feb 21, 2017
a27749c
Merge latest changes from master branch (#112)
mangchiandjjoe Feb 22, 2017
5b25d57
If QuotaControl service is not available, return utils::Status::OK (#…
mangchiandjjoe Feb 22, 2017
0d04d7a
Return HTTP status code 429 on google.rpc.Code.RESOURCE_EXHAUSTED (#119)
mangchiandjjoe Feb 22, 2017
5d47547
Resolved conflicts
mangchiandjjoe Feb 23, 2017
acd5c35
Merge branch 'master' into rate_limiting
mangchiandjjoe Feb 23, 2017
d412726
Fixed incorrectly resolved conflicts (#123)
mangchiandjjoe Feb 23, 2017
1031393
Added unit test cases for rate limiting (#124)
mangchiandjjoe Feb 24, 2017
ee657a9
Rename response.http.code (#125) (#128)
mangchiandjjoe Feb 24, 2017
f0d91dc
Added handling of error code QUOTA_SYSTEM_UNAVAILABLE (#148)
mangchiandjjoe Mar 6, 2017
3699b46
Integrated service control client library with quota cache aggregatio…
mangchiandjjoe Mar 7, 2017
291a907
Resolved conflicts
mangchiandjjoe Mar 7, 2017
b35f641
Merge branch 'master' into rate_limiting
mangchiandjjoe Mar 7, 2017
9efd2b3
Fixed error on merge (#151)
mangchiandjjoe Mar 7, 2017
cafe153
Fixed the compatibility issue with the latest update on esp (#152)
mangchiandjjoe Mar 7, 2017
484475d
Removed copied proto files (#208)
mangchiandjjoe Mar 31, 2017
9228d89
Set default allocate quota request timeout to 1sec and applied latest…
mangchiandjjoe Mar 31, 2017
495ed68
Merged key_restriction related changes from master (#213)
mangchiandjjoe Mar 31, 2017
d63d7d0
Merge latest changes from master branch (#217)
mangchiandjjoe Apr 3, 2017
09a034a
Updated the commit id of cloudendpoints/service-control-client-cxx (#…
mangchiandjjoe Apr 4, 2017
7ce2e43
Update commitid of cloudendpoints/service-control-client-cxx repo (#220)
mangchiandjjoe Apr 6, 2017
e01bc97
Resolved conflicts
mangchiandjjoe Apr 6, 2017
50fdfaa
Merge branch 'master' into rate_limiting
lizan Apr 7, 2017
58fdcd7
Merge branch 'master' into rate_limiting
lizan Apr 7, 2017
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
4 changes: 4 additions & 0 deletions contrib/endpoints/include/api_manager/method.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ class MethodInfo {

// Get the names of url system parameters
virtual const std::set<std::string> &system_query_parameter_names() const = 0;

// Get quota metric cost vector
virtual const std::vector<std::pair<std::string, int>> &metric_cost_vector()
const = 0;
};

} // namespace api_manager
Expand Down
22 changes: 15 additions & 7 deletions contrib/endpoints/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,9 @@ def googleapis_repositories(protobuf_repo="@protobuf_git//", bind=True):
#
################################################################################
#

licenses(["notice"])

load("{}:protobuf.bzl", "cc_proto_library")

exports_files(glob(["google/**"]))
load("@protobuf_git//:protobuf.bzl", "cc_proto_library")

cc_proto_library(
name = "servicecontrol",
Expand Down Expand Up @@ -259,9 +256,13 @@ cc_proto_library(
"google/api/log.proto",
"google/api/logging.proto",
"google/api/metric.proto",
"google/api/experimental/experimental.proto",
"google/api/experimental/authorization_config.proto",
"google/api/monitored_resource.proto",
"google/api/monitoring.proto",
"google/api/quota.proto",
"google/api/service.proto",
"google/api/source_info.proto",
"google/api/system_parameter.proto",
"google/api/usage.proto",
],
Expand Down Expand Up @@ -290,10 +291,9 @@ cc_proto_library(
)
""".format(protobuf_repo)


native.new_git_repository(
name = "googleapis_git",
commit = "db1d4547dc56a798915e0eb2c795585385922165",
commit = "2fe0050bd2a6d4c6ba798c0311f0b149b8997314",
remote = "https://github.com/googleapis/googleapis.git",
build_file_content = BUILD,
)
Expand Down Expand Up @@ -324,7 +324,7 @@ def servicecontrol_client_repositories(bind=True):

native.git_repository(
name = "servicecontrol_client_git",
commit = "d739d755365c6a13d0b4164506fd593f53932f5d",
commit = "3d1a30d9221e700542eeaaf20eab69faddb63894",
remote = "https://github.com/cloudendpoints/service-control-client-cxx.git",
)

Expand All @@ -333,3 +333,11 @@ def servicecontrol_client_repositories(bind=True):
name = "servicecontrol_client",
actual = "@servicecontrol_client_git//:service_control_client_lib",
)
native.bind(
name = "quotacontrol",
actual = "@servicecontrol_client_git//proto:quotacontrol",
)
native.bind(
name = "quotacontrol_genproto",
actual = "@servicecontrol_client_git//proto:quotacontrol_genproto",
)
2 changes: 2 additions & 0 deletions contrib/endpoints/src/api_manager/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ cc_library(
"method_impl.cc",
"path_matcher.cc",
"path_matcher_node.cc",
"quota_control.cc",
"quota_control.h",
"request_handler.cc",
],
linkopts = select({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class ServiceAccountToken {
enum JWT_TOKEN_TYPE {
JWT_TOKEN_FOR_SERVICE_CONTROL = 0,
JWT_TOKEN_FOR_CLOUD_TRACING,
JWT_TOKEN_FOR_QUOTA_CONTROL,
JWT_TOKEN_TYPE_MAX,
};
// Set audience. Only calcualtes JWT token with specified audience.
Expand Down
3 changes: 3 additions & 0 deletions contrib/endpoints/src/api_manager/check_workflow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "contrib/endpoints/src/api_manager/check_auth.h"
#include "contrib/endpoints/src/api_manager/check_service_control.h"
#include "contrib/endpoints/src/api_manager/fetch_metadata.h"
#include "contrib/endpoints/src/api_manager/quota_control.h"

using ::google::api_manager::utils::Status;

Expand All @@ -33,6 +34,8 @@ void CheckWorkflow::RegisterAll() {
Register(CheckAuth);
// Checks service control.
Register(CheckServiceControl);
// Quota control
Register(QuotaControl);
}

void CheckWorkflow::Register(CheckHandler handler) {
Expand Down
20 changes: 20 additions & 0 deletions contrib/endpoints/src/api_manager/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,23 @@ MethodInfoImpl *Config::GetOrCreateMethodInfoImpl(const string &name,
return i->second.get();
}

bool Config::LoadQuotaRule(ApiManagerEnvInterface *env) {
for (const auto &rule : service_.quota().metric_rules()) {
auto method = utils::FindOrNull(method_map_, rule.selector());
if (method) {
for (auto &metric_cost : rule.metric_costs()) {
(*method)->add_metric_cost(metric_cost.first, metric_cost.second);
}
} else {
env->LogError("Metric rule with selector " + rule.selector() +
"is mismatched.");
return false;
}
}

return true;
}

bool Config::LoadHttpMethods(ApiManagerEnvInterface *env,
PathMatcherBuilder *pmb) {
std::set<std::string> all_urls, urls_with_options;
Expand Down Expand Up @@ -443,6 +460,9 @@ std::unique_ptr<Config> Config::Create(ApiManagerEnvInterface *env,
if (!config->LoadBackends(env)) {
return nullptr;
}
if (!config->LoadQuotaRule(env)) {
return nullptr;
}
return config;
}

Expand Down
3 changes: 3 additions & 0 deletions contrib/endpoints/src/api_manager/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "contrib/endpoints/src/api_manager/method_impl.h"
#include "contrib/endpoints/src/api_manager/path_matcher.h"
#include "contrib/endpoints/src/api_manager/proto/server_config.pb.h"
#include "google/api/quota.pb.h"
#include "google/api/service.pb.h"

namespace google {
Expand Down Expand Up @@ -111,6 +112,8 @@ class Config {
// Load SystemParameters info to MethodInfo.
bool LoadSystemParameters(ApiManagerEnvInterface *env);

bool LoadQuotaRule(ApiManagerEnvInterface *env);

// Gets the MethodInfoImpl creating it if necessary
MethodInfoImpl *GetOrCreateMethodInfoImpl(const std::string &name,
const std::string &api_name,
Expand Down
84 changes: 84 additions & 0 deletions contrib/endpoints/src/api_manager/config_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,90 @@ TEST(Config, TestCorsDisabled) {
ASSERT_EQ(nullptr, method1);
}

TEST(Config, TestInvalidMetricRules) {
MockApiManagerEnvironmentWithLog env;
// There is no http.rule or api.method to match the selector.
static const char config_text[] = R"(
name: "Service.Name"
quota {
metric_rules {
selector: "GetShelves"
metric_costs {
key: "test.googleapis.com/operation/read_book"
value: 100
}
}
}
)";

std::unique_ptr<Config> config = Config::Create(&env, config_text, "");
EXPECT_EQ(nullptr, config);
}

TEST(Config, TestMetricRules) {
MockApiManagerEnvironmentWithLog env;
static const char config_text[] = R"(
name: "Service.Name"
http {
rules {
selector: "DeleteShelf"
delete: "/shelves"
}
rules {
selector: "GetShelves"
get: "/shelves"
}
}
quota {
metric_rules {
selector: "GetShelves"
metric_costs {
key: "test.googleapis.com/operation/get_shelves"
value: 100
}
metric_costs {
key: "test.googleapis.com/operation/request"
value: 10
}
}
metric_rules {
selector: "DeleteShelf"
metric_costs {
key: "test.googleapis.com/operation/delete_shelves"
value: 200
}
}
}
)";

std::unique_ptr<Config> config = Config::Create(&env, config_text, "");
ASSERT_TRUE(config);

const MethodInfo *method1 = config->GetMethodInfo("GET", "/shelves");
ASSERT_NE(nullptr, method1);

std::vector<std::pair<std::string, int>> metric_cost_vector =
method1->metric_cost_vector();
std::sort(metric_cost_vector.begin(), metric_cost_vector.end());
ASSERT_EQ(2, metric_cost_vector.size());
ASSERT_EQ("test.googleapis.com/operation/get_shelves",
metric_cost_vector[0].first);
ASSERT_EQ(100, metric_cost_vector[0].second);

ASSERT_EQ("test.googleapis.com/operation/request",
metric_cost_vector[1].first);
ASSERT_EQ(10, metric_cost_vector[1].second);

const MethodInfo *method2 = config->GetMethodInfo("DELETE", "/shelves");
ASSERT_NE(nullptr, method1);

metric_cost_vector = method2->metric_cost_vector();
ASSERT_EQ(1, metric_cost_vector.size());
ASSERT_EQ("test.googleapis.com/operation/delete_shelves",
metric_cost_vector[0].first);
ASSERT_EQ(200, metric_cost_vector[0].second);
}

} // namespace

} // namespace api_manager
Expand Down
10 changes: 10 additions & 0 deletions contrib/endpoints/src/api_manager/context/request_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,16 @@ void RequestContext::FillCheckRequestInfo(
request_->FindHeader(kXIosBundleId, &info->ios_bundle_id);
}

void RequestContext::FillAllocateQuotaRequestInfo(
service_control::QuotaRequestInfo *info) {
FillOperationInfo(info);

info->client_ip = request_->GetClientIP();
info->method_name = this->method_call_.method_info->name();
info->metric_cost_vector =
&this->method_call_.method_info->metric_cost_vector();
}

void RequestContext::FillReportRequestInfo(
Response *response, service_control::ReportRequestInfo *info) {
FillOperationInfo(info);
Expand Down
3 changes: 3 additions & 0 deletions contrib/endpoints/src/api_manager/context/request_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ class RequestContext {
// Fill CheckRequestInfo
void FillCheckRequestInfo(service_control::CheckRequestInfo *info);

// FillAllocateQuotaRequestInfo
void FillAllocateQuotaRequestInfo(service_control::QuotaRequestInfo *info);

// Fill ReportRequestInfo
void FillReportRequestInfo(Response *response,
service_control::ReportRequestInfo *info);
Expand Down
18 changes: 15 additions & 3 deletions contrib/endpoints/src/api_manager/method_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <map>
#include <memory>
#include <set>
#include <vector>

#include "contrib/endpoints/include/api_manager/method.h"
#include "contrib/endpoints/src/api_manager/utils/stl_util.h"
Expand Down Expand Up @@ -62,6 +63,10 @@ class MethodInfoImpl : public MethodInfo {

const std::string &backend_address() const { return backend_address_; }

const std::vector<std::pair<std::string, int>> &metric_cost_vector() const {
return metric_cost_vector_;
}

const std::string &rpc_method_full_name() const {
return rpc_method_full_name_;
}
Expand Down Expand Up @@ -90,6 +95,10 @@ class MethodInfoImpl : public MethodInfo {
url_query_parameters_[name].push_back(url_query_parameter);
}

void add_metric_cost(const std::string &metric, int64_t cost) {
metric_cost_vector_.push_back(std::make_pair(metric, cost));
}

// After add all system parameters, lookup some of them to cache
// their lookup results.
void process_system_parameters();
Expand Down Expand Up @@ -139,13 +148,13 @@ class MethodInfoImpl : public MethodInfo {
// such as API Key)?
bool allow_unregistered_calls_;
// Issuers to allowed audiences map.
std::map<std::string, std::set<std::string> > issuer_audiences_map_;
std::map<std::string, std::set<std::string>> issuer_audiences_map_;

// system parameter map of parameter name to http_header name.
std::map<std::string, std::vector<std::string> > http_header_parameters_;
std::map<std::string, std::vector<std::string>> http_header_parameters_;

// system parameter map of parameter name to url query parameter name.
std::map<std::string, std::vector<std::string> > url_query_parameters_;
std::map<std::string, std::vector<std::string>> url_query_parameters_;

// all the names of system query parameters
std::set<std::string> system_query_parameter_names_;
Expand Down Expand Up @@ -175,6 +184,9 @@ class MethodInfoImpl : public MethodInfo {

// Whether the response is streaming or not.
bool response_streaming_;

// map of metric and its cost
std::vector<std::pair<std::string, int>> metric_cost_vector_;
};

typedef std::unique_ptr<MethodInfoImpl> MethodInfoImplPtr;
Expand Down
2 changes: 2 additions & 0 deletions contrib/endpoints/src/api_manager/mock_method_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class MockMethodInfo : public MethodInfo {
MOCK_CONST_METHOD0(response_streaming, bool());
MOCK_CONST_METHOD0(system_query_parameter_names,
const std::set<std::string>&());
MOCK_CONST_METHOD0(metric_cost_vector,
const std::vector<std::pair<std::string, int>>&());
};

} // namespace api_manager
Expand Down
18 changes: 18 additions & 0 deletions contrib/endpoints/src/api_manager/proto/server_config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ message ServiceControlConfig {
// The intermediate reports for streaming calls should not be more frequent
// than this value (in seconds)
int32 intermediate_report_min_interval = 7;

// Quota aggregator config
QuotaAggregatorConfig quota_aggregator_config = 8;

// Timeout in milliseconds on service control allocate quota requests.
// If the value is <= 0, default timeout is 5000 milliseconds.
int32 quota_timeout_ms = 9;
}

// Check aggregator config
Expand All @@ -82,6 +89,17 @@ message CheckAggregatorConfig {
int32 response_expiration_ms = 3;
}

// Quota aggregator config
message QuotaAggregatorConfig {
// The maximum number of cache entries that can be kept in the aggregation
// cache. Cache is disabled when entries <= 0.
int32 cache_entries = 1;

// The maximum milliseconds before aggregated quota requests are refreshed to
// the server.
int32 refresh_interval_ms = 2;
}

// Report aggregator config
message ReportAggregatorConfig {
// The maximum number of cache entries that can be kept in the aggregation
Expand Down
Loading