Set up http server
- set up http server for a) handling the service requests and b) serving the static assets for the ocis-web extension - align the server command with other ocis-extensions, including config variable naming
This commit is contained in:
+74
-29
@@ -2,14 +2,17 @@ package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"syscall"
|
||||
|
||||
"github.com/owncloud/ocis-accounts/pkg/flagset"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
|
||||
"github.com/micro/cli/v2"
|
||||
"github.com/oklog/run"
|
||||
"github.com/owncloud/ocis-accounts/pkg/config"
|
||||
"github.com/owncloud/ocis-accounts/pkg/flagset"
|
||||
"github.com/owncloud/ocis-accounts/pkg/metrics"
|
||||
"github.com/owncloud/ocis-accounts/pkg/server/grpc"
|
||||
"github.com/owncloud/ocis-accounts/pkg/server/http"
|
||||
svc "github.com/owncloud/ocis-accounts/pkg/service/v0"
|
||||
)
|
||||
|
||||
@@ -20,41 +23,83 @@ func Server(cfg *config.Config) *cli.Command {
|
||||
Usage: "Start ocis accounts service",
|
||||
Description: "uses an LDAP server as the storage backend",
|
||||
Flags: flagset.ServerWithConfig(cfg),
|
||||
Before: func(c *cli.Context) error {
|
||||
return ParseConfig(c, cfg)
|
||||
Before: func(ctx *cli.Context) error {
|
||||
if cfg.HTTP.Root != "/" {
|
||||
cfg.HTTP.Root = strings.TrimSuffix(cfg.HTTP.Root, "/")
|
||||
}
|
||||
|
||||
// When running on single binary mode the before hook from the root command won't get called. We manually
|
||||
// call this before hook from ocis command, so the configuration can be loaded.
|
||||
return ParseConfig(ctx, cfg)
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
logger := NewLogger(cfg)
|
||||
gr := run.Group{}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
defer cancel()
|
||||
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.Flags(flagset.RootWithConfig(config.New())),
|
||||
var (
|
||||
gr = run.Group{}
|
||||
ctx, cancel = context.WithCancel(context.Background())
|
||||
mtrcs = metrics.New()
|
||||
)
|
||||
|
||||
gr.Add(func() error {
|
||||
logger.Info().Str("service", service.Name()).Msg("Reporting settings bundle to account service")
|
||||
go svc.RegisterSettingsBundles(&logger)
|
||||
return service.Run()
|
||||
}, func(err error) {
|
||||
if err != nil {
|
||||
logger.Error().Err(err).Msg("account service died")
|
||||
} else {
|
||||
defer cancel()
|
||||
|
||||
{
|
||||
server := http.Server(
|
||||
http.Logger(logger),
|
||||
http.Name(cfg.Server.Name),
|
||||
http.Context(ctx),
|
||||
http.Config(cfg),
|
||||
http.Metrics(mtrcs),
|
||||
http.Flags(flagset.RootWithConfig(cfg)),
|
||||
http.Flags(flagset.ServerWithConfig(cfg)),
|
||||
)
|
||||
|
||||
gr.Add(server.Run, func(_ error) {
|
||||
logger.Info().
|
||||
Str("service", service.Name()).
|
||||
Str("server", "http").
|
||||
Msg("Shutting down server")
|
||||
}
|
||||
cancel()
|
||||
})
|
||||
|
||||
cancel()
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
server := grpc.Server(
|
||||
grpc.Logger(logger),
|
||||
grpc.Name(cfg.Server.Name),
|
||||
grpc.Context(ctx),
|
||||
grpc.Config(cfg),
|
||||
grpc.Metrics(mtrcs),
|
||||
)
|
||||
|
||||
gr.Add(func() error {
|
||||
logger.Info().Str("service", server.Name()).Msg("Reporting settings bundles to settings service")
|
||||
go svc.RegisterSettingsBundles(&logger)
|
||||
return server.Run()
|
||||
}, func(_ error) {
|
||||
logger.Info().
|
||||
Str("server", "grpc").
|
||||
Msg("Shutting down server")
|
||||
|
||||
cancel()
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
stop := make(chan os.Signal, 1)
|
||||
|
||||
gr.Add(func() error {
|
||||
signal.Notify(stop, os.Interrupt)
|
||||
|
||||
<-stop
|
||||
|
||||
return nil
|
||||
}, func(err error) {
|
||||
close(stop)
|
||||
cancel()
|
||||
})
|
||||
}
|
||||
|
||||
run.SignalHandler(ctx, syscall.SIGKILL)
|
||||
return gr.Run()
|
||||
},
|
||||
}
|
||||
|
||||
@@ -24,6 +24,19 @@ type LDAPSchema struct {
|
||||
Groups string
|
||||
}
|
||||
|
||||
// HTTP defines the available http configuration.
|
||||
type HTTP struct {
|
||||
Addr string
|
||||
Namespace string
|
||||
Root string
|
||||
}
|
||||
|
||||
// GRPC defines the available grpc configuration.
|
||||
type GRPC struct {
|
||||
Addr string
|
||||
Namespace string
|
||||
}
|
||||
|
||||
// Server configures a server.
|
||||
type Server struct {
|
||||
Name string
|
||||
@@ -42,6 +55,8 @@ type Log struct {
|
||||
// Config merges all Account config parameters.
|
||||
type Config struct {
|
||||
LDAP LDAP
|
||||
HTTP HTTP
|
||||
GRPC GRPC
|
||||
Server Server
|
||||
Log Log
|
||||
}
|
||||
|
||||
+35
-20
@@ -35,36 +35,51 @@ func RootWithConfig(cfg *config.Config) []cli.Flag {
|
||||
// ServerWithConfig applies cfg to the root flagset
|
||||
func ServerWithConfig(cfg *config.Config) []cli.Flag {
|
||||
return []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "http-namespace",
|
||||
Value: "com.owncloud.web",
|
||||
Usage: "Set the base namespace for the http namespace",
|
||||
EnvVars: []string{"ACCOUNTS_HTTP_NAMESPACE"},
|
||||
Destination: &cfg.HTTP.Namespace,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "http-addr",
|
||||
Value: "localhost:9181",
|
||||
Usage: "Address to bind http server",
|
||||
EnvVars: []string{"ACCOUNTS_HTTP_ADDR"},
|
||||
Destination: &cfg.HTTP.Addr,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "http-root",
|
||||
Value: "/",
|
||||
Usage: "Root path of http server",
|
||||
EnvVars: []string{"ACCOUNTS_HTTP_ROOT"},
|
||||
Destination: &cfg.HTTP.Root,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "grpc-namespace",
|
||||
Value: "com.owncloud.api",
|
||||
Usage: "Set the base namespace for the grpc namespace",
|
||||
EnvVars: []string{"ACCOUNTS_GRPC_NAMESPACE"},
|
||||
Destination: &cfg.GRPC.Namespace,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "grpc-addr",
|
||||
Value: "localhost:9180",
|
||||
Usage: "Address to bind grpc server",
|
||||
EnvVars: []string{"ACCOUNTS_GRPC_ADDR"},
|
||||
Destination: &cfg.GRPC.Addr,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "name",
|
||||
Value: "accounts",
|
||||
DefaultText: "accounts",
|
||||
Usage: "service name",
|
||||
EnvVars: []string{"ACCOUNTS_NAME"},
|
||||
Destination: &cfg.Server.Name,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "namespace",
|
||||
Aliases: []string{"ns"},
|
||||
Value: "com.owncloud.api",
|
||||
DefaultText: "com.owncloud.api",
|
||||
Usage: "namespace",
|
||||
EnvVars: []string{"ACCOUNTS_NAMESPACE"},
|
||||
Destination: &cfg.Server.Namespace,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "address",
|
||||
Aliases: []string{"addr"},
|
||||
Value: "localhost:9180",
|
||||
DefaultText: "localhost:9180",
|
||||
Usage: "service endpoint",
|
||||
EnvVars: []string{"ACCOUNTS_ADDRESS"},
|
||||
Destination: &cfg.Server.Address,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "accounts-data-path",
|
||||
Value: "/var/tmp/ocis-accounts",
|
||||
DefaultText: "/var/tmp/ocis-accounts",
|
||||
Usage: "accounts folder",
|
||||
EnvVars: []string{"ACCOUNTS_DATA_PATH"},
|
||||
Destination: &cfg.Server.AccountsDataPath,
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package metrics
|
||||
|
||||
var (
|
||||
// Namespace defines the namespace for the defines metrics.
|
||||
Namespace = "ocis"
|
||||
|
||||
// Subsystem defines the subsystem for the defines metrics.
|
||||
Subsystem = "accounts"
|
||||
)
|
||||
|
||||
// Metrics defines the available metrics of this service.
|
||||
type Metrics struct {
|
||||
// Counter *prometheus.CounterVec
|
||||
}
|
||||
|
||||
// New initializes the available metrics.
|
||||
func New() *Metrics {
|
||||
m := &Metrics{
|
||||
}
|
||||
// TODO: implement metrics
|
||||
return m
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/micro/cli/v2"
|
||||
"github.com/owncloud/ocis-accounts/pkg/config"
|
||||
"github.com/owncloud/ocis-accounts/pkg/metrics"
|
||||
"github.com/owncloud/ocis-pkg/v2/log"
|
||||
)
|
||||
|
||||
@@ -14,11 +15,10 @@ 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
|
||||
Metrics *metrics.Metrics
|
||||
Flags []cli.Flag
|
||||
}
|
||||
|
||||
@@ -33,13 +33,6 @@ func newOptions(opts ...Option) Options {
|
||||
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) {
|
||||
@@ -47,10 +40,10 @@ func Name(val string) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// Address provides an address for the service.
|
||||
func Address(val string) Option {
|
||||
// Logger provides a function to set the logger option.
|
||||
func Logger(val log.Logger) Option {
|
||||
return func(o *Options) {
|
||||
o.Address = val
|
||||
o.Logger = val
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,10 +61,10 @@ func Config(val *config.Config) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// Namespace provides a function to set the namespace option.
|
||||
func Namespace(val string) Option {
|
||||
// Metrics provides a function to set the metrics option.
|
||||
func Metrics(val *metrics.Metrics) Option {
|
||||
return func(o *Options) {
|
||||
o.Namespace = val
|
||||
o.Metrics = val
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,15 +6,15 @@ import (
|
||||
"github.com/owncloud/ocis-pkg/v2/service/grpc"
|
||||
)
|
||||
|
||||
// NewService initializes a new go-micro service ready to run
|
||||
func NewService(opts ...Option) grpc.Service {
|
||||
// Server 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.Name(options.Config.Server.Name),
|
||||
grpc.Context(options.Context),
|
||||
grpc.Address(options.Address),
|
||||
grpc.Namespace(options.Namespace),
|
||||
grpc.Address(options.Config.GRPC.Addr),
|
||||
grpc.Namespace(options.Config.GRPC.Namespace),
|
||||
grpc.Logger(options.Logger),
|
||||
grpc.Flags(options.Flags...),
|
||||
)
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/micro/cli/v2"
|
||||
"github.com/owncloud/ocis-accounts/pkg/config"
|
||||
"github.com/owncloud/ocis-accounts/pkg/metrics"
|
||||
"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
|
||||
Logger log.Logger
|
||||
Context context.Context
|
||||
Config *config.Config
|
||||
Metrics *metrics.Metrics
|
||||
Flags []cli.Flag
|
||||
}
|
||||
|
||||
// newOptions initializes the available default options.
|
||||
func newOptions(opts ...Option) Options {
|
||||
opt := Options{}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
return opt
|
||||
}
|
||||
|
||||
// Name provides a name for the service.
|
||||
func Name(val string) Option {
|
||||
return func(o *Options) {
|
||||
o.Name = val
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
// Metrics provides a function to set the metrics option.
|
||||
func Metrics(val *metrics.Metrics) Option {
|
||||
return func(o *Options) {
|
||||
o.Metrics = val
|
||||
}
|
||||
}
|
||||
|
||||
// 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...)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/owncloud/ocis-accounts/pkg/assets"
|
||||
"github.com/owncloud/ocis-accounts/pkg/proto/v0"
|
||||
svc "github.com/owncloud/ocis-accounts/pkg/service/v0"
|
||||
"github.com/owncloud/ocis-accounts/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 {
|
||||
options := newOptions(opts...)
|
||||
|
||||
service := http.NewService(
|
||||
http.Logger(options.Logger),
|
||||
http.Name(options.Name),
|
||||
http.Version(version.String),
|
||||
http.Address(options.Config.HTTP.Addr),
|
||||
http.Namespace(options.Config.HTTP.Namespace),
|
||||
http.Context(options.Context),
|
||||
http.Flags(options.Flags...),
|
||||
)
|
||||
|
||||
handler, err := svc.New(svc.Logger(options.Logger), svc.Config(options.Config))
|
||||
if err != nil {
|
||||
options.Logger.Fatal().Err(err).Msg("could not initialize service handler")
|
||||
}
|
||||
|
||||
mux := chi.NewMux()
|
||||
|
||||
mux.Use(middleware.RealIP)
|
||||
mux.Use(middleware.RequestID)
|
||||
mux.Use(middleware.Cache)
|
||||
mux.Use(middleware.Cors)
|
||||
mux.Use(middleware.Secure)
|
||||
|
||||
mux.Use(middleware.Version(
|
||||
options.Name,
|
||||
version.String,
|
||||
))
|
||||
|
||||
mux.Use(middleware.Logger(
|
||||
options.Logger,
|
||||
))
|
||||
|
||||
mux.Use(middleware.Static(
|
||||
options.Config.HTTP.Root,
|
||||
assets.New(
|
||||
assets.Logger(options.Logger),
|
||||
assets.Config(options.Config),
|
||||
),
|
||||
))
|
||||
|
||||
mux.Route(options.Config.HTTP.Root, func(r chi.Router) {
|
||||
proto.RegisterAccountsServiceWeb(r, handler)
|
||||
proto.RegisterGroupsServiceWeb(r, handler)
|
||||
})
|
||||
|
||||
service.Handle(
|
||||
"/",
|
||||
mux,
|
||||
)
|
||||
|
||||
if err := service.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return service
|
||||
}
|
||||
Reference in New Issue
Block a user