components

package module
v1.0.6-10 Latest Latest
Warning

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

Go to latest
Published: Oct 7, 2022 License: MIT Imports: 13 Imported by: 0

README

Pip.Services Logo
Component definitions for Golang

This module is a part of the Pip.Services polyglot microservices toolkit.

The Components module contains standard component definitions that can be used to build applications and services.

The module contains the following packages:

  • Auth - authentication credential stores
  • Build - factories
  • Cache - distributed cache
  • Component - the root package
  • Config - configuration readers
  • Connect - connection discovery services
  • Count - performance counters
  • Info - context info
  • Lock - distributed locks
  • Log - logging components
  • Test - test components

Quick links:

Use

Get the package from the Github repository:

go get -u github.com/pip-services3-gox/pip-services3-components-gox@latest

Example how to use Logging and Performance counters. Here we are going to use CompositeLogger and CompositeCounters components. They will pass through calls to loggers and counters that are set in references.

import (
	"context"

	"github.com/pip-services3-gox/pip-services3-commons-gox/config"
	"github.com/pip-services3-gox/pip-services3-commons-gox/refer"
	"github.com/pip-services3-gox/pip-services3-components-gox/count"
	"github.com/pip-services3-gox/pip-services3-components-gox/log"
)

type MyComponent struct {
	logger   *log.CompositeLogger
	counters *count.CompositeCounters
}

func (c *MyComponent) Configure(ctx context.Context, config *config.ConfigParams) {
	c.logger.Configure(ctx, config)
}

func (c *MyComponent) SetReferences(ctx context.Context, references refer.IReferences) {
	c.logger.SetReferences(ctx, references)
	c.counters.SetReferences(ctx, references)
}

func (c *MyComponent) MyMethod(ctx context.Context, correlationId string, param1 any) {
	c.logger.Trace(ctx, correlationId, "Executed method mycomponent.mymethod")
	c.counters.Increment(ctx, "mycomponent.mymethod.exec_count", 1)
	timing := c.counters.BeginTiming(ctx, "mycomponent.mymethod.exec_time")
	defer timing.EndTiming(ctx)
	// ....

	if err != nil {
		c.logger.Error(ctx, correlationId, err, "Failed to execute mycomponent.mymethod")
		c.counters.Increment(ctx, "mycomponent.mymethod.error_count", 1)
	}
}

Example how to get connection parameters and credentials using resolvers. The resolvers support "discovery_key" and "store_key" configuration parameters to retrieve configuration from discovery services and credential stores respectively.

package main

import (
	"context"

	"github.com/pip-services3-gox/pip-services3-commons-gox/config"
	"github.com/pip-services3-gox/pip-services3-commons-gox/refer"
	"github.com/pip-services3-gox/pip-services3-components-gox/auth"
	"github.com/pip-services3-gox/pip-services3-components-gox/connect"
)

func main() {
	// Using the component
	myComponent := NewMyComponent()

	myComponent.Configure(context.Background(), config.NewConfigParamsFromTuples(
		"connection.host", "localhost",
		"connection.port", 1234,
		"credential.username", "anonymous",
		"credential.password", "pass123",
	))

	err := myComponent.Open(context.Background(), "123")
}

type MyComponent struct {
	connectionResolver *connect.ConnectionResolver
	credentialResolver *auth.CredentialResolver
}

func NewMyComponent() *MyComponent {
	return &MyComponent{
		connectionResolver: connect.NewEmptyConnectionResolver(),
		credentialResolver: auth.NewEmptyCredentialResolver(),
	}
}

func (c *MyComponent) Configure(ctx context.Context, config *config.ConfigParams) {
	c.connectionResolver.Configure(ctx, config)
	c.credentialResolver.Configure(ctx, config)
}

func (c *MyComponent) SetReferences(ctx context.Context, references refer.IReferences) {
	c.connectionResolver.SetReferences(ctx, references)
	c.credentialResolver.SetReferences(ctx, references)
}

// ...

func (c *MyComponent) IsOpen() bool {
	panic("not implemented") // TODO: Implement
}

func (c *MyComponent) Open(ctx context.Context, correlationId string) error {
	connection, err := c.connectionResolver.Resolve(correlationId)
	credential, err := c.credentialResolver.Lookup(ctx, correlationId)

	host := connection.Host()
	port := connection.Port()
	user := credential.Username()
	pass := credential.Password()
}

func (c *MyComponent) Close(ctx context.Context, correlationId string) error {
	panic("not implemented") // TODO: Implement
}

Example how to use caching and locking. Here we assume that references are passed externally.

package main

