frame

package module
v1.7.8 Latest Latest
Warning

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

Go to latest
Published: Apr 21, 2022 License: Apache-2.0 Imports: 43 Imported by: 29

README

frame Build Status

A simple frame for quickly setting up api servers based on gocloud framework.

Features include:

  • An http server
  • A grpc server
  • Database setup using Gorm with migrations and multitenancy support
  • Easy queue publish and subscription support
  • Localization
  • Authentication adaptor for oauth2 and jwt access
  • Authorization adaptor

The goal of this project is to simplify starting up servers with minimal boiler plate code. All components are very pluggable with only the necessary configured items loading at runtime thanks to the power of go-cloud under the hood.

Getting started:

    go get -u github.com/pitabwire/frame

Example

import (
	"context"
	"fmt"
	"github.com/gorilla/mux"
	"github.com/pitabwire/frame"
	"log"
	"net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Frame says yelloo!")
}


func main() {

	serviceName := "service_authentication"
	ctx := context.Background()

	router := mux.NewRouter().StrictSlash(true)
	router.HandleFunc("/", handler)

	server := frame.HttpHandler(router)
	service := frame.NewService(serviceName,server)
	err := service.Run(ctx, ":7654")
	if err != nil {
		log.Fatal("main -- Could not run Server : %v", err)
	}

}

Detailed guides can be found here

development

To run tests start the docker compose file in ./tests then run :

    go test -json -cover ./...

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AuthHasAccess added in v1.4.0

func AuthHasAccess(ctx context.Context, action string, subject string) (error, bool)

AuthHasAccess binary check to confirm if subject can perform action specified

func AuthenticationMiddleware added in v1.0.7

func AuthenticationMiddleware(next http.Handler, audience string, issuer string) http.Handler

AuthenticationMiddleware Simple http middleware function to verify and extract authentication data supplied in a jwt as authorization bearer token

func DBErrorIsRecordNotFound added in v1.2.6

func DBErrorIsRecordNotFound(err error) bool

DBErrorIsRecordNotFound validate if supplied error is because of record missing in DB

func DBPropertiesFromMap added in v1.2.6

func DBPropertiesFromMap(propsMap map[string]string) datatypes.JSONMap

DBPropertiesFromMap converts a map into a JSONMap object

func DBPropertiesToMap added in v1.2.6

func DBPropertiesToMap(props datatypes.JSONMap) map[string]string

DBPropertiesToMap converts the supplied db json content into a golang map

func GetEnv

func GetEnv(key, fallback string) string

GetEnv Obtains the environment key or returns the default value

func GetIp

func GetIp(r *http.Request) string

GetIp convenience method to extract the remote ip address from our inbound request

func GetLocalIP

func GetLocalIP() string

GetLocalIP convenince method that obtains the non localhost ip address for machine running app

func GetMacAddress

func GetMacAddress() string

GetMacAddress convenience method to get some unique address based on the network interfaces the application is running on.

func StreamAuthInterceptor added in v1.0.7

func StreamAuthInterceptor(audience string, issuer string) grpc.StreamServerInterceptor

StreamAuthInterceptor An authentication claims extractor that will always verify the information flowing in the streams as true jwt claims

func ToContext

func ToContext(ctx context.Context, service *Service) context.Context

ToContext pushes a service instance into the supplied context for easier propagation

func UnaryAuthInterceptor added in v1.0.7

func UnaryAuthInterceptor(audience string, issuer string) grpc.UnaryServerInterceptor

UnaryAuthInterceptor Simple grpc interceptor to extract the jwt supplied via authorization bearer token and verify the authentication claims in the token

Types

type AuthenticationClaims added in v1.0.7

type AuthenticationClaims struct {
	ProfileID   string   `json:"sub,omitempty"`
	TenantID    string   `json:"tenant_id,omitempty"`
	PartitionID string   `json:"partition_id,omitempty"`
	AccessID    string   `json:"access_id,omitempty"`
	Roles       []string `json:"roles,omitempty"`
	jwt.RegisteredClaims
}

