Skip to content

Commit

Permalink
add domain folder; add requestId middleware; improve logging middleware
Browse files Browse the repository at this point in the history
Signed-off-by: Lukas <lukas.jarosch@mail.com>
  • Loading branch information
lukasjarosch committed Jul 16, 2019
1 parent d5952f5 commit e59753a
Show file tree
Hide file tree
Showing 25 changed files with 283 additions and 50 deletions.
23 changes: 13 additions & 10 deletions a_main-packr.go

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ func initCmd(cmd *cobra.Command, args []string) {
logrus.Info("generated internal/service/service.go")
}

// domain/errors.go
errors := template.NewGenerator(template.DomainErrorsOptions())
if err := errors.GenerateFile(TemplateFilesystem); err != nil {
logrus.Error(fmt.Sprintf("failed to generate domain errors stub: %s", err.Error()))
} else {
logrus.Info("generated internal/domain/errors.go")
}

// middleware.go
middleware := template.NewGenerator(template.MiddlewareOptions())
if err := middleware.GenerateFile(TemplateFilesystem); err != nil {
Expand Down
32 changes: 29 additions & 3 deletions cmd/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,22 @@ import (
"fmt"
"os"

"github.com/lukasjarosch/godin/internal/bundle"

"strings"

"path"

"time"

"github.com/lukasjarosch/godin/internal"
"github.com/lukasjarosch/godin/internal/fs"
"github.com/lukasjarosch/godin/internal/generate"
"github.com/lukasjarosch/godin/internal/godin"
"github.com/lukasjarosch/godin/internal/template"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
config "github.com/spf13/viper"
"time"
"github.com/lukasjarosch/godin/internal"
)

func init() {
Expand Down Expand Up @@ -80,7 +83,7 @@ func updateCmd(cmd *cobra.Command, args []string) {
logrus.Infof("updated main.go: %s", cmdMain.TargetPath())
}

// update internal/service/<serviceName>/implementation.go
// update internal/service/usecase/<serviceName>.go
implementationGen := generate.NewImplementation(TemplateFilesystem, service.Interface, tplContext)
if err := implementationGen.Update(); err != nil {
logrus.Errorf("failed to update implementation: %s: %s", implementationGen.TargetPath(), err.Error())
Expand Down Expand Up @@ -158,6 +161,29 @@ func updateCmd(cmd *cobra.Command, args []string) {
}
}

// AMQP SUBSCRIBER BUNDLE
if config.IsSet(bundle.SubscriberKey) {

// subscriber/initialize.go
amqpSubscriberInit := generate.NewAMQPSubscriber(TemplateFilesystem, service.Interface, tplContext)
fs.MakeDirs([]string{path.Dir(amqpSubscriberInit.TargetPath())}) // ignore errors, just ensure the path exists
if err := amqpSubscriberInit.Update(); err != nil {
logrus.Errorf("failed to update internal/service/subscriber/initialize.go: %s", err)
} else {
logrus.Infof("updated %s", amqpSubscriberInit.TargetPath())
}

for _, subscriber := range tplContext.Service.Subscriber {
fileName := bundle.SubscriberFileName(subscriber.Subscription.Topic)
impl := generate.NewAMQPSubscriberHandler(subscriber, TemplateFilesystem, service.Interface, tplContext)
if err := impl.Update(); err != nil {
logrus.Errorf("failed to update internal/service/subscriber/%s: %s", fileName, err)
} else {
logrus.Infof("updated %s", impl.TargetPath())
}
}
}

// k8s/service.yaml
k8sService := template.NewGenerator(template.K8sServiceOptions())
if err := k8sService.GenerateFile(TemplateFilesystem); err != nil {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ require (
github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365
github.com/imdario/mergo v0.3.7 // indirect
github.com/manifoldco/promptui v0.3.2
github.com/mitchellh/mapstructure v1.1.2
github.com/pelletier/go-toml v1.3.0 // indirect
github.com/pkg/errors v0.8.1
github.com/sirupsen/logrus v1.4.2
Expand Down
31 changes: 25 additions & 6 deletions internal/bundle/subscribe.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package bundle

import (
"fmt"
"github.com/iancoleman/strcase"
"strings"

"github.com/lukasjarosch/godin/internal/godin"
Expand All @@ -24,8 +25,8 @@ func InitializeSubscriber() (*subscriber, error) {
return nil, err
}

handlerName := strings.Replace(sub.Topic, ".", "_", -1)
handlerName = strings.ToLower(handlerName)
subscriberKey := strings.Replace(sub.Topic, ".", "_", -1)
subscriberKey = strings.ToLower(subscriberKey)

// defaults
sub.AutoAck = false
Expand All @@ -35,19 +36,37 @@ func InitializeSubscriber() (*subscriber, error) {
sub.Queue.AutoDelete = false

confSub := config.GetStringMap(SubscriberKey)
if _, ok := confSub[handlerName]; ok == true {
return nil, fmt.Errorf("subscriber '%s' is already registered", handlerName)
if _, ok := confSub[subscriberKey]; ok == true {
return nil, fmt.Errorf("subscriber '%s' is already registered", subscriberKey)
}
confSub[handlerName] = sub
confSub[subscriberKey] = sub
config.Set(SubscriberKey, confSub)
godin.SaveConfiguration()

return &subscriber{
Subscription: sub,
HandlerName: handlerName,
HandlerName: subscriberKey,
}, nil
}

// SubscriberHandlerName returns the handler name of the subscriber based on the subscription topic
// The topic 'user.created' will be handled by the 'UserCreatedSubscriber'
func SubscriberHandlerName(topic string) string {
name := strings.ToLower(topic)
name = strings.Replace(name, ".", "_", -1)
name += "_subscriber"
name = strcase.ToCamel(name)

return name
}

// SubscriberFileName assembles the target .go file into which the handler is going to be generated.
func SubscriberFileName(topic string) string {
name := strings.ToLower(topic)
name = strings.Replace(name, ".", "_", -1)
return fmt.Sprintf("%s.go", name)
}

func promptValues(sub *amqp.Subscription) (err error) {
// Topic
p := prompt.NewPrompt(
Expand Down
42 changes: 42 additions & 0 deletions internal/generate/amqp_subscriber_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package generate

import (
"fmt"
"github.com/gobuffalo/packr"
"github.com/lukasjarosch/godin/internal/bundle"
"github.com/lukasjarosch/godin/internal/template"
"github.com/vetcher/go-astra/types"
)

type AmqpSubscriberHandler struct {
BaseGenerator
}

func NewAMQPSubscriberHandler(sub template.Subscriber, box packr.Box, serviceInterface *types.Interface, ctx template.Context, options ...Option) *AmqpSubscriberHandler {
defaults := &Options{
Context: ctx,
Overwrite: true,
IsGoSource: true,
Template: "amqp_subscriber_handler",
TargetFile: fmt.Sprintf("internal/service/subscriber/%s", bundle.SubscriberFileName(sub.Subscription.Topic)),
}

for _, opt := range options {
opt(defaults)
}

return &AmqpSubscriberHandler{
BaseGenerator{
box: box,
iface: serviceInterface,
opts: defaults,
},
}
}

func (s *AmqpSubscriberHandler) Update() error {
if s.TargetExists() {
return nil
}
return s.GenerateFull()
}
38 changes: 38 additions & 0 deletions internal/generate/amqp_subscriber_init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package generate

import (
"github.com/gobuffalo/packr"
"github.com/lukasjarosch/godin/internal/template"
"github.com/vetcher/go-astra/types"
)

type AmqpSubscriber struct {
BaseGenerator
}

func NewAMQPSubscriber(box packr.Box, serviceInterface *types.Interface, ctx template.Context, options ...Option) *AmqpSubscriber {
defaults := &Options{
Context: ctx,
Overwrite: true,
IsGoSource: true,
Template: "amqp_subscriber_init",
TargetFile: "internal/service/subscriber/initialize.go",
}

for _, opt := range options {
opt(defaults)
}

return &AmqpSubscriber{
BaseGenerator{
box: box,
iface: serviceInterface,
opts: defaults,
},
}
}

// Update will call GenerateFull. The cmd/main.go cannot be updated.
func (s *AmqpSubscriber) Update() error {
return s.GenerateFull()
}
3 changes: 2 additions & 1 deletion internal/generate/implementation.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package generate

import (
"fmt"
"github.com/gobuffalo/packr"
"github.com/lukasjarosch/godin/internal/parse"
"github.com/lukasjarosch/godin/internal/template"
Expand All @@ -21,7 +22,7 @@ func NewImplementation(box packr.Box, serviceInterface *types.Interface, ctx tem
Overwrite:true,
IsGoSource:true,
Template:"implementation",
TargetFile: filepath.Join("internal", "service", config.GetString("service.name"), "implementation.go"),
TargetFile: filepath.Join("internal", "service", "usecase", fmt.Sprintf("%s.go", config.GetString("service.name"))),
}

for _, opt := range options {
Expand Down
4 changes: 2 additions & 2 deletions internal/godin/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ var DefaultDirectoryList = []string{
"internal/service",
"internal/service/endpoint",
"internal/service/middleware",
"internal/service/usecase",
"internal/service/domain",
"pkg/grpc",
"k8s",
}
Expand Down Expand Up @@ -64,11 +66,9 @@ func (p *Project) SetupDirectories() error {

// add service-specific folders
serviceCmdDir := filepath.Join("cmd", config.GetString("service.name"))
serviceDir := filepath.Join("internal", "service", config.GetString("service.name"))

dirs := DefaultDirectoryList
dirs = append(dirs, serviceCmdDir)
dirs = append(dirs, serviceDir)

if err := fs.MakeDirs(dirs); err != nil {
return errors.Wrap(err, "SetupDirectories")
Expand Down
12 changes: 7 additions & 5 deletions internal/template/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/lukasjarosch/godin/internal/bundle"
"github.com/lukasjarosch/godin/pkg/amqp"
"github.com/mitchellh/mapstructure"

"github.com/lukasjarosch/godin/internal"
"github.com/lukasjarosch/godin/internal/parse"
Expand All @@ -28,11 +29,12 @@ func NewContextFromConfig() Context {
// amqp subscribers
sub := config.GetStringMap(bundle.SubscriberKey)
if len(sub) > 0 {
for _, subscriber := range sub {
sub := subscriber.(amqp.Subscription)
for x := range sub {
s := &amqp.Subscription{}
mapstructure.Decode(sub[x], s)
subscribers = append(subscribers, Subscriber{
Subscription: sub,
Handler: bundle.HandlerName(sub.Topic),
Subscription: *s,
Handler: bundle.SubscriberHandlerName(s.Topic),
})
}
}
Expand Down Expand Up @@ -253,7 +255,7 @@ func (m Method) ReturnImplementationMissing() string {
var list []string
for _, ret := range m.Returns {
if ret.Type == "error" {
list = append(list, "fmt.Errorf(\"NOT_IMPLEMENTED\")")
list = append(list, "domain.ErrNotImplemented")
} else {
list = append(list, ret.NilValue())
}
Expand Down
15 changes: 15 additions & 0 deletions internal/template/godin.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ var fileOptions = map[string]GenerateOptions{
TargetFile: "k8s/deployment.yaml",
Overwrite: true,
},
"errors": {
Template: "domain_errors",
IsGoSource: true,
TargetFile: "internal/service/domain/errors.go",
Overwrite: false,
},
}

func FileOptions(name string, tplContext Context, targetPath string) GenerateOptions {
Expand Down Expand Up @@ -153,3 +159,12 @@ func GitignoreOptions() GenerateOptions {

return opts
}

func DomainErrorsOptions() GenerateOptions {
ctx := Context{}

opts := fileOptions["errors"]
opts.Context = ctx

return opts
}
2 changes: 1 addition & 1 deletion pkg/log/example/example.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package main

import "github.com/lukasjarosch/godin/pkg/log"
import "github.com/go-godin/log"

func main() {

Expand Down
2 changes: 1 addition & 1 deletion pkg/middleware/logging.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package middleware

import (
"github.com/lukasjarosch/godin/pkg/log"
"github.com/go-godin/log"
"github.com/go-kit/kit/endpoint"
"context"
"time"
Expand Down
34 changes: 34 additions & 0 deletions templates/amqp_subscriber_handler.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Code generated by Godin v{{ .Godin.Version }}; DO NOT EDIT.
package subscriber

import (
godinAMQP "github.com/lukasjarosch/godin/pkg/amqp"
"github.com/go-godin/log"
"github.com/streadway/amqp"
)

{{- $serviceName := title .Service.Name -}}

{{ range .Service.Subscriber }}
func Init{{ .Handler }}(channel *amqp.Channel, svc service.{{ $serviceName }}, logger log.Logger) (subscriber godinAMQP.Subscriber, err error) {
subscription := &godinAMQP.Subscription{
Exchange: "{{ .Subscription.Exchange }}",
AutoAck: {{ .Subscription.AutoAck }},
Queue: godinAMQP.SubscriptionQueue{
AutoDelete: {{ .Subscription.Queue.AutoDelete }},
Durable: {{ .Subscription.Queue.Durable }},
Exclusive: {{ .Subscription.Queue.Exclusive }},
Name: "{{ .Subscription.Queue.Name }}",
NoWait: {{ .Subscription.Queue.NoWait }},
},
Topic: "{{ .Subscription.Topic }}",
}
subscriber = godinAMQP.NewSubscriber(channel, subscription)
if err = subscriber.Subscribe({{ .Handler }}(logger, svc)); err != nil {
logger.Error("failed to subscribe to {{ .Subscription.Topic }}", "err", err)
return subscriber, err
}
logger.Info("subscribed to topic '{{ .Subscription.Topic }}'", "topic", subscription.Topic, "queue", subscription.Queue.Name, "exchange", subscription.Exchange)
return subscriber, nil
}
{{ end }}
Loading

0 comments on commit e59753a

Please sign in to comment.