VOL-1497 : Add more control to kv/memory access
- Added kv locking mechanism (etcd only)
- (watch) control path access whenever possible
- (watch) use a transaction for updates and merge with memory
- cleaned up vendoring
- misc changes to fix exceptions found along the way
Amendments:
- Copyright header got removed in auto-generated file
- Changed default locking to false for KV list operation
- Updated backend api to allow the passing of locking parameter
Change-Id: Ie1a55d3ca8b9d92ae71a85ce42bb22fcf1419e2c
diff --git a/vendor/github.com/hashicorp/consul/api/kv.go b/vendor/github.com/hashicorp/consul/api/kv.go
index 97f5156..bd45a06 100644
--- a/vendor/github.com/hashicorp/consul/api/kv.go
+++ b/vendor/github.com/hashicorp/consul/api/kv.go
@@ -45,44 +45,6 @@
// KVPairs is a list of KVPair objects
type KVPairs []*KVPair
-// KVOp constants give possible operations available in a KVTxn.
-type KVOp string
-
-const (
- KVSet KVOp = "set"
- KVDelete KVOp = "delete"
- KVDeleteCAS KVOp = "delete-cas"
- KVDeleteTree KVOp = "delete-tree"
- KVCAS KVOp = "cas"
- KVLock KVOp = "lock"
- KVUnlock KVOp = "unlock"
- KVGet KVOp = "get"
- KVGetTree KVOp = "get-tree"
- KVCheckSession KVOp = "check-session"
- KVCheckIndex KVOp = "check-index"
- KVCheckNotExists KVOp = "check-not-exists"
-)
-
-// KVTxnOp defines a single operation inside a transaction.
-type KVTxnOp struct {
- Verb KVOp
- Key string
- Value []byte
- Flags uint64
- Index uint64
- Session string
-}
-
-// KVTxnOps defines a set of operations to be performed inside a single
-// transaction.
-type KVTxnOps []*KVTxnOp
-
-// KVTxnResponse has the outcome of a transaction.
-type KVTxnResponse struct {
- Results []*KVPair
- Errors TxnErrors
-}
-
// KV is used to manipulate the K/V API
type KV struct {
c *Client
@@ -300,121 +262,25 @@
return res, qm, nil
}
-// TxnOp is the internal format we send to Consul. It's not specific to KV,
-// though currently only KV operations are supported.
-type TxnOp struct {
- KV *KVTxnOp
-}
-
-// TxnOps is a list of transaction operations.
-type TxnOps []*TxnOp
-
-// TxnResult is the internal format we receive from Consul.
-type TxnResult struct {
- KV *KVPair
-}
-
-// TxnResults is a list of TxnResult objects.
-type TxnResults []*TxnResult
-
-// TxnError is used to return information about an operation in a transaction.
-type TxnError struct {
- OpIndex int
- What string
-}
-
-// TxnErrors is a list of TxnError objects.
-type TxnErrors []*TxnError
-
-// TxnResponse is the internal format we receive from Consul.
-type TxnResponse struct {
- Results TxnResults
- Errors TxnErrors
-}
-
-// Txn is used to apply multiple KV operations in a single, atomic transaction.
-//
-// Note that Go will perform the required base64 encoding on the values
-// automatically because the type is a byte slice. Transactions are defined as a
-// list of operations to perform, using the KVOp constants and KVTxnOp structure
-// to define operations. If any operation fails, none of the changes are applied
-// to the state store. Note that this hides the internal raw transaction interface
-// and munges the input and output types into KV-specific ones for ease of use.
-// If there are more non-KV operations in the future we may break out a new
-// transaction API client, but it will be easy to keep this KV-specific variant
-// supported.
-//
-// Even though this is generally a write operation, we take a QueryOptions input
-// and return a QueryMeta output. If the transaction contains only read ops, then
-// Consul will fast-path it to a different endpoint internally which supports
-// consistency controls, but not blocking. If there are write operations then
-// the request will always be routed through raft and any consistency settings
-// will be ignored.
-//
-// Here's an example:
-//
-// ops := KVTxnOps{
-// &KVTxnOp{
-// Verb: KVLock,
-// Key: "test/lock",
-// Session: "adf4238a-882b-9ddc-4a9d-5b6758e4159e",
-// Value: []byte("hello"),
-// },
-// &KVTxnOp{
-// Verb: KVGet,
-// Key: "another/key",
-// },
-// }
-// ok, response, _, err := kv.Txn(&ops, nil)
-//
-// If there is a problem making the transaction request then an error will be
-// returned. Otherwise, the ok value will be true if the transaction succeeded
-// or false if it was rolled back. The response is a structured return value which
-// will have the outcome of the transaction. Its Results member will have entries
-// for each operation. Deleted keys will have a nil entry in the, and to save
-// space, the Value of each key in the Results will be nil unless the operation
-// is a KVGet. If the transaction was rolled back, the Errors member will have
-// entries referencing the index of the operation that failed along with an error
-// message.
+// The Txn function has been deprecated from the KV object; please see the Txn
+// object for more information about Transactions.
func (k *KV) Txn(txn KVTxnOps, q *QueryOptions) (bool, *KVTxnResponse, *QueryMeta, error) {
- r := k.c.newRequest("PUT", "/v1/txn")
- r.setQueryOptions(q)
-
- // Convert into the internal format since this is an all-KV txn.
- ops := make(TxnOps, 0, len(txn))
- for _, kvOp := range txn {
- ops = append(ops, &TxnOp{KV: kvOp})
+ var ops TxnOps
+ for _, op := range txn {
+ ops = append(ops, &TxnOp{KV: op})
}
- r.obj = ops
- rtt, resp, err := k.c.doRequest(r)
+
+ respOk, txnResp, qm, err := k.c.txn(ops, q)
if err != nil {
return false, nil, nil, err
}
- defer resp.Body.Close()
- qm := &QueryMeta{}
- parseQueryMeta(resp, qm)
- qm.RequestTime = rtt
-
- if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusConflict {
- var txnResp TxnResponse
- if err := decodeBody(resp, &txnResp); err != nil {
- return false, nil, nil, err
- }
-
- // Convert from the internal format.
- kvResp := KVTxnResponse{
- Errors: txnResp.Errors,
- }
- for _, result := range txnResp.Results {
- kvResp.Results = append(kvResp.Results, result.KV)
- }
- return resp.StatusCode == http.StatusOK, &kvResp, qm, nil
+ // Convert from the internal format.
+ kvResp := KVTxnResponse{
+ Errors: txnResp.Errors,
}
-
- var buf bytes.Buffer
- if _, err := io.Copy(&buf, resp.Body); err != nil {
- return false, nil, nil, fmt.Errorf("Failed to read response: %v", err)
+ for _, result := range txnResp.Results {
+ kvResp.Results = append(kvResp.Results, result.KV)
}
- return false, nil, nil, fmt.Errorf("Failed request: %s", buf.String())
+ return respOk, &kvResp, qm, nil
}