AuthenticationClaims Create a struct that will be encoded to a JWT. We add jwt.StandardClaims as an embedded type, to provide fields like expiry time

func ClaimsFromContext added in v1.0.7

func ClaimsFromContext(ctx context.Context) *AuthenticationClaims

ClaimsFromContext extracts authentication claims from the supplied context if any exist

func ClaimsFromMap added in v1.1.0

func ClaimsFromMap(m map[string]string) *AuthenticationClaims

ClaimsFromMap extracts authentication claims from the supplied map if they exist

func (*AuthenticationClaims) AsMetadata added in v1.0.7

func (a *AuthenticationClaims) AsMetadata() map[string]string

AsMetadata Creates a string map to be used as metadata in queue data

func (*AuthenticationClaims) ClaimsToContext added in v1.0.7

func (a *AuthenticationClaims) ClaimsToContext(ctx context.Context) context.Context

ClaimsToContext adds authentication claims to the current supplied context

func (*AuthenticationClaims) VerifyIssuer added in v1.7.2

func (a *AuthenticationClaims) VerifyIssuer(cmp string, req bool) bool

VerifyIssuer compares the iss claim against cmp. If required is false, this method will return true if the value matches or is unset

type BaseModel

type BaseModel struct {
	ID          string `gorm:"type:varchar(50);primary_key"`
	CreatedAt   time.Time
	ModifiedAt  time.Time
	Version     uint           `gorm:"DEFAULT 0"`
	TenantID    string         `gorm:"type:varchar(50);"`
	PartitionID string         `gorm:"type:varchar(50);"`
	AccessID    string         `gorm:"type:varchar(50);"`
	DeletedAt   gorm.DeletedAt `sql:"index"`
}

BaseModel base table struct to be extended by other models

func (*BaseModel) BeforeCreate

func (model *BaseModel) BeforeCreate(db *gorm.DB) error

func (*BaseModel) BeforeSave added in v1.2.9

func (model *BaseModel) BeforeSave(db *gorm.DB) error

BeforeSave Ensures we update a migrations time stamps

func (*BaseModel) BeforeUpdate

func (model *BaseModel) BeforeUpdate(db *gorm.DB) error

BeforeUpdate Updates time stamp every time we update status of a migration

func (*BaseModel) GenID added in v1.2.5

func (model *BaseModel) GenID(ctx context.Context)

GenID creates a new id for model if its not existent

func (*BaseModel) GetID

func (model *BaseModel) GetID() string

func (*BaseModel) GetVersion added in v1.7.3

func (model *BaseModel) GetVersion() uint

func (*BaseModel) ValidXID added in v1.7.0

func (model *BaseModel) ValidXID(id string) bool

ValidXID Validates that the supplied string is an xid

type BaseModelI

type BaseModelI interface {
	GetID() string
	GetVersion() uint
}

type BaseRepository added in v1.7.4

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

func NewBaseRepository added in v1.7.5

func NewBaseRepository(readDb *gorm.DB, writeDB *gorm.DB, instanceCreator func() BaseModelI) *BaseRepository

func (*BaseRepository) Delete added in v1.7.4

func (repo *BaseRepository) Delete(id string) error

func (*BaseRepository) GetAllBy added in v1.7.4

func (repo *BaseRepository) GetAllBy(properties map[string]interface{}, result []BaseModelI) error

func (*BaseRepository) GetByID added in v1.7.4

func (repo *BaseRepository) GetByID(id string, result BaseModelI) error

func (*BaseRepository) GetLastestBy added in v1.7.4

func (repo *BaseRepository) GetLastestBy(properties map[string]interface{}, result BaseModelI) error

func (*BaseRepository) Save added in v1.7.4

func (repo *BaseRepository) Save(instance BaseModelI) error

