Switch from Godep to go vendoring
This commit is contained in:
parent
6b37713bc0
commit
cd317761c5
1504 changed files with 263076 additions and 34441 deletions
65
vendor/github.com/blevesearch/bleve/http/alias.go
generated
vendored
Normal file
65
vendor/github.com/blevesearch/bleve/http/alias.go
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type AliasAction struct {
|
||||
Alias string `json:"alias"`
|
||||
AddIndexes []string `json:"add"`
|
||||
RemoveIndexes []string `json:"remove"`
|
||||
}
|
||||
|
||||
type AliasHandler struct{}
|
||||
|
||||
func NewAliasHandler() *AliasHandler {
|
||||
return &AliasHandler{}
|
||||
}
|
||||
|
||||
func (h *AliasHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
|
||||
// read the request body
|
||||
requestBody, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error reading request body: %v", err), 400)
|
||||
return
|
||||
}
|
||||
|
||||
var aliasAction AliasAction
|
||||
// interpret request body as alias actions
|
||||
if len(requestBody) > 0 {
|
||||
err := json.Unmarshal(requestBody, &aliasAction)
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error parsing alias actions: %v", err), 400)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
showError(w, req, "request body must contain alias actions", 400)
|
||||
return
|
||||
}
|
||||
|
||||
err = UpdateAlias(aliasAction.Alias, aliasAction.AddIndexes, aliasAction.RemoveIndexes)
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error updating alias: %v", err), 400)
|
||||
return
|
||||
}
|
||||
|
||||
rv := struct {
|
||||
Status string `json:"status"`
|
||||
}{
|
||||
Status: "ok",
|
||||
}
|
||||
mustEncode(w, rv)
|
||||
}
|
74
vendor/github.com/blevesearch/bleve/http/debug.go
generated
vendored
Normal file
74
vendor/github.com/blevesearch/bleve/http/debug.go
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/blevesearch/bleve/index/upside_down"
|
||||
)
|
||||
|
||||
// DebugDocumentHandler allows you to debug the index content
|
||||
// for a given document id.
|
||||
type DebugDocumentHandler struct {
|
||||
defaultIndexName string
|
||||
IndexNameLookup varLookupFunc
|
||||
DocIDLookup varLookupFunc
|
||||
}
|
||||
|
||||
func NewDebugDocumentHandler(defaultIndexName string) *DebugDocumentHandler {
|
||||
return &DebugDocumentHandler{
|
||||
defaultIndexName: defaultIndexName,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *DebugDocumentHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
|
||||
// find the index to operate on
|
||||
var indexName string
|
||||
if h.IndexNameLookup != nil {
|
||||
indexName = h.IndexNameLookup(req)
|
||||
}
|
||||
if indexName == "" {
|
||||
indexName = h.defaultIndexName
|
||||
}
|
||||
index := IndexByName(indexName)
|
||||
if index == nil {
|
||||
showError(w, req, fmt.Sprintf("no such index '%s'", indexName), 404)
|
||||
return
|
||||
}
|
||||
|
||||
// find the docID
|
||||
var docID string
|
||||
if h.DocIDLookup != nil {
|
||||
docID = h.DocIDLookup(req)
|
||||
}
|
||||
|
||||
rv := make([]interface{}, 0)
|
||||
rowChan := index.DumpDoc(docID)
|
||||
for row := range rowChan {
|
||||
switch row := row.(type) {
|
||||
case error:
|
||||
showError(w, req, fmt.Sprintf("error debugging document: %v", row), 500)
|
||||
return
|
||||
case upside_down.UpsideDownCouchRow:
|
||||
tmp := struct {
|
||||
Key []byte `json:"key"`
|
||||
Val []byte `json:"val"`
|
||||
}{
|
||||
Key: row.Key(),
|
||||
Val: row.Value(),
|
||||
}
|
||||
rv = append(rv, tmp)
|
||||
}
|
||||
}
|
||||
mustEncode(w, rv)
|
||||
}
|
56
vendor/github.com/blevesearch/bleve/http/doc_count.go
generated
vendored
Normal file
56
vendor/github.com/blevesearch/bleve/http/doc_count.go
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type DocCountHandler struct {
|
||||
defaultIndexName string
|
||||
IndexNameLookup varLookupFunc
|
||||
}
|
||||
|
||||
func NewDocCountHandler(defaultIndexName string) *DocCountHandler {
|
||||
return &DocCountHandler{
|
||||
defaultIndexName: defaultIndexName,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *DocCountHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
// find the index to operate on
|
||||
var indexName string
|
||||
if h.IndexNameLookup != nil {
|
||||
indexName = h.IndexNameLookup(req)
|
||||
}
|
||||
if indexName == "" {
|
||||
indexName = h.defaultIndexName
|
||||
}
|
||||
index := IndexByName(indexName)
|
||||
if index == nil {
|
||||
showError(w, req, fmt.Sprintf("no such index '%s'", indexName), 404)
|
||||
return
|
||||
}
|
||||
|
||||
docCount, err := index.DocCount()
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error counting docs: %v", err), 500)
|
||||
return
|
||||
}
|
||||
rv := struct {
|
||||
Status string `json:"status"`
|
||||
Count uint64 `json:"count"`
|
||||
}{
|
||||
Status: "ok",
|
||||
Count: docCount,
|
||||
}
|
||||
mustEncode(w, rv)
|
||||
}
|
67
vendor/github.com/blevesearch/bleve/http/doc_delete.go
generated
vendored
Normal file
67
vendor/github.com/blevesearch/bleve/http/doc_delete.go
generated
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type DocDeleteHandler struct {
|
||||
defaultIndexName string
|
||||
IndexNameLookup varLookupFunc
|
||||
DocIDLookup varLookupFunc
|
||||
}
|
||||
|
||||
func NewDocDeleteHandler(defaultIndexName string) *DocDeleteHandler {
|
||||
return &DocDeleteHandler{
|
||||
defaultIndexName: defaultIndexName,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *DocDeleteHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
|
||||
// find the index to operate on
|
||||
var indexName string
|
||||
if h.IndexNameLookup != nil {
|
||||
indexName = h.IndexNameLookup(req)
|
||||
}
|
||||
if indexName == "" {
|
||||
indexName = h.defaultIndexName
|
||||
}
|
||||
index := IndexByName(indexName)
|
||||
if index == nil {
|
||||
showError(w, req, fmt.Sprintf("no such index '%s'", indexName), 404)
|
||||
return
|
||||
}
|
||||
|
||||
// find the doc id
|
||||
var docID string
|
||||
if h.DocIDLookup != nil {
|
||||
docID = h.DocIDLookup(req)
|
||||
}
|
||||
if docID == "" {
|
||||
showError(w, req, "document id cannot be empty", 400)
|
||||
return
|
||||
}
|
||||
|
||||
err := index.Delete(docID)
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error deleting document '%s': %v", docID, err), 500)
|
||||
return
|
||||
}
|
||||
|
||||
rv := struct {
|
||||
Status string `json:"status"`
|
||||
}{
|
||||
Status: "ok",
|
||||
}
|
||||
mustEncode(w, rv)
|
||||
}
|
107
vendor/github.com/blevesearch/bleve/http/doc_get.go
generated
vendored
Normal file
107
vendor/github.com/blevesearch/bleve/http/doc_get.go
generated
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/blevesearch/bleve/document"
|
||||
)
|
||||
|
||||
type DocGetHandler struct {
|
||||
defaultIndexName string
|
||||
IndexNameLookup varLookupFunc
|
||||
DocIDLookup varLookupFunc
|
||||
}
|
||||
|
||||
func NewDocGetHandler(defaultIndexName string) *DocGetHandler {
|
||||
return &DocGetHandler{
|
||||
defaultIndexName: defaultIndexName,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *DocGetHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
// find the index to operate on
|
||||
var indexName string
|
||||
if h.IndexNameLookup != nil {
|
||||
indexName = h.IndexNameLookup(req)
|
||||
}
|
||||
if indexName == "" {
|
||||
indexName = h.defaultIndexName
|
||||
}
|
||||
index := IndexByName(indexName)
|
||||
if index == nil {
|
||||
showError(w, req, fmt.Sprintf("no such index '%s'", indexName), 404)
|
||||
return
|
||||
}
|
||||
|
||||
// find the doc id
|
||||
var docID string
|
||||
if h.DocIDLookup != nil {
|
||||
docID = h.DocIDLookup(req)
|
||||
}
|
||||
if docID == "" {
|
||||
showError(w, req, "document id cannot be empty", 400)
|
||||
return
|
||||
}
|
||||
|
||||
doc, err := index.Document(docID)
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error deleting document '%s': %v", docID, err), 500)
|
||||
return
|
||||
}
|
||||
if doc == nil {
|
||||
showError(w, req, fmt.Sprintf("no such document '%s'", docID), 404)
|
||||
return
|
||||
}
|
||||
|
||||
rv := struct {
|
||||
ID string `json:"id"`
|
||||
Fields map[string]interface{} `json:"fields"`
|
||||
}{
|
||||
ID: docID,
|
||||
Fields: map[string]interface{}{},
|
||||
}
|
||||
for _, field := range doc.Fields {
|
||||
var newval interface{}
|
||||
switch field := field.(type) {
|
||||
case *document.TextField:
|
||||
newval = string(field.Value())
|
||||
case *document.NumericField:
|
||||
n, err := field.Number()
|
||||
if err == nil {
|
||||
newval = n
|
||||
}
|
||||
case *document.DateTimeField:
|
||||
d, err := field.DateTime()
|
||||
if err == nil {
|
||||
newval = d.Format(time.RFC3339Nano)
|
||||
}
|
||||
}
|
||||
existing, existed := rv.Fields[field.Name()]
|
||||
if existed {
|
||||
switch existing := existing.(type) {
|
||||
case []interface{}:
|
||||
rv.Fields[field.Name()] = append(existing, newval)
|
||||
case interface{}:
|
||||
arr := make([]interface{}, 2)
|
||||
arr[0] = existing
|
||||
arr[1] = newval
|
||||
rv.Fields[field.Name()] = arr
|
||||
}
|
||||
} else {
|
||||
rv.Fields[field.Name()] = newval
|
||||
}
|
||||
}
|
||||
|
||||
mustEncode(w, rv)
|
||||
}
|
75
vendor/github.com/blevesearch/bleve/http/doc_index.go
generated
vendored
Normal file
75
vendor/github.com/blevesearch/bleve/http/doc_index.go
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type DocIndexHandler struct {
|
||||
defaultIndexName string
|
||||
IndexNameLookup varLookupFunc
|
||||
DocIDLookup varLookupFunc
|
||||
}
|
||||
|
||||
func NewDocIndexHandler(defaultIndexName string) *DocIndexHandler {
|
||||
return &DocIndexHandler{
|
||||
defaultIndexName: defaultIndexName,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *DocIndexHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
|
||||
// find the index to operate on
|
||||
var indexName string
|
||||
if h.IndexNameLookup != nil {
|
||||
indexName = h.IndexNameLookup(req)
|
||||
}
|
||||
if indexName == "" {
|
||||
indexName = h.defaultIndexName
|
||||
}
|
||||
index := IndexByName(indexName)
|
||||
if index == nil {
|
||||
showError(w, req, fmt.Sprintf("no such index '%s'", indexName), 404)
|
||||
return
|
||||
}
|
||||
|
||||
// find the doc id
|
||||
var docID string
|
||||
if h.DocIDLookup != nil {
|
||||
docID = h.DocIDLookup(req)
|
||||
}
|
||||
if docID == "" {
|
||||
showError(w, req, "document id cannot be empty", 400)
|
||||
return
|
||||
}
|
||||
|
||||
// read the request body
|
||||
requestBody, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error reading request body: %v", err), 400)
|
||||
return
|
||||
}
|
||||
|
||||
err = index.Index(docID, requestBody)
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error indexing document '%s': %v", docID, err), 500)
|
||||
return
|
||||
}
|
||||
|
||||
rv := struct {
|
||||
Status string `json:"status"`
|
||||
}{
|
||||
Status: "ok",
|
||||
}
|
||||
mustEncode(w, rv)
|
||||
}
|
58
vendor/github.com/blevesearch/bleve/http/fields.go
generated
vendored
Normal file
58
vendor/github.com/blevesearch/bleve/http/fields.go
generated
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type ListFieldsHandler struct {
|
||||
defaultIndexName string
|
||||
IndexNameLookup varLookupFunc
|
||||
}
|
||||
|
||||
func NewListFieldsHandler(defaultIndexName string) *ListFieldsHandler {
|
||||
return &ListFieldsHandler{
|
||||
defaultIndexName: defaultIndexName,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *ListFieldsHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
|
||||
// find the index to operate on
|
||||
var indexName string
|
||||
if h.IndexNameLookup != nil {
|
||||
indexName = h.IndexNameLookup(req)
|
||||
}
|
||||
if indexName == "" {
|
||||
indexName = h.defaultIndexName
|
||||
}
|
||||
index := IndexByName(indexName)
|
||||
if index == nil {
|
||||
showError(w, req, fmt.Sprintf("no such index '%s'", indexName), 404)
|
||||
return
|
||||
}
|
||||
|
||||
fields, err := index.Fields()
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error: %v", err), 500)
|
||||
return
|
||||
}
|
||||
|
||||
fieldsResponse := struct {
|
||||
Fields []string `json:"fields"`
|
||||
}{
|
||||
Fields: fields,
|
||||
}
|
||||
|
||||
// encode the response
|
||||
mustEncode(w, fieldsResponse)
|
||||
}
|
704
vendor/github.com/blevesearch/bleve/http/handlers_test.go
generated
vendored
Normal file
704
vendor/github.com/blevesearch/bleve/http/handlers_test.go
generated
vendored
Normal file
|
@ -0,0 +1,704 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func docIDLookup(req *http.Request) string {
|
||||
return req.FormValue("docID")
|
||||
}
|
||||
|
||||
func indexNameLookup(req *http.Request) string {
|
||||
return req.FormValue("indexName")
|
||||
}
|
||||
|
||||
func TestHandlers(t *testing.T) {
|
||||
|
||||
basePath := "testbase"
|
||||
err := os.MkdirAll(basePath, 0700)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() {
|
||||
err := os.RemoveAll(basePath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
createIndexHandler := NewCreateIndexHandler(basePath)
|
||||
createIndexHandler.IndexNameLookup = indexNameLookup
|
||||
|
||||
getIndexHandler := NewGetIndexHandler()
|
||||
getIndexHandler.IndexNameLookup = indexNameLookup
|
||||
|
||||
deleteIndexHandler := NewDeleteIndexHandler(basePath)
|
||||
deleteIndexHandler.IndexNameLookup = indexNameLookup
|
||||
|
||||
listIndexesHandler := NewListIndexesHandler()
|
||||
|
||||
docIndexHandler := NewDocIndexHandler("")
|
||||
docIndexHandler.IndexNameLookup = indexNameLookup
|
||||
docIndexHandler.DocIDLookup = docIDLookup
|
||||
|
||||
docCountHandler := NewDocCountHandler("")
|
||||
docCountHandler.IndexNameLookup = indexNameLookup
|
||||
|
||||
docGetHandler := NewDocGetHandler("")
|
||||
docGetHandler.IndexNameLookup = indexNameLookup
|
||||
docGetHandler.DocIDLookup = docIDLookup
|
||||
|
||||
docDeleteHandler := NewDocDeleteHandler("")
|
||||
docDeleteHandler.IndexNameLookup = indexNameLookup
|
||||
docDeleteHandler.DocIDLookup = docIDLookup
|
||||
|
||||
searchHandler := NewSearchHandler("")
|
||||
searchHandler.IndexNameLookup = indexNameLookup
|
||||
|
||||
listFieldsHandler := NewListFieldsHandler("")
|
||||
listFieldsHandler.IndexNameLookup = indexNameLookup
|
||||
|
||||
debugHandler := NewDebugDocumentHandler("")
|
||||
debugHandler.IndexNameLookup = indexNameLookup
|
||||
debugHandler.DocIDLookup = docIDLookup
|
||||
|
||||
aliasHandler := NewAliasHandler()
|
||||
|
||||
tests := []struct {
|
||||
Desc string
|
||||
Handler http.Handler
|
||||
Path string
|
||||
Method string
|
||||
Params url.Values
|
||||
Body []byte
|
||||
Status int
|
||||
ResponseBody []byte
|
||||
ResponseMatch map[string]bool
|
||||
}{
|
||||
{
|
||||
Desc: "create index",
|
||||
Handler: createIndexHandler,
|
||||
Path: "/create",
|
||||
Method: "PUT",
|
||||
Params: url.Values{"indexName": []string{"ti1"}},
|
||||
Body: []byte("{}"),
|
||||
Status: http.StatusOK,
|
||||
ResponseBody: []byte(`{"status":"ok"}`),
|
||||
},
|
||||
{
|
||||
Desc: "create existing index",
|
||||
Handler: createIndexHandler,
|
||||
Path: "/create",
|
||||
Method: "PUT",
|
||||
Params: url.Values{"indexName": []string{"ti1"}},
|
||||
Body: []byte("{}"),
|
||||
Status: http.StatusInternalServerError,
|
||||
ResponseMatch: map[string]bool{
|
||||
`path already exists`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "create index missing index",
|
||||
Handler: createIndexHandler,
|
||||
Path: "/create",
|
||||
Method: "PUT",
|
||||
Body: []byte("{}"),
|
||||
Status: http.StatusBadRequest,
|
||||
ResponseBody: []byte(`index name is required`),
|
||||
},
|
||||
{
|
||||
Desc: "create index invalid json",
|
||||
Handler: createIndexHandler,
|
||||
Path: "/create",
|
||||
Method: "PUT",
|
||||
Params: url.Values{"indexName": []string{"ti9"}},
|
||||
Body: []byte("{"),
|
||||
Status: http.StatusBadRequest,
|
||||
ResponseMatch: map[string]bool{
|
||||
`error parsing index mapping`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "get index",
|
||||
Handler: getIndexHandler,
|
||||
Path: "/get",
|
||||
Method: "GET",
|
||||
Params: url.Values{"indexName": []string{"ti1"}},
|
||||
Status: http.StatusOK,
|
||||
ResponseMatch: map[string]bool{
|
||||
`"status":"ok"`: true,
|
||||
`"name":"ti1"`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "get index does not exist",
|
||||
Handler: getIndexHandler,
|
||||
Path: "/get",
|
||||
Method: "GET",
|
||||
Params: url.Values{"indexName": []string{"dne"}},
|
||||
Status: http.StatusNotFound,
|
||||
ResponseMatch: map[string]bool{
|
||||
`no such index`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "get index missing name",
|
||||
Handler: getIndexHandler,
|
||||
Path: "/get",
|
||||
Method: "GET",
|
||||
Status: http.StatusBadRequest,
|
||||
ResponseBody: []byte(`index name is required`),
|
||||
},
|
||||
{
|
||||
Desc: "create another index",
|
||||
Handler: createIndexHandler,
|
||||
Path: "/create",
|
||||
Method: "PUT",
|
||||
Params: url.Values{"indexName": []string{"ti2"}},
|
||||
Body: []byte("{}"),
|
||||
Status: http.StatusOK,
|
||||
ResponseBody: []byte(`{"status":"ok"}`),
|
||||
},
|
||||
{
|
||||
Desc: "list indexes",
|
||||
Handler: listIndexesHandler,
|
||||
Path: "/list",
|
||||
Method: "GET",
|
||||
Status: http.StatusOK,
|
||||
ResponseMatch: map[string]bool{
|
||||
`"status":"ok"`: true,
|
||||
`"ti1"`: true,
|
||||
`"ti2"`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "delete index",
|
||||
Handler: deleteIndexHandler,
|
||||
Path: "/delete",
|
||||
Method: "DELETE",
|
||||
Params: url.Values{"indexName": []string{"ti2"}},
|
||||
Status: http.StatusOK,
|
||||
ResponseBody: []byte(`{"status":"ok"}`),
|
||||
},
|
||||
{
|
||||
Desc: "delete index missing name",
|
||||
Handler: deleteIndexHandler,
|
||||
Path: "/delete",
|
||||
Method: "DELETE",
|
||||
Status: http.StatusBadRequest,
|
||||
ResponseBody: []byte(`index name is required`),
|
||||
},
|
||||
{
|
||||
Desc: "list indexes after delete",
|
||||
Handler: listIndexesHandler,
|
||||
Path: "/list",
|
||||
Method: "GET",
|
||||
Status: http.StatusOK,
|
||||
ResponseMatch: map[string]bool{
|
||||
`"status":"ok"`: true,
|
||||
`"ti1"`: true,
|
||||
`"ti2"`: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "index doc",
|
||||
Handler: docIndexHandler,
|
||||
Path: "/ti1/a",
|
||||
Method: "PUT",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"ti1"},
|
||||
"docID": []string{"a"},
|
||||
},
|
||||
Body: []byte(`{"name":"a","body":"test","rating":7,"created":"2014-11-26","former_ratings":[3,4,2]}`),
|
||||
Status: http.StatusOK,
|
||||
ResponseBody: []byte(`{"status":"ok"}`),
|
||||
},
|
||||
{
|
||||
Desc: "index doc invalid index",
|
||||
Handler: docIndexHandler,
|
||||
Path: "/tix/a",
|
||||
Method: "PUT",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"tix"},
|
||||
"docID": []string{"a"},
|
||||
},
|
||||
Body: []byte(`{"name":"a","body":"test","rating":7,"created":"2014-11-26","former_ratings":[3,4,2]}`),
|
||||
Status: http.StatusNotFound,
|
||||
ResponseBody: []byte(`no such index 'tix'`),
|
||||
},
|
||||
{
|
||||
Desc: "index doc missing ID",
|
||||
Handler: docIndexHandler,
|
||||
Path: "/ti1/a",
|
||||
Method: "PUT",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"ti1"},
|
||||
},
|
||||
Body: []byte(`{"name":"a","body":"test","rating":7,"created":"2014-11-26","former_ratings":[3,4,2]}`),
|
||||
Status: http.StatusBadRequest,
|
||||
ResponseBody: []byte(`document id cannot be empty`),
|
||||
},
|
||||
{
|
||||
Desc: "doc count",
|
||||
Handler: docCountHandler,
|
||||
Path: "/ti1/count",
|
||||
Method: "GET",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"ti1"},
|
||||
},
|
||||
Status: http.StatusOK,
|
||||
ResponseBody: []byte(`{"status":"ok","count":1}`),
|
||||
},
|
||||
{
|
||||
Desc: "doc count invalid index",
|
||||
Handler: docCountHandler,
|
||||
Path: "/tix/count",
|
||||
Method: "GET",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"tix"},
|
||||
},
|
||||
Status: http.StatusNotFound,
|
||||
ResponseBody: []byte(`no such index 'tix'`),
|
||||
},
|
||||
{
|
||||
Desc: "doc get",
|
||||
Handler: docGetHandler,
|
||||
Path: "/ti1/a",
|
||||
Method: "GET",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"ti1"},
|
||||
"docID": []string{"a"},
|
||||
},
|
||||
Status: http.StatusOK,
|
||||
ResponseMatch: map[string]bool{
|
||||
`"id":"a"`: true,
|
||||
`"body":"test"`: true,
|
||||
`"name":"a"`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "doc get invalid index",
|
||||
Handler: docGetHandler,
|
||||
Path: "/tix/a",
|
||||
Method: "GET",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"tix"},
|
||||
"docID": []string{"a"},
|
||||
},
|
||||
Status: http.StatusNotFound,
|
||||
ResponseBody: []byte(`no such index 'tix'`),
|
||||
},
|
||||
{
|
||||
Desc: "doc get missing ID",
|
||||
Handler: docGetHandler,
|
||||
Path: "/ti1/a",
|
||||
Method: "GET",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"ti1"},
|
||||
},
|
||||
Status: http.StatusBadRequest,
|
||||
ResponseBody: []byte(`document id cannot be empty`),
|
||||
},
|
||||
{
|
||||
Desc: "index another doc",
|
||||
Handler: docIndexHandler,
|
||||
Path: "/ti1/b",
|
||||
Method: "PUT",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"ti1"},
|
||||
"docID": []string{"b"},
|
||||
},
|
||||
Body: []byte(`{"name":"b","body":"del"}`),
|
||||
Status: http.StatusOK,
|
||||
ResponseBody: []byte(`{"status":"ok"}`),
|
||||
},
|
||||
{
|
||||
Desc: "doc count again",
|
||||
Handler: docCountHandler,
|
||||
Path: "/ti1/count",
|
||||
Method: "GET",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"ti1"},
|
||||
},
|
||||
Status: http.StatusOK,
|
||||
ResponseBody: []byte(`{"status":"ok","count":2}`),
|
||||
},
|
||||
{
|
||||
Desc: "delete doc",
|
||||
Handler: docDeleteHandler,
|
||||
Path: "/ti1/b",
|
||||
Method: "DELETE",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"ti1"},
|
||||
"docID": []string{"b"},
|
||||
},
|
||||
Status: http.StatusOK,
|
||||
ResponseBody: []byte(`{"status":"ok"}`),
|
||||
},
|
||||
{
|
||||
Desc: "delete doc invalid index",
|
||||
Handler: docDeleteHandler,
|
||||
Path: "/tix/b",
|
||||
Method: "DELETE",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"tix"},
|
||||
"docID": []string{"b"},
|
||||
},
|
||||
Status: http.StatusNotFound,
|
||||
ResponseBody: []byte(`no such index 'tix'`),
|
||||
},
|
||||
{
|
||||
Desc: "delete doc missing docID",
|
||||
Handler: docDeleteHandler,
|
||||
Path: "/ti1/b",
|
||||
Method: "DELETE",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"ti1"},
|
||||
},
|
||||
Status: http.StatusBadRequest,
|
||||
ResponseBody: []byte(`document id cannot be empty`),
|
||||
},
|
||||
{
|
||||
Desc: "doc get",
|
||||
Handler: docGetHandler,
|
||||
Path: "/ti1/b",
|
||||
Method: "GET",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"ti1"},
|
||||
"docID": []string{"b"},
|
||||
},
|
||||
Status: http.StatusNotFound,
|
||||
ResponseMatch: map[string]bool{
|
||||
`no such document`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "search",
|
||||
Handler: searchHandler,
|
||||
Path: "/ti1/search",
|
||||
Method: "POST",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"ti1"},
|
||||
},
|
||||
Body: []byte(`{
|
||||
"from": 0,
|
||||
"size": 10,
|
||||
"query": {
|
||||
"fuzziness": 0,
|
||||
"prefix_length": 0,
|
||||
"field": "body",
|
||||
"match": "test"
|
||||
}
|
||||
}`),
|
||||
Status: http.StatusOK,
|
||||
ResponseMatch: map[string]bool{
|
||||
`"total_hits":1`: true,
|
||||
`"id":"a"`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "search index doesnt exist",
|
||||
Handler: searchHandler,
|
||||
Path: "/tix/search",
|
||||
Method: "POST",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"tix"},
|
||||
},
|
||||
Body: []byte(`{
|
||||
"from": 0,
|
||||
"size": 10,
|
||||
"query": {
|
||||
"fuzziness": 0,
|
||||
"prefix_length": 0,
|
||||
"field": "body",
|
||||
"match": "test"
|
||||
}
|
||||
}`),
|
||||
Status: http.StatusNotFound,
|
||||
ResponseBody: []byte(`no such index 'tix'`),
|
||||
},
|
||||
{
|
||||
Desc: "search invalid json",
|
||||
Handler: searchHandler,
|
||||
Path: "/ti1/search",
|
||||
Method: "POST",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"ti1"},
|
||||
},
|
||||
Body: []byte(`{`),
|
||||
Status: http.StatusBadRequest,
|
||||
ResponseMatch: map[string]bool{
|
||||
`error parsing query`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "search query does not validate",
|
||||
Handler: searchHandler,
|
||||
Path: "/ti1/search",
|
||||
Method: "POST",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"ti1"},
|
||||
},
|
||||
Body: []byte(`{
|
||||
"from": 0,
|
||||
"size": 10,
|
||||
"query": {
|
||||
"field": "body",
|
||||
"terms": []
|
||||
}
|
||||
}`),
|
||||
Status: http.StatusBadRequest,
|
||||
ResponseMatch: map[string]bool{
|
||||
`error validating query`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "list fields",
|
||||
Handler: listFieldsHandler,
|
||||
Path: "/ti1/fields",
|
||||
Method: "GET",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"ti1"},
|
||||
},
|
||||
Status: http.StatusOK,
|
||||
ResponseMatch: map[string]bool{
|
||||
`"fields":`: true,
|
||||
`"name"`: true,
|
||||
`"body"`: true,
|
||||
`"_all"`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "list fields invalid index",
|
||||
Handler: listFieldsHandler,
|
||||
Path: "/tix/fields",
|
||||
Method: "GET",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"tix"},
|
||||
},
|
||||
Status: http.StatusNotFound,
|
||||
ResponseBody: []byte(`no such index 'tix'`),
|
||||
},
|
||||
{
|
||||
Desc: "debug doc",
|
||||
Handler: debugHandler,
|
||||
Path: "/ti1/a/debug",
|
||||
Method: "GET",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"ti1"},
|
||||
"docID": []string{"a"},
|
||||
},
|
||||
Status: http.StatusOK,
|
||||
ResponseMatch: map[string]bool{
|
||||
`"key"`: true,
|
||||
`"val"`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "debug doc invalid index",
|
||||
Handler: debugHandler,
|
||||
Path: "/ti1/a/debug",
|
||||
Method: "GET",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"tix"},
|
||||
"docID": []string{"a"},
|
||||
},
|
||||
Status: http.StatusNotFound,
|
||||
ResponseBody: []byte(`no such index 'tix'`),
|
||||
},
|
||||
{
|
||||
Desc: "create alias",
|
||||
Handler: aliasHandler,
|
||||
Path: "/alias",
|
||||
Method: "POST",
|
||||
Body: []byte(`{
|
||||
"alias": "a1",
|
||||
"add": ["ti1"]
|
||||
}`),
|
||||
Status: http.StatusOK,
|
||||
ResponseBody: []byte(`{"status":"ok"}`),
|
||||
},
|
||||
{
|
||||
Desc: "create alias invalid json",
|
||||
Handler: aliasHandler,
|
||||
Path: "/alias",
|
||||
Method: "POST",
|
||||
Body: []byte(`{`),
|
||||
Status: http.StatusBadRequest,
|
||||
ResponseMatch: map[string]bool{
|
||||
`error parsing alias actions`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "create alias empty",
|
||||
Handler: aliasHandler,
|
||||
Path: "/alias",
|
||||
Method: "POST",
|
||||
Body: []byte(``),
|
||||
Status: http.StatusBadRequest,
|
||||
ResponseMatch: map[string]bool{
|
||||
`request body must contain alias actions`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "create alias referring to non-existant index",
|
||||
Handler: aliasHandler,
|
||||
Path: "/alias",
|
||||
Method: "POST",
|
||||
Body: []byte(`{
|
||||
"alias": "a2",
|
||||
"add": ["tix"]
|
||||
}`),
|
||||
Status: http.StatusBadRequest,
|
||||
ResponseMatch: map[string]bool{
|
||||
`index named 'tix' does not exist`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "create alias removing from new",
|
||||
Handler: aliasHandler,
|
||||
Path: "/alias",
|
||||
Method: "POST",
|
||||
Body: []byte(`{
|
||||
"alias": "a2",
|
||||
"remove": ["ti1"]
|
||||
}`),
|
||||
Status: http.StatusBadRequest,
|
||||
ResponseMatch: map[string]bool{
|
||||
`cannot remove indexes from a new alias`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "create alias same name as index",
|
||||
Handler: aliasHandler,
|
||||
Path: "/alias",
|
||||
Method: "POST",
|
||||
Body: []byte(`{
|
||||
"alias": "ti1",
|
||||
"remove": ["ti1"]
|
||||
}`),
|
||||
Status: http.StatusBadRequest,
|
||||
ResponseMatch: map[string]bool{
|
||||
`is not an alias`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "search alias",
|
||||
Handler: searchHandler,
|
||||
Path: "/a1/search",
|
||||
Method: "POST",
|
||||
Params: url.Values{
|
||||
"indexName": []string{"a1"},
|
||||
},
|
||||
Body: []byte(`{
|
||||
"from": 0,
|
||||
"size": 10,
|
||||
"query": {
|
||||
"fuzziness": 0,
|
||||
"prefix_length": 0,
|
||||
"field": "body",
|
||||
"match": "test"
|
||||
}
|
||||
}`),
|
||||
Status: http.StatusOK,
|
||||
ResponseMatch: map[string]bool{
|
||||
`"total_hits":1`: true,
|
||||
`"id":"a"`: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "create index to add to alias",
|
||||
Handler: createIndexHandler,
|
||||
Path: "/create",
|
||||
Method: "PUT",
|
||||
Params: url.Values{"indexName": []string{"ti6"}},
|
||||
Body: []byte("{}"),
|
||||
Status: http.StatusOK,
|
||||
ResponseBody: []byte(`{"status":"ok"}`),
|
||||
},
|
||||
{
|
||||
Desc: "update alias add ti6",
|
||||
Handler: aliasHandler,
|
||||
Path: "/alias",
|
||||
Method: "POST",
|
||||
Body: []byte(`{
|
||||
"alias": "a1",
|
||||
"add": ["ti6"]
|
||||
}`),
|
||||
Status: http.StatusOK,
|
||||
ResponseBody: []byte(`{"status":"ok"}`),
|
||||
},
|
||||
{
|
||||
Desc: "update alias add doesnt exist",
|
||||
Handler: aliasHandler,
|
||||
Path: "/alias",
|
||||
Method: "POST",
|
||||
Body: []byte(`{
|
||||
"alias": "a1",
|
||||
"add": ["ti99"]
|
||||
}`),
|
||||
Status: http.StatusBadRequest,
|
||||
ResponseBody: []byte(`error updating alias: index named 'ti99' does not exist`),
|
||||
},
|
||||
{
|
||||
Desc: "update alias remove ti6",
|
||||
Handler: aliasHandler,
|
||||
Path: "/alias",
|
||||
Method: "POST",
|
||||
Body: []byte(`{
|
||||
"alias": "a1",
|
||||
"remove": ["ti6"]
|
||||
}`),
|
||||
Status: http.StatusOK,
|
||||
ResponseBody: []byte(`{"status":"ok"}`),
|
||||
},
|
||||
{
|
||||
Desc: "update alias remove doesnt exist",
|
||||
Handler: aliasHandler,
|
||||
Path: "/alias",
|
||||
Method: "POST",
|
||||
Body: []byte(`{
|
||||
"alias": "a1",
|
||||
"remove": ["ti98"]
|
||||
}`),
|
||||
Status: http.StatusBadRequest,
|
||||
ResponseBody: []byte(`error updating alias: index named 'ti98' does not exist`),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
record := httptest.NewRecorder()
|
||||
req := &http.Request{
|
||||
Method: test.Method,
|
||||
URL: &url.URL{Path: test.Path},
|
||||
Form: test.Params,
|
||||
Body: ioutil.NopCloser(bytes.NewBuffer(test.Body)),
|
||||
}
|
||||
test.Handler.ServeHTTP(record, req)
|
||||
if got, want := record.Code, test.Status; got != want {
|
||||
t.Errorf("%s: response code = %d, want %d", test.Desc, got, want)
|
||||
t.Errorf("%s: response body = %s", test.Desc, record.Body)
|
||||
}
|
||||
|
||||
got := bytes.TrimRight(record.Body.Bytes(), "\n")
|
||||
if test.ResponseBody != nil {
|
||||
if !reflect.DeepEqual(got, test.ResponseBody) {
|
||||
t.Errorf("%s: expected: '%s', got: '%s'", test.Desc, test.ResponseBody, got)
|
||||
}
|
||||
}
|
||||
for pattern, shouldMatch := range test.ResponseMatch {
|
||||
didMatch := bytes.Contains(got, []byte(pattern))
|
||||
if didMatch != shouldMatch {
|
||||
t.Errorf("%s: expected match %t for pattern %s, got %t", test.Desc, shouldMatch, pattern, didMatch)
|
||||
t.Errorf("%s: response body was: %s", test.Desc, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
78
vendor/github.com/blevesearch/bleve/http/index_create.go
generated
vendored
Normal file
78
vendor/github.com/blevesearch/bleve/http/index_create.go
generated
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/blevesearch/bleve"
|
||||
)
|
||||
|
||||
type CreateIndexHandler struct {
|
||||
basePath string
|
||||
IndexNameLookup varLookupFunc
|
||||
}
|
||||
|
||||
func NewCreateIndexHandler(basePath string) *CreateIndexHandler {
|
||||
return &CreateIndexHandler{
|
||||
basePath: basePath,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *CreateIndexHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
// find the name of the index to create
|
||||
var indexName string
|
||||
if h.IndexNameLookup != nil {
|
||||
indexName = h.IndexNameLookup(req)
|
||||
}
|
||||
if indexName == "" {
|
||||
showError(w, req, "index name is required", 400)
|
||||
return
|
||||
}
|
||||
|
||||
indexMapping := bleve.NewIndexMapping()
|
||||
|
||||
// read the request body
|
||||
requestBody, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error reading request body: %v", err), 400)
|
||||
return
|
||||
}
|
||||
|
||||
// interpret request body as index mapping
|
||||
if len(requestBody) > 0 {
|
||||
err := json.Unmarshal(requestBody, &indexMapping)
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error parsing index mapping: %v", err), 400)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
newIndex, err := bleve.New(h.indexPath(indexName), indexMapping)
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error creating index: %v", err), 500)
|
||||
return
|
||||
}
|
||||
RegisterIndexName(indexName, newIndex)
|
||||
rv := struct {
|
||||
Status string `json:"status"`
|
||||
}{
|
||||
Status: "ok",
|
||||
}
|
||||
mustEncode(w, rv)
|
||||
}
|
||||
|
||||
func (h *CreateIndexHandler) indexPath(name string) string {
|
||||
return h.basePath + string(os.PathSeparator) + name
|
||||
}
|
70
vendor/github.com/blevesearch/bleve/http/index_delete.go
generated
vendored
Normal file
70
vendor/github.com/blevesearch/bleve/http/index_delete.go
generated
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
type DeleteIndexHandler struct {
|
||||
basePath string
|
||||
IndexNameLookup varLookupFunc
|
||||
}
|
||||
|
||||
func NewDeleteIndexHandler(basePath string) *DeleteIndexHandler {
|
||||
return &DeleteIndexHandler{
|
||||
basePath: basePath,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *DeleteIndexHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
// find the name of the index to delete
|
||||
var indexName string
|
||||
if h.IndexNameLookup != nil {
|
||||
indexName = h.IndexNameLookup(req)
|
||||
}
|
||||
if indexName == "" {
|
||||
showError(w, req, "index name is required", 400)
|
||||
return
|
||||
}
|
||||
|
||||
indexToDelete := UnregisterIndexByName(indexName)
|
||||
if indexToDelete == nil {
|
||||
showError(w, req, fmt.Sprintf("no such index '%s'", indexName), 404)
|
||||
return
|
||||
}
|
||||
|
||||
// close the index
|
||||
err := indexToDelete.Close()
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error closing index: %v", err), 500)
|
||||
return
|
||||
}
|
||||
|
||||
// now delete it
|
||||
err = os.RemoveAll(h.indexPath(indexName))
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error deleting index: %v", err), 500)
|
||||
return
|
||||
}
|
||||
|
||||
rv := struct {
|
||||
Status string `json:"status"`
|
||||
}{
|
||||
Status: "ok",
|
||||
}
|
||||
mustEncode(w, rv)
|
||||
}
|
||||
|
||||
func (h *DeleteIndexHandler) indexPath(name string) string {
|
||||
return h.basePath + string(os.PathSeparator) + name
|
||||
}
|
54
vendor/github.com/blevesearch/bleve/http/index_get.go
generated
vendored
Normal file
54
vendor/github.com/blevesearch/bleve/http/index_get.go
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/blevesearch/bleve"
|
||||
)
|
||||
|
||||
type GetIndexHandler struct {
|
||||
IndexNameLookup varLookupFunc
|
||||
}
|
||||
|
||||
func NewGetIndexHandler() *GetIndexHandler {
|
||||
return &GetIndexHandler{}
|
||||
}
|
||||
|
||||
func (h *GetIndexHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
// find the name of the index to create
|
||||
var indexName string
|
||||
if h.IndexNameLookup != nil {
|
||||
indexName = h.IndexNameLookup(req)
|
||||
}
|
||||
if indexName == "" {
|
||||
showError(w, req, "index name is required", 400)
|
||||
return
|
||||
}
|
||||
|
||||
index := IndexByName(indexName)
|
||||
if index == nil {
|
||||
showError(w, req, fmt.Sprintf("no such index '%s'", indexName), 404)
|
||||
return
|
||||
}
|
||||
|
||||
rv := struct {
|
||||
Status string `json:"status"`
|
||||
Name string `json:"name"`
|
||||
Mapping *bleve.IndexMapping `json:"mapping"`
|
||||
}{
|
||||
Status: "ok",
|
||||
Name: indexName,
|
||||
Mapping: index.Mapping(),
|
||||
}
|
||||
mustEncode(w, rv)
|
||||
}
|
33
vendor/github.com/blevesearch/bleve/http/index_list.go
generated
vendored
Normal file
33
vendor/github.com/blevesearch/bleve/http/index_list.go
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type ListIndexesHandler struct {
|
||||
}
|
||||
|
||||
func NewListIndexesHandler() *ListIndexesHandler {
|
||||
return &ListIndexesHandler{}
|
||||
}
|
||||
|
||||
func (h *ListIndexesHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
indexNames := IndexNames()
|
||||
rv := struct {
|
||||
Status string `json:"status"`
|
||||
Indexes []string `json:"indexes"`
|
||||
}{
|
||||
Status: "ok",
|
||||
Indexes: indexNames,
|
||||
}
|
||||
mustEncode(w, rv)
|
||||
}
|
120
vendor/github.com/blevesearch/bleve/http/registry.go
generated
vendored
Normal file
120
vendor/github.com/blevesearch/bleve/http/registry.go
generated
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/blevesearch/bleve"
|
||||
)
|
||||
|
||||
var indexNameMapping map[string]bleve.Index
|
||||
var indexNameMappingLock sync.RWMutex
|
||||
var indexStats = bleve.IndexStats{}
|
||||
|
||||
func RegisterIndexName(name string, idx bleve.Index) {
|
||||
indexNameMappingLock.Lock()
|
||||
defer indexNameMappingLock.Unlock()
|
||||
|
||||
if indexNameMapping == nil {
|
||||
indexNameMapping = make(map[string]bleve.Index)
|
||||
}
|
||||
indexNameMapping[name] = idx
|
||||
indexStats[name] = idx.Stats()
|
||||
}
|
||||
|
||||
func UnregisterIndexByName(name string) bleve.Index {
|
||||
indexNameMappingLock.Lock()
|
||||
defer indexNameMappingLock.Unlock()
|
||||
|
||||
if indexNameMapping == nil {
|
||||
return nil
|
||||
}
|
||||
rv := indexNameMapping[name]
|
||||
if rv != nil {
|
||||
delete(indexNameMapping, name)
|
||||
}
|
||||
delete(indexStats, name)
|
||||
return rv
|
||||
}
|
||||
|
||||
func IndexByName(name string) bleve.Index {
|
||||
indexNameMappingLock.RLock()
|
||||
defer indexNameMappingLock.RUnlock()
|
||||
|
||||
return indexNameMapping[name]
|
||||
}
|
||||
|
||||
func IndexNames() []string {
|
||||
indexNameMappingLock.RLock()
|
||||
defer indexNameMappingLock.RUnlock()
|
||||
|
||||
rv := make([]string, len(indexNameMapping))
|
||||
count := 0
|
||||
for k := range indexNameMapping {
|
||||
rv[count] = k
|
||||
count++
|
||||
}
|
||||
return rv
|
||||
}
|
||||
|
||||
func IndexStats() bleve.IndexStats {
|
||||
return indexStats
|
||||
}
|
||||
|
||||
func UpdateAlias(alias string, add, remove []string) error {
|
||||
indexNameMappingLock.Lock()
|
||||
defer indexNameMappingLock.Unlock()
|
||||
|
||||
index, exists := indexNameMapping[alias]
|
||||
if !exists {
|
||||
// new alias
|
||||
if len(remove) > 0 {
|
||||
return fmt.Errorf("cannot remove indexes from a new alias")
|
||||
}
|
||||
indexes := make([]bleve.Index, len(add))
|
||||
for i, addIndexName := range add {
|
||||
addIndex, indexExists := indexNameMapping[addIndexName]
|
||||
if !indexExists {
|
||||
return fmt.Errorf("index named '%s' does not exist", addIndexName)
|
||||
}
|
||||
indexes[i] = addIndex
|
||||
}
|
||||
indexAlias := bleve.NewIndexAlias(indexes...)
|
||||
indexNameMapping[alias] = indexAlias
|
||||
} else {
|
||||
// something with this name already exists
|
||||
indexAlias, isAlias := index.(bleve.IndexAlias)
|
||||
if !isAlias {
|
||||
return fmt.Errorf("'%s' is not an alias", alias)
|
||||
}
|
||||
// build list of add indexes
|
||||
addIndexes := make([]bleve.Index, len(add))
|
||||
for i, addIndexName := range add {
|
||||
addIndex, indexExists := indexNameMapping[addIndexName]
|
||||
if !indexExists {
|
||||
return fmt.Errorf("index named '%s' does not exist", addIndexName)
|
||||
}
|
||||
addIndexes[i] = addIndex
|
||||
}
|
||||
// build list of remove indexes
|
||||
removeIndexes := make([]bleve.Index, len(remove))
|
||||
for i, removeIndexName := range remove {
|
||||
removeIndex, indexExists := indexNameMapping[removeIndexName]
|
||||
if !indexExists {
|
||||
return fmt.Errorf("index named '%s' does not exist", removeIndexName)
|
||||
}
|
||||
removeIndexes[i] = removeIndex
|
||||
}
|
||||
indexAlias.Swap(addIndexes, removeIndexes)
|
||||
}
|
||||
return nil
|
||||
}
|
84
vendor/github.com/blevesearch/bleve/http/search.go
generated
vendored
Normal file
84
vendor/github.com/blevesearch/bleve/http/search.go
generated
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/blevesearch/bleve"
|
||||
)
|
||||
|
||||
// SearchHandler can handle search requests sent over HTTP
|
||||
type SearchHandler struct {
|
||||
defaultIndexName string
|
||||
IndexNameLookup varLookupFunc
|
||||
}
|
||||
|
||||
func NewSearchHandler(defaultIndexName string) *SearchHandler {
|
||||
return &SearchHandler{
|
||||
defaultIndexName: defaultIndexName,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *SearchHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
|
||||
// find the index to operate on
|
||||
var indexName string
|
||||
if h.IndexNameLookup != nil {
|
||||
indexName = h.IndexNameLookup(req)
|
||||
}
|
||||
if indexName == "" {
|
||||
indexName = h.defaultIndexName
|
||||
}
|
||||
index := IndexByName(indexName)
|
||||
if index == nil {
|
||||
showError(w, req, fmt.Sprintf("no such index '%s'", indexName), 404)
|
||||
return
|
||||
}
|
||||
|
||||
// read the request body
|
||||
requestBody, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error reading request body: %v", err), 400)
|
||||
return
|
||||
}
|
||||
|
||||
logger.Printf("request body: %s", requestBody)
|
||||
|
||||
// parse the request
|
||||
var searchRequest bleve.SearchRequest
|
||||
err = json.Unmarshal(requestBody, &searchRequest)
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error parsing query: %v", err), 400)
|
||||
return
|
||||
}
|
||||
|
||||
logger.Printf("parsed request %#v", searchRequest)
|
||||
|
||||
// validate the query
|
||||
err = searchRequest.Query.Validate()
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error validating query: %v", err), 400)
|
||||
return
|
||||
}
|
||||
|
||||
// execute the query
|
||||
searchResponse, err := index.Search(&searchRequest)
|
||||
if err != nil {
|
||||
showError(w, req, fmt.Sprintf("error executing query: %v", err), 500)
|
||||
return
|
||||
}
|
||||
|
||||
// encode the response
|
||||
mustEncode(w, searchResponse)
|
||||
}
|
46
vendor/github.com/blevesearch/bleve/http/util.go
generated
vendored
Normal file
46
vendor/github.com/blevesearch/bleve/http/util.go
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func showError(w http.ResponseWriter, r *http.Request,
|
||||
msg string, code int) {
|
||||
logger.Printf("Reporting error %v/%v", code, msg)
|
||||
http.Error(w, msg, code)
|
||||
}
|
||||
|
||||
func mustEncode(w io.Writer, i interface{}) {
|
||||
if headered, ok := w.(http.ResponseWriter); ok {
|
||||
headered.Header().Set("Cache-Control", "no-cache")
|
||||
headered.Header().Set("Content-type", "application/json")
|
||||
}
|
||||
|
||||
e := json.NewEncoder(w)
|
||||
if err := e.Encode(i); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
type varLookupFunc func(req *http.Request) string
|
||||
|
||||
var logger = log.New(ioutil.Discard, "bleve.http", log.LstdFlags)
|
||||
|
||||
// SetLog sets the logger used for logging
|
||||
// by default log messages are sent to ioutil.Discard
|
||||
func SetLog(l *log.Logger) {
|
||||
logger = l
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue