-
Notifications
You must be signed in to change notification settings - Fork 3
/
natscat.go
187 lines (169 loc) · 3.87 KB
/
natscat.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// Copyright 2017 Sigurd Hogsbro
// NATSCAT
// =======
package main
import (
"bufio"
"bytes"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"strings"
"github.com/nats-io/go-nats"
"github.com/urfave/cli"
)
var (
appName = "natscat"
listen bool
verbose bool
buffered bool
serverURL string
subject string
message string
)
func cmdLine(c *cli.Context) error {
verbose = c.Bool("verbose")
listen = c.Bool("listen")
buffered = c.Bool("buffered")
if !listen && c.NArg() > 0 {
message = strings.Join(c.Args()[0:], " ")
buffered = true
}
if subject == "" {
cli.ShowCommandHelp(c, "")
log.Fatalf("%s: Must specify subject string\n", appName)
}
if !listen {
if strings.IndexAny(subject, "*>") >= 0 {
log.Fatalf("%s: Cannot specify wildcard subject when publishing\n", appName)
}
}
return nil
}
func cat() {
nc, err := nats.Connect(serverURL)
if err != nil {
log.Fatal(err)
}
defer nc.Close()
if verbose {
log.Printf("%s: Connected to %s\n", appName, nc.ConnectedUrl())
}
switch {
case listen:
// Listening for messages
if verbose {
log.Printf("%s: Listening on [%s], buffered %v\n", appName, subject, buffered)
}
nc.Subscribe(subject, func(m *nats.Msg) {
if verbose {
log.Println(m.Subject, string(m.Data))
log.Printf("[%s] %s\n", m.Subject, string(m.Data))
}
if buffered {
// print the message followed by CR/LF
fmt.Println(string(m.Data))
} else {
// Write the binary message body to stdout
buf := bytes.NewBuffer(m.Data)
buf.WriteTo(os.Stdout)
}
})
select {}
case message != "":
// Publish specified message
nc.Publish(subject, []byte(message))
if verbose {
log.Printf("%s: [%s] Wrote '%s'\n", appName, subject, message)
}
case message == "":
// Publish message(s) from stdin
count := 0
if buffered {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
line := scanner.Text()
nc.Publish(subject, []byte(line))
count++
}
if verbose {
log.Printf("%s: [%s] Wrote %d lines\n", appName, subject, count)
}
} else {
bytes, _ := ioutil.ReadAll(os.Stdin)
count = len(bytes)
nc.Publish(subject, bytes)
if verbose {
log.Printf("%s: [%s] Wrote %d bytes\n", appName, subject, count)
}
}
}
if err := nc.LastError(); err != nil {
log.Fatal(err)
}
}
func main() {
// Log to stderr without timestamp
log.SetFlags(0)
cli.VersionFlag = cli.BoolFlag{
Name: "version, V",
Usage: "print the version",
}
cli.VersionPrinter = func(c *cli.Context) {
fmt.Printf("%s: version %s\n", c.App.Name, c.App.Version)
os.Exit(1)
}
hp := cli.HelpPrinter
cli.HelpPrinter = func(w io.Writer, templ string, data interface{}) {
hp(w, templ, data)
os.Exit(1)
}
app := cli.NewApp()
app.Name = appName
app.Usage = "cat to/from NATS subject"
app.UsageText = "natscats [global options] topic [message to post]"
app.Author = "Sigurd Høgsbro"
app.Email = "[email protected]"
app.Version = "0.2"
app.Flags = []cli.Flag{
cli.BoolFlag{
Name: "buffered, b",
Usage: "read/write messages in buffered mode, terminated by CR/LF",
Destination: &buffered,
},
cli.StringFlag{
Name: "message, m",
Usage: "message to publish",
Value: "",
Destination: &message,
},
cli.BoolFlag{
Name: "verbose, v",
Usage: "verbose logging",
Destination: &verbose,
},
cli.BoolFlag{
Name: "listen, l",
Usage: "listen for messages",
Destination: &listen,
},
cli.StringFlag{
Name: "subject, s",
Value: "",
Usage: "[Required] NATS subject ('*' and '>' wildcards only valid when listening)",
Destination: &subject,
},
cli.StringFlag{
Name: "server, S",
Value: nats.DefaultURL,
Usage: "NATS server URL(s), comma-separated",
EnvVar: "NATS",
Destination: &serverURL,
},
}
app.Action = cmdLine
app.Run(os.Args)
cat()
}