func (*BaseRepository) Search added in v1.7.4

func (repo *BaseRepository) Search(query string, searchFields []string, result []BaseModelI) error

type BaseRepositoryI added in v1.7.6

type BaseRepositoryI interface {
	GetByID(id string, result BaseModelI) error
	Delete(id string) error
	Save(instance BaseModelI) error
}

type EventI added in v1.6.1

type EventI interface {
	// Name represents the unique human readable id of the event that is used to pick it from the registry
	//or route follow up processing for system to process using this particular event
	Name() string

	// PayloadType determines the type of payload the event uses. This is useful for decoding queue data.
	PayloadType() interface{}

	// Validate enables automatic validation of payload supplied to the event without handling it in the execute block
	Validate(ctx context.Context, payload interface{}) error

	// Execute performs all the logic required to action a step in the sequence of events required to achieve the end goal.
	Execute(ctx context.Context, payload interface{}) error
}

EventI an interface to represent a system event. All logic of an event is handled in the execute task and can also emit other events into the system or if they don't emit an event the process is deemed complete.

type ILogger added in v1.6.1

type ILogger interface {
	Debug(template string, args ...interface{})
	Info(template string, args ...interface{})
	Warn(template string, args ...interface{})
	Error(template string, args ...interface{})
	Panic(template string, args ...interface{})
	Fatal(template string, args ...interface{})
}

type JSONWebKeys added in v1.1.7

type JSONWebKeys struct {
	Kty string   `json:"kty"`
	Kid string   `json:"kid"`
	Use string   `json:"use"`
	N   string   `json:"n"`
	E   string   `json:"e"`
	X5c []string `json:"x5c"`
}

type Jwks added in v1.1.7

type Jwks struct {
	Keys []JSONWebKeys `json:"keys"`
}

type Migration

type Migration struct {
	BaseModel

	Name      string `gorm:"type:varchar(50);uniqueIndex"`
	Patch     string `gorm:"type:text"`
	AppliedAt sql.NullTime
}

Migration Our simple table holding all the migration data

type Option

type Option func(service *Service)

func Datastore

func Datastore(ctx context.Context, postgresqlConnection string, readOnly bool) Option

Datastore Option method to store a connection that will be utilized when connecting to the database

func GrpcServer

func GrpcServer(grpcServer *grpc.Server) Option

GrpcServer Option to specify an instantiated grpc server with an implementation that can be utilized to handle incoming requests.

func HttpHandler

func HttpHandler(h http.Handler) Option

HttpHandler Option to specify an http handler that can be used to handle inbound http requests

func HttpOptions

func HttpOptions(httpOpts *server.Options) Option

HttpOptions Option to customize the default http server further to utilize enhanced features

func Logger added in v1.6.1

func Logger() Option

Logger Option that helps with initialization of our internal logger

func NoopHttpOptions added in v1.2.15

func NoopHttpOptions() Option

NoopHttpOptions Option to force the underlying http driver to not listen on a port. This is mostly useful when writing tests especially against the frame service

func QueuePath added in v1.4.0

func QueuePath(path string) Option

QueuePath Option that helps to specify or override the default /queue path to handle cloud events

func RegisterEvents added in v1.6.3

func RegisterEvents(events ...EventI) Option

RegisterEvents Option to write an event or list of events into the service registry for future use. All events are unique and shouldn't share a name otherwise the last one registered will take presedence

func RegisterPublisher

func RegisterPublisher(reference string, queueUrl string) Option

RegisterPublisher Option to register publishing path referenced within the system

func RegisterSubscriber

func RegisterSubscriber(reference string, queueUrl string, concurrency int,
	handler SubscribeWorker) Option

RegisterSubscriber Option to register a new subscription handler

func ServerListener

func ServerListener(listener net.Listener) Option

ServerListener Option to specify user preferred listener instead of the default provided one.

func Translations added in v1.0.5

