Skip to content
This repository has been archived by the owner on Feb 28, 2019. It is now read-only.

Commit

Permalink
Add namespace validation logic
Browse files Browse the repository at this point in the history
  • Loading branch information
xichen2020 committed Dec 30, 2017
1 parent 489645b commit f0bd12f
Show file tree
Hide file tree
Showing 21 changed files with 302 additions and 164 deletions.
15 changes: 12 additions & 3 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import:
- package: github.com/m3db/m3cluster
version: 4b25af16e37d029b79bae754d35655e6be382f94
- package: github.com/m3db/m3metrics
version: 5ec29cb202a5cba188f0fe4a934545a42623a8a7
version: f5cc881ab5d3577071d9664d60939bb668ed01c2
- package: github.com/m3db/m3x
version: 515e3030818e6dab3fd418f05b96174ae4c527df
- package: github.com/apache/thrift
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package server
package http

import (
"time"
Expand Down
113 changes: 113 additions & 0 deletions server/http/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package http

import (
"net/http"
"sync"

mserver "github.com/m3db/m3ctl/server"
"github.com/m3db/m3ctl/service"
"github.com/m3db/m3x/log"

"github.com/gorilla/mux"
)

const (
publicPathPrefix = "/public"
publicDirPath = "public"
staticPathPrefix = "/static"
staticDirPath = "ui/build/static"
indexFilePath = "ui/build/index.html"
)

type server struct {
server *http.Server
services []service.Service
logger log.Logger
wg sync.WaitGroup
}

// NewServer creates a new HTTP server.
func NewServer(address string, opts Options, services ...service.Service) mserver.Server {
cloned := make([]service.Service, len(services))
copy(cloned, services)
s := &http.Server{
Addr: address,
Handler: initRouter(cloned),
ReadTimeout: opts.ReadTimeout(),
WriteTimeout: opts.WriteTimeout(),
}
return &server{
server: s,
services: cloned,
logger: opts.InstrumentOptions().Logger(),
}
}

func (s *server) ListenAndServe() error {
s.wg.Add(1)
go func() {
defer s.wg.Done()
if err := s.server.ListenAndServe(); err != nil {
s.logger.Errorf("could not start listening and serving traffic: %v", err)
}
}()
return nil
}

func (s *server) Close() {
s.server.Close()
s.wg.Wait()
for _, service := range s.services {
service.Close()
}
}

func initRouter(services []service.Service) http.Handler {
router := mux.NewRouter()
registerStaticRoutes(router)
registerServiceRoutes(router, services)
return router
}

func registerStaticRoutes(router *mux.Router) {
// Register public handler.
publicHandler := http.StripPrefix(publicPathPrefix, http.FileServer(http.Dir(publicDirPath)))
router.PathPrefix(publicPathPrefix).Handler(publicHandler)

// Register static handler.
staticHandler := http.StripPrefix(staticPathPrefix, http.FileServer(http.Dir(staticDirPath)))
router.PathPrefix(staticPathPrefix).Handler(staticHandler)

// Register not found handler.
router.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, indexFilePath)
})
}

func registerServiceRoutes(router *mux.Router, services []service.Service) {
for _, service := range services {
pathPrefix := service.URLPrefix()
subRouter := router.PathPrefix(pathPrefix).Subrouter()
service.RegisterHandlers(subRouter)
}
}
39 changes: 9 additions & 30 deletions services/r2ctl/server/server.go → server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,17 @@
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// THE SOFTWARE

package server

import (
"net/http"
// Server is a server capable of listening to incoming traffic and closing itself
// when it's shut down.
type Server interface {
// ListenAndServe forever listens to new incoming connections and
// handles data from those connections.
ListenAndServe() error

"github.com/gorilla/mux"
)

// NewServer creates a new http server for R2.
func NewServer(address string, serverOpts Options, r2Service, healthService Service) *http.Server {
router := mux.NewRouter()

r2Router := router.PathPrefix(r2Service.URLPrefix()).Subrouter()
r2Service.RegisterHandlers(r2Router)

healthRouter := router.PathPrefix(healthService.URLPrefix()).Subrouter()
healthService.RegisterHandlers(healthRouter)

router.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "ui/build/index.html")
})

