Documentation ¶
Overview ¶
Pakcage plugin provides means to create an Aker plugin. It exposes the ListenAndServeHTTP function, which is the main entry point for a plugin.
Following is an example plugin implementation that returns configured response body and status code.
package main import ( "net/http" "github.com/SAP/aker/plugin" ) type MessageHandler struct { Message []byte Code int } func (h *MessageHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { w.WriteHeader(h.Code) w.Write(h.Message) } func main() { plugin.ListenAndServeHTTP(func(data []byte) (http.Handler, error) { var handler = &MessageHandler{} if err := plugin.UnmarshalConfig(data, &handler); err != nil { return nil, err } return handler, nil }) }
Creating a plugin requires implementing a HandlerFactory object, which basically is just a function that accepts a byte array as input parameter and returns a http.Handler and an error. The byte array provided as input contains all configuration that was passed to the Aker process and is intended to configure the implemented plugin.
The factory should use UnmarshalConfig to get a Go struct representation of the data. The underlying notation is YAML, thus if you want to make use of Go's struct field tags, you should use 'yaml:<opts>' for configuring how the unmarshaller should handle the Go struct fields.
func myFactory(data []byte) (http.Handler, error) { var myConfig struct{ a int b string } cfg if err := plugin.UnmarshalConfig(data, &cfg); err != nil { return nil, err } return newMyHandler(cfg), nil }
The communication between Aker and each plugin, and between each pair of plugins, happens via HTTP, which is transported over unix domain sockets. The ListenAndServeHTTP method takes care of cleaning up the socket file, once the plugin receives signal to exit. Because of that, it is undesirable to call os.Exit from within a plugin, since this will leave the allocated socket file on the file system.
Plugin's Stdin and Stderr are captured by Aker, so writing to them is the way to send log messages to the central Aker log. They'll get decorated by appending the plugin name in front of each log line.
[plugin-name]: 2016/07/19 14:28:59 [INFO] Starting...
It is advisable to use the logger provided by the logging package.
Request tracking mechanism is provided by Aker. Each incoming HTTP request is decorated with the X-Aker-Request-Id header, as well as each response. If a plugin encounters problem with some request, it is advisable to dump the value of the X-Aker-Request-Id header for debugging purposes. The X-Aker-Request-Id header is also propagated to the end user, so when one complains, she is able to provide the header value for tracing.
If a plugin is part of a plugin chain, which means that each request gets processed by multiple plugins before it is returned to Aker and thus to the user, then the way of telling the requests not to continue further the plugin chain is to write something to the response by calling Write or WriteHeader of the http.Responsewriter. This will stop the request from going through sequential plugins and will return the response to the end user.
Index ¶
Constants ¶
This section is empty.
Variables ¶
DefaultOpener redirects the plugin's stdout and stderr to the calling process's stdout and stderr.
var DefaultServer = NewServer(os.Stdin, gologger.DefaultLogger, socketProxy{}, notifier{})
DefaultServer is a server with default configuration. One should not need to create a different server. If you're creating new server and reading this, you're doing something wrong.
It uses os.Stdin for reading configuration. It uses the gologger.DefaultLogger to log. It uses the socket package for HTTP over unix domain sockets. It uses the signal package from the standard library for signal handling.
Functions ¶
func ListenAndServeHTTP ¶
func ListenAndServeHTTP(factory HandlerFactory) error
ListenAndServeHTTP calls ListenAndServeHTTP of the DefaultServer.
func MarshalConfig ¶
MarshalConfig returns the plugin configuration data encoding of v.
func UnmarshalConfig ¶
UnmarshalConfig parses the plugin configuration data and stores the result in the value pointed by v.
Types ¶
type ConfigDecodeError ¶
type ConfigDecodeError struct {
// contains filtered or unexported fields
}
func (*ConfigDecodeError) Error ¶
func (e *ConfigDecodeError) Error() string
type HTTPServer ¶
HTTPServer represents a HTTP server that could be started and then stopped.
type Notifier ¶
type Notifier interface { // Notify relays incoming signals to c. If no // signals are provided, all incoming signals will be relayed to c. // Otherwise, just the provided signals will. Notify(c chan<- os.Signal, sig ...os.Signal) }
Notifier notifies on OS signals.
type Opener ¶
type Opener struct { // Stdout of the child process is redirected to PluginStdout. PluginStdout io.Writer // Stderr of the child process is redirected to PluginStderr. PluginStderr io.Writer }
Opener opens a plugin as a subprocess.
type Plugin ¶
Plugin represents an Aker plugin.
func (*Plugin) SocketPath ¶
SocketPath returns the path of the socket that the plugin is binded to.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server provides a functionality to run a Plugin.
func (*Server) ListenAndServeHTTP ¶
func (s *Server) ListenAndServeHTTP(factory HandlerFactory) error
ListenAndServeHTTP starts the http.Handler returned by the factory as plugin.
type Socket ¶
type Socket interface { // ProxyHTTP should return a Handler that proxies all request to the // provided unix domain socket path. ProxyHTTP(socketPath string) http.Handler // NewHTTPServer creates a HTTPServer on the provided unix socket path. // The server uses the passed handler for serving HTTP requests. // The server is not started. It is caller's responsibility to start it. NewHTTPServer(path string, h http.Handler) HTTPServer }
Socket enables running HTTP using unix domain socket transport.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
This file was generated by counterfeiter This file was generated by counterfeiter This file was generated by counterfeiter
|
This file was generated by counterfeiter This file was generated by counterfeiter This file was generated by counterfeiter |
Used only for testing.
|
Used only for testing. |