Skip to content

Commit

Permalink
Simple filter build+link example.
Browse files Browse the repository at this point in the history
Duplicated the Echo network filter in Envoy, renamed Echo2, and
linked/configured in an Envoy static binary.
  • Loading branch information
htuch committed May 5, 2017
1 parent ea2922b commit 9f006f6
Show file tree
Hide file tree
Showing 13 changed files with 236 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bazel-*
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "envoy"]
path = envoy
url = https://github.com/lyft/envoy.git
53 changes: 53 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package(default_visibility = ["//visibility:public"])

load(
"@envoy//bazel:envoy_build_system.bzl",
"envoy_cc_binary",
"envoy_cc_library",
"envoy_cc_test",
)

envoy_cc_binary(
name = "envoy",
repository = "@envoy",
deps = [
":echo2_config",
"@envoy//source/exe:envoy_main_lib",
],
)

envoy_cc_library(
name = "echo2_lib",
srcs = ["echo2.cc"],
hdrs = ["echo2.h"],
repository = "@envoy",
deps = [
"@envoy//include/envoy/buffer:buffer_interface",
"@envoy//include/envoy/network:connection_interface",
"@envoy//include/envoy/network:filter_interface",
"@envoy//source/common/common:assert_lib",
"@envoy//source/common/common:logger_lib",
],
)

envoy_cc_library(
name = "echo2_config",
srcs = ["echo2_config.cc"],
repository = "@envoy",
deps = [
":echo2_lib",
"@envoy//include/envoy/network:connection_interface",
"@envoy//source/server:configuration_lib",
],
)

envoy_cc_test(
name = "echo2_integration_test",
srcs = ["echo2_integration_test.cc"],
data = ["echo2_server.json"],
repository = "@envoy",
deps = [
":echo2_config",
"@envoy//test/integration:integration_lib"
],
)
36 changes: 34 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,34 @@
# envoy-consumer
Example project consuming Envoy and injecting additional filters/tests
# Envoy filter example

This project demonstrates the linking of additional filters with the Envoy binary.
A new filter `echo2` is introduced, identical modulo renaming to the existing
[`echo`](https://github.com/lyft/envoy/blob/master/source/common/filter/echo.h)
filter. Integration tests demonstrating the filter's end-to-end behavior are
also provided.

## Building

To build the Envoy static binary:

1. `git submodule update --init`
2. `bazel build //:envoy`

## Testing

To run the `echo2` integration test:

`bazel test //:echo2_integration_test`

To run the regular Envoy tests from this project:

`bazel test @envoy//...`

## How it works

The [Envoy repository](https://github.com/lyft/envoy/) is provided as a submodule.
The [`WORKSPACE`](WORKSPACE) file maps the `@envoy` repository to this local path.

The [`BUILD`](BUILD) file introduces a new Envoy static binary target, `envoy`,
that links together the new filter and `@envoy//source/exe:envoy_main_lib`. The
`echo2` filter registers itself during the static initialization phase of the
Envoy binary as a new filter.
12 changes: 12 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
workspace(name = "envoy")

local_repository(
name = "envoy",
path = "envoy",
)

load("@envoy//bazel:repositories.bzl", "envoy_dependencies")
load("@envoy//bazel:cc_configure.bzl", "cc_configure")

envoy_dependencies()
cc_configure()
1 change: 1 addition & 0 deletions bazel/get_workspace_status
17 changes: 17 additions & 0 deletions echo2.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "echo2.h"

#include "envoy/buffer/buffer.h"
#include "envoy/network/connection.h"

#include "common/common/assert.h"

namespace Filter {

Network::FilterStatus Echo2::onData(Buffer::Instance& data) {
conn_log_trace("echo: got {} bytes", read_callbacks_->connection(), data.length());
read_callbacks_->connection().write(data);
ASSERT(0 == data.length());
return Network::FilterStatus::StopIteration;
}

} // Filter
25 changes: 25 additions & 0 deletions echo2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include "envoy/network/filter.h"

#include "common/common/logger.h"

namespace Filter {

/**
* Implementation of a basic echo filter.
*/
class Echo2 : public Network::ReadFilter, Logger::Loggable<Logger::Id::filter> {
public:
// Network::ReadFilter
Network::FilterStatus onData(Buffer::Instance& data) override;
Network::FilterStatus onNewConnection() override { return Network::FilterStatus::Continue; }
void initializeReadFilterCallbacks(Network::ReadFilterCallbacks& callbacks) override {
read_callbacks_ = &callbacks;
}

private:
Network::ReadFilterCallbacks* read_callbacks_{};
};

} // Filter
32 changes: 32 additions & 0 deletions echo2_config.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "envoy/network/connection.h"

#include "echo2.h"
#include "server/configuration_impl.h"

namespace Server {
namespace Configuration {

/**
* Config registration for the echo filter. @see NetworkFilterConfigFactory.
*/
class Echo2ConfigFactory : public NetworkFilterConfigFactory {
public:
// NetworkFilterConfigFactory
NetworkFilterFactoryCb tryCreateFilterFactory(NetworkFilterType type, const std::string& name,
const Json::Object&, Server::Instance&) {
if (type != NetworkFilterType::Read || name != "echo2") {
return nullptr;
}

return [](Network::FilterManager& filter_manager)
-> void { filter_manager.addReadFilter(Network::ReadFilterSharedPtr{new Filter::Echo2()}); };
}
};

/**
* Static registration for the echo filter. @see RegisterNetworkFilterConfigFactory.
*/
static RegisterNetworkFilterConfigFactory<Echo2ConfigFactory> registered_;

} // Configuration
} // Server
33 changes: 33 additions & 0 deletions echo2_integration_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "test/integration/integration.h"
#include "test/integration/utility.h"

class Echo2IntegrationTest : public BaseIntegrationTest, public testing::Test {
public:
/**
* Global initializer for all integration tests.
*/
static void SetUpTestCase() {
createTestServer("echo2_server.json", {"echo"});
}

/**
* Global destructor for all integration tests.
*/
static void TearDownTestCase() {
test_server_.reset();
}
};

TEST_F(Echo2IntegrationTest, Echo) {
Buffer::OwnedImpl buffer("hello");
std::string response;
RawConnectionDriver connection(lookupPort("echo"), buffer,
[&](Network::ClientConnection&, const Buffer::Instance& data)
-> void {
response.append(TestUtility::bufferToString(data));
connection.close();
});

connection.run();
EXPECT_EQ("hello", response);
}
23 changes: 23 additions & 0 deletions echo2_server.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"listeners": [
{
"address": "tcp://127.0.0.1:0",
"use_original_dst": true,
"filters": [
{ "type": "read", "name": "ratelimit",
"config": {
"domain": "foo",
"descriptors": [[{"key": "foo", "value": "bar"}]],
"stat_prefix": "name"
}
},
{ "type": "read", "name": "echo2", "config": {} }
]
}],

"admin": { "access_log_path": "/dev/null", "profile_path": "{{ test_tmpdir }}/envoy.prof", "address": "tcp://127.0.0.1:0" },

"cluster_manager": {
"clusters": []
}
}
1 change: 1 addition & 0 deletions envoy
Submodule envoy added at 203ff1
1 change: 1 addition & 0 deletions tools/bazel.rc

0 comments on commit 9f006f6

Please sign in to comment.