Skip to content

Commit

Permalink
GOCBC-12: Implemented management operations through Manager types.
Browse files Browse the repository at this point in the history
  • Loading branch information
brett19 committed Mar 9, 2015
1 parent 085d90d commit 54ad129
Show file tree
Hide file tree
Showing 4 changed files with 438 additions and 0 deletions.
13 changes: 13 additions & 0 deletions bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,11 @@ func (b *Bucket) getViewEp() string {
return capiEps[rand.Intn(len(capiEps))]
}

func (b *Bucket) getMgmtEp() string {
mgmtEps := b.client.MgmtEps()
return mgmtEps[rand.Intn(len(mgmtEps))]
}

type viewItem struct {
Bytes []byte
}
Expand Down Expand Up @@ -381,3 +386,11 @@ func (b *Bucket) ExecuteViewQuery(q *ViewQuery) ViewResults {
func (b *Bucket) IoRouter() *gocbcore.Agent {
return b.client
}

func (b *Bucket) Manager(username, password string) *BucketManager {
return &BucketManager{
bucket: b,
username: username,
password: password,
}
}
209 changes: 209 additions & 0 deletions bucketmgr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
package gocb

import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
)

type View struct {
Map string `json:"map,omitempty"`
Reduce string `json:"reduce,omitempty"`
}

func (v View) hasReduce() bool {
return v.Reduce != ""
}

type DesignDocument struct {
Name string `json:"-"`
Views map[string]View `json:"views,omitempty"`
SpatialViews map[string]View `json:"spatial,omitempty"`
}

type BucketManager struct {
bucket *Bucket
username string
password string
}

func (bm *BucketManager) capiRequest(method, uri, contentType string, body io.Reader) (*http.Response, error) {
if contentType == "" && body != nil {
panic("Content-type must be specified for non-null body.")
}

reqUri := bm.bucket.getViewEp() + uri
req, err := http.NewRequest(method, reqUri, body)
if contentType != "" {
req.Header.Add("Content-Type", contentType)
}
if err != nil {
return nil, err
}

req.SetBasicAuth(bm.username, bm.password)
return bm.bucket.httpCli.Do(req)
}

func (bm *BucketManager) mgmtRequest(method, uri, contentType string, body io.Reader) (*http.Response, error) {
if contentType == "" && body != nil {
panic("Content-type must be specified for non-null body.")
}

reqUri := bm.bucket.getMgmtEp() + uri
req, err := http.NewRequest(method, reqUri, body)
if contentType != "" {
req.Header.Add("Content-Type", contentType)
}
if err != nil {
return nil, err
}

req.SetBasicAuth(bm.username, bm.password)
return bm.bucket.httpCli.Do(req)
}

func (bm *BucketManager) Flush() error {
reqUri := fmt.Sprintf("/pools/default/%s/controller/doFlush", bm.bucket.name)
resp, err := bm.mgmtRequest("POST", reqUri, "", nil)
if err != nil {
return err
}

if resp.StatusCode != 200 {
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
resp.Body.Close()
return clientError{string(data)}
}
return nil
}

func (bm *BucketManager) GetDesignDocument(name string) (*DesignDocument, error) {
reqUri := fmt.Sprintf("/_design/%s", name)

resp, err := bm.capiRequest("GET", reqUri, "", nil)
if err != nil {
return nil, err
}

if resp.StatusCode != 200 {
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
resp.Body.Close()
return nil, clientError{string(data)}
}

ddocObj := DesignDocument{}
jsonDec := json.NewDecoder(resp.Body)
err = jsonDec.Decode(&ddocObj)
if err != nil {
return nil, err
}

ddocObj.Name = name
return &ddocObj, nil
}

func (bm *BucketManager) GetDesignDocuments() ([]*DesignDocument, error) {
reqUri := fmt.Sprintf("/pools/default/buckets/%s/ddocs", bm.bucket.name)

resp, err := bm.mgmtRequest("GET", reqUri, "", nil)
if err != nil {
return nil, err
}

if resp.StatusCode != 200 {
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
resp.Body.Close()
return nil, clientError{string(data)}
}

var ddocsObj struct {
Rows []struct {
Doc struct {
Meta struct {
Id string
}
Json DesignDocument
}
}
}
jsonDec := json.NewDecoder(resp.Body)
err = jsonDec.Decode(&ddocsObj)
if err != nil {
return nil, err
}

var ddocs []*DesignDocument
for _, ddocData := range ddocsObj.Rows {
ddoc := &ddocData.Doc.Json
ddoc.Name = ddocData.Doc.Meta.Id[8:]
ddocs = append(ddocs, ddoc)
}

return ddocs, nil
}

func (bm *BucketManager) InsertDesignDocument(ddoc *DesignDocument) error {
oldDdoc, _ := bm.GetDesignDocument(ddoc.Name)
if oldDdoc != nil {
return clientError{"Design document already exists"}
}
return bm.UpsertDesignDocument(ddoc)
}

func (bm *BucketManager) UpsertDesignDocument(ddoc *DesignDocument) error {
reqUri := fmt.Sprintf("/_design/%s", ddoc.Name)

data, err := json.Marshal(&ddoc)
if err != nil {
return err
}

resp, err := bm.capiRequest("PUT", reqUri, "application/json", bytes.NewReader(data))
if err != nil {
return err
}

if resp.StatusCode != 201 {
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
resp.Body.Close()
return clientError{string(data)}
}

return nil
}

func (bm *BucketManager) RemoveDesignDocument(name string) error {
reqUri := fmt.Sprintf("/_design/%s", name)

resp, err := bm.capiRequest("DELETE", reqUri, "", nil)
if err != nil {
return err
}

if resp.StatusCode != 200 {
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
resp.Body.Close()
return clientError{string(data)}
}

return nil
}
26 changes: 26 additions & 0 deletions cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,32 @@ func (c *Cluster) OpenBucket(bucket, password string) (*Bucket, error) {
}, nil
}

func (c *Cluster) Manager(username, password string) *ClusterManager {
_, httpHosts, isSslHosts := specToHosts(c.spec)
var mgmtHosts []string

for _, host := range httpHosts {
if isSslHosts {
mgmtHosts = append(mgmtHosts, "https://"+host)
} else {
mgmtHosts = append(mgmtHosts, "http://"+host)
}
}

return &ClusterManager{
hosts: mgmtHosts,
username: username,
password: password,
httpCli: &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
},
}
}

type StreamingBucket struct {
client *gocbcore.Agent
}
Expand Down
Loading

0 comments on commit 54ad129

Please sign in to comment.