// Sets the value for a given key. func SetKeyHandler(w http.ResponseWriter, req *http.Request, s Server) error { vars := mux.Vars(req) key := "/" + vars["key"] req.ParseForm() // Parse non-blank value. value := req.Form.Get("value") if len(value) == 0 { return etcdErr.NewError(200, "Set", s.Store().Index()) } // Convert time-to-live to an expiration time. expireTime, err := store.TTL(req.Form.Get("ttl")) if err != nil { return etcdErr.NewError(202, "Set", s.Store().Index()) } // If the "prevValue" is specified then test-and-set. Otherwise create a new key. var c raft.Command if prevValueArr, ok := req.Form["prevValue"]; ok { if len(prevValueArr[0]) > 0 { // test against previous value c = s.Store().CommandFactory().CreateCompareAndSwapCommand(key, value, prevValueArr[0], 0, expireTime) } else { // test against existence c = s.Store().CommandFactory().CreateCreateCommand(key, false, value, expireTime, false) } } else { c = s.Store().CommandFactory().CreateSetCommand(key, false, value, expireTime) } return s.Dispatch(c, w, req) }
func (e EtcdConnector) Set(key string, dir bool, value string, ttl string, w http.ResponseWriter, req *http.Request) error { ps := e.etcd.PeerServer registry := e.etcd.Registry if ps.RaftServer().State() == raft.Leader { expireTime, err := store.TTL(ttl) if err != nil { return etcdErr.NewError(etcdErr.EcodeTTLNaN, "Create", e.etcd.EtcdServer.Store().Index()) } c := e.etcd.EtcdServer.Store().CommandFactory().CreateSetCommand(key, dir, value, expireTime) result, err := ps.RaftServer().Do(c) if err != nil { return err } if result == nil { return etcdErr.NewError(300, "Empty result from raft", e.etcd.EtcdServer.Store().Index()) } if w != nil { w.WriteHeader(http.StatusOK) } return nil } else { leader := ps.RaftServer().Leader() // No leader available. if leader == "" { return etcdErr.NewError(300, "", e.etcd.EtcdServer.Store().Index()) } leaderUrl, _ := registry.ClientURL(leader) client := http.DefaultClient v := "?" if !dir { v += "value=" + value + "&ttl=" + ttl } else { v += "dir=" + strconv.FormatBool(dir) + "&ttl=" + ttl } req, _ := http.NewRequest("PUT", leaderUrl+"/v2/keys"+key+v, nil) resp, err := client.Do(req) resp.Body.Close() if err != nil { log.Println(err) return err } else { if w != nil { w.WriteHeader(http.StatusOK) } return nil } } return nil }
func (e EtcdConnector) CreateSetCommand(key string, dir bool, value string, ttl string) (raft.Command, error) { expireTime, err := store.TTL(ttl) if err != nil { return nil, etcdErr.NewError(etcdErr.EcodeTTLNaN, "Create", e.etcd.EtcdServer.Store().Index()) } c := e.etcd.EtcdServer.Store().CommandFactory().CreateSetCommand(key, dir, value, expireTime) return c, nil }
func PostHandler(w http.ResponseWriter, req *http.Request, s Server) error { vars := mux.Vars(req) key := "/" + vars["key"] value := req.FormValue("value") dir := (req.FormValue("dir") == "true") expireTime, err := store.TTL(req.FormValue("ttl")) if err != nil { return etcdErr.NewError(etcdErr.EcodeTTLNaN, "Create", s.Store().Index()) } c := s.Store().CommandFactory().CreateCreateCommand(key, dir, value, expireTime, true) return s.Dispatch(c, w, req) }
func PutHandler(w http.ResponseWriter, req *http.Request, s Server) error { var c raft.Command vars := mux.Vars(req) key := "/" + vars["key"] req.ParseForm() value := req.Form.Get("value") dir := (req.FormValue("dir") == "true") expireTime, err := store.TTL(req.Form.Get("ttl")) if err != nil { return etcdErr.NewError(etcdErr.EcodeTTLNaN, "Update", s.Store().Index()) } _, valueOk := req.Form["prevValue"] prevValue := req.FormValue("prevValue") _, indexOk := req.Form["prevIndex"] prevIndexStr := req.FormValue("prevIndex") _, existOk := req.Form["prevExist"] prevExist := req.FormValue("prevExist") // Set handler: create a new node or replace the old one. if !valueOk && !indexOk && !existOk { return SetHandler(w, req, s, key, dir, value, expireTime) } // update with test if existOk { if prevExist == "false" { // Create command: create a new node. Fail, if a node already exists // Ignore prevIndex and prevValue return CreateHandler(w, req, s, key, dir, value, expireTime) } if prevExist == "true" && !indexOk && !valueOk { return UpdateHandler(w, req, s, key, value, expireTime) } } var prevIndex uint64 if indexOk { prevIndex, err = strconv.ParseUint(prevIndexStr, 10, 64) // bad previous index if err != nil { return etcdErr.NewError(etcdErr.EcodeIndexNaN, "CompareAndSwap", s.Store().Index()) } } else { prevIndex = 0 } if valueOk { if prevValue == "" { return etcdErr.NewError(etcdErr.EcodePrevValueRequired, "CompareAndSwap", s.Store().Index()) } } c = s.Store().CommandFactory().CreateCompareAndSwapCommand(key, value, prevValue, prevIndex, expireTime) return s.Dispatch(c, w, req) }