service

package module
v0.13.0 Latest Latest
Warning

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

Go to latest
Published: Jul 4, 2018 License: BSD-3-Clause Imports: 14 Imported by: 5

README

service Latest Tag Build Status Go Report Card GoDoc

The robµlab service library is a convenience wrapper for easy microservice creation.


How to add to your project?

Run this in your project

$ burrow get github.com/embeddedenterprises/service

and use the library in your sourcecode like this.

package main

import (
	"os"

	"github.com/EmbeddedEnterprises/service"
	"github.com/gammazero/nexus/client"
	"github.com/op/go-logging"
)

func main() {
	srv := service.New(service.Config{
		Name:          "example",
		Serialization: client.MSGPACK,
		Version:       "0.1.0",
		Description:   "Simple example microservice from the documentation.",
		URL:           "ws://localhost:8000/ws",
	})
	srv.Connect()

	// register and subscribe here

	srv.Run()
	os.Exit(service.ExitSuccess)
}

Running the examples

Simple example

First you have to start a crossbar broker in the background.

$ docker run -p 127.0.0.1:8080:8080 --name crossbar --rm crossbario/crossbar:latest

The you can run the example service like this:

$ burrow run --example simple -- -b ws://localhost:8080/ws -r realm1
Authentication example

First you have to start the crossbar broker configured for authentication in the background.

$ docker run -p 127.0.0.1:8080:8080 \
    --mount type=bind,source=$(pwd)/example/auth/crossbar.json,target=/node/.crossbar/config.json \
    --name crossbar --rm crossbario/crossbar:latest

Then you can run the auth example like this:

$ burrow run --example auth -- -b ws://localhost:8080/ws
# Should yield 'no such principal with authid WRONG'

$ burrow run --example auth -- -b ws://localhost:8080/ws -u CORRECT
# Should yield 'authentication failed'

$ burrow run --example auth -- -b ws://localhost:8080/ws -u CORRECT -p CORRECT
# Should work just like the 'simple' example.

Documentation

Index

Examples

Constants

View Source
const (
	// ExitSuccess indicates that the service terminated without an error.
	ExitSuccess int = iota

	// ExitArgument indicates that the service terminated early as an argument was missing or malformed.
	ExitArgument

	// ExitService indicates that the service implementation ran into an unhandled error and could not be recovered.
	ExitService

	// ExitConnect indicates that the service failed to connect to the broker.
	ExitConnect

	// ExitRegistration indicates that the service failed to register or subscribe for a given topic or method.
	ExitRegistration
)
View Source
const BinaryDataExtension byte = 42
View Source
const EnvBrokerURL string = "SERVICE_BROKER_URL"

EnvBrokerURL defines the environment variable name for the broker url definition.

View Source
const EnvLogFormat string = "SERVICE_LOGFORMAT"

EnvLogFormat defines the environment variable name for the logging format string definition.

View Source
const EnvPassword string = "SERVICE_PASSWORD"

EnvPassword defines the environment variable name for the password the service is using to authenticate on the broker.

View Source
const EnvRealm string = "SERVICE_REALM"

EnvRealm defines the environment variable name for the realm definition.

View Source
const EnvSerialization string = "SERVICE_SERIALIZATION"

EnvSerialization defines the environment variable name for the serialization definition. Possible values are json and msgpack

View Source
const EnvTLSClientCertFile string = "TLS_CLIENT_CERT"

EnvTLSClientCertFile defines the environment variable name for the TLS client certificate public key to present to the router.

View Source
const EnvTLSClientKeyFile string = "TLS_CLIENT_KEY"

EnvTLSClientKeyFile defines the environment variable name for the TLS client certificate private key to present to the router.

View Source
const EnvTLSServerCertFile string = "TLS_SERVER_CERT"

EnvTLSServerCertFile defines the environment variable name for the TLS server certificate public key to verify the server certificate against.

View Source
const EnvUsername string = "SERVICE_USERNAME"

EnvUsername defines the environment variable name for the username the service is using to authenticate on the broker.

View Source
const Version string = "0.13.0"

Version defines the git tag this code is built with

Variables

This section is empty.

Functions

func IsRPCError added in v0.13.0

func IsRPCError(err error) bool

IsRPCError checks whether the given error is a wamp RPC error

func IsSpecificRPCError added in v0.13.0

func IsSpecificRPCError(err error, uri wamp.URI) bool

