|
package main |
|
|
|
import ( |
|
"context" |
|
"encoding/json" |
|
"errors" |
|
"fmt" |
|
"net/http" |
|
|
|
"github.com/Sirupsen/logrus" |
|
"github.com/gorilla/mux" |
|
opentracing "github.com/opentracing/opentracing-go" |
|
) |
|
|
|
// errors |
|
var ( |
|
ErrAgentNotFound = errors.New("Agent not found") |
|
) |
|
|
|
// Env represents a service environment |
|
type Env struct { |
|
logger *logrus.Entry |
|
hostPort string |
|
tracer opentracing.Tracer |
|
} |
|
|
|
// Middleware defines HTTP middleware |
|
type Middleware func(next http.HandlerFunc) http.HandlerFunc |
|
|
|
// HealthCheckResponse contains a health check response |
|
type HealthCheckResponse struct { |
|
Status string `json:"status"` |
|
} |
|
|
|
// Agent represents a secret aget |
|
type Agent struct { |
|
ID string `json:"id"` |
|
Name string `json:"name"` |
|
} |
|
|
|
// AgentResponse contains an agent request response |
|
type AgentResponse struct { |
|
Agent Agent `json:"agent"` |
|
Status string `json:"status"` |
|
} |
|
|
|
// AgentAction perform an agent action |
|
func AgentAction() (*AgentResponse, error) { |
|
agent := &AgentResponse{ |
|
Agent{ |
|
ID: "007", |
|
Name: "James Bond", |
|
}, |
|
"License to Kill", |
|
} |
|
return agent, nil |
|
} |
|
|
|
// IndexHandler serves up an index file for every request |
|
func IndexHandler(e *Env) func(w http.ResponseWriter, r *http.Request) { |
|
logger := e.logger.WithField("handler", "IndexHandler") |
|
return func(w http.ResponseWriter, r *http.Request) { |
|
logger.Debug("index called") |
|
w.Write([]byte("Hello World.")) |
|
} |
|
} |
|
|
|
// HealthCheckHandler returns health check status |
|
func HealthCheckHandler(e *Env) func(w http.ResponseWriter, r *http.Request) { |
|
logger := e.logger.WithField("handler", "IndexHandler") |
|
return func(w http.ResponseWriter, r *http.Request) { |
|
logger.Debug("health check ok") |
|
j, _ := json.Marshal(HealthCheckResponse{ |
|
Status: "ok", |
|
}) |
|
w.Write(j) |
|
} |
|
} |
|
|
|
// AgentStatusHandler returns information on an agent |
|
func AgentStatusHandler(e *Env) func(w http.ResponseWriter, r *http.Request) { |
|
logger := e.logger.WithField("handler", "AgentStatusHandler") |
|
return func(w http.ResponseWriter, r *http.Request) { |
|
if span := opentracing.SpanFromContext(r.Context()); span != nil { |
|
subSpan := opentracing.StartSpan( |
|
"AgentStatusHandler", |
|
opentracing.ChildOf(span.Context())) |
|
defer subSpan.Finish() |
|
} |
|
|
|
logger.Debug("Agent status handler called") |
|
NoopOperation(r.Context()) |
|
|
|
agent, err := AgentAction() |
|
if err == ErrAgentNotFound { |
|
logger.Debug(ErrAgentNotFound.Error) |
|
w.Write([]byte(err.Error())) |
|
w.WriteHeader(http.StatusNotFound) |
|
return |
|
} |
|
if err != nil { |
|
logger.Error(ErrAgentNotFound.Error()) |
|
w.Write([]byte(err.Error())) |
|
w.WriteHeader(http.StatusInternalServerError) |
|
return |
|
} |
|
j, _ := json.Marshal(agent) |
|
w.Write(j) |
|
} |
|
} |
|
|
|
// NoopOperation performs a noop |
|
func NoopOperation(ctx context.Context) { |
|
if span := opentracing.SpanFromContext(ctx); span != nil { |
|
subSpan := opentracing.StartSpan( |
|
"NoopOperation", |
|
opentracing.ChildOf(span.Context())) |
|
defer subSpan.Finish() |
|
subSpan.SetTag("foo", "bar") |
|
} |
|
} |
|
|
|
const jaegerServiceName = "agent_service" |
|
const jaegerHostPort = "192.168.99.100:5775" |
|
|
|
func main() { |
|
|
|
// logger |
|
log := logrus.New() |
|
log.SetLevel(logrus.DebugLevel) |
|
log.Formatter = &logrus.JSONFormatter{} |
|
logger := log.WithField("type", "handler") |
|
|
|
tracer, closer, tracerErr := NewJaegerTracer(jaegerServiceName, jaegerHostPort, false) |
|
if tracerErr != nil { |
|
log.Panic(tracerErr) |
|
} |
|
defer closer.Close() |
|
|
|
// setup environment |
|
env := &Env{ |
|
logger: logger, |
|
hostPort: "8000", |
|
tracer: tracer, |
|
} |
|
|
|
// routes |
|
r := mux.NewRouter() |
|
|
|
// API |
|
api := r.PathPrefix("/v1").Subrouter() |
|
api.HandleFunc("/health", HealthCheckHandler(env)).Methods("GET") |
|
api.HandleFunc("/agent", env.TracingMiddleware(AgentStatusHandler(env))).Methods("GET") |
|
r.PathPrefix("/").HandlerFunc(IndexHandler(env)).Methods("GET") |
|
|
|
// print out routes before starting |
|
fmt.Println("Routes:") |
|
r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error { |
|
t, err := route.GetPathTemplate() |
|
if err != nil { |
|
return err |
|
} |
|
fmt.Printf(" %s\n", t) |
|
return nil |
|
}) |
|
|
|
fmt.Println("Listening on :8000") |
|
log.Fatal(http.ListenAndServe(":8000", r)) |
|
} |