// ToJson returns a JSON representation of the object. func (n *ActionNode) ToJson() string { result := jscfg.ToJson(n) + "\n" if n.Args == nil { result += "{}\n" } else { result += jscfg.ToJson(n.Args) + "\n" } if n.Reply == nil { result += "{}\n" } else { result += jscfg.ToJson(n.Reply) + "\n" } return result }
func (zkts *Server) CreateKeyspace(keyspace string, value *topo.Keyspace) error { keyspacePath := path.Join(globalKeyspacesPath, keyspace) pathList := []string{ keyspacePath, path.Join(keyspacePath, "action"), path.Join(keyspacePath, "actionlog"), path.Join(keyspacePath, "shards"), } alreadyExists := false for i, zkPath := range pathList { c := "" if i == 0 { c = jscfg.ToJson(value) } _, err := zk.CreateRecursive(zkts.zconn, zkPath, c, 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { alreadyExists = true } else { return fmt.Errorf("error creating keyspace: %v %v", zkPath, err) } } } if alreadyExists { return topo.ErrNodeExists } event.Dispatch(&events.KeyspaceChange{ KeyspaceInfo: *topo.NewKeyspaceInfo(keyspace, value, -1), Status: "created", }) return nil }
func (zkts *Server) UpdateShardReplicationFields(cell, keyspace, shard string, update func(*topo.ShardReplication) error) error { // create the parent directory to be sure it's here zkDir := path.Join("/zk", cell, "vt", "replication", keyspace) if _, err := zk.CreateRecursive(zkts.zconn, zkDir, "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)); err != nil && !zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { return err } // now update the data zkPath := shardReplicationPath(cell, keyspace, shard) f := func(oldValue string, oldStat zk.Stat) (string, error) { sr := &topo.ShardReplication{} if oldValue != "" { if err := json.Unmarshal([]byte(oldValue), sr); err != nil { return "", err } } if err := update(sr); err != nil { return "", err } return jscfg.ToJson(sr), nil } err := zkts.zconn.RetryChange(zkPath, 0, zookeeper.WorldACL(zookeeper.PERM_ALL), f) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { err = topo.ErrNoNode } return err } return nil }
func (zkts *Server) UpdateSrvKeyspace(cell, keyspace string, srvKeyspace *topo.SrvKeyspace) error { path := zkPathForVtKeyspace(cell, keyspace) data := jscfg.ToJson(srvKeyspace) _, err := zkts.zconn.Set(path, data, -1) if zookeeper.IsError(err, zookeeper.ZNONODE) { _, err = zk.CreateRecursive(zkts.zconn, path, data, 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) } return err }
func TestExtraFieldsJson(t *testing.T) { swra := &SlaveWasRestartedArgs{ Parent: topo.TabletAlias{ Uid: 1, Cell: "aa", }, } data := jscfg.ToJson(swra) output := &slaveWasRestartedTestArgs{} decoder := json.NewDecoder(strings.NewReader(data)) err := decoder.Decode(output) if err != nil { t.Errorf("Cannot re-decode struct without field: %v", err) } }
func (zkts *Server) UpdateEndPoints(cell, keyspace, shard string, tabletType topo.TabletType, addrs *topo.EndPoints) error { path := zkPathForVtName(cell, keyspace, shard, tabletType) data := jscfg.ToJson(addrs) _, err := zk.CreateRecursive(zkts.zconn, path, data, 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { // Node already exists - just stomp away. Multiple writers shouldn't be here. // We use RetryChange here because it won't update the node unnecessarily. f := func(oldValue string, oldStat zk.Stat) (string, error) { return data, nil } err = zkts.zconn.RetryChange(path, 0, zookeeper.WorldACL(zookeeper.PERM_ALL), f) } } return err }
func (zkts *Server) UpdateShard(si *topo.ShardInfo, existingVersion int64) (int64, error) { shardPath := path.Join(globalKeyspacesPath, si.Keyspace(), "shards", si.ShardName()) stat, err := zkts.zconn.Set(shardPath, jscfg.ToJson(si.Shard), int(existingVersion)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { err = topo.ErrNoNode } return -1, err } event.Dispatch(&events.ShardChange{ ShardInfo: *si, Status: "updated", }) return int64(stat.Version()), nil }
func (zkts *Server) UpdateKeyspace(ki *topo.KeyspaceInfo, existingVersion int64) (int64, error) { keyspacePath := path.Join(globalKeyspacesPath, ki.KeyspaceName()) data := jscfg.ToJson(ki.Keyspace) stat, err := zkts.zconn.Set(keyspacePath, data, int(existingVersion)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { err = topo.ErrNoNode } return -1, err } event.Dispatch(&events.KeyspaceChange{ KeyspaceInfo: *ki, Status: "updated", }) return int64(stat.Version()), nil }
func TestMissingFieldsJson(t *testing.T) { swra := &slaveWasRestartedTestArgs{ Parent: topo.TabletAlias{ Uid: 1, Cell: "aa", }, ExpectedMasterAddr: "a1", ExpectedMasterIpAddr: "i1", ScrapStragglers: true, } data := jscfg.ToJson(swra) output := &SlaveWasRestartedArgs{} decoder := json.NewDecoder(strings.NewReader(data)) err := decoder.Decode(output) if err != nil { t.Errorf("Cannot re-decode struct without field: %v", err) } }
func (zkts *Server) updateTabletEndpoint(oldValue string, oldStat zk.Stat, addr *topo.EndPoint) (newValue string, err error) { if oldStat == nil { // The incoming object doesn't exist - we haven't been placed in the serving // graph yet, so don't update. Assume the next process that rebuilds the graph // will get the updated tablet location. return "", skipUpdateErr } var addrs *topo.EndPoints if oldValue != "" { addrs = &topo.EndPoints{} if len(oldValue) > 0 { if err := json.Unmarshal([]byte(oldValue), addrs); err != nil { return "", fmt.Errorf("EndPoints unmarshal failed: %v %v", oldValue, err) } } foundTablet := false for i, entry := range addrs.Entries { if entry.Uid == addr.Uid { foundTablet = true if !topo.EndPointEquality(&entry, addr) { addrs.Entries[i] = *addr } break } } if !foundTablet { addrs.Entries = append(addrs.Entries, *addr) } } else { addrs = topo.NewEndPoints() addrs.Entries = append(addrs.Entries, *addr) } return jscfg.ToJson(addrs), nil }
func (zkts *Server) UpdateTabletFields(tabletAlias topo.TabletAlias, update func(*topo.Tablet) error) error { // Store the last tablet value so we can log it if the change succeeds. var lastTablet *topo.Tablet zkTabletPath := TabletPathForAlias(tabletAlias) f := func(oldValue string, oldStat zk.Stat) (string, error) { if oldValue == "" { return "", fmt.Errorf("no data for tablet addr update: %v", tabletAlias) } tablet, err := tabletFromJson(oldValue) if err != nil { return "", err } if err := update(tablet); err != nil { return "", err } lastTablet = tablet return jscfg.ToJson(tablet), nil } err := zkts.zconn.RetryChange(zkTabletPath, 0, zookeeper.WorldACL(zookeeper.PERM_ALL), f) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { err = topo.ErrNoNode } return err } if lastTablet != nil { event.Dispatch(&events.TabletChange{ Tablet: *lastTablet, Status: "updated", }) } return nil }
func (hr *HookResult) String() string { return jscfg.ToJson(hr) }
func (tablet *Tablet) Json() string { return jscfg.ToJson(tablet) }
func (sd *SchemaDefinition) String() string { return jscfg.ToJson(sd) }
func (scr *SchemaChangeResult) String() string { return jscfg.ToJson(scr) }
func WriteAddrs(zconn zk.Conn, zkPath string, addrs *LegacyZknsAddrs) error { data := jscfg.ToJson(addrs) _, err := zk.CreateOrUpdate(zconn, zkPath, data, 0, zookeeper.WorldACL(zookeeper.PERM_ALL), true) return err }
func (zkts *Server) UpdateSrvShard(cell, keyspace, shard string, srvShard *topo.SrvShard) error { path := zkPathForVtShard(cell, keyspace, shard) data := jscfg.ToJson(srvShard) _, err := zkts.zconn.Set(path, data, -1) return err }