common

package
v9.0.0-...-75dab31 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 22, 2016 License: Apache-2.0 Imports: 25 Imported by: 0

README

Common utilities

Documentation

Overview

Package common authentication related code.

Package common build information support.

This file contains the implementation of HttpClient and related utilities.

Package common contains various things common to all Romana services.

Package common contains things related to the REST framework.

Contains general routines and definitions for a generic back-end storage (currently geared towards RDBMS but not necessarily limited to that).

Index

Constants

View Source
const (
	// For passing in Gorilla Mux context the unmarshalled data
	ContextKeyUnmarshalledMap string = "UnmarshalledMap"
	// For passing in Gorilla Mux context path variables
	ContextKeyQueryVariables string = "QueryVars"
	// 	 For passing in Gorilla Mux context the original body data
	ContextKeyOriginalBody string = "OriginalBody"
	ContextKeyMarshaller   string = "Marshaller"
	// DefaultRestTimeout, in milliseconds.
	DefaultRestTimeout    = 500
	DefaultRestRetries    = 3
	ReadWriteTimeoutDelta = 10

	// Name of the query parameter used for request token
	RequestTokenQueryParameter = "RequestToken"

	HeaderContentType = "content-type"

	Starting ServiceMessage = "Starting."

	// JSON
	TimeoutMessage = "{ \"error\" : \"Timed out\" }"

	// Empty string returned when there is a string return
	// but there is an error so no point in returning any
	// value.
	ErrorNoValue = ""
)

Constants

Variables

View Source
var ContentTypeMarshallers map[string]Marshaller = map[string]Marshaller{

	"":                                  jsonMarshaller{},
	"application/json":                  jsonMarshaller{},
	"application/vnd.romana.v1+json":    jsonMarshaller{},
	"application/vnd.romana+json":       jsonMarshaller{},
	"application/x-www-form-urlencoded": formMarshaller{},
}

ContentTypeMarshallers maps MIME type to Marshaller instances

Functions

func BuildInfo

func BuildInfo() string

BuildInfo return build revision and time string.

func IPv4ToInt

func IPv4ToInt(ip net.IP) uint64

func IntToIPv4

func IntToIPv4(ipInt uint64) net.IP

func MakeMultiError

func MakeMultiError(errors []error) error

MakeMultiError creates a single MultiError (or nil!) out of an array of error objects.

func MockPortsInConfig

func MockPortsInConfig(fname string) error

MockPortsInConfig will take the config file specified and replace the ports with 0 to use arbitrary ports and write it out to /tmp/romana.yaml

func PressEnterToContinue

func PressEnterToContinue()

func ToBool

func ToBool(val string) (bool, error)

toBool is a convenience function that's like ParseBool but allows also "on"/"off" values.

func WriteConfig

func WriteConfig(config Config, fname string) error

WriteConfig writes config from file to structure

Types

type Api

type Api struct {
	// Host to listen on.
	Host string `yaml:"host" json:"host"`
	// Port to listen on.
	Port uint64 `yaml:"port" json:"port"`
	// Root service URL
	RootServiceUrl string `json:"root_service_url,omitempty" yaml:"root_service_url,omitempty"`
	// Rest timeout in milliseconds (if omitted, defaults to DefaultRestTimeout)
	RestTimeoutMillis int64 `yaml:"rest_timeout_millis,omitempty" json:"rest_timeout_millis,omitempty"`
	RestRetries       int   `yaml:"rest_retries,omitempty" json:"rest_retries,omitempty"`
	RestTestMode      bool  `yaml:"rest_test_mode,omitempty" json:"rest_test_mode,omitempty"`
}

Api part of service configuration (host/port).

func (Api) GetHostPort

func (api Api) GetHostPort() string

type AuthBackend

type AuthBackend interface {
}

AuthBackend interface for auth realted stuff.

type AuthMiddleware

type AuthMiddleware struct {
	Authenticator Authenticator
}

AuthMiddleware wrapper for auth.

func NewAuth

func NewAuth() *AuthMiddleware

NewAuth creates AuthMiddleware

func (AuthMiddleware) ServeHTTP

func (am AuthMiddleware) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)

type Authenticator

type Authenticator interface {
	// As this is a placeholder, we are not dealing with
	// details yet, tokens vs credentials, principals vs roles, etc.
	Authenticate() Principal
}

Authenticator is the interface that will be used by AuthMiddleware to provide authentication. Details to be worked out later.

type CommonConfig

type CommonConfig struct {
	Api *Api `yaml:"api" json:"api"`
}

CommonConfig stores configuration that is common to all services. For things such as API information (host/port), DB, etc.

type Config

type Config struct {
	Services map[string]ServiceConfig
}

Config provides the main configuration object

func ReadConfig

func ReadConfig(fname string) (Config, error)

