Switches to "KV" instead of "KV" for the KV operations.

This commit is contained in:
James Phillips 2016-05-11 10:58:27 -07:00
parent 38d0f6676f
commit 960b9d6fb6
9 changed files with 114 additions and 114 deletions

View File

@ -278,7 +278,7 @@ func (k *KV) deleteInternal(key string, params map[string]string, q *WriteOption
// TxnOp is the internal format we send to Consul. It's not specific to KV, // TxnOp is the internal format we send to Consul. It's not specific to KV,
// though currently only KV operations are supported. // though currently only KV operations are supported.
type TxnOp struct { type TxnOp struct {
KVS *KVTxnOp KV *KVTxnOp
} }
// TxnOps is a list of transaction operations. // TxnOps is a list of transaction operations.
@ -286,7 +286,7 @@ type TxnOps []*TxnOp
// TxnResult is the internal format we receive from Consul. // TxnResult is the internal format we receive from Consul.
type TxnResult struct { type TxnResult struct {
KVS *struct{ DirEnt *KVPair } KV *struct{ DirEnt *KVPair }
} }
// TxnResults is a list of TxnResult objects. // TxnResults is a list of TxnResult objects.
@ -349,8 +349,8 @@ func (k *KV) Txn(txn KVTxnOps, q *WriteOptions) (bool, *KVTxnResponse, *WriteMet
// Convert into the internal format since this is an all-KV txn. // Convert into the internal format since this is an all-KV txn.
ops := make(TxnOps, 0, len(txn)) ops := make(TxnOps, 0, len(txn))
for _, kvsOp := range txn { for _, kvOp := range txn {
ops = append(ops, &TxnOp{KVS: kvsOp}) ops = append(ops, &TxnOp{KV: kvOp})
} }
r.obj = ops r.obj = ops
rtt, resp, err := k.c.doRequest(r) rtt, resp, err := k.c.doRequest(r)
@ -374,8 +374,8 @@ func (k *KV) Txn(txn KVTxnOps, q *WriteOptions) (bool, *KVTxnResponse, *WriteMet
} }
for _, result := range txnResp.Results { for _, result := range txnResp.Results {
var entry *KVPair var entry *KVPair
if result.KVS != nil { if result.KV != nil {
entry = result.KVS.DirEnt entry = result.KV.DirEnt
} }
kvResp.Results = append(kvResp.Results, entry) kvResp.Results = append(kvResp.Results, entry)
} }

View File

@ -10,14 +10,14 @@ import (
"github.com/hashicorp/consul/consul/structs" "github.com/hashicorp/consul/consul/structs"
) )
// fixupKVSOps takes the raw decoded JSON and base64 decodes all the KVS values, // fixupKVOps takes the raw decoded JSON and base64 decodes values in KV ops,
// replacing them with byte arrays with the data. // replacing them with byte arrays.
func fixupKVSOps(raw interface{}) error { func fixupKVOps(raw interface{}) error {
// decodeValue decodes the value member of the given operation. // decodeValue decodes the value member of the given operation.
decodeValue := func(rawKVS interface{}) error { decodeValue := func(rawKV interface{}) error {
rawMap, ok := rawKVS.(map[string]interface{}) rawMap, ok := rawKV.(map[string]interface{})
if !ok { if !ok {
return fmt.Errorf("unexpected raw KVS type: %T", rawKVS) return fmt.Errorf("unexpected raw KV type: %T", rawKV)
} }
for k, v := range rawMap { for k, v := range rawMap {
switch strings.ToLower(k) { switch strings.ToLower(k) {
@ -44,16 +44,16 @@ func fixupKVSOps(raw interface{}) error {
return nil return nil
} }
// fixupKVSOp looks for non-nil KVS operations and passes them on for // fixupKVOp looks for non-nil KV operations and passes them on for
// value conversion. // value conversion.
fixupKVSOp := func(rawOp interface{}) error { fixupKVOp := func(rawOp interface{}) error {
rawMap, ok := rawOp.(map[string]interface{}) rawMap, ok := rawOp.(map[string]interface{})
if !ok { if !ok {
return fmt.Errorf("unexpected raw op type: %T", rawOp) return fmt.Errorf("unexpected raw op type: %T", rawOp)
} }
for k, v := range rawMap { for k, v := range rawMap {
switch strings.ToLower(k) { switch strings.ToLower(k) {
case "kvs": case "kv":
if v == nil { if v == nil {
return nil return nil
} }
@ -68,7 +68,7 @@ func fixupKVSOps(raw interface{}) error {
return fmt.Errorf("unexpected raw type: %t", raw) return fmt.Errorf("unexpected raw type: %t", raw)
} }
for _, rawOp := range rawSlice { for _, rawOp := range rawSlice {
if err := fixupKVSOp(rawOp); err != nil { if err := fixupKVOp(rawOp); err != nil {
return err return err
} }
} }
@ -91,34 +91,34 @@ func (s *HTTPServer) Txn(resp http.ResponseWriter, req *http.Request) (interface
// decode it, we will return a 400 since we don't have enough context to // decode it, we will return a 400 since we don't have enough context to
// associate the error with a given operation. // associate the error with a given operation.
var ops api.TxnOps var ops api.TxnOps
if err := decodeBody(req, &ops, fixupKVSOps); err != nil { if err := decodeBody(req, &ops, fixupKVOps); err != nil {
resp.WriteHeader(http.StatusBadRequest) resp.WriteHeader(http.StatusBadRequest)
resp.Write([]byte(fmt.Sprintf("Failed to parse body: %v", err))) resp.Write([]byte(fmt.Sprintf("Failed to parse body: %v", err)))
return nil, nil return nil, nil
} }
// Convert the KVS API format into the RPC format. Note that fixupKVSOps // Convert the KV API format into the RPC format. Note that fixupKVOps
// above will have already converted the base64 encoded strings into // above will have already converted the base64 encoded strings into
// byte arrays so we can assign right over. // byte arrays so we can assign right over.
for _, in := range ops { for _, in := range ops {
if in.KVS != nil { if in.KV != nil {
if size := len(in.KVS.Value); size > maxKVSize { if size := len(in.KV.Value); size > maxKVSize {
resp.WriteHeader(http.StatusRequestEntityTooLarge) resp.WriteHeader(http.StatusRequestEntityTooLarge)
resp.Write([]byte(fmt.Sprintf("Value for key %q is too large (%d > %d bytes)", resp.Write([]byte(fmt.Sprintf("Value for key %q is too large (%d > %d bytes)",
in.KVS.Key, size, maxKVSize))) in.KV.Key, size, maxKVSize)))
return nil, nil return nil, nil
} }
out := &structs.TxnOp{ out := &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSOp(in.KVS.Verb), Verb: structs.KVSOp(in.KV.Verb),
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: in.KVS.Key, Key: in.KV.Key,
Value: in.KVS.Value, Value: in.KV.Value,
Flags: in.KVS.Flags, Flags: in.KV.Flags,
Session: in.KVS.Session, Session: in.KV.Session,
RaftIndex: structs.RaftIndex{ RaftIndex: structs.RaftIndex{
ModifyIndex: in.KVS.Index, ModifyIndex: in.KV.Index,
}, },
}, },
}, },

View File

@ -56,7 +56,7 @@ func TestTxnEndpoint_Bad_Size(t *testing.T) {
buf := bytes.NewBuffer([]byte(fmt.Sprintf(` buf := bytes.NewBuffer([]byte(fmt.Sprintf(`
[ [
{ {
"KVS": { "KV": {
"Verb": "set", "Verb": "set",
"Key": "key", "Key": "key",
"Value": %q "Value": %q
@ -79,7 +79,7 @@ func TestTxnEndpoint_Bad_Size(t *testing.T) {
}) })
} }
func TestTxnEndpoint_KVS_Actions(t *testing.T) { func TestTxnEndpoint_KV_Actions(t *testing.T) {
httpTest(t, func(srv *HTTPServer) { httpTest(t, func(srv *HTTPServer) {
// Make sure all incoming fields get converted properly to the internal // Make sure all incoming fields get converted properly to the internal
// RPC format. // RPC format.
@ -89,7 +89,7 @@ func TestTxnEndpoint_KVS_Actions(t *testing.T) {
buf := bytes.NewBuffer([]byte(fmt.Sprintf(` buf := bytes.NewBuffer([]byte(fmt.Sprintf(`
[ [
{ {
"KVS": { "KV": {
"Verb": "lock", "Verb": "lock",
"Key": "key", "Key": "key",
"Value": "aGVsbG8gd29ybGQ=", "Value": "aGVsbG8gd29ybGQ=",
@ -98,7 +98,7 @@ func TestTxnEndpoint_KVS_Actions(t *testing.T) {
} }
}, },
{ {
"KVS": { "KV": {
"Verb": "get", "Verb": "get",
"Key": "key" "Key": "key"
} }
@ -126,11 +126,11 @@ func TestTxnEndpoint_KVS_Actions(t *testing.T) {
if len(txnResp.Results) != 2 { if len(txnResp.Results) != 2 {
t.Fatalf("bad: %v", txnResp) t.Fatalf("bad: %v", txnResp)
} }
index = txnResp.Results[0].KVS.DirEnt.ModifyIndex index = txnResp.Results[0].KV.DirEnt.ModifyIndex
expected := structs.TxnResponse{ expected := structs.TxnResponse{
Results: structs.TxnResults{ Results: structs.TxnResults{
&structs.TxnResult{ &structs.TxnResult{
KVS: &structs.TxnKVSResult{ KV: &structs.TxnKVResult{
DirEnt: &structs.DirEntry{ DirEnt: &structs.DirEntry{
Key: "key", Key: "key",
Value: nil, Value: nil,
@ -145,7 +145,7 @@ func TestTxnEndpoint_KVS_Actions(t *testing.T) {
}, },
}, },
&structs.TxnResult{ &structs.TxnResult{
KVS: &structs.TxnKVSResult{ KV: &structs.TxnKVResult{
DirEnt: &structs.DirEntry{ DirEnt: &structs.DirEntry{
Key: "key", Key: "key",
Value: []byte("hello world"), Value: []byte("hello world"),
@ -172,7 +172,7 @@ func TestTxnEndpoint_KVS_Actions(t *testing.T) {
buf := bytes.NewBuffer([]byte(fmt.Sprintf(` buf := bytes.NewBuffer([]byte(fmt.Sprintf(`
[ [
{ {
"KVS": { "KV": {
"Verb": "cas", "Verb": "cas",
"Key": "key", "Key": "key",
"Value": "Z29vZGJ5ZSB3b3JsZA==", "Value": "Z29vZGJ5ZSB3b3JsZA==",
@ -180,7 +180,7 @@ func TestTxnEndpoint_KVS_Actions(t *testing.T) {
} }
}, },
{ {
"KVS": { "KV": {
"Verb": "get", "Verb": "get",
"Key": "key" "Key": "key"
} }
@ -208,11 +208,11 @@ func TestTxnEndpoint_KVS_Actions(t *testing.T) {
if len(txnResp.Results) != 2 { if len(txnResp.Results) != 2 {
t.Fatalf("bad: %v", txnResp) t.Fatalf("bad: %v", txnResp)
} }
modIndex := txnResp.Results[0].KVS.DirEnt.ModifyIndex modIndex := txnResp.Results[0].KV.DirEnt.ModifyIndex
expected := structs.TxnResponse{ expected := structs.TxnResponse{
Results: structs.TxnResults{ Results: structs.TxnResults{
&structs.TxnResult{ &structs.TxnResult{
KVS: &structs.TxnKVSResult{ KV: &structs.TxnKVResult{
DirEnt: &structs.DirEntry{ DirEnt: &structs.DirEntry{
Key: "key", Key: "key",
Value: nil, Value: nil,
@ -225,7 +225,7 @@ func TestTxnEndpoint_KVS_Actions(t *testing.T) {
}, },
}, },
&structs.TxnResult{ &structs.TxnResult{
KVS: &structs.TxnKVSResult{ KV: &structs.TxnKVResult{
DirEnt: &structs.DirEntry{ DirEnt: &structs.DirEntry{
Key: "key", Key: "key",
Value: []byte("goodbye world"), Value: []byte("goodbye world"),
@ -250,7 +250,7 @@ func TestTxnEndpoint_KVS_Actions(t *testing.T) {
buf := bytes.NewBuffer([]byte(` buf := bytes.NewBuffer([]byte(`
[ [
{ {
"KVS": { "KV": {
"Verb": "lock", "Verb": "lock",
"Key": "key", "Key": "key",
"Value": "aGVsbG8gd29ybGQ=", "Value": "aGVsbG8gd29ybGQ=",
@ -258,7 +258,7 @@ func TestTxnEndpoint_KVS_Actions(t *testing.T) {
} }
}, },
{ {
"KVS": { "KV": {
"Verb": "get", "Verb": "get",
"Key": "key" "Key": "key"
} }

View File

@ -1252,7 +1252,7 @@ func TestFSM_Txn(t *testing.T) {
Datacenter: "dc1", Datacenter: "dc1",
Ops: structs.TxnOps{ Ops: structs.TxnOps{
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSSet, Verb: structs.KVSSet,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "/test/path", Key: "/test/path",

View File

@ -7,7 +7,7 @@ import (
"github.com/hashicorp/go-memdb" "github.com/hashicorp/go-memdb"
) )
func (s *StateStore) txnKVS(tx *memdb.Txn, idx uint64, op *structs.TxnKVSOp) (*structs.TxnKVSResult, error) { func (s *StateStore) txnKVS(tx *memdb.Txn, idx uint64, op *structs.TxnKVOp) (*structs.TxnKVResult, error) {
var entry *structs.DirEntry var entry *structs.DirEntry
var err error var err error
@ -63,7 +63,7 @@ func (s *StateStore) txnKVS(tx *memdb.Txn, idx uint64, op *structs.TxnKVSOp) (*s
entry, err = s.kvsCheckIndexTxn(tx, op.DirEnt.Key, op.DirEnt.ModifyIndex) entry, err = s.kvsCheckIndexTxn(tx, op.DirEnt.Key, op.DirEnt.ModifyIndex)
default: default:
err = fmt.Errorf("unknown KVS verb %q", op.Verb) err = fmt.Errorf("unknown KV verb %q", op.Verb)
} }
if err != nil { if err != nil {
return nil, err return nil, err
@ -74,12 +74,12 @@ func (s *StateStore) txnKVS(tx *memdb.Txn, idx uint64, op *structs.TxnKVSOp) (*s
// the state store). // the state store).
if entry != nil { if entry != nil {
if op.Verb == structs.KVSGet { if op.Verb == structs.KVSGet {
return &structs.TxnKVSResult{entry}, nil return &structs.TxnKVResult{entry}, nil
} }
clone := entry.Clone() clone := entry.Clone()
clone.Value = nil clone.Value = nil
return &structs.TxnKVSResult{clone}, nil return &structs.TxnKVResult{clone}, nil
} }
return nil, nil return nil, nil
@ -99,8 +99,8 @@ func (s *StateStore) TxnRun(idx uint64, ops structs.TxnOps) (structs.TxnResults,
var err error var err error
// Dispatch based on the type of operation. // Dispatch based on the type of operation.
if op.KVS != nil { if op.KV != nil {
result.KVS, err = s.txnKVS(tx, idx, op.KVS) result.KV, err = s.txnKVS(tx, idx, op.KV)
} else { } else {
err = fmt.Errorf("no operation specified") err = fmt.Errorf("no operation specified")
} }

View File

@ -28,7 +28,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
// Set up a transaction that hits every operation. // Set up a transaction that hits every operation.
ops := structs.TxnOps{ ops := structs.TxnOps{
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSSet, Verb: structs.KVSSet,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/new", Key: "foo/new",
@ -37,7 +37,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSDelete, Verb: structs.KVSDelete,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/zorp", Key: "foo/zorp",
@ -45,7 +45,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSDeleteCAS, Verb: structs.KVSDeleteCAS,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/delete", Key: "foo/delete",
@ -56,7 +56,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSDeleteTree, Verb: structs.KVSDeleteTree,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/bar", Key: "foo/bar",
@ -64,7 +64,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSGet, Verb: structs.KVSGet,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/update", Key: "foo/update",
@ -72,7 +72,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSCheckIndex, Verb: structs.KVSCheckIndex,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/update", Key: "foo/update",
@ -83,7 +83,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSCAS, Verb: structs.KVSCAS,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/update", Key: "foo/update",
@ -95,7 +95,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSGet, Verb: structs.KVSGet,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/update", Key: "foo/update",
@ -103,7 +103,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSGet, Verb: structs.KVSGet,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "not/there", Key: "not/there",
@ -111,7 +111,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSCheckIndex, Verb: structs.KVSCheckIndex,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/update", Key: "foo/update",
@ -122,7 +122,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSGet, Verb: structs.KVSGet,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/lock", Key: "foo/lock",
@ -130,7 +130,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSLock, Verb: structs.KVSLock,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/lock", Key: "foo/lock",
@ -139,7 +139,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSCheckSession, Verb: structs.KVSCheckSession,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/lock", Key: "foo/lock",
@ -148,7 +148,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSUnlock, Verb: structs.KVSUnlock,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/lock", Key: "foo/lock",
@ -157,7 +157,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSCheckSession, Verb: structs.KVSCheckSession,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/lock", Key: "foo/lock",
@ -177,7 +177,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
// Make sure the response looks as expected. // Make sure the response looks as expected.
expected := structs.TxnResults{ expected := structs.TxnResults{
&structs.TxnResult{ &structs.TxnResult{
KVS: &structs.TxnKVSResult{ KV: &structs.TxnKVResult{
DirEnt: &structs.DirEntry{ DirEnt: &structs.DirEntry{
Key: "foo/new", Key: "foo/new",
RaftIndex: structs.RaftIndex{ RaftIndex: structs.RaftIndex{
@ -191,7 +191,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
&structs.TxnResult{}, // delete tree &structs.TxnResult{}, // delete tree
&structs.TxnResult{}, // delete CAS &structs.TxnResult{}, // delete CAS
&structs.TxnResult{ &structs.TxnResult{
KVS: &structs.TxnKVSResult{ KV: &structs.TxnKVResult{
DirEnt: &structs.DirEntry{ DirEnt: &structs.DirEntry{
Key: "foo/update", Key: "foo/update",
Value: []byte("stale"), Value: []byte("stale"),
@ -203,7 +203,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnResult{ &structs.TxnResult{
KVS: &structs.TxnKVSResult{ KV: &structs.TxnKVResult{
DirEnt: &structs.DirEntry{ DirEnt: &structs.DirEntry{
Key: "foo/update", Key: "foo/update",
@ -215,7 +215,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnResult{ &structs.TxnResult{
KVS: &structs.TxnKVSResult{ KV: &structs.TxnKVResult{
DirEnt: &structs.DirEntry{ DirEnt: &structs.DirEntry{
Key: "foo/update", Key: "foo/update",
RaftIndex: structs.RaftIndex{ RaftIndex: structs.RaftIndex{
@ -226,7 +226,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnResult{ &structs.TxnResult{
KVS: &structs.TxnKVSResult{ KV: &structs.TxnKVResult{
DirEnt: &structs.DirEntry{ DirEnt: &structs.DirEntry{
Key: "foo/update", Key: "foo/update",
Value: []byte("new"), Value: []byte("new"),
@ -239,7 +239,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
&structs.TxnResult{}, // get on not/there &structs.TxnResult{}, // get on not/there
&structs.TxnResult{ &structs.TxnResult{
KVS: &structs.TxnKVSResult{ KV: &structs.TxnKVResult{
DirEnt: &structs.DirEntry{ DirEnt: &structs.DirEntry{
Key: "foo/update", Key: "foo/update",
RaftIndex: structs.RaftIndex{ RaftIndex: structs.RaftIndex{
@ -251,7 +251,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
&structs.TxnResult{}, // get on foo/lock before it's created &structs.TxnResult{}, // get on foo/lock before it's created
&structs.TxnResult{ &structs.TxnResult{
KVS: &structs.TxnKVSResult{ KV: &structs.TxnKVResult{
DirEnt: &structs.DirEntry{ DirEnt: &structs.DirEntry{
Key: "foo/lock", Key: "foo/lock",
Session: session, Session: session,
@ -264,7 +264,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnResult{ &structs.TxnResult{
KVS: &structs.TxnKVSResult{ KV: &structs.TxnKVResult{
DirEnt: &structs.DirEntry{ DirEnt: &structs.DirEntry{
Key: "foo/lock", Key: "foo/lock",
Session: session, Session: session,
@ -277,7 +277,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnResult{ &structs.TxnResult{
KVS: &structs.TxnKVSResult{ KV: &structs.TxnKVResult{
DirEnt: &structs.DirEntry{ DirEnt: &structs.DirEntry{
Key: "foo/lock", Key: "foo/lock",
LockIndex: 1, LockIndex: 1,
@ -289,7 +289,7 @@ func TestStateStore_Txn_KVS(t *testing.T) {
}, },
}, },
&structs.TxnResult{ &structs.TxnResult{
KVS: &structs.TxnKVSResult{ KV: &structs.TxnKVResult{
DirEnt: &structs.DirEntry{ DirEnt: &structs.DirEntry{
Key: "foo/lock", Key: "foo/lock",
LockIndex: 1, LockIndex: 1,
@ -431,7 +431,7 @@ func TestStateStore_Txn_KVS_Rollback(t *testing.T) {
// Set up a transaction that fails every operation. // Set up a transaction that fails every operation.
ops := structs.TxnOps{ ops := structs.TxnOps{
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSCAS, Verb: structs.KVSCAS,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/update", Key: "foo/update",
@ -443,7 +443,7 @@ func TestStateStore_Txn_KVS_Rollback(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSLock, Verb: structs.KVSLock,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/lock", Key: "foo/lock",
@ -452,7 +452,7 @@ func TestStateStore_Txn_KVS_Rollback(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSUnlock, Verb: structs.KVSUnlock,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/lock", Key: "foo/lock",
@ -461,7 +461,7 @@ func TestStateStore_Txn_KVS_Rollback(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSCheckSession, Verb: structs.KVSCheckSession,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/lock", Key: "foo/lock",
@ -470,7 +470,7 @@ func TestStateStore_Txn_KVS_Rollback(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSCheckSession, Verb: structs.KVSCheckSession,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "nope", Key: "nope",
@ -479,7 +479,7 @@ func TestStateStore_Txn_KVS_Rollback(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSCheckIndex, Verb: structs.KVSCheckIndex,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/lock", Key: "foo/lock",
@ -490,7 +490,7 @@ func TestStateStore_Txn_KVS_Rollback(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSCheckIndex, Verb: structs.KVSCheckIndex,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "nope", Key: "nope",
@ -501,7 +501,7 @@ func TestStateStore_Txn_KVS_Rollback(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: "nope", Verb: "nope",
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo/delete", Key: "foo/delete",
@ -527,7 +527,7 @@ func TestStateStore_Txn_KVS_Rollback(t *testing.T) {
`key "nope" doesn't exist`, `key "nope" doesn't exist`,
"current modify index", "current modify index",
`key "nope" doesn't exist`, `key "nope" doesn't exist`,
"unknown KVS verb", "unknown KV verb",
} }
if len(errors) != len(expected) { if len(errors) != len(expected) {
t.Fatalf("bad len: %d != %d", len(errors), len(expected)) t.Fatalf("bad len: %d != %d", len(errors), len(expected))
@ -552,7 +552,7 @@ func TestStateStore_Txn_Watches(t *testing.T) {
verifyWatch(t, s.GetKVSWatch("multi/two"), func() { verifyWatch(t, s.GetKVSWatch("multi/two"), func() {
ops := structs.TxnOps{ ops := structs.TxnOps{
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSSet, Verb: structs.KVSSet,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "multi/one", Key: "multi/one",
@ -561,7 +561,7 @@ func TestStateStore_Txn_Watches(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSSet, Verb: structs.KVSSet,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "multi/two", Key: "multi/two",
@ -585,7 +585,7 @@ func TestStateStore_Txn_Watches(t *testing.T) {
verifyNoWatch(t, s.GetKVSWatch("multi/two"), func() { verifyNoWatch(t, s.GetKVSWatch("multi/two"), func() {
ops := structs.TxnOps{ ops := structs.TxnOps{
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSSet, Verb: structs.KVSSet,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "multi/one", Key: "multi/one",
@ -594,7 +594,7 @@ func TestStateStore_Txn_Watches(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSSet, Verb: structs.KVSSet,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "multi/two", Key: "multi/two",
@ -603,7 +603,7 @@ func TestStateStore_Txn_Watches(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSLock, Verb: structs.KVSLock,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "multi/nope", Key: "multi/nope",

View File

@ -4,23 +4,23 @@ import (
"fmt" "fmt"
) )
// TxnKVSOp is used to define a single operation on the KVS inside a // TxnKVOp is used to define a single operation on the KVS inside a
// transaction // transaction
type TxnKVSOp struct { type TxnKVOp struct {
Verb KVSOp Verb KVSOp
DirEnt DirEntry DirEnt DirEntry
} }
// TxnKVSResult is used to define the result of a single operation on the KVS // TxnKVResult is used to define the result of a single operation on the KVS
// inside a transaction. // inside a transaction.
type TxnKVSResult struct { type TxnKVResult struct {
DirEnt *DirEntry DirEnt *DirEntry
} }
// TxnOp is used to define a single operation inside a transaction. Only one // TxnOp is used to define a single operation inside a transaction. Only one
// of the types should be filled out per entry. // of the types should be filled out per entry.
type TxnOp struct { type TxnOp struct {
KVS *TxnKVSOp KV *TxnKVOp
} }
// TxnOps is a list of operations within a transaction. // TxnOps is a list of operations within a transaction.
@ -56,7 +56,7 @@ type TxnErrors []*TxnError
// TxnResult is used to define the result of a given operation inside a // TxnResult is used to define the result of a given operation inside a
// transaction. Only one of the types should be filled out per entry. // transaction. Only one of the types should be filled out per entry.
type TxnResult struct { type TxnResult struct {
KVS *TxnKVSResult KV *TxnKVResult
} }
// TxnResults is a list of TxnResult entries. // TxnResults is a list of TxnResult entries.

View File

@ -20,18 +20,18 @@ func (t *Txn) Apply(args *structs.TxnRequest, reply *structs.TxnResponse) error
} }
defer metrics.MeasureSince([]string{"consul", "txn", "apply"}, time.Now()) defer metrics.MeasureSince([]string{"consul", "txn", "apply"}, time.Now())
// Perform the pre-apply checks for any KVS operations. // Perform the pre-apply checks for any KV operations.
acl, err := t.srv.resolveToken(args.Token) acl, err := t.srv.resolveToken(args.Token)
if err != nil { if err != nil {
return err return err
} }
for i, op := range args.Ops { for i, op := range args.Ops {
if op.KVS != nil { if op.KV != nil {
ok, err := kvsPreApply(t.srv, acl, op.KVS.Verb, &op.KVS.DirEnt) ok, err := kvsPreApply(t.srv, acl, op.KV.Verb, &op.KV.DirEnt)
if err != nil { if err != nil {
reply.Errors = append(reply.Errors, &structs.TxnError{i, err.Error()}) reply.Errors = append(reply.Errors, &structs.TxnError{i, err.Error()})
} else if !ok { } else if !ok {
err = fmt.Errorf("failed to lock key %q due to lock delay", op.KVS.DirEnt.Key) err = fmt.Errorf("failed to lock key %q due to lock delay", op.KV.DirEnt.Key)
reply.Errors = append(reply.Errors, &structs.TxnError{i, err.Error()}) reply.Errors = append(reply.Errors, &structs.TxnError{i, err.Error()})
} }
} }

View File

@ -29,7 +29,7 @@ func TestTxn_Apply(t *testing.T) {
Datacenter: "dc1", Datacenter: "dc1",
Ops: structs.TxnOps{ Ops: structs.TxnOps{
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSSet, Verb: structs.KVSSet,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "test", Key: "test",
@ -39,7 +39,7 @@ func TestTxn_Apply(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSGet, Verb: structs.KVSGet,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "test", Key: "test",
@ -71,7 +71,7 @@ func TestTxn_Apply(t *testing.T) {
expected := structs.TxnResponse{ expected := structs.TxnResponse{
Results: structs.TxnResults{ Results: structs.TxnResults{
&structs.TxnResult{ &structs.TxnResult{
KVS: &structs.TxnKVSResult{ KV: &structs.TxnKVResult{
DirEnt: &structs.DirEntry{ DirEnt: &structs.DirEntry{
Key: "test", Key: "test",
Flags: 42, Flags: 42,
@ -84,7 +84,7 @@ func TestTxn_Apply(t *testing.T) {
}, },
}, },
&structs.TxnResult{ &structs.TxnResult{
KVS: &structs.TxnKVSResult{ KV: &structs.TxnKVResult{
DirEnt: &structs.DirEntry{ DirEnt: &structs.DirEntry{
Key: "test", Key: "test",
Flags: 42, Flags: 42,
@ -140,7 +140,7 @@ func TestTxn_Apply_ACLDeny(t *testing.T) {
Datacenter: "dc1", Datacenter: "dc1",
Ops: structs.TxnOps{ Ops: structs.TxnOps{
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSSet, Verb: structs.KVSSet,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo", Key: "foo",
@ -148,7 +148,7 @@ func TestTxn_Apply_ACLDeny(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSDelete, Verb: structs.KVSDelete,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo", Key: "foo",
@ -156,7 +156,7 @@ func TestTxn_Apply_ACLDeny(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSDeleteCAS, Verb: structs.KVSDeleteCAS,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo", Key: "foo",
@ -164,7 +164,7 @@ func TestTxn_Apply_ACLDeny(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSDeleteTree, Verb: structs.KVSDeleteTree,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo", Key: "foo",
@ -172,7 +172,7 @@ func TestTxn_Apply_ACLDeny(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSCAS, Verb: structs.KVSCAS,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo", Key: "foo",
@ -180,7 +180,7 @@ func TestTxn_Apply_ACLDeny(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSLock, Verb: structs.KVSLock,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo", Key: "foo",
@ -188,7 +188,7 @@ func TestTxn_Apply_ACLDeny(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSUnlock, Verb: structs.KVSUnlock,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "foo", Key: "foo",
@ -196,7 +196,7 @@ func TestTxn_Apply_ACLDeny(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSGet, Verb: structs.KVSGet,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "nope", Key: "nope",
@ -204,7 +204,7 @@ func TestTxn_Apply_ACLDeny(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSCheckSession, Verb: structs.KVSCheckSession,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "nope", Key: "nope",
@ -212,7 +212,7 @@ func TestTxn_Apply_ACLDeny(t *testing.T) {
}, },
}, },
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSCheckIndex, Verb: structs.KVSCheckIndex,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "nope", Key: "nope",
@ -281,7 +281,7 @@ func TestTxn_Apply_LockDelay(t *testing.T) {
Datacenter: "dc1", Datacenter: "dc1",
Ops: structs.TxnOps{ Ops: structs.TxnOps{
&structs.TxnOp{ &structs.TxnOp{
KVS: &structs.TxnKVSOp{ KV: &structs.TxnKVOp{
Verb: structs.KVSLock, Verb: structs.KVSLock,
DirEnt: structs.DirEntry{ DirEnt: structs.DirEntry{
Key: "test", Key: "test",
@ -315,7 +315,7 @@ func TestTxn_Apply_LockDelay(t *testing.T) {
} }
if len(out.Results) != 1 || if len(out.Results) != 1 ||
len(out.Errors) != 0 || len(out.Errors) != 0 ||
out.Results[0].KVS.DirEnt.LockIndex != 2 { out.Results[0].KV.DirEnt.LockIndex != 2 {
t.Fatalf("bad: %v", out) t.Fatalf("bad: %v", out)
} }
} }