implement grpc service and remove http service

This commit is contained in:
David Christofas
2020-03-13 14:37:52 +01:00
parent 78a92cf722
commit 35141c8e09
17 changed files with 452 additions and 359 deletions
+2
View File
@@ -9,8 +9,10 @@ require (
github.com/UnnoTed/fileb0x v1.1.4 // indirect
github.com/cespare/reflex v0.2.0 // indirect
github.com/go-chi/chi v4.0.2+incompatible
github.com/golang/protobuf v1.3.2
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/micro/cli/v2 v2.1.1
github.com/micro/go-micro/v2 v2.0.0
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
github.com/ogier/pflag v0.0.1 // indirect
github.com/oklog/run v1.0.0
+1
View File
@@ -487,6 +487,7 @@ github.com/micro/go-micro v1.18.0/go.mod h1:klwUJL1gkdY1MHFyz+fFJXn52dKcty4hoe95
github.com/micro/go-micro/v2 v2.0.0 h1:bMx549RwJ9Yuiui8cDVlfYhVNP8I8KBJTMyLthEXpRw=
github.com/micro/go-micro/v2 v2.0.0/go.mod h1:v7QP5UhKRt37ixjJe8DouWmg0/eE6dltr5h0idJ9BpE=
github.com/micro/go-plugins v1.5.1/go.mod h1:jcxejzJCAMH731cQHbS/hncyKe0rxAbzKkibj8glad4=
github.com/micro/go-plugins/wrapper/trace/opencensus/v2 v2.0.1 h1:7IkXfl94MdLZQwk0lNmu9Cg5WP42Zak9EtQMeN4SvVs=
github.com/micro/go-plugins/wrapper/trace/opencensus/v2 v2.0.1/go.mod h1:QrkcwcDtIs2hIJpIEhozekyf6Rfz5C36kFI8+zzCpX0=
github.com/micro/mdns v0.3.0 h1:bYycYe+98AXR3s8Nq5qvt6C573uFTDPIYzJemWON0QE=
github.com/micro/mdns v0.3.0/go.mod h1:KJ0dW7KmicXU2BV++qkLlmHYcVv7/hHnbtguSWt9Aoc=
+17 -72
View File
@@ -2,9 +2,9 @@ package command
import (
"context"
"fmt"
"os"
"os/signal"
"strings"
"time"
"contrib.go.opencensus.io/exporter/jaeger"
@@ -17,8 +17,7 @@ import (
"github.com/owncloud/ocis-thumbnails/pkg/config"
"github.com/owncloud/ocis-thumbnails/pkg/flagset"
"github.com/owncloud/ocis-thumbnails/pkg/metrics"
"github.com/owncloud/ocis-thumbnails/pkg/server/debug"
"github.com/owncloud/ocis-thumbnails/pkg/server/http"
"github.com/owncloud/ocis-thumbnails/pkg/server/grpc"
"go.opencensus.io/stats/view"
"go.opencensus.io/trace"
)
@@ -30,10 +29,6 @@ func Server(cfg *config.Config) *cli.Command {
Usage: "Start integrated server",
Flags: flagset.ServerWithConfig(cfg),
Before: func(c *cli.Context) error {
if cfg.HTTP.Root != "/" {
cfg.HTTP.Root = strings.TrimSuffix(cfg.HTTP.Root, "/")
}
return nil
},
Action: func(c *cli.Context) error {
@@ -131,72 +126,22 @@ func Server(cfg *config.Config) *cli.Command {
defer cancel()
{
server, err := http.Server(
http.Logger(logger),
http.Context(ctx),
http.Config(cfg),
http.Metrics(metrics),
http.Flags(flagset.RootWithConfig(cfg)),
http.Flags(flagset.ServerWithConfig(cfg)),
)
service := grpc.NewService(
grpc.Logger(logger),
grpc.Context(ctx),
grpc.Config(cfg),
grpc.Name(cfg.Server.Name),
grpc.Namespace(cfg.Server.Namespace),
grpc.Address(cfg.Server.Address),
grpc.Metrics(metrics),
)
if err != nil {
logger.Info().
Err(err).
Str("transport", "http").
Msg("Failed to initialize server")
return err
}
gr.Add(func() error {
return server.Run()
}, func(_ error) {
logger.Info().
Str("transport", "http").
Msg("Shutting down server")
cancel()
})
}
{
server, err := debug.Server(
debug.Logger(logger),
debug.Context(ctx),
debug.Config(cfg),
)
if err != nil {
logger.Info().
Err(err).
Str("transport", "debug").
Msg("Failed to initialize server")
return err
}
gr.Add(func() error {
return server.ListenAndServe()
}, func(_ error) {
ctx, timeout := context.WithTimeout(ctx, 5*time.Second)
defer timeout()
defer cancel()
if err := server.Shutdown(ctx); err != nil {
logger.Info().
Err(err).
Str("transport", "debug").
Msg("Failed to shutdown server")
} else {
logger.Info().
Str("transport", "debug").
Msg("Shutting down server")
}
})
}
gr.Add(func() error {
return service.Run()
}, func(_ error) {
fmt.Println("shutting down grpc server")
cancel()
})
{
stop := make(chan os.Signal, 1)
+5 -5
View File
@@ -15,11 +15,11 @@ type Debug struct {
Zpages bool
}
// HTTP defines the available http configuration.
type HTTP struct {
Addr string
// Server defines the available server configuration.
type Server struct {
Name string
Namespace string
Root string
Address string
}
// Tracing defines the available tracing configuration.
@@ -36,7 +36,7 @@ type Config struct {
File string
Log Log
Debug Debug
HTTP HTTP
Server Server
Tracing Tracing
FileSystemStorage FileSystemStorage
WebDavSource WebDavSource
+16 -16
View File
@@ -117,25 +117,25 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag {
Destination: &cfg.Debug.Zpages,
},
&cli.StringFlag{
Name: "http-addr",
Name: "grpc-name",
Value: "thumbnails",
Usage: "Name of the service",
EnvVars: []string{"THUMBNAILS_GRPC_NAME"},
Destination: &cfg.Server.Name,
},
&cli.StringFlag{
Name: "grpc-addr",
Value: "0.0.0.0:9185",
Usage: "Address to bind http server",
EnvVars: []string{"THUMBNAILS_HTTP_ADDR"},
Destination: &cfg.HTTP.Addr,
Usage: "Address to bind grpc server",
EnvVars: []string{"THUMBNAILS_GRPC_ADDR"},
Destination: &cfg.Server.Address,
},
&cli.StringFlag{
Name: "http-namespace",
Value: "com.owncloud.web",
Usage: "Set the base namespace for the http namespace",
EnvVars: []string{"THUMBNAILS_HTTP_NAMESPACE"},
Destination: &cfg.HTTP.Namespace,
},
&cli.StringFlag{
Name: "http-root",
Value: "/",
Usage: "Root path of http server",
EnvVars: []string{"THUMBNAILS_HTTP_ROOT"},
Destination: &cfg.HTTP.Root,
Name: "grpc-namespace",
Value: "com.owncloud.api",
Usage: "Set the base namespace for the grpc namespace",
EnvVars: []string{"THUMBNAILS_GRPC_NAMESPACE"},
Destination: &cfg.Server.Namespace,
},
&cli.StringFlag{
Name: "filesystemstorage-root",
+195
View File
@@ -0,0 +1,195 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: pkg/proto/v0/thumbnails.proto
package proto
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type GetRequest_FileType int32
const (
GetRequest_PNG GetRequest_FileType = 0
GetRequest_JPG GetRequest_FileType = 1
)
var GetRequest_FileType_name = map[int32]string{
0: "PNG",
1: "JPG",
}
var GetRequest_FileType_value = map[string]int32{
"PNG": 0,
"JPG": 1,
}
func (x GetRequest_FileType) String() string {
return proto.EnumName(GetRequest_FileType_name, int32(x))
}
func (GetRequest_FileType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_e354cb4f8a62b6c2, []int{0, 0}
}
type GetRequest struct {
Filepath string `protobuf:"bytes,1,opt,name=filepath,proto3" json:"filepath,omitempty"`
Filetype GetRequest_FileType `protobuf:"varint,2,opt,name=filetype,proto3,enum=com.owncloud.ocis.thumbnails.v0.GetRequest_FileType" json:"filetype,omitempty"`
Etag string `protobuf:"bytes,3,opt,name=etag,proto3" json:"etag,omitempty"`
Width int32 `protobuf:"varint,4,opt,name=width,proto3" json:"width,omitempty"`
Height int32 `protobuf:"varint,5,opt,name=height,proto3" json:"height,omitempty"`
Authorization string `protobuf:"bytes,6,opt,name=authorization,proto3" json:"authorization,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetRequest) Reset() { *m = GetRequest{} }
func (m *GetRequest) String() string { return proto.CompactTextString(m) }
func (*GetRequest) ProtoMessage() {}
func (*GetRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_e354cb4f8a62b6c2, []int{0}
}
func (m *GetRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetRequest.Unmarshal(m, b)
}
func (m *GetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetRequest.Marshal(b, m, deterministic)
}
func (m *GetRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetRequest.Merge(m, src)
}
func (m *GetRequest) XXX_Size() int {
return xxx_messageInfo_GetRequest.Size(m)
}
func (m *GetRequest) XXX_DiscardUnknown() {
xxx_messageInfo_GetRequest.DiscardUnknown(m)
}
var xxx_messageInfo_GetRequest proto.InternalMessageInfo
func (m *GetRequest) GetFilepath() string {
if m != nil {
return m.Filepath
}
return ""
}
func (m *GetRequest) GetFiletype() GetRequest_FileType {
if m != nil {
return m.Filetype
}
return GetRequest_PNG
}
func (m *GetRequest) GetEtag() string {
if m != nil {
return m.Etag
}
return ""
}
func (m *GetRequest) GetWidth() int32 {
if m != nil {
return m.Width
}
return 0
}
func (m *GetRequest) GetHeight() int32 {
if m != nil {
return m.Height
}
return 0
}
func (m *GetRequest) GetAuthorization() string {
if m != nil {
return m.Authorization
}
return ""
}
type GetResponse struct {
Thumbnail []byte `protobuf:"bytes,1,opt,name=thumbnail,proto3" json:"thumbnail,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetResponse) Reset() { *m = GetResponse{} }
func (m *GetResponse) String() string { return proto.CompactTextString(m) }
func (*GetResponse) ProtoMessage() {}
func (*GetResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_e354cb4f8a62b6c2, []int{1}
}
func (m *GetResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetResponse.Unmarshal(m, b)
}
func (m *GetResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetResponse.Marshal(b, m, deterministic)
}
func (m *GetResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetResponse.Merge(m, src)
}
func (m *GetResponse) XXX_Size() int {
return xxx_messageInfo_GetResponse.Size(m)
}
func (m *GetResponse) XXX_DiscardUnknown() {
xxx_messageInfo_GetResponse.DiscardUnknown(m)
}
var xxx_messageInfo_GetResponse proto.InternalMessageInfo
func (m *GetResponse) GetThumbnail() []byte {
if m != nil {
return m.Thumbnail
}
return nil
}
func init() {
proto.RegisterEnum("com.owncloud.ocis.thumbnails.v0.GetRequest_FileType", GetRequest_FileType_name, GetRequest_FileType_value)
proto.RegisterType((*GetRequest)(nil), "com.owncloud.ocis.thumbnails.v0.GetRequest")
proto.RegisterType((*GetResponse)(nil), "com.owncloud.ocis.thumbnails.v0.GetResponse")
}
func init() { proto.RegisterFile("pkg/proto/v0/thumbnails.proto", fileDescriptor_e354cb4f8a62b6c2) }
var fileDescriptor_e354cb4f8a62b6c2 = []byte{
// 300 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x91, 0x4f, 0x4f, 0xc2, 0x40,
0x10, 0xc5, 0x2d, 0x50, 0xfe, 0x8c, 0x68, 0xc8, 0xc4, 0x98, 0x86, 0x60, 0x24, 0xc4, 0x03, 0x09,
0x66, 0x21, 0xe8, 0x27, 0xf0, 0x60, 0x13, 0x0f, 0x86, 0x54, 0x4e, 0xde, 0x4a, 0x19, 0xd9, 0x8d,
0xa5, 0xbb, 0xd2, 0x29, 0x04, 0x13, 0x13, 0x3f, 0xba, 0x71, 0x2b, 0x45, 0x4f, 0xea, 0x69, 0xe7,
0xfd, 0x76, 0xf2, 0x66, 0xf6, 0x2d, 0x9c, 0x99, 0xe7, 0xc5, 0xd0, 0xac, 0x34, 0xeb, 0xe1, 0x7a,
0x34, 0x64, 0x99, 0x2d, 0x67, 0x49, 0xa8, 0xe2, 0x54, 0x58, 0x86, 0xe7, 0x91, 0x5e, 0x0a, 0xbd,
0x49, 0xa2, 0x58, 0x67, 0x73, 0xa1, 0x23, 0x95, 0x8a, 0x6f, 0x3d, 0xeb, 0x51, 0xef, 0xbd, 0x04,
0xe0, 0x13, 0x07, 0xf4, 0x92, 0x51, 0xca, 0xd8, 0x86, 0xfa, 0x93, 0x8a, 0xc9, 0x84, 0x2c, 0x3d,
0xa7, 0xeb, 0xf4, 0x1b, 0x41, 0xa1, 0x71, 0x92, 0xdf, 0xf1, 0xd6, 0x90, 0x57, 0xea, 0x3a, 0xfd,
0xe3, 0xf1, 0xb5, 0xf8, 0xc5, 0x5e, 0xec, 0xad, 0xc5, 0xad, 0x8a, 0x69, 0xba, 0x35, 0x14, 0x14,
0x2e, 0x88, 0x50, 0x21, 0x0e, 0x17, 0x5e, 0xd9, 0x4e, 0xb2, 0x35, 0x9e, 0x80, 0xbb, 0x51, 0x73,
0x96, 0x5e, 0xa5, 0xeb, 0xf4, 0xdd, 0x20, 0x17, 0x78, 0x0a, 0x55, 0x49, 0x6a, 0x21, 0xd9, 0x73,
0x2d, 0xfe, 0x52, 0x78, 0x01, 0x47, 0x61, 0xc6, 0x52, 0xaf, 0xd4, 0x6b, 0xc8, 0x4a, 0x27, 0x5e,
0xd5, 0x5a, 0xfd, 0x84, 0xbd, 0x0e, 0xd4, 0x77, 0xd3, 0xb1, 0x06, 0xe5, 0xc9, 0xbd, 0xdf, 0x3a,
0xf8, 0x2c, 0xee, 0x26, 0x7e, 0xcb, 0xe9, 0x0d, 0xe0, 0xd0, 0xae, 0x99, 0x1a, 0x9d, 0xa4, 0x84,
0x1d, 0x68, 0x14, 0x6f, 0xb0, 0x19, 0x34, 0x83, 0x3d, 0x18, 0xbf, 0x41, 0x6b, 0xba, 0x13, 0x0f,
0xb4, 0x5a, 0xab, 0x88, 0x50, 0x41, 0xd3, 0x27, 0x2e, 0x30, 0x0e, 0xfe, 0x11, 0x4b, 0xfb, 0xf2,
0x6f, 0xcd, 0xf9, 0x72, 0x37, 0xb5, 0x47, 0xd7, 0x7e, 0xec, 0xac, 0x6a, 0x8f, 0xab, 0x8f, 0x00,
0x00, 0x00, 0xff, 0xff, 0x54, 0x8e, 0xdc, 0xb1, 0x00, 0x02, 0x00, 0x00,
}
+85
View File
@@ -0,0 +1,85 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: pkg/proto/v0/thumbnails.proto
package proto
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
import (
context "context"
client "github.com/micro/go-micro/v2/client"
server "github.com/micro/go-micro/v2/server"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ client.Option
var _ server.Option
// Client API for ThumbnailService service
type ThumbnailService interface {
GetThumbnail(ctx context.Context, in *GetRequest, opts ...client.CallOption) (*GetResponse, error)
}
type thumbnailService struct {
c client.Client
name string
}
func NewThumbnailService(name string, c client.Client) ThumbnailService {
return &thumbnailService{
c: c,
name: name,
}
}
func (c *thumbnailService) GetThumbnail(ctx context.Context, in *GetRequest, opts ...client.CallOption) (*GetResponse, error) {
req := c.c.NewRequest(c.name, "ThumbnailService.GetThumbnail", in)
out := new(GetResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for ThumbnailService service
type ThumbnailServiceHandler interface {
GetThumbnail(context.Context, *GetRequest, *GetResponse) error
}
func RegisterThumbnailServiceHandler(s server.Server, hdlr ThumbnailServiceHandler, opts ...server.HandlerOption) error {
type thumbnailService interface {
GetThumbnail(ctx context.Context, in *GetRequest, out *GetResponse) error
}
type ThumbnailService struct {
thumbnailService
}
h := &thumbnailServiceHandler{hdlr}
return s.Handle(s.NewHandler(&ThumbnailService{h}, opts...))
}
type thumbnailServiceHandler struct {
ThumbnailServiceHandler
}
func (h *thumbnailServiceHandler) GetThumbnail(ctx context.Context, in *GetRequest, out *GetResponse) error {
return h.ThumbnailServiceHandler.GetThumbnail(ctx, in, out)
}
+25
View File
@@ -0,0 +1,25 @@
syntax = "proto3";
package com.owncloud.ocis.thumbnails.v0;
option go_package = "proto";
service ThumbnailService {
rpc GetThumbnail(GetRequest) returns (GetResponse);
}
message GetRequest {
string filepath = 1;
enum FileType {
PNG = 0;
JPG = 1;
}
FileType filetype = 2;
string etag = 3;
int32 width = 4;
int32 height = 5;
string authorization = 6;
}
message GetResponse {
bytes thumbnail = 1;
}
-50
View File
@@ -1,50 +0,0 @@
package debug
import (
"context"
"github.com/owncloud/ocis-thumbnails/pkg/config"
"github.com/owncloud/ocis-pkg/v2/log"
)
// Option defines a single option function.
type Option func(o *Options)
// Options defines the available options for this package.
type Options struct {
Logger log.Logger
Context context.Context
Config *config.Config
}
// newOptions initializes the available default options.
func newOptions(opts ...Option) Options {
opt := Options{}
for _, o := range opts {
o(&opt)
}
return opt
}
// Logger provides a function to set the logger option.
func Logger(val log.Logger) Option {
return func(o *Options) {
o.Logger = val
}
}
// Context provides a function to set the context option.
func Context(val context.Context) Option {
return func(o *Options) {
o.Context = val
}
}
// Config provides a function to set the config option.
func Config(val *config.Config) Option {
return func(o *Options) {
o.Config = val
}
}
-51
View File
@@ -1,51 +0,0 @@
package debug
import (
"io"
"net/http"
"github.com/owncloud/ocis-thumbnails/pkg/config"
"github.com/owncloud/ocis-thumbnails/pkg/version"
"github.com/owncloud/ocis-pkg/v2/service/debug"
)
// Server initializes the debug service and server.
func Server(opts ...Option) (*http.Server, error) {
options := newOptions(opts...)
return debug.NewService(
debug.Logger(options.Logger),
debug.Name("ocis-thumbnails"),
debug.Version(version.String),
debug.Address(options.Config.Debug.Addr),
debug.Token(options.Config.Debug.Token),
debug.Pprof(options.Config.Debug.Pprof),
debug.Zpages(options.Config.Debug.Zpages),
debug.Health(health(options.Config)),
debug.Ready(ready(options.Config)),
), nil
}
// health implements the health check.
func health(cfg *config.Config) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.WriteHeader(http.StatusOK)
// TODO(tboerger): check if services are up and running
io.WriteString(w, http.StatusText(http.StatusOK))
}
}
// ready implements the ready check.
func ready(cfg *config.Config) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.WriteHeader(http.StatusOK)
// TODO(tboerger): check if services are up and running
io.WriteString(w, http.StatusText(http.StatusOK))
}
}
@@ -1,12 +1,11 @@
package http
package grpc
import (
"context"
"github.com/micro/cli/v2"
"github.com/owncloud/ocis-pkg/v2/log"
"github.com/owncloud/ocis-thumbnails/pkg/config"
"github.com/owncloud/ocis-thumbnails/pkg/metrics"
"github.com/owncloud/ocis-pkg/v2/log"
)
// Option defines a single option function.
@@ -14,12 +13,13 @@ type Option func(o *Options)
// Options defines the available options for this package.
type Options struct {
Namespace string
Name string
Address string
Logger log.Logger
Context context.Context
Config *config.Config
Metrics *metrics.Metrics
Flags []cli.Flag
Namespace string
}
// newOptions initializes the available default options.
@@ -40,6 +40,20 @@ func Logger(val log.Logger) Option {
}
}
// Name provides a name for the service.
func Name(val string) Option {
return func(o *Options) {
o.Name = val
}
}
// Address provides an address for the service.
func Address(val string) Option {
return func(o *Options) {
o.Address = val
}
}
// Context provides a function to set the context option.
func Context(val context.Context) Option {
return func(o *Options) {
@@ -61,14 +75,7 @@ func Metrics(val *metrics.Metrics) Option {
}
}
// Flags provides a function to set the flags option.
func Flags(val []cli.Flag) Option {
return func(o *Options) {
o.Flags = append(o.Flags, val...)
}
}
// Namespace provides a function to set the Namespace option.
// Namespace provides a function to set the namespace option.
func Namespace(val string) Option {
return func(o *Options) {
o.Namespace = val
+39
View File
@@ -0,0 +1,39 @@
package grpc
import (
"github.com/owncloud/ocis-pkg/v2/service/grpc"
"github.com/owncloud/ocis-thumbnails/pkg/proto/v0"
svc "github.com/owncloud/ocis-thumbnails/pkg/service/v0"
"github.com/owncloud/ocis-thumbnails/pkg/version"
)
// NewService initializes the grpc service and server.
func NewService(opts ...Option) grpc.Service {
options := newOptions(opts...)
service := grpc.NewService(
grpc.Logger(options.Logger),
grpc.Namespace(options.Namespace),
grpc.Name(options.Name),
grpc.Version(version.String),
grpc.Address(options.Address),
grpc.Context(options.Context),
)
var thumbnail proto.ThumbnailServiceHandler
{
thumbnail = svc.NewService(
svc.Config(options.Config),
)
thumbnail = svc.NewInstrument(thumbnail, options.Metrics)
thumbnail = svc.NewLogging(thumbnail, options.Logger)
}
proto.RegisterThumbnailServiceHandler(
service.Server(),
thumbnail,
)
service.Init()
return service
}
-56
View File
@@ -1,56 +0,0 @@
package http
import (
svc "github.com/owncloud/ocis-thumbnails/pkg/service/v0"
"github.com/owncloud/ocis-thumbnails/pkg/version"
"github.com/owncloud/ocis-pkg/v2/middleware"
"github.com/owncloud/ocis-pkg/v2/service/http"
)
// Server initializes the http service and server.
func Server(opts ...Option) (http.Service, error) {
options := newOptions(opts...)
service := http.NewService(
http.Logger(options.Logger),
http.Name("thumbnails"),
http.Version(version.String),
http.Namespace(options.Config.HTTP.Namespace),
http.Address(options.Config.HTTP.Addr),
http.Context(options.Context),
http.Flags(options.Flags...),
)
handle := svc.NewService(
svc.Logger(options.Logger),
svc.Config(options.Config),
svc.Middleware(
middleware.RealIP,
middleware.RequestID,
middleware.Cache,
middleware.Cors,
middleware.Secure,
middleware.Version(
"thumbnails",
version.String,
),
middleware.Logger(
options.Logger,
),
),
)
{
handle = svc.NewInstrument(handle, options.Metrics)
handle = svc.NewLogging(handle, options.Logger)
handle = svc.NewTracing(handle)
}
service.Handle(
"/",
handle,
)
service.Init()
return service, nil
}
+7 -11
View File
@@ -1,13 +1,14 @@
package svc
import (
"net/http"
"context"
"github.com/owncloud/ocis-thumbnails/pkg/metrics"
v0proto "github.com/owncloud/ocis-thumbnails/pkg/proto/v0"
)
// NewInstrument returns a service that instruments metrics.
func NewInstrument(next Service, metrics *metrics.Metrics) Service {
func NewInstrument(next v0proto.ThumbnailServiceHandler, metrics *metrics.Metrics) v0proto.ThumbnailServiceHandler {
return instrument{
next: next,
metrics: metrics,
@@ -15,16 +16,11 @@ func NewInstrument(next Service, metrics *metrics.Metrics) Service {
}
type instrument struct {
next Service
next v0proto.ThumbnailServiceHandler
metrics *metrics.Metrics
}
// ServeHTTP implements the Service interface.
func (i instrument) ServeHTTP(w http.ResponseWriter, r *http.Request) {
i.next.ServeHTTP(w, r)
}
// Dummy implements the Service interface.
func (i instrument) Thumbnails(w http.ResponseWriter, r *http.Request) {
i.next.Thumbnails(w, r)
// GetThumbnail implements the ThumbnailServiceHandler interface.
func (i instrument) GetThumbnail(ctx context.Context, req *v0proto.GetRequest, rsp *v0proto.GetResponse) error {
return i.next.GetThumbnail(ctx, req, rsp)
}
+7 -11
View File
@@ -1,13 +1,14 @@
package svc
import (
"net/http"
"context"
"github.com/owncloud/ocis-pkg/v2/log"
v0proto "github.com/owncloud/ocis-thumbnails/pkg/proto/v0"
)
// NewLogging returns a service that logs messages.
func NewLogging(next Service, logger log.Logger) Service {
func NewLogging(next v0proto.ThumbnailServiceHandler, logger log.Logger) v0proto.ThumbnailServiceHandler {
return logging{
next: next,
logger: logger,
@@ -15,16 +16,11 @@ func NewLogging(next Service, logger log.Logger) Service {
}
type logging struct {
next Service
next v0proto.ThumbnailServiceHandler
logger log.Logger
}
// ServeHTTP implements the Service interface.
func (l logging) ServeHTTP(w http.ResponseWriter, r *http.Request) {
l.next.ServeHTTP(w, r)
}
// Dummy implements the Service interface.
func (l logging) Thumbnails(w http.ResponseWriter, r *http.Request) {
l.next.Thumbnails(w, r)
// GetThumbnail implements the ThumbnailServiceHandler interface.
func (l logging) GetThumbnail(ctx context.Context, req *v0proto.GetRequest, rsp *v0proto.GetResponse) error {
return l.next.GetThumbnail(ctx, req, rsp)
}
+25 -63
View File
@@ -2,33 +2,20 @@ package svc
import (
"context"
"net/http"
"strconv"
"fmt"
"github.com/go-chi/chi"
"github.com/owncloud/ocis-pkg/v2/log"
"github.com/owncloud/ocis-thumbnails/pkg/config"
v0proto "github.com/owncloud/ocis-thumbnails/pkg/proto/v0"
"github.com/owncloud/ocis-thumbnails/pkg/thumbnails"
"github.com/owncloud/ocis-thumbnails/pkg/thumbnails/imgsource"
"github.com/owncloud/ocis-thumbnails/pkg/thumbnails/storage"
)
// Service defines the extension handlers.
type Service interface {
ServeHTTP(http.ResponseWriter, *http.Request)
Thumbnails(http.ResponseWriter, *http.Request)
}
// NewService returns a service implementation for Service.
func NewService(opts ...Option) Service {
func NewService(opts ...Option) v0proto.ThumbnailServiceHandler {
options := newOptions(opts...)
m := chi.NewMux()
m.Use(options.Middleware...)
svc := Thumbnail{
config: options.Config,
mux: m,
manager: thumbnails.NewSimpleManager(
storage.NewFileSystemStorage(
options.Config.FileSystemStorage,
@@ -40,77 +27,52 @@ func NewService(opts ...Option) Service {
logger: options.Logger,
}
m.Route(options.Config.HTTP.Root, func(r chi.Router) {
r.Get("/thumbnails", svc.Thumbnails)
})
return svc
}
// Thumbnail implements the business logic for Service.
// Thumbnail implements the GRPC handler.
type Thumbnail struct {
config *config.Config
mux *chi.Mux
manager thumbnails.Manager
source imgsource.Source
logger log.Logger
}
// ServeHTTP implements the Service interface.
func (g Thumbnail) ServeHTTP(w http.ResponseWriter, r *http.Request) {
g.mux.ServeHTTP(w, r)
}
// Thumbnails provides the endpoint to retrieve a thumbnail for an image
func (g Thumbnail) Thumbnails(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
width, _ := strconv.Atoi(query.Get("width"))
height, _ := strconv.Atoi(query.Get("height"))
fileType := query.Get("type")
filePath := query.Get("file_path")
etag := query.Get("etag")
encoder := thumbnails.EncoderForType(fileType)
// GetThumbnail retrieves a thumbnail for an image
func (g Thumbnail) GetThumbnail(ctx context.Context, req *v0proto.GetRequest, rsp *v0proto.GetResponse) error {
encoder := thumbnails.EncoderForType(req.Filetype.String())
if encoder == nil {
// TODO: better error responses
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("can't encode that"))
return
return fmt.Errorf("can't be encoded. filetype %s not supported", req.Filetype.String())
}
ctx := thumbnails.Context{
Width: width,
Height: height,
ImagePath: filePath,
tCtx := thumbnails.Context{
Width: int(req.Width),
Height: int(req.Height),
ImagePath: req.Filepath,
Encoder: encoder,
ETag: etag,
ETag: req.Etag,
}
thumbnail := g.manager.GetStored(ctx)
thumbnail := g.manager.GetStored(tCtx)
if thumbnail != nil {
w.Write(thumbnail)
return
rsp.Thumbnail = thumbnail
return nil
}
auth := r.Header.Get("Authorization")
sCtx := context.WithValue(r.Context(), imgsource.WebDavAuth, auth)
auth := req.Authorization
sCtx := context.WithValue(ctx, imgsource.WebDavAuth, auth)
// TODO: clean up error handling
img, err := g.source.Get(sCtx, ctx.ImagePath)
img, err := g.source.Get(sCtx, tCtx.ImagePath)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
return err
}
if img == nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("img is nil"))
return
return fmt.Errorf("could not retrieve image")
}
thumbnail, err = g.manager.Get(ctx, img)
thumbnail, err = g.manager.Get(tCtx, img)
if err != nil {
w.Write([]byte(err.Error()))
return
return err
}
w.WriteHeader(http.StatusCreated)
w.Write(thumbnail)
rsp.Thumbnail = thumbnail
return nil
}
+8 -11
View File
@@ -1,26 +1,23 @@
package svc
import (
"net/http"
"context"
v0proto "github.com/owncloud/ocis-thumbnails/pkg/proto/v0"
)
// NewTracing returns a service that instruments traces.
func NewTracing(next Service) Service {
func NewTracing(next v0proto.ThumbnailServiceHandler) v0proto.ThumbnailServiceHandler {
return tracing{
next: next,
}
}
type tracing struct {
next Service
next v0proto.ThumbnailServiceHandler
}
// ServeHTTP implements the Service interface.
func (t tracing) ServeHTTP(w http.ResponseWriter, r *http.Request) {
t.next.ServeHTTP(w, r)
}
// Dummy implements the Service interface.
func (t tracing) Thumbnails(w http.ResponseWriter, r *http.Request) {
t.next.Thumbnails(w, r)
// GetThumbnail implements the ThumbnailServiceHandler interface.
func (t tracing) GetThumbnail(ctx context.Context, req *v0proto.GetRequest, rsp *v0proto.GetResponse) error {
return t.next.GetThumbnail(ctx, req, rsp)
}