IsSpecificRPCError checks whether the given error is a wamp RPC error witch the expected error URI

func ReturnEmpty added in v0.12.0

func ReturnEmpty() *client.InvokeResult

ReturnEmpty constructs an empty wamp response, the equivalent of void. Its primary use is to save boilerplate code.

func ReturnError added in v0.12.0

func ReturnError(uri string) *client.InvokeResult

ReturnError constructs a wamp response which contains an error with the specified URI. Its primary use is to save boilerplate code.

func ReturnValue added in v0.12.0

func ReturnValue(value interface{}) *client.InvokeResult

ReturnValue constructs a wamp response which contains just one arbitrary value. Its primary use is to save boilerplate code.

Types

type Config

type Config struct {
	Name              string
	Version           string
	Description       string
	Serialization     serialize.Serialization
	URL               string
	Realm             string
	User              string
	Password          string
	TLSClientCertFile string
	TLSClientKeyFile  string
	TLSServerCertFile string
}

Config holds the default configuration that is applied to a `Service` instance when the configuration is not overridden by a cli argument or an environment variable. The cli argument always has priority!

type Error

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

Error is the holder of an inner error and a translated `ErrorKind`. Instances may be created with `NewError` or `NewErrorFrom`.

func NewError

func NewError(kind ErrorKind) *Error

NewError creates a new error from a given error kind.

func NewErrorFrom

func NewErrorFrom(kind ErrorKind, inner error) *Error

NewErrorFrom translates an inner to a given error kind and holds the inner error.

func (*Error) Error

func (e *Error) Error() string

type ErrorKind

type ErrorKind int

ErrorKind describes the type of an error that occurred during the execution of the microservice. It can be used as a basic set of errors that are used by implementors of this service library.

const (
	// ErrorBadArgument indicates that a given argument does not meet its requirements.
	ErrorBadArgument ErrorKind = iota

	// ErrorNotAvailable indicates that a requested resource is not available.
	ErrorNotAvailable

	// ErrorNotEnoughData indicates that the provided data is not enough.
	ErrorNotEnoughData

	// ErrorUnexpectedData indicates that the provided data is in an unexpected format.
	ErrorUnexpectedData

	// ErrorTooMuchData indicates that the provided data is too much.
	ErrorTooMuchData

	// ErrorOutOfRange indicates that a given index is out of range.
	ErrorOutOfRange

	// ErrorTimedOut indicates that a request has timed out.
	ErrorTimedOut

	// ErrorPermissionDenied indicates that the access to a resource was denied.
	ErrorPermissionDenied

	// ErrorNotFound indicates that a given resource could not be found.
	ErrorNotFound

	// ErrorUnreachableLineReached indicates that this code should not be reached as it is not implemented.
	ErrorUnreachableLineReached

	// ErrorThisWorksOnMyMachine indicates that this code needs complicated state to work. Contact your
	// system administrator for details.
	ErrorThisWorksOnMyMachine

	// ErrorItsNotABugItsAFeature indicates that the current behavior is intended. If you did not expect this to
	// happen, contact your system administrator.
	ErrorItsNotABugItsAFeature

	// ErrorAKittenDies indicates that something was nil...
	ErrorAKittenDies
)

type EventSubscription added in v0.9.0

type EventSubscription struct {
	Handler client.EventHandler
	Options wamp.Dict
}

EventSubscription holds a tuple of a `client.EventHandler` and an options map that can be used in the `SubscribeAll` function to subcribe to multiple topics at once.

type HandlerRegistration added in v0.8.0

type HandlerRegistration struct {
	Handler client.InvocationHandler
	Options wamp.Dict
}

HandlerRegistration holds a tuple of a `client.InvocationHandler` and an options map that can be used in the `RegisterAll` function to register multiple method handlers at once.

type RegistrationError added in v0.8.0

type RegistrationError struct {
	ProcedureName string
	Inner         error
}

RegistrationError describes an error that occurred during the registration of a remote procedure call. The struct holds the inner error and the procedure name that failed to register.

type Service

type Service struct {
	Logger *logging.Logger
	Client *client.Client
	// contains filtered or unexported fields
}

Service is a struct that holds all state that is needed to run the service. An instance of this struct is the main object that is used to communicate with the broker backend. Use the `New` function to create a service instance. The instance will give you access to the `Logger` and `Client` object.

func New

func New(defaultConfig Config) *Service