router.PathPrefix("/public").Handler(http.StripPrefix("/public", http.FileServer(http.Dir("public"))))

router.PathPrefix("/static").Handler(http.StripPrefix("/static", http.FileServer(http.Dir("ui/build/static"))))

return &http.Server{
WriteTimeout: serverOpts.WriteTimeout(),
ReadTimeout: serverOpts.ReadTimeout(),
Addr: address,
Handler: router,
}
// Close closes the server.
Close()
}
33 changes: 17 additions & 16 deletions health/service.go → service/health/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
"os"
"time"

"github.com/m3db/m3ctl/services/r2ctl/server"
mservice "github.com/m3db/m3ctl/service"
"github.com/m3db/m3x/instrument"

"github.com/gorilla/mux"
Expand All @@ -53,11 +53,23 @@ type service struct {
}

// NewService creates a new rules controller.
func NewService(iOpts instrument.Options) server.Service {
func NewService(iOpts instrument.Options) mservice.Service {
return &service{iOpts: iOpts}
}

func healthCheck() healthStatus {
func (s *service) URLPrefix() string {
return healthURL
}

func (s *service) RegisterHandlers(router *mux.Router) {
log := s.iOpts.Logger()
router.HandleFunc("", healthCheck)
log.Infof("Registered health endpoints")
}

func (s *service) Close() {}

func status() healthStatus {
return ok
}

Expand All @@ -69,10 +81,10 @@ func hostName() string {
return host
}

func m3ctlHealthCheck(w http.ResponseWriter, r *http.Request) {
func healthCheck(w http.ResponseWriter, r *http.Request) {
start := time.Now()
host := hostName()
status := healthCheck()
status := status()
h := healthCheckResult{Host: host, Timestamp: start, Status: status}
h.ResponseTime = time.Since(start)

Expand All @@ -86,14 +98,3 @@ func m3ctlHealthCheck(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write(body)
}

// RegisterHandlers registers health handlers.
func (s *service) RegisterHandlers(router *mux.Router) {
log := s.iOpts.Logger()
router.HandleFunc("", m3ctlHealthCheck)
log.Infof("Registered health endpoints")
}

func (s *service) URLPrefix() string {
return healthURL
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
9 changes: 6 additions & 3 deletions r2/kv/store.go → service/r2/kv/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ package kv
import (
"fmt"

"github.com/m3db/m3ctl/r2"
"github.com/m3db/m3ctl/service/r2"
"github.com/m3db/m3metrics/rules"
"github.com/m3db/m3metrics/rules/validator"
"github.com/m3db/m3x/clock"
)

Expand Down Expand Up @@ -365,6 +366,8 @@ func (s *store) FetchRollupRuleHistory(namespaceID, rollupRuleID string) ([]*rul
return hist, nil
}

func (s *store) Close() { s.ruleStore.Close() }

func (s *store) newUpdateMeta(uOpts r2.UpdateOptions) rules.UpdateMetadata {
return s.updateHelper.NewUpdateMetadata(s.nowFn().UnixNano(), uOpts.Author())
}
Expand Down Expand Up @@ -393,9 +396,9 @@ func (s *store) handleUpstreamError(err error) error {
}

switch err.(type) {
case rules.RuleConflictError:
case validator.RuleConflictError:
return r2.NewConflictError(err.Error())
case rules.ValidationError:
case validator.ValidationError:
return r2.NewBadInputError(err.Error())
default:
return r2.NewInternalError(err.Error())
Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions r2/service_routes_test.go → service/r2/routes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,3 +246,5 @@ func (s mockStore) DeleteRollupRule(namespaceID, rollupRuleID string, uOpts Upda
func (s mockStore) FetchRollupRuleHistory(namespaceID, rollupRuleID string) ([]*rules.RollupRuleView, error) {
return make([]*rules.RollupRuleView, 0), nil
}

func (s mockStore) Close() {}

0 comments on commit f0bd12f

Please sign in to comment.