Skip to content

Commit

Permalink
Extract Admin Server (yorkie-team#311)
Browse files Browse the repository at this point in the history
Admin Server needs to be handled by a different auth mechanism. It also
has to handle different workloads than RPC.

So this commit extract Admin Server from RPC Server.
  • Loading branch information
hackerwins authored and jeonjonghyeok committed Aug 4, 2022
1 parent 2ff7416 commit 572cbff
Show file tree
Hide file tree
Showing 13 changed files with 215 additions and 49 deletions.
6 changes: 6 additions & 0 deletions test/helper/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/yorkie-team/yorkie/pkg/document/json"
"github.com/yorkie-team/yorkie/pkg/document/time"
"github.com/yorkie-team/yorkie/yorkie"
"github.com/yorkie-team/yorkie/yorkie/admin"
"github.com/yorkie-team/yorkie/yorkie/backend"
"github.com/yorkie-team/yorkie/yorkie/backend/db/mongo"
"github.com/yorkie-team/yorkie/yorkie/backend/housekeeping"
Expand All @@ -42,6 +43,8 @@ const (

ProfilingPort = 21102

AdminPort = 21103

HousekeepingInterval = 1 * gotime.Second
HousekeepingDeactivateThreshold = 1 * gotime.Minute
HousekeepingCandidatesLimit = 10
Expand Down Expand Up @@ -104,6 +107,9 @@ func TestConfig(authWebhook string) *yorkie.Config {
Profiling: &profiling.Config{
Port: ProfilingPort + portOffset,
},
Admin: &admin.Config{
Port: AdminPort + portOffset,
},
Housekeeping: &housekeeping.Config{
Interval: HousekeepingInterval.String(),
DeactivateThreshold: HousekeepingDeactivateThreshold.String(),
Expand Down
131 changes: 131 additions & 0 deletions yorkie/admin/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/*
* Copyright 2022 The Yorkie Authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package admin

import (
"context"
"errors"
"fmt"
"net"

"google.golang.org/grpc"

"github.com/yorkie-team/yorkie/api"
"github.com/yorkie-team/yorkie/api/converter"
"github.com/yorkie-team/yorkie/yorkie/backend"
"github.com/yorkie-team/yorkie/yorkie/backend/db"
"github.com/yorkie-team/yorkie/yorkie/documents"
"github.com/yorkie-team/yorkie/yorkie/logging"
)

// ErrInvalidAdminPort occurs when the port in the config is invalid.
var ErrInvalidAdminPort = errors.New("invalid port number for Admin server")

// Config is the configuration for creating a Server.
type Config struct {
Port int `yaml:"Port"`
}

// Validate validates the port number.
func (c *Config) Validate() error {
if c.Port < 1 || 65535 < c.Port {
return fmt.Errorf("must be between 1 and 65535, given %d: %w", c.Port, ErrInvalidAdminPort)
}

return nil
}

// Server is the gRPC server for admin.
type Server struct {
conf *Config
grpcServer *grpc.Server
backend *backend.Backend
}

// NewServer creates a new Server.
func NewServer(conf *Config, be *backend.Backend) *Server {
grpcServer := grpc.NewServer()

server := &Server{
conf: conf,
backend: be,
grpcServer: grpcServer,
}

api.RegisterAdminServer(grpcServer, server)

return server
}

// Start starts this server by opening the rpc port.
func (s *Server) Start() error {
return s.listenAndServeGRPC()
}

// Shutdown shuts down this server.
func (s *Server) Shutdown(graceful bool) {
if graceful {
s.grpcServer.GracefulStop()
} else {
s.grpcServer.Stop()
}
}

// GRPCServer returns the gRPC server.
func (s *Server) GRPCServer() *grpc.Server {
return s.grpcServer
}

func (s *Server) listenAndServeGRPC() error {
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", s.conf.Port))
if err != nil {
logging.DefaultLogger().Error(err)
return err
}

go func() {
logging.DefaultLogger().Infof("serving Admin on %d", s.conf.Port)

if err := s.grpcServer.Serve(lis); err != nil {
if err != grpc.ErrServerStopped {
logging.DefaultLogger().Error(err)
}
}
}()

return nil
}

// ListDocuments lists documents.
func (s *Server) ListDocuments(
ctx context.Context,
req *api.ListDocumentsRequest,
) (*api.ListDocumentsResponse, error) {
docs, err := documents.ListDocumentSummaries(
ctx,
s.backend,
db.ID(req.PreviousId),
int(req.PageSize),
)
if err != nil {
return nil, err
}

return &api.ListDocumentsResponse{
Documents: converter.ToDocumentSummaries(docs),
}, nil
}
20 changes: 20 additions & 0 deletions yorkie/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (

"gopkg.in/yaml.v2"

"github.com/yorkie-team/yorkie/yorkie/admin"
"github.com/yorkie-team/yorkie/yorkie/backend"
"github.com/yorkie-team/yorkie/yorkie/backend/db/mongo"
"github.com/yorkie-team/yorkie/yorkie/backend/housekeeping"
Expand All @@ -40,6 +41,8 @@ const (

DefaultProfilingPort = 11102

DefaultAdminPort = 11103

DefaultHousekeepingInterval = time.Minute
DefaultHousekeepingDeactivateThreshold = 7 * 24 * time.Hour
DefaultHousekeepingCandidateLimit = 500
Expand All @@ -63,6 +66,7 @@ const (
type Config struct {
RPC *rpc.Config `yaml:"RPC"`
Profiling *profiling.Config `yaml:"Profiling"`
Admin *admin.Config `yaml:"Admin"`
Housekeeping *housekeeping.Config `yaml:"Housekeeping"`
Backend *backend.Config `yaml:"Backend"`
Mongo *mongo.Config `yaml:"Mongo"`
Expand Down Expand Up @@ -98,6 +102,11 @@ func (c *Config) RPCAddr() string {
return fmt.Sprintf("localhost:%d", c.RPC.Port)
}

// AdminAddr returns the Admin address.
func (c *Config) AdminAddr() string {
return fmt.Sprintf("localhost:%d", c.Admin.Port)
}

// Validate returns an error if the provided Config is invalidated.
func (c *Config) Validate() error {
if err := c.RPC.Validate(); err != nil {
Expand All @@ -108,6 +117,10 @@ func (c *Config) Validate() error {
return err
}

if err := c.Admin.Validate(); err != nil {
return err
}

if err := c.Housekeeping.Validate(); err != nil {
return err
}
Expand Down Expand Up @@ -143,6 +156,10 @@ func (c *Config) ensureDefaultValue() {
c.Profiling.Port = DefaultProfilingPort
}

if c.Admin.Port == 0 {
c.Admin.Port = DefaultAdminPort
}

if c.Backend.SnapshotThreshold == 0 {
c.Backend.SnapshotThreshold = DefaultSnapshotThreshold
}
Expand Down Expand Up @@ -208,6 +225,9 @@ func newConfig(port int, profilingPort int) *Config {
Profiling: &profiling.Config{
Port: profilingPort,
},
Admin: &admin.Config{
Port: DefaultAdminPort,
},
Housekeeping: &housekeeping.Config{
Interval: DefaultHousekeepingInterval.String(),
DeactivateThreshold: DefaultHousekeepingDeactivateThreshold.String(),
Expand Down
5 changes: 5 additions & 0 deletions yorkie/config.sample.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ Profiling:
# EnablePprof is whether to enable the pprof `/debug/pprof` endpoint.
EnablePprof: false

# Admin is the configuration for the admin server.
Admin:
# Port is the port to listen on for serving admin interface (default: 11103).
Port: 11103

# Housekeeping is the configuration for the housekeeping.
Housekeeping:
# Interval is the time between housekeeping runs (default: 1m).
Expand Down
18 changes: 17 additions & 1 deletion yorkie/admin/admin.go → yorkie/documents/admin.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
package admin
/*
* Copyright 2022 The Yorkie Authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package documents

import (
"context"
Expand Down
42 changes: 0 additions & 42 deletions yorkie/rpc/admin_server.go

This file was deleted.

17 changes: 16 additions & 1 deletion yorkie/auth/token.go → yorkie/rpc/auth/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@ package auth

import "context"

// key is the key for the context.Context.
type key int

// tokenKey is the key for the token.
const tokenKey key = 0

// TokenFromCtx returns the tokenKey from the given context.
// clientAPIKeyKey is the key for the client API key.
const clientAPIKeyKey key = 1

// TokenFromCtx returns the token from the given context.
func TokenFromCtx(ctx context.Context) string {
return ctx.Value(tokenKey).(string)
}
Expand All @@ -31,3 +36,13 @@ func TokenFromCtx(ctx context.Context) string {
func CtxWithToken(ctx context.Context, token string) context.Context {
return context.WithValue(ctx, tokenKey, token)
}

// ClientAPIKeyFromCtx returns the clientAPIKey from the given context.
func ClientAPIKeyFromCtx(ctx context.Context) string {
return ctx.Value(clientAPIKeyKey).(string)
}

// CtxWithClientAPIKey creates a new context with the given clientAPIKey.
func CtxWithClientAPIKey(ctx context.Context, clientAPIKey string) context.Context {
return context.WithValue(ctx, clientAPIKeyKey, clientAPIKey)
}
File renamed without changes.
2 changes: 1 addition & 1 deletion yorkie/rpc/interceptors/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"

"github.com/yorkie-team/yorkie/yorkie/auth"
"github.com/yorkie-team/yorkie/yorkie/rpc/auth"
)

// AuthInterceptor is an interceptor for authentication.
Expand Down
2 changes: 1 addition & 1 deletion yorkie/rpc/interceptors/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ import (

"github.com/yorkie-team/yorkie/api/converter"
"github.com/yorkie-team/yorkie/pkg/document/time"
"github.com/yorkie-team/yorkie/yorkie/auth"
"github.com/yorkie-team/yorkie/yorkie/backend/db"
"github.com/yorkie-team/yorkie/yorkie/clients"
"github.com/yorkie-team/yorkie/yorkie/logging"
"github.com/yorkie-team/yorkie/yorkie/packs"
"github.com/yorkie-team/yorkie/yorkie/rpc/auth"
)

// DefaultInterceptor is a interceptor for default.
Expand Down
3 changes: 1 addition & 2 deletions yorkie/rpc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,9 @@ func NewServer(conf *Config, be *backend.Backend) (*Server, error) {
api.RegisterYorkieServer(grpcServer, newYorkieServer(yorkieServiceCtx, be))
be.Metrics.RegisterGRPCServer(grpcServer)

// TODO(hackerwins): AdminServer and ClusterServer need to be handled by different authentication mechanism.
// TODO(hackerwins): ClusterServer need to be handled by different authentication mechanism.
// Consider extracting the servers to another grpcServer.
api.RegisterClusterServer(grpcServer, newClusterServer(be))
api.RegisterAdminServer(grpcServer, newAdminServer(be))

return &Server{
conf: conf,
Expand Down
2 changes: 1 addition & 1 deletion yorkie/rpc/yorkie_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ import (
"github.com/yorkie-team/yorkie/pkg/document/key"
"github.com/yorkie-team/yorkie/pkg/document/time"
"github.com/yorkie-team/yorkie/pkg/types"
"github.com/yorkie-team/yorkie/yorkie/auth"
"github.com/yorkie-team/yorkie/yorkie/backend"
"github.com/yorkie-team/yorkie/yorkie/backend/sync"
"github.com/yorkie-team/yorkie/yorkie/clients"
"github.com/yorkie-team/yorkie/yorkie/logging"
"github.com/yorkie-team/yorkie/yorkie/packs"
"github.com/yorkie-team/yorkie/yorkie/rpc/auth"
)

type yorkieServer struct {
Expand Down
Loading

0 comments on commit 572cbff

Please sign in to comment.