func All(conn *zk.Conn, zkConf conf.Zookeeper) (map[string]Service, error) { err := ensurePathExists(conn, zkConf.Path) if err != nil { return nil, err } services := map[string]Service{} keys, _, err2 := conn.Children(zkConf.Path) if err2 != nil { return nil, err2 } for _, childPath := range keys { bite, _, e := conn.Get(zkConf.Path + "/" + childPath) if e != nil { return nil, e break } appId, _ := unescapeSlashes(childPath) services[appId] = Service{Id: appId, Acl: string(bite)} } return services, nil }
func pollZooKeeper(conn *zk.Conn, path string, evts chan zk.Event, quit chan bool) { logger.Println("####################################Pooling zookeeper") logger.Println(path) children, _, err := conn.Children(path) if err != nil { fmt.Printf("%+v", err) panic(err) } watcherControl := make([]chan<- bool, len(children)+2) watcherControl[0] = sinkSelfEvents(conn, path, evts) watcherControl[1] = sinkChildEvents(conn, path, evts) for i, child := range children { p := path + "/" + child watcherControl[i+2] = sinkSelfEvents(conn, p, evts) } <-quit for _, ch := range watcherControl { ch <- true } }
func loadToZK(conn *zk.Conn, data [][2]string) { for _, entry := range data { k := entry[0] v := entry[1] _, err := conn.Create(k, []byte(v), 0, defaultACL()) orPanic(err) } }
/* Read ZK ACL: http://zookeeper.apache.org/doc/trunk/zookeeperProgrammers.html#sc_ACLPermissions */ func Create(conn *zk.Conn, zkConf conf.Zookeeper, appId string, domainValue string) (string, error) { path := concatPath(zkConf.Path, validateAppId(appId)) resPath, err := conn.Create(path, []byte(domainValue), 0, defaultACL()) if err != nil { return "", err } return resPath, nil }
func ensurePathExists(conn *zk.Conn, path string) error { pathExists, _, _ := conn.Exists(path) if pathExists { return nil } _, err := conn.Create(path, []byte{}, 0, defaultACL()) if err != nil { return err } return nil }
func deleteRecursive(conn *zk.Conn, path string) { children, _, err := conn.Children(path) if err != nil { log.Printf("failed to get children %s: %s", path, err) return } for _, child := range children { deleteRecursive(conn, path+"/"+child) } err = conn.Delete(path, -1) if err != nil { log.Printf("failed to delete %s: %s", path, err) } }
func ListenToConn(c *zk.Conn, path string, deb bool, repDelay time.Duration) (chan zk.Event, chan bool) { exists, _, err := c.Exists(path) if err != nil { logger.Fatalf("Couldn't determine whether node %v exists in Zookeeper", path) } if !exists { logger.Printf("Node '%v' does not exist in Zookeeper, creating...", path) err := zkNodeCreateByPath(path, c) if err != nil { logger.Fatalf("Unable to create path '%v': %v", path, err) } } quit := make(chan bool) evts := make(chan zk.Event) go pollZooKeeper(c, path, evts, quit) if deb { evts = debounce(evts, 100*time.Millisecond) } if repDelay > 0 { evts = delay(evts, repDelay) } return evts, quit }
func Put(conn *zk.Conn, zkConf conf.Zookeeper, appId string, domainValue string) (*zk.Stat, error) { path := concatPath(zkConf.Path, validateAppId(appId)) err := ensurePathExists(conn, path) if err != nil { return nil, err } stats, err := conn.Set(path, []byte(domainValue), -1) if err != nil { return nil, err } // Force triger an event on parent conn.Set(zkConf.Path, []byte{}, -1) return stats, nil }
func zkCreateNodes(path string, nodes []string, c *zk.Conn) error { if len(nodes) > 0 { // strings.Split will return empty-strings for leading split chars, lets skip over these. if len(nodes[0]) == 0 { return zkCreateNodes(path, nodes[1:], c) } fqPath := path + "/" + nodes[0] log.Printf("Creating path: %v", fqPath) exists, _, err := c.Exists(fqPath) if err != nil { return err } if !exists { _, err := c.Create(fqPath, []byte{}, 0, zk.WorldACL(zk.PermAll)) if err != nil { return err } } return zkCreateNodes(fqPath, nodes[1:], c) } return nil }
func sinkSelfEvents(conn *zk.Conn, path string, sink chan<- zk.Event) chan<- bool { control := make(chan bool) go func() { _, _, selfCh, err := conn.GetW(path) if err != nil { logger.Panicf("failed to set listener on path: %s", err.Error()) } for { select { case _ = <-control: break case ev := <-selfCh: sink <- ev _, _, selfCh, err = conn.GetW(path) if err != nil { logger.Printf("failed to set listener on path: %s\n", err.Error()) } } } }() return control }
func sinkChildEvents(conn *zk.Conn, path string, sink chan<- zk.Event) chan<- bool { control := make(chan bool) go func() { _, _, selfCh, err := conn.ChildrenW(path) if err != nil { logger.Panic("failed to set listener on path") } for { select { case _ = <-control: break case ev := <-selfCh: sink <- ev _, _, selfCh, err = conn.ChildrenW(path) if err != nil { logger.Panic("failed to set listener on path") } } } }() return control }
func Delete(conn *zk.Conn, zkConf conf.Zookeeper, appId string) error { path := concatPath(zkConf.Path, validateAppId(appId)) return conn.Delete(path, -1) }