Skip to content

Commit

Permalink
Added envoy prototype. (envoyproxy#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
chowchow316 authored Dec 23, 2016
1 parent a9b0ef4 commit 5910360
Show file tree
Hide file tree
Showing 8 changed files with 1,455 additions and 1 deletion.
34 changes: 34 additions & 0 deletions src/envoy/prototype/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 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.
#
################################################################################
#

cc_binary(
name = "envoy_esp",
srcs = [
"api_manager_filter.cc",
"api_manager_env.cc",
"api_manager_env.h",
],
deps = [
"//external:protobuf",
"//contrib/endpoints/include:api_manager",
"//contrib/endpoints/src/grpc/transcoding:transcoding",
"//external:servicecontrol",
"@envoy_git//:envoy-common",
"@envoy_git//:envoy-main"
],
linkstatic=1,
)
132 changes: 132 additions & 0 deletions src/envoy/prototype/api_manager_env.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include "api_manager_env.h"

#include "common/http/headers.h"
#include "common/http/message_impl.h"
#include "envoy/event/timer.h"

namespace Http {
namespace ApiManager {

void Http::ApiManager::Env::Log(LogLevel level, const char *message) {
switch (level) {
case LogLevel::DEBUG:
log().debug("{}", message);
break;
case LogLevel::INFO:
log().debug("{}", message);
break;
case LogLevel::WARNING:
log().warn("{}", message);
break;
case LogLevel::ERROR:
log().error("{}", message);
break;
}
}


class PeriodicTimer : public google::api_manager::PeriodicTimer,
public Logger::Loggable<Logger::Id::http> {
private:
Server::Instance &server_;
Event::TimerPtr timer_;

public:
PeriodicTimer(Server::Instance &server) : server_(server) {}
~PeriodicTimer() { Stop(); }
void Stop() {
if (timer_) {
timer_->disableTimer();
timer_ = nullptr;
}
}
void Schedule(std::chrono::milliseconds interval,
std::function<void()> continuation) {
Stop();
timer_ = server_.dispatcher().createTimer([this, continuation, interval]() {
continuation();
Schedule(interval, continuation);
});
timer_->enableTimer(interval);
}
};

std::unique_ptr<google::api_manager::PeriodicTimer> Env::StartPeriodicTimer(
std::chrono::milliseconds interval, std::function<void()> continuation) {
log().debug("start periodic timer");
auto single = new PeriodicTimer(server);
single->Schedule(interval, continuation);
std::unique_ptr<google::api_manager::PeriodicTimer> timer(single);
return timer;
}

class HTTPRequest : public Http::Message {
private:
HeaderMapImpl header_map_;
Buffer::OwnedImpl body_;

public:
HTTPRequest(google::api_manager::HTTPRequest *request)
: body_(request->body()) {
header_map_.addStatic(Headers::get().Method, request->method());
header_map_.addStatic(Headers::get().Path, "/");
header_map_.addStatic(Headers::get().Scheme, "http");
header_map_.addStatic(Headers::get().Host, "localhost");
header_map_.addStatic(Headers::get().ContentLength,
std::to_string(body_.length()));
header_map_.addStatic(LowerCaseString("x-api-manager-url"),
request->url());
for (auto header : request->request_headers()) {
LowerCaseString key(header.first);
header_map_.addStatic(key, header.second);
}
}
virtual HeaderMap &headers() override { return header_map_; }
virtual Buffer::Instance *body() override { return &body_; }
virtual void body(Buffer::InstancePtr &&body) override {}
virtual HeaderMap *trailers() override { return nullptr; }
virtual void trailers(HeaderMapPtr &&trailers) override {}
virtual std::string bodyAsString() override { return ""; }
};

class RequestCallbacks : public AsyncClient::Callbacks {
private:
std::unique_ptr<google::api_manager::HTTPRequest> request_;
std::unique_ptr<AsyncClient::Request> sent_request_;

public:
RequestCallbacks(std::unique_ptr<google::api_manager::HTTPRequest> &&request)
: request_(std::move(request)) {}
virtual void onSuccess(MessagePtr &&response) override {
google::api_manager::utils::Status status(
std::stoi(response->headers().Status()->value().c_str()), "");
std::map<std::string, std::string> headers;
response->headers().iterate(
[&](const HeaderEntry& header, void*) -> void {
// TODO: fix it
// headers.emplace(header.key().c_str(), header.value().c_str());
}, nullptr);
request_->OnComplete(status, std::move(headers), response->bodyAsString());
delete this;
}
virtual void onFailure(AsyncClient::FailureReason reason) override {
google::api_manager::utils::Status status =
google::api_manager::utils::Status::OK;
std::map<std::string, std::string> headers;
request_->OnComplete(status, std::move(headers), "");
delete this;
}
};

void Env::RunHTTPRequest(
std::unique_ptr<google::api_manager::HTTPRequest> request) {
auto &client = cm_.httpAsyncClientForCluster("api_manager");

MessagePtr message{new HTTPRequest(request.get())};
RequestCallbacks *callbacks = new RequestCallbacks(std::move(request));
client.send(
std::move(message), *callbacks,
Optional<std::chrono::milliseconds>(std::chrono::milliseconds(10000)));
}
}
}
31 changes: 31 additions & 0 deletions src/envoy/prototype/api_manager_env.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include "precompiled/precompiled.h"

#include "common/common/logger.h"
#include "envoy/upstream/cluster_manager.h"
#include "contrib/endpoints/include/api_manager/env_interface.h"
#include "server/server.h"

namespace Http {
namespace ApiManager {

class Env : public google::api_manager::ApiManagerEnvInterface,
public Logger::Loggable<Logger::Id::http> {
private:
Server::Instance& server;
Upstream::ClusterManager& cm_;

public:
Env(Server::Instance& server)
: server(server), cm_(server.clusterManager()){};

virtual void Log(LogLevel level, const char* message) override;
virtual std::unique_ptr<google::api_manager::PeriodicTimer>
StartPeriodicTimer(std::chrono::milliseconds interval,
std::function<void()> continuation) override;
virtual void RunHTTPRequest(
std::unique_ptr<google::api_manager::HTTPRequest> request) override;
};
}
}
Loading

0 comments on commit 5910360

Please sign in to comment.