forked from miku/esbulk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommon.go
138 lines (130 loc) · 3.21 KB
/
common.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
package esbulk
import (
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"strings"
"sync"
)
// Application Version
const Version = "0.3.5"
// Options represents bulk indexing options
type Options struct {
Host string
Port int
Index string
DocType string
BatchSize int
Verbose bool
}
// BulkIndex takes a set of documents as strings and indexes them into elasticsearch
func BulkIndex(docs []string, options Options) error {
link := fmt.Sprintf("https://%s:%d/%s/%s/_bulk", options.Host, options.Port, options.Index, options.DocType)
header := fmt.Sprintf(`{"index": {"_index": "%s", "_type": "%s"}}`, options.Index, options.DocType)
var lines []string
for _, doc := range docs {
if len(strings.TrimSpace(doc)) == 0 {
continue
}
lines = append(lines, header)
lines = append(lines, doc)
}
body := fmt.Sprintf("%s\n", strings.Join(lines, "\n"))
response, err := http.Post(link, "application/json", strings.NewReader(body))
if err != nil {
return err
}
return response.Body.Close()
}
// Worker will batch index documents that come in on the lines channel
func Worker(id string, options Options, lines chan string, wg *sync.WaitGroup) {
defer wg.Done()
var docs []string
counter := 0
for s := range lines {
docs = append(docs, s)
counter++
if counter%options.BatchSize == 0 {
err := BulkIndex(docs, options)
if err != nil {
log.Fatal(err)
}
if options.Verbose {
log.Printf("[%s] @%d\n", id, counter)
}
docs = docs[:0]
}
}
err := BulkIndex(docs, options)
if err != nil {
log.Fatal(err)
}
if options.Verbose {
log.Printf("[%s] @%d\n", id, counter)
}
}
// PutMapping reads and applies a mapping from a reader.
func PutMapping(options Options, body io.Reader) error {
link := fmt.Sprintf("https://%s:%d/%s/_mapping/%s", options.Host, options.Port, options.Index, options.DocType)
req, err := http.NewRequest("PUT", link, body)
if err != nil {
return err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
if options.Verbose {
log.Printf("applied mapping: %s", resp.Status)
}
return resp.Body.Close()
}
// CreateIndex creates a new index.
func CreateIndex(options Options) error {
resp, err := http.Get(fmt.Sprintf("https://%s:%d/%s", options.Host, options.Port, options.Index))
if err != nil {
return err
}
if resp.StatusCode == 200 {
return nil
}
req, err := http.NewRequest("PUT", fmt.Sprintf("https://%s:%d/%s/", options.Host, options.Port, options.Index), nil)
if err != nil {
return err
}
resp, err = http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode == 400 {
msg, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
return errors.New(string(msg))
}
if options.Verbose {
log.Printf("created index: %s\n", resp.Status)
}
return nil
}
// DeleteIndex removes an index.
func DeleteIndex(options Options) error {
link := fmt.Sprintf("https://%s:%d/%s", options.Host, options.Port, options.Index)
req, err := http.NewRequest("DELETE", link, nil)
if err != nil {
return err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
if options.Verbose {
log.Printf("purged index: %s", resp.Status)
}
return resp.Body.Close()
}