ReadConfig parses the configuration file provided and returns ReadConfig reads config from file to structure

type Datacenter

type Datacenter struct {
	Id        uint64 `sql:"AUTO_INCREMENT"`
	IpVersion uint   `json:"ip_version"`
	// We don't need to store this, but calculate and pass around
	Prefix      uint64 `json:"prefix"`
	Cidr        string
	PrefixBits  uint `json:"prefix_bits"`
	PortBits    uint `json:"port_bits"`
	TenantBits  uint `json:"tenant_bits"`
	SegmentBits uint `json:"segment_bits"`
	// We don't need to store this, but calculate and pass around
	EndpointBits      uint   `json:"endpoint_bits"`
	EndpointSpaceBits uint   `json:"endpoint_space_bits"`
	Name              string `json:"name"`
}

Datacenter represents the configuration of a datacenter

type DbStore

type DbStore struct {
	ServiceStore ServiceStore
	Config       *StoreConfig
	Db           *gorm.DB
	// contains filtered or unexported fields
}

DbStore is a structure storing information specific to RDBMS-based implementation of Store.

func (*DbStore) Connect

func (dbStore *DbStore) Connect() error

Connect connects to the appropriate DB (mutating dbStore's state with the connection information), or returns an error.

func (*DbStore) CreateSchema

func (dbStore *DbStore) CreateSchema(force bool) error

CreateSchema creates the schema in this DB. If force flag is specified, the schema is dropped and recreated.

func (*DbStore) DbStore

func (dbStore *DbStore) DbStore() DbStore

func (*DbStore) GetPasswordFunction

func (dbStore *DbStore) GetPasswordFunction() (string, error)

GetPasswordFunction returns appropriate function to hash password depending on the underlying DB (note that in sqlite it is plain text).

func (*DbStore) SetConfig

func (dbStore *DbStore) SetConfig(configMap map[string]interface{}) error

SetConfig sets the config object from a map.

type HostMessage

type HostMessage struct {
	Id        string `json:"id"`
	Name      string `json:"name"`
	Ip        string `json:"ip"`
	RomanaIp  string `json:"romana_ip"`
	AgentPort int    `json:"agent_port"`
	Links     Links  `json:"links"`
}

HostMessage is a structure representing information about the host for the purposes of REST communications

type HttpError

type HttpError struct {
	StatusCode int    `json:"status_code"`
	StatusText string `json:"status_text"`
	Message    string `json:"message"`
}

HttpError is a structure that represents, well, an Http error.

func NewError

func NewError(code int, msg string) HttpError

NewError helps to construct new Error structure.

func NewError400

func NewError400(message string, request string) HttpError

func NewError404

func NewError404(resourceType string, resourceId string) HttpError

NewError404 creates a 404 NOT FOUND message.

func NewError500

func NewError500(err error) HttpError

func (HttpError) Error

func (e HttpError) Error() string

Error is a method to satisfy error interface and returns a string representation of the error.

type IP

type IP struct {
	// contains filtered or unexported fields
}

func MakeIPv4

func MakeIPv4(a, b, c, d byte) IP

type IndexResponse

type IndexResponse struct {
	ServiceName string `json:"serviceName"`
	Links       Links
}

Response to /

type LinkResponse

type LinkResponse struct {
	Href string
	Rel  string
}

LinkResponse structure represents the commonly occurring

{
       "href" : "https://<own-addr>",
       "rel"  : "self"
 }

part of the response.

type Links []LinkResponse

func (Links) FindByRel

func (links Links) FindByRel(rel string) string

FindByRel finds the path (href) for a link based on its rel value. This is because in the REST message links are organized as an array of structures containing href and rel, but, of course, in actual usage it is easier to be used as a map.

type MakeMessage

type MakeMessage func() interface{}

MakeMessage is a factory function, which should return a pointer to an instance into which we will unmarshal wire data.

type Marshaller

type Marshaller interface {
	Marshal(v interface{}) ([]byte, error)
	Unmarshal(data []byte, v interface{}) error
}

Marshaller is capable of marshalling and unmarshalling data to/from the wire.

type MultiError

type MultiError struct {
	// contains filtered or unexported fields
}

MultiError adapts GORM (ORM - see https://github.com/jinzhu/gorm) array of errors found in GetErrors() to a single error interface. GORM does not return errors at every turn. It accumulates them and returns them whenever you feel like calling GetErrors() (https://godoc.org/github.com/jinzhu/gorm#DB.GetErrors). Since this is not consistent with the rest of the code, I prefer to isolate it here and make an adapter.

func (*MultiError) Error

func (m *MultiError) Error() string

Error satisfies Error method on error interface and returns a concatenated string of all error messages.

type NegotiatorMiddleware

type NegotiatorMiddleware struct {
}

func NewNegotiator

func NewNegotiator() *NegotiatorMiddleware

func (NegotiatorMiddleware) ServeHTTP

func (negotiator NegotiatorMiddleware) ServeHTTP(writer http.ResponseWriter, request *http.Request, next http.HandlerFunc)

type PlaceholderAuth

type PlaceholderAuth struct {
}

func (PlaceholderAuth) Authenticate

func (p PlaceholderAuth) Authenticate() Principal

type PortUpdateMessage

type PortUpdateMessage struct {
	Port uint64 `json:"port"`
}

Message to register with the root service the actual port a service is listening on.

type Principal

type Principal struct {
	Id string
	// This really is a placeholder
	Rights []string
}

Principal is a placeholder for a Principal structure for authentication. We'll leave roles and other stuff for later.

type RestClient

type RestClient struct {
	// contains filtered or unexported fields
}

Rest Client for the Romana services. Incorporates facilities to deal with various REST requests.

func NewRestClient

func NewRestClient(url string, config RestClientConfig) (*RestClient, error)

NewRestClient creates a new Rest client.

func (*RestClient) Get

func (rc *RestClient) Get(url string, result interface{}) error

Get applies GET method to the specified URL, putting the result into the provided interface

func (*RestClient) GetServiceConfig

func (rc *RestClient) GetServiceConfig(rootServiceUrl string, svc Service) (*ServiceConfig, error)

GetServiceConfig retrieves configuration for a given service from the root service.

func (*RestClient) GetServiceUrl

func (rc *RestClient) GetServiceUrl(rootServiceUrl string, name string) (string, error)

GetServiceUrl is a convenience function, which, given the root service URL and name of desired service, returns the URL of that service.

func (*RestClient) NewUrl

func (rc *RestClient) NewUrl(dest string) error

NewUrl sets the client's new URL (yes, it mutates) to dest. If dest is a relative URL then it will be based on the previous value of the URL that the RestClient had.

func (*RestClient) Post

func (rc *RestClient) Post(url string, data interface{}, result interface{}) error

Post applies POST method to the specified URL

type RestClientConfig

type RestClientConfig struct {
	TimeoutMillis int64
	Retries       int
	TestMode      bool
}

RestClientConfig holds configuration for restful client.

func GetDefaultRestClientConfig

func GetDefaultRestClientConfig() RestClientConfig

func GetRestClientConfig

func GetRestClientConfig(config ServiceConfig) RestClientConfig

GetRestClientConfig returns a RestClientConfig based on a ServiceConfig

type RestContext

type RestContext struct {
	// Path variables as described in https://godoc.org/code.google.com/p/gorilla/mux
	PathVariables map[string]string
	// QueryVariables stores key-value-list map of query variables, see url.Values
	// for more details.
	QueryVariables url.Values
	// Unique identifier for a request.
	RequestToken string
}

RestContext contains the context of the REST request other than the body data that has been unmarshaled.

type RestHandler

type RestHandler func(input interface{}, context RestContext) (interface{}, error)

RestHandler specifies type of a function that each Route provides. It takes (for now) an interface as input, and returns any interface. The middleware provided in this file takes care of unmarshalling the data from the wire to the input object (the type of the object created will be determined by the type of the instance provided in Consumes field of Route type, below), and of marshalling the returned object to the wire (the type of which is determined by type of the instance provided in Produces field of Route type, below).

type RestServiceInfo

type RestServiceInfo struct {
	// Address being listened on
	Address string
	// Channel to communicate with the service
	Channel chan ServiceMessage
}

func InitializeService

func InitializeService(service Service, config ServiceConfig) (*RestServiceInfo, error)

InitializeService initializes the service with the provided config and starts it. The channel returned allows the calller to wait for a message from the running service. Messages are of type ServiceMessage above. It can be used for launching service from tests, etc.

func ListenAndServe

func ListenAndServe(svr *http.Server) (*RestServiceInfo, error)

ListenAndServe is same as http.ListenAndServe except it returns the address that will be listened on (which is useful when using arbitrary ports). See https://github.com/golang/go/blob/master/src/net/http/server.go

func RunNegroni

func RunNegroni(n *negroni.Negroni, addr string, timeout time.Duration) (*RestServiceInfo, error)

RunNegroni is a convenience function that runs the negroni stack as a provided HTTP server, with the following caveats:

  1. the Handler field of the provided serverConfig should be nil, because the Handler used will be the n Negroni object.

type RomanaHandler

type RomanaHandler struct {
	// contains filtered or unexported fields
}

RomanaHandler interface to comply with http.Handler

func (RomanaHandler) ServeHTTP

func (romanaHandler RomanaHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request)

ServeHTTP is required by https://golang.org/pkg/net/http/#Handler

type RootIndexResponse

type RootIndexResponse struct {
	ServiceName string `json:"serviceName"`
	Links       Links
	Services    []ServiceResponse
}

RootIndexResponse represents a response from the / path specific for root service only.

type Route

type Route struct {
	// REST method
	Method string

	// Pattern (see http://www.gorillatoolkit.org/pkg/mux)
	Pattern string

	// Handler (see documentation above)
	Handler RestHandler

	// This should return a POINTER to an instance which
	// this route expects as an input.
	MakeMessage MakeMessage

	// Whether this route is using a request token. If true, the
	// request token will be parsed out of the request and made
	// available in RestContext. It can then
	// used by the handler to achieve idempotence.
	UseRequestToken bool
}

Route determines an action taken on a URL pattern/HTTP method. Each service can define a route See routes.go and handlers.go in root package for a demonstration of use

type Routes

type Routes []Route

Routes provided by each service.

type Service

type Service interface {
	// SetConfig sets the configuration, validating it if needed
	// and returning an error if not valid.
	SetConfig(config ServiceConfig) error

	// Initializes the service (mostly for error reporting, could be a no-op)
	Initialize() error

	// Returns the routes that this service works with
	Routes() Routes

	// Name returns the name of this service.
	Name() string
}

Service is the interface that microservices implement.

type ServiceConfig

type ServiceConfig struct {
	Common CommonConfig `json:"common" yaml:"common"`
	// TODO I really dislike this name, but there
	// should be some common part that's applicable
	// to all services, and something service-specific
	// that we in common do not need to know about.
	ServiceSpecific map[string]interface{} `json:"config" yaml:"config,omitempty"`
}

ServiceConfig contains common configuration for each service and also a section for service-specific configuration. This may be an overkill but if we have a type system, we should use it instead of just dictionaries.

type ServiceMessage

type ServiceMessage string

Type definitions

type ServiceResponse

type ServiceResponse struct {
	Name  string
	Links Links
}

Service information

type ServiceStore

type ServiceStore interface {
	// Entities returns list of entities (DB tables) this store is managing.
	Entities() []interface{}
	// CreateSchemaPostProcess runs whatever required post-processing after
	// schema creation (perhaps initializing DB with some initial or sample data).
	CreateSchemaPostProcess() error
}

ServiceStore interface is what each service's store needs to implement.

type ServiceUtils

type ServiceUtils struct {
	// ResourceIdToStatus is a maps request ID
	// to status. A request ID can be a RequestToken if required,
	// or a resource ID. In general the idea is that this is used
	// in conjunction with RequestToken.
	// See also
	// - Route.UseRequestToken
	// - RestContext.RequestToken
	RequestIdToStatus map[string]interface{}

	// RequestIdToTimestamp maps request ID (for more information
	// on what that is see RequestIdToStatus) to the timestamp
	// of the original request. It will later be used for things
	// such as possible expiration, etc., but for now it's just a
	// placeholder.
	RequestIdToTimestamp map[string]int64
}

ServiceUtils represents functionality common to various services. One example of such functionality is asynchronous processing -- a service can accept a request for creation of an object and return a 202 ACCEPTED, creating an entry that can be queried for status.

func (ServiceUtils) AddStatus

func (su ServiceUtils) AddStatus(requestId string, value interface{})

AddStatus adds a status of a request

func (ServiceUtils) GetStatus

func (su ServiceUtils) GetStatus(resourceType string, requestId string) (interface{}, error)

GetStatus gets the status of the request or returns an common.HttpError (404) if not found.

type Store

type Store interface {
	// SetConfig sets the configuration
	SetConfig(configMap map[string]interface{}) error
	// Connect connects to the store
	Connect() error
	// Create the schema, dropping existing one if the force flag is specified
	CreateSchema(force bool) error
}

Store defines generic store interface that can be used by any service for persistence.

type StoreConfig

type StoreConfig struct {
	Host     string
	Port     uint64
	Username string
	Password string
	Database string
	// Database type, e.g., sqlite3, mysql, etc.
	// TODO add a set of constants for it.
	Type string
}

StoreConfig stores information needed for a DB connection.

type UnmarshallerMiddleware

type UnmarshallerMiddleware struct {
}

func NewUnmarshaller

func NewUnmarshaller() *UnmarshallerMiddleware

func (UnmarshallerMiddleware) ServeHTTP

Unmarshals request body if needed. If not acceptable, returns an http.StatusNotAcceptable and this ends this request's lifecycle.

type UnwrappedRestHandlerInput

type UnwrappedRestHandlerInput struct {
	ResponseWriter http.ResponseWriter
	Request        *http.Request
}

UnwrappedRestHandlerInput is used to pass in http.Request and http.ResponseWriter, should some service like unfettered access directly to them. In such a case, the service's RestHandler's input will be of this type; and the return value will be ignored.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL