Skip to content

Commit 818ec2b

Browse files
authored
Merge pull request #79 from sdellang/httpserver
HTTP support #67
2 parents 2f5d846 + 92a5d0b commit 818ec2b

File tree

15 files changed

+295
-77
lines changed

15 files changed

+295
-77
lines changed

go.mod

+2
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@ require (
1111
github.com/spf13/viper v1.15.0
1212
github.com/squeeze69/generacodicefiscale v1.0.3
1313
golang.org/x/text v0.9.0
14+
golang.org/x/tools v0.6.0
1415
)
1516

1617
require (
1718
github.com/cespare/xxhash/v2 v2.2.0 // indirect
1819
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
1920
github.com/fsnotify/fsnotify v1.6.0 // indirect
21+
github.com/gorilla/mux v1.8.0
2022
github.com/hashicorp/hcl v1.0.0 // indirect
2123
github.com/heetch/avro v0.4.4 // indirect
2224
github.com/iancoleman/orderedmap v0.2.0 // indirect

go.sum

+3
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,8 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR
11231123
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
11241124
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
11251125
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
1126+
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
1127+
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
11261128
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
11271129
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
11281130
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
@@ -2077,6 +2079,7 @@ golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
20772079
golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
20782080
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
20792081
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
2082+
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
20802083
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
20812084
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
20822085
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

pkg/cmd/createTopic.go

+4-6
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,10 @@ package cmd
2222

2323
import (
2424
"github.com/spf13/cobra"
25+
"github.com/ugol/jr/pkg/functions"
2526
"github.com/ugol/jr/pkg/producers/kafka"
2627
)
2728

28-
const DEFAULT_PARTITIONS = 6
29-
const DEFAULT_REPLICA = 3
30-
3129
var createTopicCmd = &cobra.Command{
3230
Use: "createTopic [topic]",
3331
Short: "simple command to create a Kafka Topic",
@@ -47,7 +45,7 @@ var createTopicCmd = &cobra.Command{
4745

4846
func init() {
4947
rootCmd.AddCommand(createTopicCmd)
50-
createTopicCmd.Flags().IntP("partitions", "p", DEFAULT_PARTITIONS, "Number of partitions")
51-
createTopicCmd.Flags().IntP("replica", "r", DEFAULT_REPLICA, "Replica Factor")
52-
createTopicCmd.Flags().StringP("kafkaConfig", "F", KAFKA_CONFIG, "Kafka configuration")
48+
createTopicCmd.Flags().IntP("partitions", "p", functions.DEFAULT_PARTITIONS, "Number of partitions")
49+
createTopicCmd.Flags().IntP("replica", "r", functions.DEFAULT_REPLICA, "Replica Factor")
50+
createTopicCmd.Flags().StringP("kafkaConfig", "F", functions.KAFKA_CONFIG, "Kafka configuration")
5351
}

pkg/cmd/list.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@ package cmd
2323
import (
2424
"bytes"
2525
"fmt"
26-
"github.com/spf13/cobra"
27-
"github.com/ugol/jr/pkg/functions"
2826
"os"
2927
"path/filepath"
3028
"strings"
3129
"text/template"
30+
31+
"github.com/spf13/cobra"
32+
"github.com/ugol/jr/pkg/functions"
3233
)
3334

3435
var listCmd = &cobra.Command{
@@ -104,6 +105,6 @@ func isValidTemplate(t []byte) (bool, error) {
104105

105106
func init() {
106107
rootCmd.AddCommand(listCmd)
107-
listCmd.Flags().String("templateDir", TEMPLATEDIR, "directory containing templates")
108+
listCmd.Flags().String("templateDir", functions.TEMPLATEDIR, "directory containing templates")
108109
listCmd.Flags().BoolP("fullPath", "f", false, "Print full path")
109110
}

pkg/cmd/run.go

+18-43
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,12 @@
2121
package cmd
2222

2323
import (
24-
"github.com/spf13/cobra"
25-
"github.com/ugol/jr/pkg/functions"
2624
"os"
27-
"strings"
2825
"time"
29-
)
3026

31-
const NUM = 1
32-
const LOCALE = "US"
33-
const FREQUENCY = -1
34-
const DURATION = 0
35-
const TEMPLATEDIR = "$HOME/.jr/templates"
36-
const DEFAULT_KEY = "null"
37-
const DEFAULT_OUTPUT = "stdout"
38-
const DEFAULT_OUTPUT_TEMPLATE = "{{.V}}\n"
39-
const DEFAULT_SERIALIZER = "json-schema"
40-
const KAFKA_CONFIG = "./kafka/config.properties"
41-
const REGISTRY_CONFIG = "./kafka/registry.properties"
42-
const REDIS_TTL = 1 * time.Minute
43-
const REDIS_CONFIG = "./redis/config.json"
27+
"github.com/spf13/cobra"
28+
"github.com/ugol/jr/pkg/functions"
29+
)
4430

4531
var runCmd = &cobra.Command{
4632
Use: "run [template]",
@@ -117,52 +103,41 @@ jr run --templateFileName ~/.jr/templates/net_device.tpl
117103
Preload: preload,
118104
PreloadSize: preloadSize,
119105
}
120-
configureJrContext(conf)
121-
functions.DoTemplates(conf)
122-
},
123-
}
124106

125-
func configureJrContext(conf functions.Configuration) {
126-
functions.Random.Seed(conf.Seed)
127-
functions.JrContext.Num = conf.Num
128-
functions.JrContext.Range = make([]int, conf.Num)
129-
functions.JrContext.Frequency = conf.Frequency
130-
functions.JrContext.Locale = strings.ToLower(conf.Locale)
131-
functions.JrContext.Seed = conf.Seed
132-
functions.JrContext.TemplateDir = conf.TemplateDir
133-
functions.JrContext.CountryIndex = functions.IndexOf(strings.ToUpper(conf.Locale), "country")
107+
functions.DoTemplates(conf, nil)
108+
},
134109
}
135110

136111
func init() {
137112
rootCmd.AddCommand(runCmd)
138-
runCmd.Flags().IntP("num", "n", NUM, "Number of elements to create for each pass")
139-
runCmd.Flags().DurationP("frequency", "f", FREQUENCY, "how much time to wait for next generation pass")
140-
runCmd.Flags().DurationP("duration", "d", DURATION, "If frequency is enabled, with Duration you can set a finite amount of time")
113+
runCmd.Flags().IntP("num", "n", functions.NUM, "Number of elements to create for each pass")
114+
runCmd.Flags().DurationP("frequency", "f", functions.FREQUENCY, "how much time to wait for next generation pass")
115+
runCmd.Flags().DurationP("duration", "d", functions.DURATION, "If frequency is enabled, with Duration you can set a finite amount of time")
141116

142117
runCmd.Flags().Int64("seed", time.Now().UTC().UnixNano(), "Seed to init pseudorandom generator")
143118

144-
runCmd.Flags().String("templateDir", os.ExpandEnv(TEMPLATEDIR), "directory containing templates")
145-
runCmd.Flags().StringP("kafkaConfig", "F", KAFKA_CONFIG, "Kafka configuration")
146-
runCmd.Flags().String("registryConfig", REGISTRY_CONFIG, "Kafka configuration")
119+
runCmd.Flags().String("templateDir", os.ExpandEnv(functions.TEMPLATEDIR), "directory containing templates")
120+
runCmd.Flags().StringP("kafkaConfig", "F", functions.KAFKA_CONFIG, "Kafka configuration")
121+
runCmd.Flags().String("registryConfig", functions.REGISTRY_CONFIG, "Kafka configuration")
147122
runCmd.Flags().Bool("templateFileName", false, "If enabled, [template] must be a template file")
148123
runCmd.Flags().Bool("template", false, "If enabled, [template] must be a string containing a template, to be embedded directly in the script")
149124

150125
runCmd.Flags().StringSliceP("preload", "p", []string{""}, "Array of templates to preload")
151126
runCmd.Flags().IntSlice("preloadSize", []int{}, "Array of template sizes to preload")
152127

153-
runCmd.Flags().StringP("key", "k", DEFAULT_KEY, "A template to generate a key")
128+
runCmd.Flags().StringP("key", "k", functions.DEFAULT_KEY, "A template to generate a key")
154129
runCmd.Flags().StringSliceP("topic", "t", []string{"test"}, "Array of Kafka topic names")
155130

156131
runCmd.Flags().Bool("kcat", false, "If you want to pipe jr with kcat, use this flag: it is equivalent to --output stdout --outputTemplate '{{key}},{{value}}' --oneline")
157-
runCmd.Flags().StringP("output", "o", DEFAULT_OUTPUT, "can be one of stdout, kafka, redis, mongo")
158-
runCmd.Flags().String("outputTemplate", DEFAULT_OUTPUT_TEMPLATE, "Formatting of K,V on standard output")
132+
runCmd.Flags().StringP("output", "o", functions.DEFAULT_OUTPUT, "can be one of stdout, kafka, redis, mongo")
133+
runCmd.Flags().String("outputTemplate", functions.DEFAULT_OUTPUT_TEMPLATE, "Formatting of K,V on standard output")
159134
runCmd.Flags().BoolP("oneline", "l", false, "strips /n from output, for example to be pipelined to tools like kcat")
160135
runCmd.Flags().BoolP("autocreate", "a", false, "if enabled, autocreate topics")
161-
runCmd.Flags().String("locale", LOCALE, "Locale")
136+
runCmd.Flags().String("locale", functions.LOCALE, "Locale")
162137

163138
runCmd.Flags().BoolP("schemaRegistry", "s", false, "If you want to use Confluent Schema Registry")
164-
runCmd.Flags().String("serializer", DEFAULT_SERIALIZER, "Type of serializer: json-schema, avro-generic, avro, protobuf")
165-
runCmd.Flags().Duration("redis.ttl", REDIS_TTL, "If output is redis, ttl of the object")
166-
runCmd.Flags().String("redisConfig", REDIS_CONFIG, "Redis configuration")
139+
runCmd.Flags().String("serializer", functions.DEFAULT_SERIALIZER, "Type of serializer: json-schema, avro-generic, avro, protobuf")
140+
runCmd.Flags().Duration("redis.ttl", functions.REDIS_TTL, "If output is redis, ttl of the object")
141+
runCmd.Flags().String("redisConfig", functions.REDIS_CONFIG, "Redis configuration")
167142

168143
}

pkg/cmd/server.go

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package cmd
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"log"
7+
"net/http"
8+
"time"
9+
10+
"github.com/gorilla/mux"
11+
"github.com/spf13/cobra"
12+
"github.com/ugol/jr/pkg/functions"
13+
)
14+
15+
type JsonConfig struct {
16+
URL string `json:"url"`
17+
Template string `json:"template"`
18+
Key string `json:"key"`
19+
TemplateDir string `json:"templatedir"`
20+
Locale string `json:"locale"`
21+
Num int `json:"num"`
22+
}
23+
24+
var savedConfigurations map[string]functions.Configuration
25+
var outputTemplate = "{{.K}},{{.V}}"
26+
27+
var serverCmd = &cobra.Command{
28+
Use: "server",
29+
Short: "Starts the jr http server",
30+
Long: `Start the jr web server and takes the port flag. Default port is 8080.
31+
To configure a new http generator jr expect a configuration post on the /jr/configure address,
32+
the post body should be a json with those parameters:
33+
Name: the name of the configuration
34+
URL: the URL to expose in the form http://domain/jr/data/{URL}. URL should be unique among all the configuration otherwise an existing one will be updated.
35+
Template: the name of the template to use to generate the data
36+
Num: the number of element to create for each http get
37+
You can do multiple configurations using different URLs and different templates`,
38+
Run: func(cmd *cobra.Command, args []string) {
39+
//initialise the global map for configurations
40+
savedConfigurations = make(map[string]functions.Configuration)
41+
port, err := cmd.Flags().GetInt("port")
42+
if err != nil {
43+
log.Fatal(err)
44+
}
45+
46+
router := mux.NewRouter()
47+
router.HandleFunc("/jr/configure", handleConfiguration).Methods("POST")
48+
router.HandleFunc("/jr/data/{URL}", handleData).Methods("GET")
49+
50+
// Use the specified port, or default to 8080
51+
addr := fmt.Sprintf(":%d", port)
52+
log.Printf("Starting server on port %d\n", port)
53+
log.Fatal(http.ListenAndServe(addr, router))
54+
},
55+
}
56+
57+
func handleConfiguration(w http.ResponseWriter, r *http.Request) {
58+
// Parse request body
59+
var jsonconf JsonConfig
60+
61+
err := json.NewDecoder(r.Body).Decode(&jsonconf)
62+
if err != nil {
63+
http.Error(w, err.Error(), http.StatusBadRequest)
64+
return
65+
}
66+
67+
if jsonconf.Key == "" {
68+
jsonconf.Key = functions.DEFAULT_KEY
69+
}
70+
71+
if jsonconf.TemplateDir == "" {
72+
jsonconf.TemplateDir = functions.JrContext.TemplateDir
73+
}
74+
75+
if jsonconf.Locale == "" {
76+
jsonconf.Locale = functions.LOCALE
77+
}
78+
79+
if jsonconf.Num == 0 {
80+
jsonconf.Num = 1
81+
}
82+
83+
conf := functions.Configuration{
84+
TemplateNames: []string{jsonconf.Template},
85+
KeyTemplate: jsonconf.Key,
86+
OutputTemplate: outputTemplate,
87+
Output: "http",
88+
Oneline: true,
89+
Locale: jsonconf.Locale,
90+
Num: jsonconf.Num,
91+
Frequency: -1,
92+
Duration: 0,
93+
Seed: time.Now().UTC().UnixNano(),
94+
TemplateDir: jsonconf.TemplateDir,
95+
Autocreate: false,
96+
SchemaRegistry: false,
97+
Serializer: functions.DEFAULT_SERIALIZER,
98+
Url: jsonconf.URL,
99+
}
100+
// Save Configuration in the global map to handle it later
101+
savedConfigurations[jsonconf.URL] = conf
102+
// Respond with success message
103+
response := fmt.Sprintf("Configuration %s saved successfully", jsonconf.URL)
104+
w.Write([]byte(response))
105+
}
106+
107+
func handleData(w http.ResponseWriter, r *http.Request) {
108+
// Get the URL parameter from the request
109+
vars := mux.Vars(r)
110+
url := vars["URL"]
111+
configuration, ok := savedConfigurations[url]
112+
113+
if ok {
114+
functions.DoTemplates(configuration, &w)
115+
} else {
116+
w.WriteHeader(http.StatusNotFound)
117+
}
118+
}
119+
120+
func init() {
121+
rootCmd.AddCommand(serverCmd)
122+
serverCmd.Flags().IntP("port", "p", 8080, "Port for the server")
123+
}

