From 2ae781420776237af2441d387252fb3696952299 Mon Sep 17 00:00:00 2001 From: Qian Sun Date: Tue, 3 Jan 2017 12:59:35 -0800 Subject: [PATCH 1/3] Add mixer interface in api manager. --- WORKSPACE | 3 + contrib/endpoints/repositories.bzl | 49 ++++ contrib/endpoints/src/api_manager/mixer/BUILD | 42 ++++ .../endpoints/src/api_manager/mixer/mixer.cc | 225 ++++++++++++++++++ .../endpoints/src/api_manager/mixer/mixer.h | 59 +++++ .../src/api_manager/service_control/info.h | 3 + 6 files changed, 381 insertions(+) create mode 100644 contrib/endpoints/src/api_manager/mixer/BUILD create mode 100644 contrib/endpoints/src/api_manager/mixer/mixer.cc create mode 100644 contrib/endpoints/src/api_manager/mixer/mixer.h diff --git a/WORKSPACE b/WORKSPACE index 3bd9feb3245..bbafd205918 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -31,11 +31,14 @@ googletest_repositories() load( "//contrib/endpoints:repositories.bzl", "grpc_repositories", + "mixerapi_repositories", "servicecontrol_client_repositories", ) grpc_repositories() +mixerapi_repositories() + servicecontrol_client_repositories() load( diff --git a/contrib/endpoints/repositories.bzl b/contrib/endpoints/repositories.bzl index a14d7ce4dfd..f3df61722a2 100644 --- a/contrib/endpoints/repositories.bzl +++ b/contrib/endpoints/repositories.bzl @@ -333,3 +333,52 @@ def servicecontrol_client_repositories(bind=True): name = "servicecontrol_client", actual = "@servicecontrol_client_git//:service_control_client_lib", ) + +def mixerapi_repositories(protobuf_repo="@protobuf_git//", bind=True): + BUILD = """ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# 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. +# +################################################################################ +# +licenses(["notice"]) + +load("{}:protobuf.bzl", "cc_proto_library") + +cc_proto_library( + name = "mixer_api_cc_proto", + srcs = glob( + ["mixer/api/v1/*.proto"], + ), + default_runtime = "//external:protobuf", + protoc = "//external:protoc", + visibility = ["//visibility:public"], + deps = [ + "//external:cc_wkt_protos", + "//external:servicecontrol", + ], +) +""".format(protobuf_repo) + + native.new_git_repository( + name = "mixerapi_git", + commit = "fc5a396185edc72d06d1937f30a8148a37d4fc1b", + remote = "https://github.com/istio/api.git", + build_file_content = BUILD, + ) + if bind: + native.bind( + name = "mixer_api_cc_proto", + actual = "@mixerapi_git//:mixer_api_cc_proto", + ) diff --git a/contrib/endpoints/src/api_manager/mixer/BUILD b/contrib/endpoints/src/api_manager/mixer/BUILD new file mode 100644 index 00000000000..8082c61e201 --- /dev/null +++ b/contrib/endpoints/src/api_manager/mixer/BUILD @@ -0,0 +1,42 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# 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. +# +################################################################################ +# +package(default_visibility = ["//contrib/endpoints/src/api_manager:__subpackages__"]) + +cc_library( + name = "mixer", + srcs = [ + "mixer.cc", + ], + hdrs = [ + "mixer.h", + ], + linkopts = select({ + "//:darwin": [], + "//conditions:default": [ + "-lm", + "-luuid", + ], + }), + deps = [ + "//external:grpc++", + "//external:mixer_api_cc_proto", + "//external:protobuf", + "//contrib/endpoints/src/api_manager:impl_headers", + "//contrib/endpoints/src/api_manager/service_control", + "//contrib/endpoints/src/api_manager/utils", + ], +) diff --git a/contrib/endpoints/src/api_manager/mixer/mixer.cc b/contrib/endpoints/src/api_manager/mixer/mixer.cc new file mode 100644 index 00000000000..d3744fcb52a --- /dev/null +++ b/contrib/endpoints/src/api_manager/mixer/mixer.cc @@ -0,0 +1,225 @@ +/* Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 "contrib/endpoints/src/api_manager/mixer/mixer.h" + +#include +#include "mixer/api/v1/service.pb.h" + +using ::google::api_manager::utils::Status; +using ::google::protobuf::util::error::Code; +using ::google::protobuf::Map; + +namespace google { +namespace api_manager { +namespace mixer { +namespace { + +enum AttributeIndex { + ATTR_SERVICE_NAME = 0, + ATTR_PEER_ID, + ATTR_OPERATION_NAME, + ATTR_API_KEY, + ATTR_RESPONSE_CODE, + ATTR_URL, + ATTR_LOCATION, + ATTR_API_NAME, + ATTR_API_VERSION, + ATTR_API_METHOD, + ATTR_REQUEST_SIZE, + ATTR_RESPONSE_SIZE, + ATTR_LOG_MESSAGE, +}; + +struct AttributeDict { + int index; + std::string name; +} kAttributeNames[] = { + { + ATTR_SERVICE_NAME, "serviceName", + }, + { + ATTR_PEER_ID, "peerId", + }, + { + ATTR_OPERATION_NAME, "operationName", + }, + { + ATTR_API_KEY, "apiKey", + }, + { + ATTR_RESPONSE_CODE, "responseCode", + }, + { + ATTR_URL, "URL", + }, + { + ATTR_LOCATION, "location", + }, + { + ATTR_API_NAME, "apiName", + }, + { + ATTR_API_VERSION, "apiVersion", + }, + { + ATTR_API_METHOD, "apiMethod", + }, + { + ATTR_REQUEST_SIZE, "requestSize", + }, + { + ATTR_RESPONSE_SIZE, "responesSize", + }, + { + ATTR_LOG_MESSAGE, "logMessage", + }, +}; + +void SetAttributeDict(Map* dict) { + for (auto attr : kAttributeNames) { + (*dict)[attr.index] = attr.name; + } +} + +void CovertToPb(const service_control::CheckRequestInfo& info, + ::istio::mixer::v1::Attributes* attr) { + SetAttributeDict(attr->mutable_dictionary()); + + auto* str_attrs = attr->mutable_string_attributes(); + (*str_attrs)[ATTR_SERVICE_NAME] = info.service_name; + (*str_attrs)[ATTR_PEER_ID] = "Proxy"; + (*str_attrs)[ATTR_OPERATION_NAME] = info.operation_name; + (*str_attrs)[ATTR_API_KEY] = info.api_key; +} + +void CovertToPb(const service_control::ReportRequestInfo& info, + ::istio::mixer::v1::Attributes* attr) { + SetAttributeDict(attr->mutable_dictionary()); + + auto* str_attrs = attr->mutable_string_attributes(); + (*str_attrs)[ATTR_SERVICE_NAME] = info.service_name; + (*str_attrs)[ATTR_PEER_ID] = "Proxy"; + (*str_attrs)[ATTR_OPERATION_NAME] = info.operation_name; + (*str_attrs)[ATTR_API_KEY] = info.api_key; + + (*str_attrs)[ATTR_URL] = info.url; + (*str_attrs)[ATTR_LOCATION] = info.location; + + (*str_attrs)[ATTR_API_NAME] = info.api_name; + (*str_attrs)[ATTR_API_VERSION] = info.api_version; + (*str_attrs)[ATTR_API_METHOD] = info.api_method; + + (*str_attrs)[ATTR_LOG_MESSAGE] = info.log_message; + + auto* int_attrs = attr->mutable_int64_attributes(); + (*int_attrs)[ATTR_RESPONSE_CODE] = info.response_code; + (*int_attrs)[ATTR_REQUEST_SIZE] = info.request_size; + (*int_attrs)[ATTR_RESPONSE_SIZE] = info.response_size; +} + +} // namespace + +Mixer::Mixer(ApiManagerEnvInterface* env) : env_(env), request_index_(0) {} + +Mixer::~Mixer() {} + +Status Mixer::Init() { return Status::OK; } + +Status Mixer::Close() { return Status::OK; } + +Status Mixer::Report(const service_control::ReportRequestInfo& info) { + std::unique_ptr grpc_request(new GRPCRequest([this]( + Status status, std::string&& body) { + if (status.ok()) { + // Handle 200 response + ::istio::mixer::v1::ReportResponse response; + if (!response.ParseFromString(body)) { + status = + Status(Code::INVALID_ARGUMENT, std::string("Invalid response")); + env_->LogError(std::string("Failed parse report response: ") + body); + } + env_->LogInfo(std::string("Report response: ") + response.DebugString()); + } else { + env_->LogError(std::string("Failed to call Mixer::report, Error: ") + + status.ToString()); + } + })); + + ::istio::mixer::v1::ReportRequest request; + request.set_request_index(++request_index_); + CovertToPb(info, request.mutable_attribute_update()); + env_->LogInfo(std::string("Send Report: ") + request.DebugString()); + + std::string request_body; + request.SerializeToString(&request_body); + + grpc_request->set_service("istio.mixer.v1.Mixer") + .set_method("Report") + .set_body(request_body); + + env_->RunGRPCRequest(std::move(grpc_request)); + return Status::OK; +} + +void Mixer::Check( + const service_control::CheckRequestInfo& info, + cloud_trace::CloudTraceSpan* parent_span, + std::function + on_done) { + std::unique_ptr grpc_request(new GRPCRequest([this, on_done]( + Status status, std::string&& body) { + if (status.ok()) { + // Handle 200 response + ::istio::mixer::v1::CheckResponse response; + if (!response.ParseFromString(body)) { + status = + Status(Code::INVALID_ARGUMENT, std::string("Invalid response")); + env_->LogError(std::string("Failed parse check response: ") + body); + } + env_->LogInfo(std::string("Check response: ") + response.DebugString()); + } else { + env_->LogError(std::string("Failed to call Mixer::check, Error: ") + + status.ToString()); + } + service_control::CheckResponseInfo info; + on_done(status, info); + })); + + ::istio::mixer::v1::CheckRequest request; + request.set_request_index(++request_index_); + CovertToPb(info, request.mutable_attribute_update()); + env_->LogInfo(std::string("Send Check: ") + request.DebugString()); + + std::string request_body; + request.SerializeToString(&request_body); + + grpc_request->set_service("istio.mixer.v1.Mixer") + .set_method("Check") + .set_body(request_body); + + env_->RunGRPCRequest(std::move(grpc_request)); +} + +Status Mixer::GetStatistics(service_control::Statistics* esp_stat) const { + return Status::OK; +} + +service_control::Interface* Mixer::Create(ApiManagerEnvInterface* env) { + return new Mixer(env); +} + +} // namespace mixer +} // namespace api_manager +} // namespace google diff --git a/contrib/endpoints/src/api_manager/mixer/mixer.h b/contrib/endpoints/src/api_manager/mixer/mixer.h new file mode 100644 index 00000000000..4ce04cde5ec --- /dev/null +++ b/contrib/endpoints/src/api_manager/mixer/mixer.h @@ -0,0 +1,59 @@ +/* Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 API_MANAGER_MIXER_MIXER_H_ +#define API_MANAGER_MIXER_MIXER_H_ + +#include "contrib/endpoints/include/api_manager/env_interface.h" +#include "contrib/endpoints/src/api_manager/service_control/interface.h" + +namespace google { +namespace api_manager { +namespace mixer { + +// This implementation uses service-control-client-cxx module. +class Mixer : public service_control::Interface { + public: + static service_control::Interface* Create(ApiManagerEnvInterface* env); + + virtual ~Mixer(); + + virtual utils::Status Report(const service_control::ReportRequestInfo& info); + + virtual void Check( + const service_control::CheckRequestInfo& info, + cloud_trace::CloudTraceSpan* parent_span, + std::function + on_done); + + virtual utils::Status Init(); + virtual utils::Status Close(); + + virtual utils::Status GetStatistics(service_control::Statistics* stat) const; + + private: + // The constructor. + Mixer(ApiManagerEnvInterface* env); + + // The Api Manager environment interface. + ApiManagerEnvInterface* env_; + int64_t request_index_; +}; + +} // namespace mixer +} // namespace api_manager +} // namespace google + +#endif // API_MANAGER_MIXER_MIXER_H_ diff --git a/contrib/endpoints/src/api_manager/service_control/info.h b/contrib/endpoints/src/api_manager/service_control/info.h index 15364ad58c6..5abb1f84dbd 100644 --- a/contrib/endpoints/src/api_manager/service_control/info.h +++ b/contrib/endpoints/src/api_manager/service_control/info.h @@ -38,6 +38,9 @@ namespace service_control { // Basic information about the API call (operation). struct OperationInfo { + // The service name + ::google::protobuf::StringPiece service_name; + // Identity of the operation. It must be unique within the scope of the // service. If the service calls Check() and Report() on the same operation, // the two calls should carry the same operation id. From c9fd7724c9fa9046712f5ff035f380874dde93a2 Mon Sep 17 00:00:00 2001 From: Qian Sun Date: Tue, 3 Jan 2017 14:34:01 -0800 Subject: [PATCH 2/3] Store service_name in mixer class. --- .../endpoints/src/api_manager/mixer/mixer.cc | 22 +++++++++++-------- .../endpoints/src/api_manager/mixer/mixer.h | 9 ++++++-- .../src/api_manager/service_control/info.h | 3 --- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/contrib/endpoints/src/api_manager/mixer/mixer.cc b/contrib/endpoints/src/api_manager/mixer/mixer.cc index d3744fcb52a..bd1db2810d5 100644 --- a/contrib/endpoints/src/api_manager/mixer/mixer.cc +++ b/contrib/endpoints/src/api_manager/mixer/mixer.cc @@ -94,22 +94,24 @@ void SetAttributeDict(Map* dict) { } void CovertToPb(const service_control::CheckRequestInfo& info, + const std::string& service_name, ::istio::mixer::v1::Attributes* attr) { SetAttributeDict(attr->mutable_dictionary()); auto* str_attrs = attr->mutable_string_attributes(); - (*str_attrs)[ATTR_SERVICE_NAME] = info.service_name; + (*str_attrs)[ATTR_SERVICE_NAME] = service_name; (*str_attrs)[ATTR_PEER_ID] = "Proxy"; (*str_attrs)[ATTR_OPERATION_NAME] = info.operation_name; (*str_attrs)[ATTR_API_KEY] = info.api_key; } void CovertToPb(const service_control::ReportRequestInfo& info, + const std::string& service_name, ::istio::mixer::v1::Attributes* attr) { SetAttributeDict(attr->mutable_dictionary()); auto* str_attrs = attr->mutable_string_attributes(); - (*str_attrs)[ATTR_SERVICE_NAME] = info.service_name; + (*str_attrs)[ATTR_SERVICE_NAME] = service_name; (*str_attrs)[ATTR_PEER_ID] = "Proxy"; (*str_attrs)[ATTR_OPERATION_NAME] = info.operation_name; (*str_attrs)[ATTR_API_KEY] = info.api_key; @@ -131,7 +133,8 @@ void CovertToPb(const service_control::ReportRequestInfo& info, } // namespace -Mixer::Mixer(ApiManagerEnvInterface* env) : env_(env), request_index_(0) {} +Mixer::Mixer(ApiManagerEnvInterface* env, const std::string& service_name) + : env_(env), request_index_(0), service_name_(service_name) {} Mixer::~Mixer() {} @@ -159,13 +162,13 @@ Status Mixer::Report(const service_control::ReportRequestInfo& info) { ::istio::mixer::v1::ReportRequest request; request.set_request_index(++request_index_); - CovertToPb(info, request.mutable_attribute_update()); + CovertToPb(info, service_name(), request.mutable_attribute_update()); env_->LogInfo(std::string("Send Report: ") + request.DebugString()); std::string request_body; request.SerializeToString(&request_body); - grpc_request->set_service("istio.mixer.v1.Mixer") + grpc_request->set_server("mixer_server") .set_method("Report") .set_body(request_body); @@ -199,13 +202,13 @@ void Mixer::Check( ::istio::mixer::v1::CheckRequest request; request.set_request_index(++request_index_); - CovertToPb(info, request.mutable_attribute_update()); + CovertToPb(info, service_name(), request.mutable_attribute_update()); env_->LogInfo(std::string("Send Check: ") + request.DebugString()); std::string request_body; request.SerializeToString(&request_body); - grpc_request->set_service("istio.mixer.v1.Mixer") + grpc_request->set_server("mixer_server") .set_method("Check") .set_body(request_body); @@ -216,8 +219,9 @@ Status Mixer::GetStatistics(service_control::Statistics* esp_stat) const { return Status::OK; } -service_control::Interface* Mixer::Create(ApiManagerEnvInterface* env) { - return new Mixer(env); +service_control::Interface* Mixer::Create(ApiManagerEnvInterface* env, + const std::string& service_name) { + return new Mixer(env, service_name); } } // namespace mixer diff --git a/contrib/endpoints/src/api_manager/mixer/mixer.h b/contrib/endpoints/src/api_manager/mixer/mixer.h index 4ce04cde5ec..4863d4e8a78 100644 --- a/contrib/endpoints/src/api_manager/mixer/mixer.h +++ b/contrib/endpoints/src/api_manager/mixer/mixer.h @@ -25,7 +25,8 @@ namespace mixer { // This implementation uses service-control-client-cxx module. class Mixer : public service_control::Interface { public: - static service_control::Interface* Create(ApiManagerEnvInterface* env); + static service_control::Interface* Create(ApiManagerEnvInterface* env, + const std::string& service_name); virtual ~Mixer(); @@ -42,14 +43,18 @@ class Mixer : public service_control::Interface { virtual utils::Status Close(); virtual utils::Status GetStatistics(service_control::Statistics* stat) const; + const std::string& service_name() const { return service_name_; } private: // The constructor. - Mixer(ApiManagerEnvInterface* env); + Mixer(ApiManagerEnvInterface* env, const std::string& service_name); // The Api Manager environment interface. ApiManagerEnvInterface* env_; int64_t request_index_; + + // The service name. + std::string service_name_; }; } // namespace mixer diff --git a/contrib/endpoints/src/api_manager/service_control/info.h b/contrib/endpoints/src/api_manager/service_control/info.h index 5abb1f84dbd..15364ad58c6 100644 --- a/contrib/endpoints/src/api_manager/service_control/info.h +++ b/contrib/endpoints/src/api_manager/service_control/info.h @@ -38,9 +38,6 @@ namespace service_control { // Basic information about the API call (operation). struct OperationInfo { - // The service name - ::google::protobuf::StringPiece service_name; - // Identity of the operation. It must be unique within the scope of the // service. If the service calls Check() and Report() on the same operation, // the two calls should carry the same operation id. From 40432b906ab854ece8f3eee576ec5929c04b7679 Mon Sep 17 00:00:00 2001 From: Qian Sun Date: Tue, 3 Jan 2017 14:54:27 -0800 Subject: [PATCH 3/3] Remove getter function for service_name. --- contrib/endpoints/src/api_manager/mixer/mixer.cc | 4 ++-- contrib/endpoints/src/api_manager/mixer/mixer.h | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/contrib/endpoints/src/api_manager/mixer/mixer.cc b/contrib/endpoints/src/api_manager/mixer/mixer.cc index bd1db2810d5..c770df1d631 100644 --- a/contrib/endpoints/src/api_manager/mixer/mixer.cc +++ b/contrib/endpoints/src/api_manager/mixer/mixer.cc @@ -162,7 +162,7 @@ Status Mixer::Report(const service_control::ReportRequestInfo& info) { ::istio::mixer::v1::ReportRequest request; request.set_request_index(++request_index_); - CovertToPb(info, service_name(), request.mutable_attribute_update()); + CovertToPb(info, service_name_, request.mutable_attribute_update()); env_->LogInfo(std::string("Send Report: ") + request.DebugString()); std::string request_body; @@ -202,7 +202,7 @@ void Mixer::Check( ::istio::mixer::v1::CheckRequest request; request.set_request_index(++request_index_); - CovertToPb(info, service_name(), request.mutable_attribute_update()); + CovertToPb(info, service_name_, request.mutable_attribute_update()); env_->LogInfo(std::string("Send Check: ") + request.DebugString()); std::string request_body; diff --git a/contrib/endpoints/src/api_manager/mixer/mixer.h b/contrib/endpoints/src/api_manager/mixer/mixer.h index 4863d4e8a78..5d4052cd152 100644 --- a/contrib/endpoints/src/api_manager/mixer/mixer.h +++ b/contrib/endpoints/src/api_manager/mixer/mixer.h @@ -43,7 +43,6 @@ class Mixer : public service_control::Interface { virtual utils::Status Close(); virtual utils::Status GetStatistics(service_control::Statistics* stat) const; - const std::string& service_name() const { return service_name_; } private: // The constructor.