func GetParentInfo(node string) (node_info.NodeInfo, tree_lib.TreeError) { var ( err tree_lib.TreeError pname string ) err.From = tree_lib.FROM_GET_PARENT_INFO err = ForEach(DB_NODE, func(key []byte, val []byte) error { n := node_info.NodeInfo{} err := ffjson.Unmarshal(val, &n) if err != nil { return err } if _, ok := tree_lib.ArrayContains(n.Childs, node); ok { pname = n.Name return errors.New("Just Err for break") } return nil }) if len(pname) == 0 { return node_info.NodeInfo{}, tree_lib.TreeError{} } // Node relations first element should be parent node return GetNodeInfo(pname) }
func TagDeleteNode(tag, node string) (err tree_lib.TreeError) { var ( gB []byte tag_nodes []string ) err.From = tree_lib.FROM_TAG_DELETE_NODE gB, err = Get(DB_TAG, []byte(tag)) if !err.IsNull() { return } if len(gB) > 0 { tag_nodes = strings.Split(string(gB), ",") } if n, ok := tree_lib.ArrayContains(tag_nodes, node); !ok { tag_nodes = tag_nodes[:n+copy(tag_nodes[n:], tag_nodes[n+1:])] } err = Set(DB_TAG, []byte(tag), []byte(strings.Join(tag_nodes, ","))) return }
func TagAddNode(tag, node string) (err tree_lib.TreeError) { var ( gB []byte tag_nodes []string ) err.From = tree_lib.FROM_TAG_ADD_NODE gB, err = Get(DB_TAG, []byte(tag)) if !err.IsNull() { return } if len(gB) > 0 { tag_nodes = strings.Split(string(gB), ",") } if _, ok := tree_lib.ArrayContains(tag_nodes, node); !ok { tag_nodes = append(tag_nodes, node) } err = Set(DB_TAG, []byte(tag), []byte(strings.Join(tag_nodes, ","))) return }
func GroupDeleteNode(group, node string) (err tree_lib.TreeError) { var ( gB []byte group_nodes []string ) err.From = tree_lib.FROM_GROUP_DELETE_NODE gB, err = Get(DB_GROUP, []byte(group)) if !err.IsNull() { return } if len(gB) > 0 { group_nodes = strings.Split(string(gB), ",") } if n, ok := tree_lib.ArrayContains(group_nodes, node); ok { group_nodes = group_nodes[:n+copy(group_nodes[n:], group_nodes[n+1:])] } fmt.Println(group_nodes) err = Set(DB_GROUP, []byte(group), []byte(strings.Join(group_nodes, ","))) return }
func GroupAddNode(group, node string) (err tree_lib.TreeError) { var ( gB []byte group_nodes []string ) err.From = tree_lib.FROM_GROUP_ADD_NODE gB, err = Get(DB_GROUP, []byte(group)) if !err.IsNull() { return } if len(gB) > 0 { group_nodes = strings.Split(string(gB), ",") } if _, ok := tree_lib.ArrayContains(group_nodes, node); !ok { group_nodes = append(group_nodes, node) } err = Set(DB_GROUP, []byte(group), []byte(strings.Join(group_nodes, ","))) return }
// Key -> value ..... node_name -> node1,node2,node3 // []byte -> []string{}.Join(",") // First element of string array should be parent node func SetRelations(node string) (err tree_lib.TreeError) { err.From = tree_lib.FROM_SET_RELATIONS parent_name := "" inf := node_info.NodeInfo{} inf, err = GetNodeInfo(node) if !err.IsNull() { return } rels := inf.Childs // Getting parent node err = ForEach(DB_NODE, func(key []byte, val []byte) error { nf := node_info.NodeInfo{} err := ffjson.Unmarshal(val, &nf) if err != nil { return err } if _, ok := tree_lib.ArrayContains(nf.Childs, node); ok { parent_name = nf.Name return errors.New("") // Just ending the ForEach with empty error } return nil }) if !err.IsNull() { return } if len(parent_name) != 0 { rels = append(append([]string{}, parent_name), rels...) } err = Set(DB_RELATIONS, []byte(node), []byte(strings.Join(rels, ","))) return }
func init() { var err tree_lib.TreeError err.From = tree_lib.FROM_INIT tree_db, err.Err = bolt.Open(DB_DIR, 0600, nil) if !err.IsNull() { tree_log.Error(log_from_db, " unable to open database", err.Error()) tree_db = nil os.Exit(1) // Without database we can't keep and share configurations, so program should be exited } // creating Buckets in database tree_db.Update(func(tx *bolt.Tx) (err error) { // Setting databases for _, d := range [][]byte{DB_NODE, DB_BALANCER, DB_RANDOM, DB_GROUP, DB_TAG, DB_RELATIONS, DB_REGISTRY, DB_EVENT} { _, err = tx.CreateBucketIfNotExists(d) if err != nil { return err } } return nil }) // Handling node change event tree_event.ON(tree_event.ON_UPDATE_NODE_INFO, func(e *tree_event.Event) { var ( info node_info.NodeInfo ev_info node_info.NodeInfo names []string data []byte mark bool ) err.Err = ffjson.Unmarshal(e.Data, &ev_info) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } info, err = GetNodeInfo(ev_info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } if len(info.Name) > 0 { err = DeleteNodeFromHisGroups(info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = DeleteNodeFromHisTags(info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } if len(ev_info.TreeIp) > 0 { info.TreeIp = ev_info.TreeIp mark = true } if ev_info.TreePort != -1 { info.TreePort = ev_info.TreePort mark = true } if len(ev_info.Childs[0]) > 0 { info.Childs = append(info.Childs, ev_info.Childs[0]) } if len(ev_info.Childs[1]) > 0 { if g, ok := tree_lib.ArrayContains(info.Childs, ev_info.Childs[1]); ok { info.Childs = info.Childs[:g+copy(info.Childs[g:], info.Childs[g+1:])] } } if len(ev_info.Groups[0]) > 0 { info.Groups = append(info.Groups, ev_info.Groups[0]) } if len(ev_info.Groups[1]) > 0 { if g, ok := tree_lib.ArrayContains(info.Groups, ev_info.Groups[1]); ok { info.Groups = info.Groups[:g+copy(info.Groups[g:], info.Groups[g+1:])] } } if len(ev_info.Tags[0]) > 0 { info.Tags = append(info.Tags, ev_info.Tags[0]) } if len(ev_info.Tags[1]) > 0 { if g, ok := tree_lib.ArrayContains(info.Tags, ev_info.Tags[1]); ok { info.Tags = info.Tags[:g+copy(info.Tags[g:], info.Tags[g+1:])] } } data, err.Err = ffjson.Marshal(info) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = Set(DB_NODE, []byte(ev_info.Name), data) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } names, err = ListNodeNames() if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = AddNodeToHisGroups(info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = AddNodeToHisTags(info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } for _, n := range names { err = SetRelations(n) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } } if node_info.CurrentNodeInfo.Name == ev_info.Name && mark { var e1 tree_event.Event e1.Name = tree_event.ON_RESTART_NODE tree_event.Trigger(&e1) } } else { err = Set(DB_NODE, []byte(ev_info.Name), e.Data) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } names, err = ListNodeNames() if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = AddNodeToHisGroups(ev_info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = AddNodeToHisTags(ev_info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } for _, n := range names { err = SetRelations(n) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } } if node_info.CurrentNodeInfo.Name == ev_info.Name { var e1 *tree_event.Event e1.Name = tree_event.ON_RESTART_NODE tree_event.Trigger(e1) } } }) // Closing database before program will be exited // Just in case if program exiting force or we don't want to make dead lock tree_event.ON(tree_event.ON_PROGRAM_EXIT, func(e *tree_event.Event) { CloseDB() }) }