pkg/cmd/show.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@ package cmd
2222

2323
import (
2424
"fmt"
25-
"github.com/spf13/cobra"
2625
"log"
2726
"os"
2827
"runtime"
2928
"strings"
29+
30+
"github.com/spf13/cobra"
31+
"github.com/ugol/jr/pkg/functions"
3032
)
3133

3234
var showCmd = &cobra.Command{
@@ -66,6 +68,6 @@ var showCmd = &cobra.Command{
6668

6769
func init() {
6870
rootCmd.AddCommand(showCmd)
69-
showCmd.Flags().String("templateDir", TEMPLATEDIR, "directory containing templates")
71+
showCmd.Flags().String("templateDir", functions.TEMPLATEDIR, "directory containing templates")
7072
showCmd.Flags().BoolP("nocolor", "n", false, "disable colorized output")
7173
}

pkg/functions/constants.go

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package functions
2+
3+
import "time"
4+
5+
const NUM = 1
6+
const LOCALE = "US"
7+
const FREQUENCY = -1
8+
const DURATION = 0
9+
const TEMPLATEDIR = "$HOME/.jr/templates"
10+
const DEFAULT_KEY = "null"
11+
const DEFAULT_OUTPUT = "stdout"
12+
const DEFAULT_OUTPUT_TEMPLATE = "{{.V}}\n"
13+
const DEFAULT_SERIALIZER = "json-schema"
14+
const KAFKA_CONFIG = "./kafka/config.properties"
15+
const REGISTRY_CONFIG = "./kafka/registry.properties"
16+
const REDIS_TTL = 1 * time.Minute
17+
const REDIS_CONFIG = "./redis/config.json"
18+
const NUM_TEMPLATES = 5
19+
const DEFAULT_PARTITIONS = 6
20+
const DEFAULT_REPLICA = 3

pkg/functions/context.go

+1-6
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,6 @@ import (
2727

2828
var JrContext Context
2929

30-
const NUM = 1
31-
const NUM_TEMPLATES = 5
32-
const FREQUENCY = 0
33-
const DURATION = 0
34-
const TEMPLATEDIR = "$HOME/.jr/templates"
35-
3630
type Configuration struct {
3731
TemplateNames []string
3832
KeyTemplate string
@@ -58,6 +52,7 @@ type Configuration struct {
5852
Serializer string
5953
RedisTtl time.Duration
6054
RedisConfig string
55+
Url string
6156
}
6257

6358
// Context is the object passed on the templates which contains all the needed details.

0 commit comments

Comments
 (0)