Skip to content

Commit 9607878

Browse files
authored
Simplify plugin architecture (#14)
1 parent 2a5d97c commit 9607878

File tree

17 files changed

+179
-312
lines changed

17 files changed

+179
-312
lines changed

Makefile

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,15 @@
11
export PROJECT_HOME := $(shell pwd)
22
export DIST_PATH := $(PROJECT_HOME)/dist
3-
export PLUGIN_DIST_PATH := $(DIST_PATH)/plugins/traffic
43
export RELAY_MODULE := github.com/fullstorydev/relay-core
54

6-
.PHONY: all plugins cli compile test clean
5+
.PHONY: all compile test clean
76

87
all: compile
98

10-
plugins:
11-
mkdir -p $(DIST_PATH)/plugins/traffic/active
12-
mkdir -p $(DIST_PATH)/plugins/traffic/inactive
13-
go build -buildmode=plugin -o $(PLUGIN_DIST_PATH)/active/010-paths.so $(RELAY_MODULE)/relay/plugins/traffic/paths-plugin/main
14-
go build -buildmode=plugin -o $(PLUGIN_DIST_PATH)/active/015-paths.so $(RELAY_MODULE)/relay/plugins/traffic/content-blocker-plugin/main
15-
go build -buildmode=plugin -o $(PLUGIN_DIST_PATH)/active/020-relay.so $(RELAY_MODULE)/relay/plugins/traffic/relay-plugin/main
16-
go build -buildmode=plugin -o $(PLUGIN_DIST_PATH)/active/030-logging.so $(RELAY_MODULE)/relay/plugins/traffic/logging-plugin/main
17-
18-
cli:
9+
compile:
1910
go build -o $(DIST_PATH)/relay $(RELAY_MODULE)/relay/main
2011
go build -o $(DIST_PATH)/catcher $(RELAY_MODULE)/catcher/main
2112

22-
compile: plugins cli
23-
2413
test: compile
2514
go test -v $(RELAY_MODULE)/...
2615

relay/commands/commands.go

Lines changed: 69 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,46 @@ type EnvVar struct {
1414
EnvKey string
1515
Required bool
1616
DefaultVal string
17-
IsDir bool
1817
}
1918

2019
type Environment map[string]string
2120

22-
// GetEnvironment tries to read environment variables from various sources. In
23-
// order of precedence:
24-
// * OS environment variables.
25-
// * Values from any .env file that may exist.
26-
// * Default values specified by the caller.
27-
// It returns an error if one or more expected variables are not present in any
28-
// of the sources.
29-
func GetEnvironment(vars []EnvVar) (Environment, error) {
30-
env := map[string]string{}
21+
// EnvironmentProvider is an interface used to retrieve a string-based,
22+
// key-value set of configuration options.
23+
type EnvironmentProvider interface {
24+
// Read attempts to read the values of the provided variables from the
25+
// underlying source. If a value for a variable is found, it's written into
26+
// the provided Environment.
27+
Read(vars []EnvVar, env Environment)
28+
}
29+
30+
// GetEnvironmentOrPrintUsage reads the requested variables from an environment
31+
// provider. If a required variable is not found, usage information is printed
32+
// to stdout and an error is returned; otherwise, a populated Environment
33+
// containing the values of the requested variables is returned.
34+
func GetEnvironmentOrPrintUsage(
35+
provider EnvironmentProvider,
36+
vars []EnvVar,
37+
) (Environment, error) {
38+
env := Environment{}
3139
setupDefaultValues(vars, env)
32-
readDotEnv(vars, env)
33-
readEnvironment(vars, env)
34-
return env, checkEnvironment(vars, env)
40+
provider.Read(vars, env)
41+
42+
if err := checkEnvironment(vars, env); err != nil {
43+
printEnvUsage(vars, env)
44+
return nil, err
45+
}
46+
47+
return env, nil
48+
}
49+
50+
func setupDefaultValues(vars []EnvVar, env Environment) {
51+
for _, variable := range vars {
52+
if variable.DefaultVal == "" {
53+
continue
54+
}
55+
env[variable.EnvKey] = variable.DefaultVal
56+
}
3557
}
3658

3759
func checkEnvironment(vars []EnvVar, env Environment) error {
@@ -44,17 +66,12 @@ func checkEnvironment(vars []EnvVar, env Environment) error {
4466
if found == false || len(envVal) == 0 {
4567
return errors.New("Required environment variable is missing: " + variable.EnvKey)
4668
}
47-
48-
if variable.IsDir && checkDir(envVal) != nil {
49-
logger.Println("Could not read " + variable.EnvKey + " directory: " + envVal)
50-
return errors.New("Invalid directory: " + envVal)
51-
}
5269
}
5370

5471
return nil
5572
}
5673

57-
func PrintEnvUsage(vars []EnvVar, env Environment) {
74+
func printEnvUsage(vars []EnvVar, env Environment) {
5875
logger.Println("Required configuration variables via .env or environment:")
5976
for _, variable := range vars {
6077
if variable.Required == false {
@@ -83,21 +100,26 @@ func PrintEnvUsage(vars []EnvVar, env Environment) {
83100
}
84101
}
85102

86-
func checkDir(dirPath string) error {
87-
pathInfo, err := os.Stat(dirPath)
88-
if err != nil {
89-
return err
90-
}
91-
if pathInfo.IsDir() == false {
92-
return errors.New("Not a directory")
93-
}
94-
return nil
103+
// DefaultEnvironmentProvider tries to read environment variables from various
104+
// external sources. In order of precedence:
105+
// * OS environment variables.
106+
// * Values from any .env file that may exist.
107+
type DefaultEnvironmentProvider struct {
108+
}
109+
110+
func NewDefaultEnvironmentProvider() EnvironmentProvider {
111+
return &DefaultEnvironmentProvider{}
112+
}
113+
114+
func (provider *DefaultEnvironmentProvider) Read(vars []EnvVar, env Environment) {
115+
provider.readDotEnv(vars, env)
116+
provider.readEnvironment(vars, env)
95117
}
96118

97119
// readDotEnv reads environment variables from a .env file, if one is present,
98120
// and adds their values to env. Returns an error if reading from .env fails.
99-
func readDotEnv(vars []EnvVar, env Environment) error {
100-
dotEnvVals, err := parseDotEnv(".env")
121+
func (provider *DefaultEnvironmentProvider) readDotEnv(vars []EnvVar, env Environment) error {
122+
dotEnvVals, err := provider.parseDotEnv(".env")
101123
if err != nil {
102124
return err
103125
}
@@ -107,7 +129,7 @@ func readDotEnv(vars []EnvVar, env Environment) error {
107129
return nil
108130
}
109131

110-
func readEnvironment(vars []EnvVar, env Environment) {
132+
func (provider *DefaultEnvironmentProvider) readEnvironment(vars []EnvVar, env Environment) {
111133
for _, variable := range vars {
112134
envVal, found := os.LookupEnv(variable.EnvKey)
113135
if found && len(envVal) > 0 {
@@ -116,7 +138,7 @@ func readEnvironment(vars []EnvVar, env Environment) {
116138
}
117139
}
118140

119-
func parseDotEnv(filePath string) (Environment, error) {
141+
func (provider *DefaultEnvironmentProvider) parseDotEnv(filePath string) (Environment, error) {
120142
results := Environment{}
121143

122144
file, err := os.Open(filePath)
@@ -153,11 +175,22 @@ func parseDotEnv(filePath string) (Environment, error) {
153175
return results, nil
154176
}
155177

156-
func setupDefaultValues(vars []EnvVar, env Environment) {
178+
// TestEnvironmentProvider reads environment variables from a hard-coded list.
179+
type TestEnvironmentProvider struct {
180+
env Environment
181+
}
182+
183+
func NewTestEnvironmentProvider(env Environment) EnvironmentProvider {
184+
return &TestEnvironmentProvider{
185+
env: env,
186+
}
187+
}
188+
189+
func (provider *TestEnvironmentProvider) Read(vars []EnvVar, env Environment) {
157190
for _, variable := range vars {
158-
if variable.DefaultVal == "" {
159-
continue
191+
envVal, found := provider.env[variable.EnvKey]
192+
if found {
193+
env[variable.EnvKey] = envVal
160194
}
161-
env[variable.EnvKey] = variable.DefaultVal
162195
}
163196
}

relay/main/main.go

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package main
22

33
import (
4-
"fmt"
54
"log"
65
"os"
76
"strconv"
@@ -16,24 +15,17 @@ var logger = log.New(os.Stdout, "[relay] ", 0)
1615

1716
// These are the env variables in play
1817
var RelayPortVar = "RELAY_PORT"
19-
var RelayPluginsPathVar = "RELAY_PLUGINS_PATH"
20-
21-
var EnvVars = []commands.EnvVar{
22-
{
23-
EnvKey: RelayPortVar,
24-
Required: true,
25-
},
26-
{
27-
EnvKey: RelayPluginsPathVar,
28-
DefaultVal: "./plugins",
29-
IsDir: true,
30-
},
31-
}
3218

3319
func main() {
34-
env, err := commands.GetEnvironment(EnvVars)
20+
envProvider := commands.NewDefaultEnvironmentProvider()
21+
env, err := commands.GetEnvironmentOrPrintUsage(envProvider, []commands.EnvVar{
22+
{
23+
EnvKey: RelayPortVar,
24+
Required: true,
25+
},
26+
})
3527
if err != nil {
36-
commands.PrintEnvUsage(EnvVars, env)
28+
logger.Println(err)
3729
os.Exit(1)
3830
}
3931

@@ -44,27 +36,18 @@ func main() {
4436
}
4537
relayPort := int(parsedPort)
4638

47-
pluginsPath := env[RelayPluginsPathVar]
48-
49-
plugs := plugins.New()
50-
err = plugs.Load(pluginsPath)
39+
trafficPlugins, err := plugins.Load(plugins.Default, envProvider)
5140
if err != nil {
52-
logger.Println(fmt.Sprintf("Error loading plugins:\n\t%v", err))
53-
os.Exit(1)
54-
}
55-
56-
if pluginEnv, err := plugs.SetupEnvironment(); err != nil {
5741
logger.Println(err)
58-
commands.PrintEnvUsage(plugs.TrafficEnvVars(), pluginEnv)
5942
os.Exit(1)
6043
}
6144

6245
logger.Println("Plugins:")
63-
for _, tp := range plugs.Traffic {
46+
for _, tp := range trafficPlugins {
6447
logger.Println("\tTraffic:", tp.Name())
6548
}
6649

67-
relayService := relay.NewService(plugs)
50+
relayService := relay.NewService(trafficPlugins)
6851
if err := relayService.Start("0.0.0.0", relayPort); err != nil {
6952
panic("Could not start catcher service: " + err.Error())
7053
}

0 commit comments

Comments
 (0)