func Translations(translationsFolder string, languages ...string) Option

Translations Option to initialize/load different language packs

type Service

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

Service framework struct to hold together all application components An instance of this type scoped to stay for the lifetime of the application. It is pushed and pulled from contexts to make it easy to pass around.

func FromContext

func FromContext(ctx context.Context) *Service

FromContext obtains a service instance being propagated through the context

func NewService

func NewService(name string, opts ...Option) *Service

NewService creates a new instance of Service with the name and supplied options It is used together with the Init option to setup components of a service that is not yet running.

func (*Service) AddCleanupMethod

func (s *Service) AddCleanupMethod(f func())

AddCleanupMethod Adds user defined functions to be run just before completely stopping the service. These are responsible for properly and gracefully stopping active components.

func (*Service) AddHealthCheck

func (s *Service) AddHealthCheck(checker health.Checker)

AddHealthCheck Adds health checks that are run periodically to ascertain the system is ok The arguments are implementations of the checker interface and should work with just about any system that is given to them.

func (*Service) AddPreStartMethod added in v1.1.3

func (s *Service) AddPreStartMethod(f func(s *Service))

AddPreStartMethod Adds user defined functions that can be run just before the service starts receiving requests but is fully initialized.

func (*Service) Bundle added in v1.0.6

func (s *Service) Bundle() *i18n.Bundle

Bundle Access the translation bundle instatiated in the system

func (*Service) DB

func (s *Service) DB(ctx context.Context, readOnly bool) *gorm.DB

DB obtains an already instantiated db connection with the option to specify if you want write or read only db connection

func (*Service) Emit added in v1.6.1

func (s *Service) Emit(ctx context.Context, name string, payload interface{}) error

Emit a simple method used to deploy

func (*Service) Init added in v1.0.4

func (s *Service) Init(opts ...Option)

Init evaluates the options provided as arguments and supplies them to the service object

func (*Service) InvokeRestService added in v1.0.15

func (s *Service) InvokeRestService(ctx context.Context, method string, endpointUrl string, payload map[string]interface{}, headers map[string][]string) (int, []byte, error)

InvokeRestService convenience method to call a http endpoint and utilize the raw results

func (*Service) L added in v1.6.1

func (s *Service) L() ILogger

func (*Service) MigrateDatastore

func (s *Service) MigrateDatastore(ctx context.Context, migrationsDirPath string, migrations ...interface{}) error

MigrateDatastore finds missing migrations and records them in the database

func (*Service) Name added in v1.4.0

func (s *Service) Name() string

Name gets the name of the service. Its the first argument used when NewService is called

func (Service) Publish

func (s Service) Publish(ctx context.Context, reference string, payload interface{}) error

Publish Queue method to write a new message into the queue pre initialized with the supplied reference

func (*Service) Run

func (s *Service) Run(ctx context.Context, address string) error

Run is used to actually instantiate the initialised components and keep them useful by handling incoming requests

func (*Service) Stop

func (s *Service) Stop()

Stop Used to gracefully run clean up methods. Ensuring all requests that were being handled are completed well without interuptions.

func (*Service) Translate added in v1.1.9

func (s *Service) Translate(request interface{}, messageId string) string

Translate performs a quick translation based on the supplied message id

func (*Service) TranslateWithMap added in v1.1.9

func (s *Service) TranslateWithMap(request interface{}, messageId string, variables map[string]interface{}) string

TranslateWithMap performs a translation with variables based on the supplied message id

func (*Service) TranslateWithMapAndCount added in v1.1.9

func (s *Service) TranslateWithMapAndCount(request interface{}, messageId string, variables map[string]interface{}, count int) string

TranslateWithMapAndCount performs a translation with variables based on the supplied message id and can pluralize

type SubscribeWorker

type SubscribeWorker interface {
	Handle(ctx context.Context, message []byte) error
}

Jump to

Keyboard shortcuts

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