Skip to content

Commit

Permalink
Merge 41d76c8 into 7465ba3
Browse files Browse the repository at this point in the history
  • Loading branch information
rcmgleite committed Aug 16, 2018
2 parents 7465ba3 + 41d76c8 commit 1edf6fb
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 18 deletions.
7 changes: 7 additions & 0 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
"github.com/topfreegames/pitaya/config"
"github.com/topfreegames/pitaya/constants"
pcontext "github.com/topfreegames/pitaya/context"
"github.com/topfreegames/pitaya/defaultpipelines"
"github.com/topfreegames/pitaya/errors"
"github.com/topfreegames/pitaya/internal/codec"
"github.com/topfreegames/pitaya/internal/message"
Expand Down Expand Up @@ -137,6 +138,7 @@ func Configure(
app.server.Metadata = serverMetadata
app.messageEncoder = message.NewMessagesEncoder(app.config.GetBool("pitaya.handler.messages.compression"))
configureMetrics(serverType)
configureDefaultPipelines(app.config)
app.configured = true
}

Expand All @@ -161,7 +163,12 @@ func configureMetrics(serverType string) {
AddMetricsReporter(metricsReporter)
}
}
}

func configureDefaultPipelines(config *config.Config) {
if config.GetBool("pitaya.defaultpipelines.structvalidation.enabled") {
BeforeHandler(defaultpipelines.StructValidatorInstance.Validate)
}
}

// AddAcceptor adds a new acceptor to app
Expand Down
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func (c *Config) fillDefaultValues() {
"pitaya.metrics.prometheus.port": 9090,
"pitaya.metrics.prometheus.enabled": false,
"pitaya.metrics.tags": map[string]string{},
"pitaya.defaultpipelines.structvalidation.enabled": false,
}

for param := range defaultsMap {
Expand Down
34 changes: 34 additions & 0 deletions defaultpipelines/default_struct_validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package defaultpipelines

import (
"context"
"sync"

validator "gopkg.in/go-playground/validator.v9"
)

// DefaultValidator is the default arguments validator for handlers
// in pitaya
type DefaultValidator struct {
once sync.Once
validate *validator.Validate
}

// Validate is the the function responsible for validating the 'in' parameter
// based on the struct tags the parameter has.
// This function has the pipeline.Handler signature so
// it is possible to use it as a pipeline function
func (v *DefaultValidator) Validate(ctx context.Context, in interface{}) (interface{}, error) {
v.lazyinit()
if err := v.validate.Struct(in); err != nil {
return nil, err
}

return in, nil
}

func (v *DefaultValidator) lazyinit() {
v.once.Do(func() {
v.validate = validator.New()
})
}
17 changes: 17 additions & 0 deletions defaultpipelines/struct_validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package defaultpipelines

import (
"context"
)

// StructValidator is the interface that must be implemented
// by a struct validator for the request arguments on pitaya.
//
// The default struct validator used by pitaya is https://github.com/go-playground/validator.
type StructValidator interface {
Validate(context.Context, interface{}) (interface{}, error)
}

// StructValidatorInstance holds the default validator
// on start but can be overridden if needed.
var StructValidatorInstance StructValidator = &DefaultValidator{}
18 changes: 18 additions & 0 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -245,3 +245,21 @@ These configurations are only used if the modules are created. It is recommended
- time.Time
- Duration of the etcd lease before automatic renewal

Default Pipelines
=================

These configurations control if the default pipelines should be enabled or not

.. list-table::
:widths: 15 10 10 50
:header-rows: 1
:stub-columns: 1

* - Configuration
- Default value
- Type
- Description
* - pitaya.defaultpipelines.structvalidation.enabled
- false
- bool
- Whether Pitaya should use the default struct validator for handler arguments
29 changes: 11 additions & 18 deletions examples/demo/pipeline/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import (
"fmt"

"github.com/sirupsen/logrus"
"github.com/spf13/viper"
"github.com/topfreegames/pitaya"
"github.com/topfreegames/pitaya/acceptor"
"github.com/topfreegames/pitaya/component"
"github.com/topfreegames/pitaya/serialize/json"
validator "gopkg.in/go-playground/validator.v9"
)

// MetagameServer ...
Expand All @@ -26,7 +26,10 @@ func NewMetagameMock() *MetagameServer {
}
}

// CreatePlayerCheatArgs ...
// CreatePlayerCheatArgs is the struct used as parameter for the CreatePlayerCheat handler
// Using the 'validate' tag it's possible to add validations on all struct fields.
// For reference on the default validator see https://github.com/go-playground/validator.
// Also, to enable this validation pipeline see docs/configuration.rst.
type CreatePlayerCheatArgs struct {
Name string `json:"name"`
Email string `json:"email" validate:"email"`
Expand All @@ -47,20 +50,6 @@ func (g *MetagameServer) CreatePlayerCheat(ctx context.Context, args *CreatePlay
}, nil
}

// This is a beforeHandler that validates the handler argument based on the struct tags.
// As for this example, the CreatePlayerCheatArgs has the 'validate' tags for email,
// softCurrency and hardCurrency. If any of the validations fail an error will be returned
func handlerParamsValidator(ctx context.Context, in interface{}) (interface{}, error) {
var validate *validator.Validate
validate = validator.New()

if err := validate.Struct(in); err != nil {
return nil, err
}

return in, nil
}

// Simple example of a before pipeline that actually asserts the type of the
// in parameter.
// IMPORTANT: that this kind of pipeline will be hard to exist in real code
Expand Down Expand Up @@ -99,13 +88,17 @@ func main() {
)

// Pipelines registration
pitaya.BeforeHandler(handlerParamsValidator)
pitaya.BeforeHandler(metagameServer.simpleBefore)
pitaya.AfterHandler(metagameServer.simpleAfter)

port := 3251
tcp := acceptor.NewTCPAcceptor(fmt.Sprintf(":%d", port))
pitaya.AddAcceptor(tcp)
pitaya.Configure(*isFrontend, *svType, pitaya.Cluster, map[string]string{})

config := viper.New()

// Enable default validator
config.Set("pitaya.defaultpipelines.structvalidation.enabled", true)
pitaya.Configure(*isFrontend, *svType, pitaya.Cluster, map[string]string{}, config)
pitaya.Start()
}

0 comments on commit 1edf6fb

Please sign in to comment.