Basic service boilerplate for settings bundles

This commit is contained in:
Benedikt Kulmann
2020-04-15 10:28:32 +02:00
parent a8af03c338
commit 5b89729d1e
18 changed files with 1007 additions and 142 deletions

View File

@@ -4,6 +4,8 @@ IMPORT := github.com/owncloud/$(NAME)
BIN := bin
DIST := dist
HUGO := hugo
PROTO_VERSION := v0
PROTO_SRC := pkg/proto/$(PROTO_VERSION)/*.proto
ifeq ($(OS), Windows_NT)
EXECUTABLE := $(NAME).exe
@@ -155,41 +157,6 @@ docs: docs-copy docs-build
watch:
go run github.com/cespare/reflex -c reflex.conf
# $(GOPATH)/bin/protoc-gen-go:
# GO111MODULE=off go get -v github.com/golang/protobuf/protoc-gen-go
# $(GOPATH)/bin/protoc-gen-micro:
# GO111MODULE=off go get -v github.com/micro/protoc-gen-micro
# $(GOPATH)/bin/protoc-gen-microweb:
# GO111MODULE=off go get -v github.com/webhippie/protoc-gen-microweb
# $(GOPATH)/bin/protoc-gen-swagger:
# GO111MODULE=off go get -v github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
# pkg/proto/v0/example.pb.go: pkg/proto/v0/example.proto
# protoc \
# -I=third_party/ \
# -I=pkg/proto/v0/ \
# --go_out=logtostderr=true:pkg/proto/v0 example.proto
# pkg/proto/v0/example.pb.micro.go: pkg/proto/v0/example.proto
# protoc \
# -I=third_party/ \
# -I=pkg/proto/v0/ \
# --micro_out=logtostderr=true:pkg/proto/v0 example.proto
# pkg/proto/v0/example.pb.web.go: pkg/proto/v0/example.proto
# protoc \
# -I=third_party/ \
# -I=pkg/proto/v0/ \
# --microweb_out=logtostderr=true:pkg/proto/v0 example.proto
# pkg/proto/v0/example.swagger.json: pkg/proto/v0/example.proto
# protoc \
# -I=third_party/ \
# -I=pkg/proto/v0/ \
# --swagger_out=logtostderr=true:pkg/proto/v0 example.proto
# .PHONY: protobuf
# protobuf: $(GOPATH)/bin/protoc-gen-go $(GOPATH)/bin/protoc-gen-micro $(GOPATH)/bin/protoc-gen-microweb $(GOPATH)/bin/protoc-gen-swagger pkg/proto/v0/example.pb.go pkg/proto/v0/example.pb.micro.go pkg/proto/v0/example.pb.web.go pkg/proto/v0/example.swagger.json
.PHONY: protoc-micro
protoc-micro:
protoc --go_out=. --micro_out=. $(PROTO_SRC)

4
go.mod
View File

@@ -8,11 +8,13 @@ require (
contrib.go.opencensus.io/exporter/zipkin v0.1.1
github.com/UnnoTed/fileb0x v1.1.4
github.com/go-chi/chi v4.1.0+incompatible
github.com/golang/protobuf v1.3.2
github.com/micro/cli/v2 v2.1.1
github.com/micro/go-micro/v2 v2.0.0
github.com/oklog/run v1.0.0
github.com/openzipkin/zipkin-go v0.2.2
github.com/owncloud/ocis-pkg/v2 v2.0.1
github.com/restic/calens v0.1.0
github.com/restic/calens v0.2.0
github.com/spf13/viper v1.5.0
go.opencensus.io v0.22.2
)

11
go.sum
View File

@@ -35,6 +35,9 @@ github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvd
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.0.2/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Masterminds/sprig/v3 v3.0.1/go.mod h1:Cp7HwZjmqKrC+Y7XqSJOU2yRvAJRGLiohfgz5ZJj8+4=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
@@ -203,6 +206,8 @@ github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
@@ -252,8 +257,10 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
github.com/haya14busa/goverage v0.0.0-20180129164344-eec3514a20b5 h1:FdBGmSkD2QpQzRWup//SGObvWf2nq89zj9+ta9OvI3A=
github.com/haya14busa/goverage v0.0.0-20180129164344-eec3514a20b5/go.mod h1:0YZ2wQSuwviXXXGUiK6zXzskyBLAbLXhamxzcFHSLoM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df/go.mod h1:QMZY7/J/KSQEhKWFeDesPjMj+wCHReeknARU3wqlyN4=
github.com/ijc/Gotty v0.0.0-20170406111628-a8b993ba6abd/go.mod h1:3LVOLeyx9XVvwPgrt2be44XgSqndprz1G18rSk8KD84=
github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
@@ -341,6 +348,7 @@ github.com/micro/go-micro v1.18.0 h1:gP70EZVHpJuUIT0YWth192JmlIci+qMOEByHm83XE9E
github.com/micro/go-micro v1.18.0/go.mod h1:klwUJL1gkdY1MHFyz+fFJXn52dKcty4hoe95Mp571AA=
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/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=
@@ -351,6 +359,7 @@ github.com/miekg/dns v1.1.22 h1:Jm64b3bO9kP43ddLjL2EY3Io6bmy1qGb9Xxz6TqS6rc=
github.com/miekg/dns v1.1.22/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.27 h1:aEH/kqUzUxGJ/UHcEKdJY+ugH6WEzsEBBSPa8zuy1aM=
github.com/miekg/dns v1.1.27/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed/go.mod h1:3rdaFaCv4AyBgu5ALFM0+tSuHrBh6v692nyQe3ikrq0=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
@@ -360,6 +369,7 @@ github.com/mitchellh/hashstructure v1.0.0 h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9
github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -465,6 +475,7 @@ github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKc
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/restic/calens v0.1.0 h1:RHGokdZ72dICyIz1EjEsfZwUhvNZz/zy2SawxJktdWA=
github.com/restic/calens v0.1.0/go.mod h1:u67f5msOjCTDYNzOf/NoAUSdmXP03YXPCwIQLYADy5M=
github.com/restic/calens v0.2.0/go.mod h1:UXwyAKS4wsgUZGEc7NrzzygJbLsQZIo3wl+62Q1wvmU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=

View File

@@ -2,6 +2,7 @@ package command
import (
"context"
"github.com/owncloud/ocis-settings/pkg/server/grpc"
"os"
"os/signal"
"strings"
@@ -16,9 +17,7 @@ import (
zipkinhttp "github.com/openzipkin/zipkin-go/reporter/http"
"github.com/owncloud/ocis-settings/pkg/config"
"github.com/owncloud/ocis-settings/pkg/flagset"
"github.com/owncloud/ocis-settings/pkg/metrics"
"github.com/owncloud/ocis-settings/pkg/server/debug"
"github.com/owncloud/ocis-settings/pkg/server/http"
"go.opencensus.io/stats/view"
"go.opencensus.io/trace"
)
@@ -129,31 +128,20 @@ func Server(cfg *config.Config) *cli.Command {
var (
gr = run.Group{}
ctx, cancel = context.WithCancel(context.Background())
metrics = metrics.New()
)
defer cancel()
{
server, err := http.Server(
http.Logger(logger),
http.Namespace(httpNamespace),
http.Context(ctx),
http.Config(cfg),
http.Metrics(metrics),
http.Flags(flagset.RootWithConfig(config.New())),
http.Flags(flagset.ServerWithConfig(config.New())),
server := grpc.Server(
grpc.Name("ocis-settings"),
grpc.Address(":9190"),
grpc.Logger(logger),
grpc.Context(ctx),
grpc.Config(cfg),
grpc.Namespace(httpNamespace),
)
if err != nil {
logger.Error().
Err(err).
Str("server", "http").
Msg("Failed to initialize server")
return err
}
gr.Add(func() error {
return server.Run()
}, func(_ error) {

View File

@@ -31,9 +31,15 @@ type Tracing struct {
Service string
}
// Storage defines the available storage configuration.
type Storage struct {
RootMountPath string
}
// Config combines all available configuration parts.
type Config struct {
File string
Storage Storage
Log Log
Debug Debug
HTTP HTTP

View File

@@ -134,5 +134,12 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag {
EnvVars: []string{"SETTINGS_HTTP_ROOT"},
Destination: &cfg.HTTP.Root,
},
&cli.StringFlag{
Name: "settings-root-mount-path",
Value: "/",
Usage: "Mount path for the storage",
EnvVars: []string{"SETTINGS_ROOT_MOUNT_PATH"},
Destination: &cfg.Storage.RootMountPath,
},
}
}

475
pkg/proto/v0/settings.pb.go Normal file
View File

@@ -0,0 +1,475 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: pkg/proto/v0/settings.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
// requests and responses
type CreateSettingsBundleRequest struct {
SettingsBundle *SettingsBundle `protobuf:"bytes,1,opt,name=settingsBundle,proto3" json:"settingsBundle,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CreateSettingsBundleRequest) Reset() { *m = CreateSettingsBundleRequest{} }
func (m *CreateSettingsBundleRequest) String() string { return proto.CompactTextString(m) }
func (*CreateSettingsBundleRequest) ProtoMessage() {}
func (*CreateSettingsBundleRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_199e73d7d5fd837b, []int{0}
}
func (m *CreateSettingsBundleRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CreateSettingsBundleRequest.Unmarshal(m, b)
}
func (m *CreateSettingsBundleRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CreateSettingsBundleRequest.Marshal(b, m, deterministic)
}
func (m *CreateSettingsBundleRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_CreateSettingsBundleRequest.Merge(m, src)
}
func (m *CreateSettingsBundleRequest) XXX_Size() int {
return xxx_messageInfo_CreateSettingsBundleRequest.Size(m)
}
func (m *CreateSettingsBundleRequest) XXX_DiscardUnknown() {
xxx_messageInfo_CreateSettingsBundleRequest.DiscardUnknown(m)
}
var xxx_messageInfo_CreateSettingsBundleRequest proto.InternalMessageInfo
func (m *CreateSettingsBundleRequest) GetSettingsBundle() *SettingsBundle {
if m != nil {
return m.SettingsBundle
}
return nil
}
type CreateSettingsBundleResponse struct {
SettingsBundle *SettingsBundle `protobuf:"bytes,1,opt,name=settingsBundle,proto3" json:"settingsBundle,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CreateSettingsBundleResponse) Reset() { *m = CreateSettingsBundleResponse{} }
func (m *CreateSettingsBundleResponse) String() string { return proto.CompactTextString(m) }
func (*CreateSettingsBundleResponse) ProtoMessage() {}
func (*CreateSettingsBundleResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_199e73d7d5fd837b, []int{1}
}
func (m *CreateSettingsBundleResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CreateSettingsBundleResponse.Unmarshal(m, b)
}
func (m *CreateSettingsBundleResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CreateSettingsBundleResponse.Marshal(b, m, deterministic)
}
func (m *CreateSettingsBundleResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_CreateSettingsBundleResponse.Merge(m, src)
}
func (m *CreateSettingsBundleResponse) XXX_Size() int {
return xxx_messageInfo_CreateSettingsBundleResponse.Size(m)
}
func (m *CreateSettingsBundleResponse) XXX_DiscardUnknown() {
xxx_messageInfo_CreateSettingsBundleResponse.DiscardUnknown(m)
}
var xxx_messageInfo_CreateSettingsBundleResponse proto.InternalMessageInfo
func (m *CreateSettingsBundleResponse) GetSettingsBundle() *SettingsBundle {
if m != nil {
return m.SettingsBundle
}
return nil
}
type GetSettingsBundleRequest struct {
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
Extension string `protobuf:"bytes,2,opt,name=extension,proto3" json:"extension,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetSettingsBundleRequest) Reset() { *m = GetSettingsBundleRequest{} }
func (m *GetSettingsBundleRequest) String() string { return proto.CompactTextString(m) }
func (*GetSettingsBundleRequest) ProtoMessage() {}
func (*GetSettingsBundleRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_199e73d7d5fd837b, []int{2}
}
func (m *GetSettingsBundleRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetSettingsBundleRequest.Unmarshal(m, b)
}
func (m *GetSettingsBundleRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetSettingsBundleRequest.Marshal(b, m, deterministic)
}
func (m *GetSettingsBundleRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetSettingsBundleRequest.Merge(m, src)
}
func (m *GetSettingsBundleRequest) XXX_Size() int {
return xxx_messageInfo_GetSettingsBundleRequest.Size(m)
}
func (m *GetSettingsBundleRequest) XXX_DiscardUnknown() {
xxx_messageInfo_GetSettingsBundleRequest.DiscardUnknown(m)
}
var xxx_messageInfo_GetSettingsBundleRequest proto.InternalMessageInfo
func (m *GetSettingsBundleRequest) GetKey() string {
if m != nil {
return m.Key
}
return ""
}
func (m *GetSettingsBundleRequest) GetExtension() string {
if m != nil {
return m.Extension
}
return ""
}
type GetSettingsBundleResponse struct {
SettingsBundle *SettingsBundle `protobuf:"bytes,1,opt,name=settingsBundle,proto3" json:"settingsBundle,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetSettingsBundleResponse) Reset() { *m = GetSettingsBundleResponse{} }
func (m *GetSettingsBundleResponse) String() string { return proto.CompactTextString(m) }
func (*GetSettingsBundleResponse) ProtoMessage() {}
func (*GetSettingsBundleResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_199e73d7d5fd837b, []int{3}
}
func (m *GetSettingsBundleResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetSettingsBundleResponse.Unmarshal(m, b)
}
func (m *GetSettingsBundleResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetSettingsBundleResponse.Marshal(b, m, deterministic)
}
func (m *GetSettingsBundleResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetSettingsBundleResponse.Merge(m, src)
}
func (m *GetSettingsBundleResponse) XXX_Size() int {
return xxx_messageInfo_GetSettingsBundleResponse.Size(m)
}
func (m *GetSettingsBundleResponse) XXX_DiscardUnknown() {
xxx_messageInfo_GetSettingsBundleResponse.DiscardUnknown(m)
}
var xxx_messageInfo_GetSettingsBundleResponse proto.InternalMessageInfo
func (m *GetSettingsBundleResponse) GetSettingsBundle() *SettingsBundle {
if m != nil {
return m.SettingsBundle
}
return nil
}
type ListSettingsBundlesRequest struct {
Extension string `protobuf:"bytes,1,opt,name=extension,proto3" json:"extension,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ListSettingsBundlesRequest) Reset() { *m = ListSettingsBundlesRequest{} }
func (m *ListSettingsBundlesRequest) String() string { return proto.CompactTextString(m) }
func (*ListSettingsBundlesRequest) ProtoMessage() {}
func (*ListSettingsBundlesRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_199e73d7d5fd837b, []int{4}
}
func (m *ListSettingsBundlesRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListSettingsBundlesRequest.Unmarshal(m, b)
}
func (m *ListSettingsBundlesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ListSettingsBundlesRequest.Marshal(b, m, deterministic)
}
func (m *ListSettingsBundlesRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_ListSettingsBundlesRequest.Merge(m, src)
}
func (m *ListSettingsBundlesRequest) XXX_Size() int {
return xxx_messageInfo_ListSettingsBundlesRequest.Size(m)
}
func (m *ListSettingsBundlesRequest) XXX_DiscardUnknown() {
xxx_messageInfo_ListSettingsBundlesRequest.DiscardUnknown(m)
}
var xxx_messageInfo_ListSettingsBundlesRequest proto.InternalMessageInfo
func (m *ListSettingsBundlesRequest) GetExtension() string {
if m != nil {
return m.Extension
}
return ""
}
type ListSettingsBundlesResponse struct {
SettingsBundles []*SettingsBundle `protobuf:"bytes,1,rep,name=settingsBundles,proto3" json:"settingsBundles,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ListSettingsBundlesResponse) Reset() { *m = ListSettingsBundlesResponse{} }
func (m *ListSettingsBundlesResponse) String() string { return proto.CompactTextString(m) }
func (*ListSettingsBundlesResponse) ProtoMessage() {}
func (*ListSettingsBundlesResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_199e73d7d5fd837b, []int{5}
}
func (m *ListSettingsBundlesResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListSettingsBundlesResponse.Unmarshal(m, b)
}
func (m *ListSettingsBundlesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ListSettingsBundlesResponse.Marshal(b, m, deterministic)
}
func (m *ListSettingsBundlesResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_ListSettingsBundlesResponse.Merge(m, src)
}
func (m *ListSettingsBundlesResponse) XXX_Size() int {
return xxx_messageInfo_ListSettingsBundlesResponse.Size(m)
}
func (m *ListSettingsBundlesResponse) XXX_DiscardUnknown() {
xxx_messageInfo_ListSettingsBundlesResponse.DiscardUnknown(m)
}
var xxx_messageInfo_ListSettingsBundlesResponse proto.InternalMessageInfo
func (m *ListSettingsBundlesResponse) GetSettingsBundles() []*SettingsBundle {
if m != nil {
return m.SettingsBundles
}
return nil
}
// payloads
type SettingsBundle struct {
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
DisplayName string `protobuf:"bytes,2,opt,name=displayName,proto3" json:"displayName,omitempty"`
Extension string `protobuf:"bytes,3,opt,name=extension,proto3" json:"extension,omitempty"`
Settings []*Setting `protobuf:"bytes,4,rep,name=settings,proto3" json:"settings,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *SettingsBundle) Reset() { *m = SettingsBundle{} }
func (m *SettingsBundle) String() string { return proto.CompactTextString(m) }
func (*SettingsBundle) ProtoMessage() {}
func (*SettingsBundle) Descriptor() ([]byte, []int) {
return fileDescriptor_199e73d7d5fd837b, []int{6}
}
func (m *SettingsBundle) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SettingsBundle.Unmarshal(m, b)
}
func (m *SettingsBundle) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SettingsBundle.Marshal(b, m, deterministic)
}
func (m *SettingsBundle) XXX_Merge(src proto.Message) {
xxx_messageInfo_SettingsBundle.Merge(m, src)
}
func (m *SettingsBundle) XXX_Size() int {
return xxx_messageInfo_SettingsBundle.Size(m)
}
func (m *SettingsBundle) XXX_DiscardUnknown() {
xxx_messageInfo_SettingsBundle.DiscardUnknown(m)
}
var xxx_messageInfo_SettingsBundle proto.InternalMessageInfo
func (m *SettingsBundle) GetKey() string {
if m != nil {
return m.Key
}
return ""
}
func (m *SettingsBundle) GetDisplayName() string {
if m != nil {
return m.DisplayName
}
return ""
}
func (m *SettingsBundle) GetExtension() string {
if m != nil {
return m.Extension
}
return ""
}
func (m *SettingsBundle) GetSettings() []*Setting {
if m != nil {
return m.Settings
}
return nil
}
type Setting struct {
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
DisplayName string `protobuf:"bytes,2,opt,name=displayName,proto3" json:"displayName,omitempty"`
Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
Values []*SettingsValue `protobuf:"bytes,4,rep,name=values,proto3" json:"values,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Setting) Reset() { *m = Setting{} }
func (m *Setting) String() string { return proto.CompactTextString(m) }
func (*Setting) ProtoMessage() {}
func (*Setting) Descriptor() ([]byte, []int) {
return fileDescriptor_199e73d7d5fd837b, []int{7}
}
func (m *Setting) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Setting.Unmarshal(m, b)
}
func (m *Setting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Setting.Marshal(b, m, deterministic)
}
func (m *Setting) XXX_Merge(src proto.Message) {
xxx_messageInfo_Setting.Merge(m, src)
}
func (m *Setting) XXX_Size() int {
return xxx_messageInfo_Setting.Size(m)
}
func (m *Setting) XXX_DiscardUnknown() {
xxx_messageInfo_Setting.DiscardUnknown(m)
}
var xxx_messageInfo_Setting proto.InternalMessageInfo
func (m *Setting) GetKey() string {
if m != nil {
return m.Key
}
return ""
}
func (m *Setting) GetDisplayName() string {
if m != nil {
return m.DisplayName
}
return ""
}
func (m *Setting) GetDescription() string {
if m != nil {
return m.Description
}
return ""
}
func (m *Setting) GetValues() []*SettingsValue {
if m != nil {
return m.Values
}
return nil
}
type SettingsValue struct {
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *SettingsValue) Reset() { *m = SettingsValue{} }
func (m *SettingsValue) String() string { return proto.CompactTextString(m) }
func (*SettingsValue) ProtoMessage() {}
func (*SettingsValue) Descriptor() ([]byte, []int) {
return fileDescriptor_199e73d7d5fd837b, []int{8}
}
func (m *SettingsValue) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SettingsValue.Unmarshal(m, b)
}
func (m *SettingsValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SettingsValue.Marshal(b, m, deterministic)
}
func (m *SettingsValue) XXX_Merge(src proto.Message) {
xxx_messageInfo_SettingsValue.Merge(m, src)
}
func (m *SettingsValue) XXX_Size() int {
return xxx_messageInfo_SettingsValue.Size(m)
}
func (m *SettingsValue) XXX_DiscardUnknown() {
xxx_messageInfo_SettingsValue.DiscardUnknown(m)
}
var xxx_messageInfo_SettingsValue proto.InternalMessageInfo
func (m *SettingsValue) GetType() string {
if m != nil {
return m.Type
}
return ""
}
func init() {
proto.RegisterType((*CreateSettingsBundleRequest)(nil), "proto.CreateSettingsBundleRequest")
proto.RegisterType((*CreateSettingsBundleResponse)(nil), "proto.CreateSettingsBundleResponse")
proto.RegisterType((*GetSettingsBundleRequest)(nil), "proto.GetSettingsBundleRequest")
proto.RegisterType((*GetSettingsBundleResponse)(nil), "proto.GetSettingsBundleResponse")
proto.RegisterType((*ListSettingsBundlesRequest)(nil), "proto.ListSettingsBundlesRequest")
proto.RegisterType((*ListSettingsBundlesResponse)(nil), "proto.ListSettingsBundlesResponse")
proto.RegisterType((*SettingsBundle)(nil), "proto.SettingsBundle")
proto.RegisterType((*Setting)(nil), "proto.Setting")
proto.RegisterType((*SettingsValue)(nil), "proto.SettingsValue")
}
func init() {
proto.RegisterFile("pkg/proto/v0/settings.proto", fileDescriptor_199e73d7d5fd837b)
}
var fileDescriptor_199e73d7d5fd837b = []byte{
// 392 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x94, 0x41, 0x4f, 0xea, 0x40,
0x10, 0xc7, 0x53, 0xe0, 0xc1, 0x63, 0x08, 0xbc, 0xf7, 0xf6, 0x61, 0x52, 0x0b, 0x89, 0x75, 0xb9,
0x18, 0x63, 0xc0, 0xe0, 0xcd, 0xc4, 0x98, 0xe0, 0xc1, 0xc4, 0x18, 0x0f, 0x25, 0xe1, 0x40, 0x50,
0x53, 0x61, 0x42, 0x1a, 0xb0, 0xad, 0xdd, 0x85, 0xc8, 0x87, 0xd0, 0x8f, 0xe1, 0xe7, 0x34, 0xb4,
0x8b, 0xb0, 0xeb, 0x96, 0x83, 0x7a, 0xda, 0xcd, 0xcc, 0x7f, 0xfe, 0xfb, 0xdb, 0xe9, 0x6c, 0xa1,
0x16, 0x4e, 0xc6, 0xad, 0x30, 0x0a, 0x78, 0xd0, 0x9a, 0x1f, 0xb7, 0x18, 0x72, 0xee, 0xf9, 0x63,
0xd6, 0x8c, 0x23, 0xe4, 0x57, 0xbc, 0xd0, 0x01, 0xd4, 0x2e, 0x22, 0x74, 0x39, 0x76, 0x45, 0xba,
0x33, 0xf3, 0x47, 0x53, 0x74, 0xf0, 0x69, 0x86, 0x8c, 0x93, 0x33, 0xa8, 0x30, 0x29, 0x61, 0x1a,
0xb6, 0x71, 0x50, 0x6a, 0xef, 0x24, 0x2e, 0x4d, 0xa5, 0x4a, 0x11, 0xd3, 0x5b, 0xa8, 0xeb, 0xdd,
0x59, 0x18, 0xf8, 0x0c, 0xbf, 0x6b, 0x7f, 0x05, 0xe6, 0x25, 0x72, 0x3d, 0xf9, 0x5f, 0xc8, 0x4e,
0x70, 0x11, 0xfb, 0x15, 0x9d, 0xe5, 0x96, 0xd4, 0xa1, 0x88, 0xcf, 0x1c, 0x7d, 0xe6, 0x05, 0xbe,
0x99, 0x89, 0xe3, 0xeb, 0x00, 0xed, 0xc3, 0xae, 0xc6, 0xeb, 0x67, 0x38, 0x4f, 0xc1, 0xba, 0xf6,
0x98, 0x62, 0xce, 0x56, 0xa4, 0x12, 0x97, 0xa1, 0x72, 0xdd, 0x41, 0x4d, 0x5b, 0x2b, 0xc8, 0xce,
0xe1, 0x8f, 0x7c, 0x18, 0x33, 0x0d, 0x3b, 0x9b, 0x8e, 0xa6, 0xaa, 0xe9, 0xab, 0x01, 0x15, 0x59,
0xa3, 0x69, 0x9d, 0x0d, 0xa5, 0x91, 0xc7, 0xc2, 0xa9, 0xbb, 0xb8, 0x71, 0x1f, 0x51, 0x34, 0x6f,
0x33, 0x24, 0x5f, 0x22, 0xab, 0x5c, 0x82, 0x1c, 0xc2, 0xef, 0xd5, 0xb9, 0x66, 0x2e, 0xc6, 0xab,
0xc8, 0x78, 0xce, 0x47, 0x9e, 0xbe, 0x18, 0x50, 0x10, 0xd1, 0x2f, 0x91, 0x2c, 0x15, 0xc8, 0x86,
0x91, 0x17, 0xf2, 0x35, 0xcb, 0x66, 0x88, 0x1c, 0x41, 0x7e, 0xee, 0x4e, 0x67, 0xb8, 0x62, 0xa9,
0x2a, 0xad, 0xea, 0x2d, 0x93, 0x8e, 0xd0, 0xd0, 0x06, 0x94, 0xa5, 0x04, 0x21, 0x90, 0xe3, 0x8b,
0x10, 0x05, 0x55, 0xbc, 0x6f, 0xbf, 0x65, 0xa0, 0x9c, 0x74, 0xaf, 0x8b, 0xd1, 0xdc, 0x1b, 0x22,
0xb9, 0x87, 0xaa, 0x6e, 0xf4, 0x09, 0x15, 0x87, 0x6d, 0x79, 0x75, 0x56, 0x63, 0xab, 0x46, 0x7c,
0xf9, 0x1e, 0xfc, 0xfb, 0x34, 0xb0, 0x64, 0x4f, 0x54, 0xa6, 0x3d, 0x0b, 0xcb, 0x4e, 0x17, 0x08,
0xdf, 0x01, 0xfc, 0xd7, 0x0c, 0x1c, 0xd9, 0x17, 0x85, 0xe9, 0x83, 0x6c, 0xd1, 0x6d, 0x92, 0xc4,
0xbd, 0x53, 0xe8, 0x27, 0x3f, 0x9e, 0x87, 0x7c, 0xbc, 0x9c, 0xbc, 0x07, 0x00, 0x00, 0xff, 0xff,
0x1d, 0x4a, 0xf8, 0xc6, 0xa5, 0x04, 0x00, 0x00,
}

View File

@@ -0,0 +1,119 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: pkg/proto/v0/settings.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 BundleService service
type BundleService interface {
CreateSettingsBundle(ctx context.Context, in *CreateSettingsBundleRequest, opts ...client.CallOption) (*CreateSettingsBundleResponse, error)
GetSettingsBundle(ctx context.Context, in *GetSettingsBundleRequest, opts ...client.CallOption) (*GetSettingsBundleResponse, error)
ListSettingsBundles(ctx context.Context, in *ListSettingsBundlesRequest, opts ...client.CallOption) (*ListSettingsBundlesResponse, error)
}
type bundleService struct {
c client.Client
name string
}
func NewBundleService(name string, c client.Client) BundleService {
return &bundleService{
c: c,
name: name,
}
}
func (c *bundleService) CreateSettingsBundle(ctx context.Context, in *CreateSettingsBundleRequest, opts ...client.CallOption) (*CreateSettingsBundleResponse, error) {
req := c.c.NewRequest(c.name, "BundleService.CreateSettingsBundle", in)
out := new(CreateSettingsBundleResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *bundleService) GetSettingsBundle(ctx context.Context, in *GetSettingsBundleRequest, opts ...client.CallOption) (*GetSettingsBundleResponse, error) {
req := c.c.NewRequest(c.name, "BundleService.GetSettingsBundle", in)
out := new(GetSettingsBundleResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *bundleService) ListSettingsBundles(ctx context.Context, in *ListSettingsBundlesRequest, opts ...client.CallOption) (*ListSettingsBundlesResponse, error) {
req := c.c.NewRequest(c.name, "BundleService.ListSettingsBundles", in)
out := new(ListSettingsBundlesResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for BundleService service
type BundleServiceHandler interface {
CreateSettingsBundle(context.Context, *CreateSettingsBundleRequest, *CreateSettingsBundleResponse) error
GetSettingsBundle(context.Context, *GetSettingsBundleRequest, *GetSettingsBundleResponse) error
ListSettingsBundles(context.Context, *ListSettingsBundlesRequest, *ListSettingsBundlesResponse) error
}
func RegisterBundleServiceHandler(s server.Server, hdlr BundleServiceHandler, opts ...server.HandlerOption) error {
type bundleService interface {
CreateSettingsBundle(ctx context.Context, in *CreateSettingsBundleRequest, out *CreateSettingsBundleResponse) error
GetSettingsBundle(ctx context.Context, in *GetSettingsBundleRequest, out *GetSettingsBundleResponse) error
ListSettingsBundles(ctx context.Context, in *ListSettingsBundlesRequest, out *ListSettingsBundlesResponse) error
}
type BundleService struct {
bundleService
}
h := &bundleServiceHandler{hdlr}
return s.Handle(s.NewHandler(&BundleService{h}, opts...))
}
type bundleServiceHandler struct {
BundleServiceHandler
}
func (h *bundleServiceHandler) CreateSettingsBundle(ctx context.Context, in *CreateSettingsBundleRequest, out *CreateSettingsBundleResponse) error {
return h.BundleServiceHandler.CreateSettingsBundle(ctx, in, out)
}
func (h *bundleServiceHandler) GetSettingsBundle(ctx context.Context, in *GetSettingsBundleRequest, out *GetSettingsBundleResponse) error {
return h.BundleServiceHandler.GetSettingsBundle(ctx, in, out)
}
func (h *bundleServiceHandler) ListSettingsBundles(ctx context.Context, in *ListSettingsBundlesRequest, out *ListSettingsBundlesResponse) error {
return h.BundleServiceHandler.ListSettingsBundles(ctx, in, out)
}

View File

@@ -0,0 +1,55 @@
syntax = "proto3";
package proto;
option go_package = "proto";
service BundleService {
rpc CreateSettingsBundle(CreateSettingsBundleRequest) returns (CreateSettingsBundleResponse);
rpc GetSettingsBundle(GetSettingsBundleRequest) returns (GetSettingsBundleResponse);
rpc ListSettingsBundles(ListSettingsBundlesRequest) returns (ListSettingsBundlesResponse);
}
// requests and responses
message CreateSettingsBundleRequest {
SettingsBundle settingsBundle = 1;
}
message CreateSettingsBundleResponse {
SettingsBundle settingsBundle = 1;
}
message GetSettingsBundleRequest {
string extension = 1;
string key = 2;
}
message GetSettingsBundleResponse {
SettingsBundle settingsBundle = 1;
}
message ListSettingsBundlesRequest {
string extension = 1;// can be limited to all settings bundles of an extension
}
message ListSettingsBundlesResponse {
repeated SettingsBundle settingsBundles = 1;
}
// payloads
message SettingsBundle {
string extension = 1;
string key = 2;
string displayName = 3;
repeated Setting settings = 4;
}
message Setting {
string key = 1;
string displayName = 2;
string description = 3;
repeated SettingsValue values = 4;
}
message SettingsValue {
string type = 1;
}

74
pkg/server/grpc/option.go Normal file
View File

@@ -0,0 +1,74 @@
package grpc
import (
"context"
"github.com/owncloud/ocis-settings/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 {
Name string
Address string
Logger log.Logger
Context context.Context
Config *config.Config
Namespace string
}
// 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
}
}
// 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) {
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
}
}
// Namespace provides a function to set the namespace option.
func Namespace(val string) Option {
return func(o *Options) {
o.Namespace = val
}
}

28
pkg/server/grpc/server.go Normal file
View File

@@ -0,0 +1,28 @@
package grpc
import (
"github.com/owncloud/ocis-settings/pkg/proto/v0"
svc "github.com/owncloud/ocis-settings/pkg/service/v0"
"github.com/owncloud/ocis-pkg/v2/service/grpc"
)
// NewService initializes a new go-micro service ready to run
func Server(opts ...Option) grpc.Service {
options := newOptions(opts...)
service := grpc.NewService(
grpc.Name(options.Name),
grpc.Context(options.Context),
grpc.Address(options.Address),
grpc.Namespace(options.Namespace),
grpc.Logger(options.Logger),
)
hdlr := svc.NewService(options.Config)
if err := proto.RegisterBundleServiceHandler(service.Server(), hdlr); err != nil {
options.Logger.Fatal().Err(err).Msg("could not register service handler")
}
service.Init()
return service
}

View File

@@ -1,30 +1,15 @@
package svc
import (
"net/http"
"github.com/owncloud/ocis-settings/pkg/metrics"
)
// NewInstrument returns a service that instruments metrics.
func NewInstrument(next Service, metrics *metrics.Metrics) Service {
return instrument{
next: next,
metrics: metrics,
}
return Service{}
}
type instrument struct {
next Service
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) Dummy(w http.ResponseWriter, r *http.Request) {
i.next.Dummy(w, r)
}

View File

@@ -1,30 +1,15 @@
package svc
import (
"net/http"
"github.com/owncloud/ocis-pkg/v2/log"
)
// NewLogging returns a service that logs messages.
func NewLogging(next Service, logger log.Logger) Service {
return logging{
next: next,
logger: logger,
}
return Service{}
}
type logging struct {
next Service
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) Dummy(w http.ResponseWriter, r *http.Request) {
l.next.Dummy(w, r)
}

View File

@@ -1,52 +1,58 @@
package svc
import (
"net/http"
"context"
"github.com/owncloud/ocis-settings/pkg/settings"
store "github.com/owncloud/ocis-settings/pkg/store/filesystem"
"github.com/go-chi/chi"
"github.com/owncloud/ocis-settings/pkg/proto/v0"
"github.com/owncloud/ocis-settings/pkg/config"
)
// Service defines the extension handlers.
type Service interface {
ServeHTTP(http.ResponseWriter, *http.Request)
Dummy(http.ResponseWriter, *http.Request)
type Service struct {
config *config.Config
manager settings.Manager
}
// NewService returns a service implementation for Service.
func NewService(opts ...Option) Service {
options := newOptions(opts...)
m := chi.NewMux()
m.Use(options.Middleware...)
svc := Settings{
config: options.Config,
mux: m,
func NewService(cfg *config.Config) Service {
return Service{
config:cfg,
manager:store.New(cfg),
}
m.Route(options.Config.HTTP.Root, func(r chi.Router) {
r.Get("/", svc.Dummy)
})
return svc
}
// Settings defines implements the business logic for Service.
type Settings struct {
config *config.Config
mux *chi.Mux
func (g Service) CreateSettingsBundle(c context.Context, req *proto.CreateSettingsBundleRequest, res *proto.CreateSettingsBundleResponse) error {
r, err := g.manager.Write(req.SettingsBundle)
if err != nil {
return err
}
res.SettingsBundle = r
return nil
}
// ServeHTTP implements the Service interface.
func (g Settings) ServeHTTP(w http.ResponseWriter, r *http.Request) {
g.mux.ServeHTTP(w, r)
func (g Service) GetSettingsBundle(c context.Context, req *proto.GetSettingsBundleRequest, res *proto.GetSettingsBundleResponse) error {
r, err := g.manager.Read(req.Extension, req.Key)
if err != nil {
return err
}
res.SettingsBundle = r
return nil
}
// Dummy implements the Service interface.
func (g Settings) Dummy(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.WriteHeader(http.StatusOK)
w.Write([]byte("Hello ocis-settings!"))
func (g Service) ListSettingsBundles(c context.Context, req *proto.ListSettingsBundlesRequest, res *proto.ListSettingsBundlesResponse) error {
r, err := listSettingsBundles(g, req.Extension)
if err != nil {
return err
}
res.SettingsBundles = r
return nil
}
func listSettingsBundles(g Service, extension string) ([]*proto.SettingsBundle, error) {
if len(extension) == 0 {
return g.manager.List()
} else {
return g.manager.ListByExtension(extension)
}
}

View File

@@ -1,26 +1,10 @@
package svc
import (
"net/http"
)
// NewTracing returns a service that instruments traces.
func NewTracing(next Service) Service {
return tracing{
next: next,
}
return Service{}
}
type tracing struct {
next Service
}
// 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) Dummy(w http.ResponseWriter, r *http.Request) {
t.next.Dummy(w, r)
}

22
pkg/settings/settings.go Normal file
View File

@@ -0,0 +1,22 @@
package settings
import (
"github.com/owncloud/ocis-settings/pkg/config"
"github.com/owncloud/ocis-settings/pkg/proto/v0"
)
var (
// Registry uses the strategy pattern as a registry
Registry = map[string]RegisterFunc{}
)
// RegisterFunc stores store constructors
type RegisterFunc func(*config.Config) Manager
// Manager
type Manager interface {
Read(extension string, key string) (*proto.SettingsBundle, error)
Write(bundle *proto.SettingsBundle) (*proto.SettingsBundle, error)
List() ([]*proto.SettingsBundle, error)
ListByExtension(extension string) ([]*proto.SettingsBundle, error)
}

View File

@@ -0,0 +1,145 @@
// Package store implements the go-micro store interface
package store
import (
"encoding/json"
"fmt"
olog "github.com/owncloud/ocis-pkg/v2/log"
"github.com/owncloud/ocis-settings/pkg/config"
"github.com/owncloud/ocis-settings/pkg/proto/v0"
"github.com/owncloud/ocis-settings/pkg/settings"
"io/ioutil"
"os"
"path"
"strings"
)
var (
// StoreName is the default name for the settings store
StoreName = "ocis-settings-store"
managerName = "filesystem"
emptyKeyError = "key cannot be empty"
)
// Store interacts with the filesystem to manage settings information
type Store struct {
mountPath string
Logger olog.Logger
}
// New creates a new store
func New(cfg *config.Config) settings.Manager {
s := Store{}
dest := path.Join(cfg.Storage.RootMountPath, StoreName)
if _, err := os.Stat(dest); err != nil {
s.Logger.Info().Msgf("creating container on %v", dest)
err := os.MkdirAll(dest, 0700)
if err != nil {
s.Logger.Err(err).Msgf("providing container on %v", dest)
}
}
s.mountPath = dest
return &s
}
// List returns all the bundles in the mountPath folder
func (s Store) List() ([]*proto.SettingsBundle, error) {
records := []*proto.SettingsBundle{}
bundles, err := ioutil.ReadDir(s.mountPath)
if err != nil {
s.Logger.Err(err).Msgf("error reading %v", s.mountPath)
return nil, err
}
s.Logger.Info().Msg("listing bundles")
for _, v := range bundles {
records = append(records, parseFileName(v.Name()))
}
return records, nil
}
// ListByExtension returns all bundles in the mountPath folder belonging to the given extension
func (s Store) ListByExtension(extension string) ([]*proto.SettingsBundle, error) {
records := []*proto.SettingsBundle{}
bundles, err := ioutil.ReadDir(s.mountPath)
if err != nil {
s.Logger.Err(err).Msgf("error reading %v", s.mountPath)
return nil, err
}
s.Logger.Info().Msgf("listing bundles by extension %v", extension)
for _, v := range bundles {
record := parseFileName(v.Name())
if record.Extension == extension {
records = append(records, record)
}
}
return records, nil
}
// Read tries to find a bundle by the given extension and key within the mountPath
func (s Store) Read(extension string, key string) (*proto.SettingsBundle, error) {
fileName := buildFileNameFromData(extension, key)
contents, err := ioutil.ReadFile(path.Join(s.mountPath, fileName))
if err != nil {
s.Logger.Err(err).Msgf("error reading contents for extension %v and key %v: file not found", extension, key)
return nil, err
}
record := proto.SettingsBundle{}
if err = json.Unmarshal(contents, &record); err != nil {
s.Logger.Err(err).Msg("error unmarshalling record")
return nil, err
}
return &record, nil
}
// Write writes the given record into a file within the mountPath
func (s Store) Write(rec *proto.SettingsBundle) (*proto.SettingsBundle, error) {
if len(rec.Key) < 1 {
s.Logger.Error().Msg("key cannot be empty")
return nil, fmt.Errorf(emptyKeyError)
}
contents, err := json.Marshal(rec)
if err != nil {
s.Logger.Err(err).Msg("record could not be marshalled")
return nil, err
}
recordPath := path.Join(s.mountPath, buildFileNameFromBundle(rec))
if err := ioutil.WriteFile(recordPath, contents, 0644); err != nil {
return nil, err
}
s.Logger.Info().Msgf("%v bytes written to %v", len(contents), recordPath)
return rec, nil
}
// Builds a unique file name from the given bundle
func buildFileNameFromBundle(bundle *proto.SettingsBundle) string {
return buildFileNameFromData(bundle.Extension, bundle.Key)
}
// Builds a unique file name from the given params
func buildFileNameFromData(extension string, key string) string {
return extension + "__" + key + ".json"
}
// Extracts extension and key from the given fileName and builds a (minimalistic) bundle from it
func parseFileName(fileName string) *proto.SettingsBundle {
parts := strings.Split(strings.Replace(fileName, ".json", "", 1), "__")
return &proto.SettingsBundle{
Key: parts[1],
Extension: parts[0],
}
}
func init() {
settings.Registry[managerName] = New
}

6
pkg/store/registry.go Normal file
View File

@@ -0,0 +1,6 @@
package store
import (
// init filesystem store
_ "github.com/owncloud/ocis-settings/pkg/store/filesystem"
)