func (z *zkCluster) GetQueryNodes() ([]clustering.QueryNode, errors.Error) { impl, ok := getConfigStoreImplementation(z) if !ok { return nil, errors.NewAdminConnectionError(nil, z.ConfigurationStoreId()) } qryNodes := []clustering.QueryNode{} nodes, _, err := impl.conn.Children("/" + z.Name()) if err != nil { return nil, errors.NewAdminGetClusterError(err, z.Name()) } for _, name := range nodes { nodePath := "/" + z.Name() + "/" + name data, _, err := impl.conn.Get(nodePath) if err != nil { return nil, errors.NewAdminGetNodeError(err, nodePath) } queryNode := &zkQueryNodeConfig{} err = json.Unmarshal(data, queryNode) if err != nil { return nil, errors.NewAdminDecodingError(err) } qryNodes = append(qryNodes, queryNode) } return qryNodes, nil }
func (this *cbCluster) QueryNodeNames() ([]string, errors.Error) { queryNodeNames := []string{} // Get a handle of the go-couchbase connection: cbConn, ok := this.configStore.(*cbConfigStore) if !ok { return nil, errors.NewAdminConnectionError(nil, this.ConfigurationStoreId()) } pool, poolServices, err := cbConn.getPoolServices(this.ClusterName) if err != nil { return queryNodeNames, err } // If pool services rev matches the cluster's rev, return cluster's query node names: if poolServices.Rev == this.poolSrvRev { return this.queryNodeNames, nil } // If pool services and cluster rev do not match, update the cluster's rev and query node data: queryNodeNames = []string{} queryNodes := map[string]services{} for _, nodeServices := range poolServices.NodesExt { var queryServices services for name, protocol := range n1qlProtocols { if nodeServices.Services[name] != 0 { if queryServices == nil { queryServices = services{} } queryServices[protocol] = nodeServices.Services[name] } } if len(queryServices) == 0 { // no n1ql service at this node continue } hostname := nodeServices.Hostname if nodeServices.ThisNode { for _, node := range pool.Nodes { if node.ThisNode { tokens := strings.Split(node.Hostname, ":") hostname = tokens[0] break } } } queryNodeNames = append(queryNodeNames, hostname) queryNodes[hostname] = queryServices } this.Lock() defer this.Unlock() this.queryNodeNames = queryNodeNames this.queryNodes = queryNodes this.poolSrvRev = poolServices.Rev return this.queryNodeNames, nil }
func (z *zkCluster) RemoveQueryNodeByName(name string) (clustering.QueryNode, errors.Error) { impl, ok := getConfigStoreImplementation(z) if !ok { return nil, errors.NewAdminConnectionError(nil, z.ConfigurationStoreId()) } err := impl.conn.Delete("/"+z.Name()+"/"+name, 0) if err != nil { return nil, errors.NewAdminRemoveNodeError(err, "/"+z.Name()+"/"+name) } return nil, nil }
// create a cbConfigStore given the path to a couchbase instance func NewConfigstore(path string) (clustering.ConfigurationStore, errors.Error) { if strings.HasPrefix(path, _PREFIX) { path = path[len(_PREFIX):] } c, err := couchbase.Connect(path) if err != nil { return nil, errors.NewAdminConnectionError(err, path) } return &cbConfigStore{ adminUrl: path, cbConn: &c, }, nil }
// create a zkConfigStore given the path to a zookeeper instance func NewConfigstore(path string) (clustering.ConfigurationStore, errors.Error) { if strings.HasPrefix(path, _PREFIX) { path = path[len(_PREFIX):] } zks := strings.Split(path, ",") conn, _, err := zk.Connect(zks, time.Second) if err != nil { return nil, errors.NewAdminConnectionError(err, path) } return &zkConfigStore{ conn: conn, url: path, }, nil }
func (z *zkCluster) QueryNodeNames() ([]string, errors.Error) { queryNodeNames := []string{} impl, ok := getConfigStoreImplementation(z) if !ok { return nil, errors.NewAdminConnectionError(nil, z.ConfigurationStoreId()) } nodes, _, err := impl.conn.Children("/" + z.ClusterName) if err != nil { return nil, errors.NewAdminGetClusterError(err, z.ClusterName) } for _, name := range nodes { queryNodeNames = append(queryNodeNames, name) } return queryNodeNames, nil }
func (z *zkCluster) QueryNodeByName(name string) (clustering.QueryNode, errors.Error) { impl, ok := getConfigStoreImplementation(z) if !ok { return nil, errors.NewAdminConnectionError(nil, z.ConfigurationStoreId()) } nodePath := "/" + z.ClusterName + "/" + name data, _, err := impl.conn.Get(nodePath) if err != nil { return nil, errors.NewAdminGetNodeError(err, nodePath) } var queryNode zkQueryNodeConfig err = json.Unmarshal(data, &queryNode) if err != nil { return nil, errors.NewAdminDecodingError(err) } return &queryNode, nil }
func (z *zkCluster) AddQueryNode(n clustering.QueryNode) (clustering.QueryNode, errors.Error) { impl, ok := getConfigStoreImplementation(z) if !ok { return nil, errors.NewAdminConnectionError(nil, z.ConfigurationStoreId()) } // Check that query node has compatible backend connections: if n.Standalone().Datastore().URL() != z.DatastoreURI { return nil, errors.NewWarning(fmt.Sprintf("Failed to add Query Node %v: incompatible datastore with cluster %s", n, z.DatastoreURI)) } if n.Standalone().ConfigurationStore().URL() != z.ConfigstoreURI { return nil, errors.NewWarning(fmt.Sprintf("Failed to add Query Node %v: incompatible configstore with cluster %s", n, z.ConfigstoreURI)) } // Check that query node is version compatible with the cluster: if !z.Version().Compatible(n.Standalone().Version()) { return nil, errors.NewWarning(fmt.Sprintf("Failed to add Query Node %v: not version compatible with cluster (%v)", n, z.Version())) } qryNodeImpl, ok := n.(*zkQueryNodeConfig) if !ok { return nil, errors.NewWarning(fmt.Sprintf("Failed to add Query Node %v: cannot set cluster reference", n)) } // The query node can be accepted into the cluster - set its cluster reference and name and unset its Standalone: qryNodeImpl.ClusterRef = z qryNodeImpl.ClusterName = z.Name() qryNodeImpl.StandaloneRef = nil // Add entry for query node: ephemeral node flags := int32(zk.FlagEphemeral) acl := zk.WorldACL(zk.PermAll) // TODO: credentials - expose in the API key := "/" + z.Name() + "/" + n.Name() value, err := json.Marshal(n) if err != nil { return nil, errors.NewAdminEncodingError(err) } _, err = impl.conn.Create(key, value, flags, acl) if err != nil { return nil, errors.NewAdminAddNodeError(err, "/"+z.Name()+"/"+n.Name()) } return n, nil }