import (
	"context"

	"github.com/pip-services3-gox/pip-services3-commons-gox/refer"
	"github.com/pip-services3-gox/pip-services3-components-gox/cache"
	"github.com/pip-services3-gox/pip-services3-components-gox/lock"
)

func main() {
	// Use the component
	myComponent := NewMyComponent()

	myComponent.SetReferences(context.Background(), refer.NewReferencesFromTuples(context.Background(),
		refer.NewDescriptor("pip-services", "cache", "memory", "default", "1.0"), cache.NewMemoryCache[any](),
		refer.NewDescriptor("pip-services", "lock", "memory", "default", "1.0"), lock.NewMemoryLock(),
	))

	result, err := myComponent.MyMethod(context.Background(), "123", "my_param")
}

type MyComponent struct {
	cache cache.ICache[any]
	lock  lock.ILock
}

func NewMyComponent() *MyComponent {
	return &MyComponent{}
}

func (c *MyComponent) SetReferences(ctx context.Context, references refer.IReferences) {
	res, errDescr := references.GetOneRequired(refer.NewDescriptor("*", "cache", "*", "*", "1.0"))
	if errDescr != nil {
		panic(errDescr)
	}
	c.cache = res.(cache.ICache[any])

	res, errDescr = references.GetOneRequired(refer.NewDescriptor("*", "lock", "*", "*", "1.0"))
	if errDescr != nil {
		panic(errDescr)
	}
	c.lock = res.(lock.ILock)
}

func (c *MyComponent) MyMethod(ctx context.Context, correlationId string, param1 any) (any, error) {
	// First check cache for result
	result, err := c.cache.Retrieve(ctx, correlationId, "mykey")
	if result != nil || err != nil {
		return result, err
	}

	// Lock..
	err = c.lock.AcquireLock(ctx, correlationId, "mykey", 1000, 1000)
	if err != nil {
		return result, err
	}

	// Do processing
	// ...

	// Store result to cache async
	_, err = c.cache.Store(ctx, correlationId, "mykey", result, 3600000)
	if err != nil {
		return result, err
	}

	// Release lock async
	err = c.lock.ReleaseLock(ctx, correlationId, "mykey")
	if err != nil {
		return result, err
	}
	return result, nil
}

If you need to create components using their locators (descriptors) implement component factories similar to the example below.

package main

import (
	"github.com/pip-services3-gox/pip-services3-commons-gox/refer"
	"github.com/pip-services3-gox/pip-services3-components-gox/build"
)

var MyComponentDescriptor = refer.NewDescriptor("myservice", "mycomponent", "default", "*", "1.0")

func NewMyFactory() *build.Factory {
	factory := build.NewFactory()

	factory.RegisterType(MyComponentDescriptor, NewMyComponent)

	return factory
}

func main() {
	// Using the factory
	myFactory := NewMyFactory()
	myComponent1, err = myFactory.Create(refer.NewDescriptor("myservice", "mycomponent", "default", "myComponent1", "1.0"))
	myComponent2, err := myFactory.Create(refer.NewDescriptor("myservice", "mycomponent", "default", "myComponent2", "1.0"))
}

Develop

For development you shall install the following prerequisites:

  • Golang v1.18+
  • Visual Studio Code or another IDE of your choice
  • Docker
  • Git

Run automated tests:

go test -v ./test/...

Generate API documentation:

./docgen.ps1

Before committing changes run dockerized test as:

./test.ps1
./clear.ps1

Contacts

The library is created and maintained by Sergey Seroukhov.

The documentation is written by Levichev Dmitry.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Component

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

Abstract component that supportes configurable dependencies, logging and performance counters.

Configuration parameters
	- dependencies:
		- [dependency name 1]: Dependency 1 locator (descriptor)
		- ...
		- [dependency name N]: Dependency N locator (descriptor)
References
	- *:counters:*:*:1.0     (optional) ICounters components to pass collected measurements
	- *:logger:*:*:1.0       (optional) ILogger components to pass log messages
	- *:tracer:*:*:1.0       (optional) ITracer components to trace executed operations
	- ...                                    References must match configured dependencies.

func InheritComponent

func InheritComponent() *Component

func (*Component) Configure

func (c *Component) Configure(ctx context.Context, config *config.ConfigParams)

Configures component by passing configuration parameters.

Parameters:
	- ctx context.Context
	- config    configuration parameters to be set.

func (*Component) SetReferences

func (c *Component) SetReferences(ctx context.Context, references refer.IReferences)

SetReferences sets the component references. References must match configured dependencies.

Parameters:
	- ctx context.Context
	- references IReferences references to set.

Directories

Path Synopsis
log

Jump to

Keyboard shortcuts

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