Merge pull request #3082 from owncloud/thumbnails_refactor_interface

Use decorator pattern and allow more methods to be decorated
This commit is contained in:
Willy Kloucek
2022-02-04 11:33:50 +01:00
committed by GitHub
6 changed files with 80 additions and 19 deletions

View File

@@ -6,6 +6,7 @@ import (
"github.com/owncloud/ocis/ocis-pkg/version"
thumbnailssvc "github.com/owncloud/ocis/protogen/gen/ocis/services/thumbnails/v0"
svc "github.com/owncloud/ocis/thumbnails/pkg/service/v0"
"github.com/owncloud/ocis/thumbnails/pkg/service/v0/decorators"
"github.com/owncloud/ocis/thumbnails/pkg/thumbnail/imgsource"
"github.com/owncloud/ocis/thumbnails/pkg/thumbnail/storage"
)
@@ -30,7 +31,7 @@ func NewService(opts ...Option) grpc.Service {
options.Logger.Error().Err(err).Msg("could not get gateway client")
return grpc.Service{}
}
var thumbnail thumbnailssvc.ThumbnailServiceHandler
var thumbnail decorators.DecoratedService
{
thumbnail = svc.NewService(
svc.Config(options.Config),
@@ -45,9 +46,9 @@ func NewService(opts ...Option) grpc.Service {
svc.CS3Source(imgsource.NewCS3Source(tconf, gc)),
svc.CS3Client(gc),
)
thumbnail = svc.NewInstrument(thumbnail, options.Metrics)
thumbnail = svc.NewLogging(thumbnail, options.Logger)
thumbnail = svc.NewTracing(thumbnail)
thumbnail = decorators.NewInstrument(thumbnail, options.Metrics)
thumbnail = decorators.NewLogging(thumbnail, options.Logger)
thumbnail = decorators.NewTracing(thumbnail)
}
_ = thumbnailssvc.RegisterThumbnailServiceHandler(

View File

@@ -0,0 +1,59 @@
package decorators
import (
"context"
thumbnailssvc "github.com/owncloud/ocis/protogen/gen/ocis/services/thumbnails/v0"
)
// Interface acting as facade, holding all the interfaces that this
// thumbnails microservice is expecting to implement.
// For now, only the thumbnailssvc.ThumbnailServiceHandler is present,
// but a future configsvc.ConfigServiceHandler is expected to be added here
//
// This interface will also act as the base interface to implement
// a decorator pattern.
type DecoratedService interface {
thumbnailssvc.ThumbnailServiceHandler
}
// Base type to implement the decorators. It will provide a basic implementation
// by delegating to the decoratedService
//
// Expected implementations will be like:
// ```
// type MyDecorator struct {
// Decorator
// myCustomOpts *opts
// additionalSrv *srv
// }
//
// func NewMyDecorator(next DecoratedService, customOpts *customOpts) DecoratedService {
// .....
// return MyDecorator{
// Decorator: Decorator{next: next},
// myCustomOpts: opts,
// additionalSrv: srv,
// }
// }
// ```
type Decorator struct {
next DecoratedService
}
// Base implementation for the GetThumbnail (for the thumbnailssvc).
// It will just delegate to the underlying decoratedService
//
// Your custom decorator is expected to overwrite this function,
// but it MUST call the underlying decoratedService at some point
// ```
// func (d MyDecorator) GetThumbnail(ctx context.Context, req *thumbnailssvc.GetThumbnailRequest, resp *thumbnailssvc.GetThumbnailResponse) error {
// doSomething()
// err := d.next.GetThumbnail(ctx, req, resp)
// doAnotherThing()
// return err
// }
// ```
func (deco Decorator) GetThumbnail(ctx context.Context, req *thumbnailssvc.GetThumbnailRequest, resp *thumbnailssvc.GetThumbnailResponse) error {
return deco.next.GetThumbnail(ctx, req, resp)
}

View File

@@ -1,4 +1,4 @@
package svc
package decorators
import (
"context"
@@ -9,15 +9,15 @@ import (
)
// NewInstrument returns a service that instruments metrics.
func NewInstrument(next thumbnailssvc.ThumbnailServiceHandler, metrics *metrics.Metrics) thumbnailssvc.ThumbnailServiceHandler {
func NewInstrument(next DecoratedService, metrics *metrics.Metrics) DecoratedService {
return instrument{
next: next,
metrics: metrics,
Decorator: Decorator{next: next},
metrics: metrics,
}
}
type instrument struct {
next thumbnailssvc.ThumbnailServiceHandler
Decorator
metrics *metrics.Metrics
}

View File

@@ -1,4 +1,4 @@
package svc
package decorators
import (
"context"
@@ -9,15 +9,15 @@ import (
)
// NewLogging returns a service that logs messages.
func NewLogging(next thumbnailssvc.ThumbnailServiceHandler, logger log.Logger) thumbnailssvc.ThumbnailServiceHandler {
func NewLogging(next DecoratedService, logger log.Logger) DecoratedService {
return logging{
next: next,
logger: logger,
Decorator: Decorator{next: next},
logger: logger,
}
}
type logging struct {
next thumbnailssvc.ThumbnailServiceHandler
Decorator
logger log.Logger
}

View File

@@ -1,4 +1,4 @@
package svc
package decorators
import (
"context"
@@ -11,14 +11,14 @@ import (
)
// NewTracing returns a service that instruments traces.
func NewTracing(next thumbnailssvc.ThumbnailServiceHandler) thumbnailssvc.ThumbnailServiceHandler {
func NewTracing(next DecoratedService) DecoratedService {
return tracing{
next: next,
Decorator: Decorator{next: next},
}
}
type tracing struct {
next thumbnailssvc.ThumbnailServiceHandler
Decorator
}
// GetThumbnail implements the ThumbnailServiceHandler interface.

View File

@@ -14,6 +14,7 @@ import (
"github.com/owncloud/ocis/ocis-pkg/log"
thumbnailssvc "github.com/owncloud/ocis/protogen/gen/ocis/services/thumbnails/v0"
"github.com/owncloud/ocis/thumbnails/pkg/preprocessor"
"github.com/owncloud/ocis/thumbnails/pkg/service/v0/decorators"
"github.com/owncloud/ocis/thumbnails/pkg/thumbnail"
"github.com/owncloud/ocis/thumbnails/pkg/thumbnail/imgsource"
"github.com/pkg/errors"
@@ -22,7 +23,7 @@ import (
)
// NewService returns a service implementation for Service.
func NewService(opts ...Option) thumbnailssvc.ThumbnailServiceHandler {
func NewService(opts ...Option) decorators.DecoratedService {
options := newOptions(opts...)
logger := options.Logger
resolutions, err := thumbnail.ParseResolutions(options.Config.Thumbnail.Resolutions)