Skip to content

Commit

Permalink
Update top level init
Browse files Browse the repository at this point in the history
  • Loading branch information
Asim committed Jan 1, 2016
1 parent d705d3f commit 0d50b2e
Show file tree
Hide file tree
Showing 9 changed files with 512 additions and 82 deletions.
150 changes: 91 additions & 59 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@ package cmd
import (
"flag"
"fmt"
"io"
"math/rand"
"os"
"strings"
"text/tabwriter"
"text/template"
"time"

"github.com/codegangsta/cli"
"github.com/micro/cli"
"github.com/micro/go-micro/broker"
"github.com/micro/go-micro/client"
"github.com/micro/go-micro/registry"
Expand All @@ -20,10 +17,27 @@ import (
"github.com/micro/go-micro/transport"
)

type Cmd interface {
// The cli app within this cmd
App() *cli.App
// Adds options, parses flags and initialise
// exits on error
Init(opts ...Option)
// Options set within this command
Options() Options
}

type cmd struct {
opts Options
app *cli.App
}

type Option func(o *Options)

var (
Actions = []func(*cli.Context){}
DefaultCmd = newCmd()

Flags = []cli.Flag{
DefaultFlags = []cli.Flag{
cli.StringFlag{
Name: "server_name",
EnvVar: "MICRO_SERVER_NAME",
Expand Down Expand Up @@ -127,19 +141,19 @@ var (
},
}

Brokers = map[string]func([]string, ...broker.Option) broker.Broker{
DefaultBrokers = map[string]func([]string, ...broker.Option) broker.Broker{
"http": broker.NewBroker,
}

Registries = map[string]func([]string, ...registry.Option) registry.Registry{
DefaultRegistries = map[string]func([]string, ...registry.Option) registry.Registry{
"consul": registry.NewRegistry,
}

Selectors = map[string]func(...selector.Option) selector.Selector{
DefaultSelectors = map[string]func(...selector.Option) selector.Selector{
"random": selector.NewSelector,
}

Transports = map[string]func([]string, ...transport.Option) transport.Transport{
DefaultTransports = map[string]func([]string, ...transport.Option) transport.Transport{
"http": transport.NewTransport,
}
)
Expand All @@ -148,37 +162,68 @@ func init() {
rand.Seed(time.Now().Unix())
}

func Setup(c *cli.Context) error {
os.Args = os.Args[:1]
func newCmd(opts ...Option) Cmd {
options := Options{
Brokers: DefaultBrokers,
Registries: DefaultRegistries,
Selectors: DefaultSelectors,
Transports: DefaultTransports,
}

flag.Set("logtostderr", fmt.Sprintf("%v", c.Bool("logtostderr")))
flag.Set("alsologtostderr", fmt.Sprintf("%v", c.Bool("alsologtostderr")))
flag.Set("stderrthreshold", c.String("stderrthreshold"))
flag.Set("log_backtrace_at", c.String("log_backtrace_at"))
flag.Set("log_dir", c.String("log_dir"))
flag.Set("vmodule", c.String("vmodule"))
flag.Set("v", c.String("v"))
for _, o := range opts {
o(&options)
}

cmd := new(cmd)
cmd.opts = options
cmd.app = cli.NewApp()
cmd.app.Name = cmd.opts.Name
cmd.app.Version = cmd.opts.Version
cmd.app.Usage = cmd.opts.Description
cmd.app.Before = cmd.Before
cmd.app.Flags = DefaultFlags
cmd.app.Action = func(c *cli.Context) {}
return cmd
}

func (c *cmd) App() *cli.App {
return c.app
}

func (c *cmd) Options() Options {
return c.opts
}

func (c *cmd) Before(ctx *cli.Context) error {
// Due to logger issues with glog, we need to do this
os.Args = os.Args[:1]
flag.Set("logtostderr", fmt.Sprintf("%v", ctx.Bool("logtostderr")))
flag.Set("alsologtostderr", fmt.Sprintf("%v", ctx.Bool("alsologtostderr")))
flag.Set("stderrthreshold", ctx.String("stderrthreshold"))
flag.Set("log_backtrace_at", ctx.String("log_backtrace_at"))
flag.Set("log_dir", ctx.String("log_dir"))
flag.Set("vmodule", ctx.String("vmodule"))
flag.Set("v", ctx.String("v"))
flag.Parse()

if b, ok := Brokers[c.String("broker")]; ok {
broker.DefaultBroker = b(strings.Split(c.String("broker_address"), ","))
if b, ok := c.opts.Brokers[ctx.String("broker")]; ok {
broker.DefaultBroker = b(strings.Split(ctx.String("broker_address"), ","))
}

if r, ok := Registries[c.String("registry")]; ok {
registry.DefaultRegistry = r(strings.Split(c.String("registry_address"), ","))
if r, ok := c.opts.Registries[ctx.String("registry")]; ok {
registry.DefaultRegistry = r(strings.Split(ctx.String("registry_address"), ","))
}

if s, ok := Selectors[c.String("selector")]; ok {
if s, ok := c.opts.Selectors[ctx.String("selector")]; ok {
selector.DefaultSelector = s(selector.Registry(registry.DefaultRegistry))
}

if t, ok := Transports[c.String("transport")]; ok {
transport.DefaultTransport = t(strings.Split(c.String("transport_address"), ","))
if t, ok := c.opts.Transports[ctx.String("transport")]; ok {
transport.DefaultTransport = t(strings.Split(ctx.String("transport_address"), ","))
}

metadata := make(map[string]string)
for _, d := range c.StringSlice("server_metadata") {
for _, d := range ctx.StringSlice("server_metadata") {
var key, val string
parts := strings.Split(d, "=")
key = parts[0]
Expand All @@ -189,11 +234,11 @@ func Setup(c *cli.Context) error {
}

server.DefaultServer = server.NewServer(
server.Name(c.String("server_name")),
server.Version(c.String("server_version")),
server.Id(c.String("server_id")),
server.Address(c.String("server_address")),
server.Advertise(c.String("server_advertise")),
server.Name(ctx.String("server_name")),
server.Version(ctx.String("server_version")),
server.Id(ctx.String("server_id")),
server.Address(ctx.String("server_address")),
server.Advertise(ctx.String("server_advertise")),
server.Metadata(metadata),
)

Expand All @@ -202,33 +247,20 @@ func Setup(c *cli.Context) error {
return nil
}

func Init() {
cli.AppHelpTemplate = `
GLOBAL OPTIONS:
{{range .Flags}}{{.}}
{{end}}
`

cli.HelpPrinter = func(writer io.Writer, templ string, data interface{}) {
w := tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0)
t := template.Must(template.New("help").Parse(templ))
err := t.Execute(w, data)
if err != nil {
panic(err)
}
w.Flush()
os.Exit(2)
func (c *cmd) Init(opts ...Option) {
for _, o := range opts {
o(&c.opts)
}
c.app.Name = c.opts.Name
c.app.Version = c.opts.Version
c.app.Usage = c.opts.Description
c.app.RunAndExitOnError()
}

app := cli.NewApp()
app.HideVersion = true
app.Usage = "a go micro app"
app.Action = func(c *cli.Context) {
for _, action := range Actions {
action(c)
}
}
app.Before = Setup
app.Flags = Flags
app.RunAndExitOnError()
func Init(opts ...Option) {
DefaultCmd.Init(opts...)
}

func NewCmd(opts ...Option) Cmd {
return newCmd(opts...)
}
61 changes: 61 additions & 0 deletions cmd/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package cmd

import (
"github.com/micro/go-micro/broker"
"github.com/micro/go-micro/registry"
"github.com/micro/go-micro/selector"
"github.com/micro/go-micro/transport"
)

type Options struct {
Name string
Description string
Version string

Brokers map[string]func([]string, ...broker.Option) broker.Broker
Registries map[string]func([]string, ...registry.Option) registry.Registry
Selectors map[string]func(...selector.Option) selector.Selector
Transports map[string]func([]string, ...transport.Option) transport.Transport
}

func Name(n string) Option {
return func(o *Options) {
o.Name = n
}
}

func Description(d string) Option {
return func(o *Options) {
o.Description = d
}
}

func Version(v string) Option {
return func(o *Options) {
o.Version = v
}
}

func Broker(name string, b func([]string, ...broker.Option) broker.Broker) Option {
return func(o *Options) {
o.Brokers[name] = b
}
}

func Registry(name string, r func([]string, ...registry.Option) registry.Registry) Option {
return func(o *Options) {
o.Registries[name] = r
}
}

func Selector(name string, s func(...selector.Option) selector.Selector) Option {
return func(o *Options) {
o.Selectors[name] = s
}
}

func Transport(name string, t func([]string, ...transport.Option) transport.Transport) Option {
return func(o *Options) {
o.Transports[name] = t
}
}
38 changes: 38 additions & 0 deletions examples/service/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Service

This is an example of creating a micro service using the top level interface.

## Prereqs

Micro services need a discovery system so they can find each other. Micro uses consul by default but
its easily swapped out with etcd, kubernetes, or various other systems. We'll run consul for convenience.

1. Follow the install instructions - [https://www.consul.io/intro/getting-started/install.html](https://www.consul.io/intro/getting-started/install.html)

2. Run Consul

```shell
$ consul agent -server -bootstrap-expect 1 -data-dir /tmp/consul
```

## Run the example

1. Get the service

```shell
go get github.com/micro/go-micro/examples/service
```

2. Run the server

```shell
$GOPATH/bin/service
```

3. Run the client

```shell
$GOPATH/bin/service --client
```

And that's all there is to it.
Loading

0 comments on commit 0d50b2e

Please sign in to comment.