New creates a new service instance from the provided default configuration. The configuration can be overridden with command line arguments or environment variables.

You can look in the `examples` of the source repository for a more detailed example.

This function can exit the program early when

1. A version print was requested by the command line interface.

2. An error occurred while parsing the command line arguments.

3. An internal error occurrs that cannot be recovered.

Example
package main

import (
	"os"

	"github.com/EmbeddedEnterprises/service"
	"github.com/gammazero/nexus/client"
)

func main() {
	srv := service.New(service.Config{
		Name:          "example",
		Serialization: client.MSGPACK,
		Version:       "0.1.0",
		Description:   "Simple example microservice from the documentation.",
		URL:           "ws://localhost:8000/ws",
	})
	srv.Connect()

	// register and subscribe here

	srv.Run()
	os.Exit(service.ExitSuccess)
}

func (*Service) Connect

func (srv *Service) Connect()

Connect establishes a connection with the broker and must be called before `Run`!

This function may exit the program early when

1. Logger creation failed.

2. The client failed to join the realm.

func (*Service) RegisterAll added in v0.8.0

func (srv *Service) RegisterAll(procedures map[string]HandlerRegistration) *RegistrationError

RegisterAll can be used to register multiple remote procedure calls at once.

Example
package main

import (
	"context"
	"os"

	"github.com/EmbeddedEnterprises/service"
	"github.com/gammazero/nexus/client"
	"github.com/gammazero/nexus/wamp"
)

func dummyRegistration(_ context.Context, _ wamp.List, _, _ wamp.Dict) *client.InvokeResult {
	return service.ReturnEmpty()
}

func main() {
	srv := service.New(service.Config{
		Name:          "example",
		Serialization: client.MSGPACK,
		Version:       "0.1.0",
		Description:   "Simple example microservice from the documentation.",
		URL:           "ws://localhost:8000/ws",
	})
	srv.Connect()

	options := wamp.Dict{}
	procedures := map[string]service.HandlerRegistration{
		"example.get_magic":     {dummyRegistration, options},
		"example.do_stuff":      {dummyRegistration, options},
		"example.set_something": {dummyRegistration, options},
	}
	if err := srv.RegisterAll(procedures); err != nil {
		srv.Logger.Criticalf(
			"Failed to register procedure '%s' in broker: %s",
			err.ProcedureName,
			err,
		)
		os.Exit(service.ExitRegistration)
	}

	srv.Run()
	os.Exit(service.ExitSuccess)
}

func (*Service) Run

func (srv *Service) Run()

Run starts the microservice. This function blocks until the user interrupts the process with a SIGINT. It can be considered as the main loop of the service. This function may be only called once.

This function can exit the program early when

1. The client failed to leave the realm.

2. The client connection failed to close.

func (*Service) SubscribeAll added in v0.8.0

func (srv *Service) SubscribeAll(events map[string]EventSubscription) *SubscriptionError

SubscribeAll can be used to subscribe to multiple topics at once.

Example
package main

import (
	"os"

	"github.com/EmbeddedEnterprises/service"
	"github.com/gammazero/nexus/client"
	"github.com/gammazero/nexus/wamp"
)

func dummySubscription(_ wamp.List, _, _ wamp.Dict) {
}

func main() {
	srv := service.New(service.Config{
		Name:          "example",
		Serialization: client.MSGPACK,
		Version:       "0.1.0",
		Description:   "Simple example microservice from the documentation.",
		URL:           "ws://localhost:8000/ws",
	})
	srv.Connect()

	options := wamp.Dict{}
	events := map[string]service.EventSubscription{
		"example.goo_happened": {dummySubscription, options},
		"example.gesus_joined": {dummySubscription, options},
		"example.no_more_mate": {dummySubscription, options},
	}
	if err := srv.SubscribeAll(events); err != nil {
		srv.Logger.Criticalf(
			"Failed to subscribe to topic '%s' in broker: %s",
			err.Topic,
			err,
		)
		os.Exit(service.ExitRegistration)
	}

	srv.Run()
	os.Exit(service.ExitSuccess)
}

type SubscriptionError added in v0.9.0

type SubscriptionError struct {
	Topic string
	Inner error
}

SubscriptionError describes an error that occurred during the subscription on a topic. The struct holds the inner error and the topic name that failed to subscribe.

Directories

Path Synopsis
example
auth command
simple command

Jump to

Keyboard shortcuts

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