Пример #1
0
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
}
Пример #2
0
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
}
Пример #3
0
// 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
}
Пример #4
0
// 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
}
Пример #5
0
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
}
Пример #6
0
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
}
Пример #7
0
func (c *cbCluster) QueryNodeNames() ([]string, errors.Error) {
	queryNodeNames := []string{}
	// Get a handle of the go-couchbase connection:
	cbConn, ok := c.configStore.(*cbConfigStore)
	if !ok {
		return nil, errors.NewAdminConnectionError(nil, c.ConfigurationStoreId())
	}
	poolServices, err := cbConn.getPoolServices(c.ClusterName)
	if err != nil {
		return queryNodeNames, err
	}
	// If the go-couchbase pool services rev matches the cluster's rev, return cluster's query node names:
	if poolServices.Rev == c.poolSrvRev {
		return c.queryNodeNames, nil
	}
	// If the rev numbers do not match, update the cluster's rev and query node data:
	queryNodeNames = []string{}
	queryNodes := make(map[string]int)
	for _, ns := range poolServices.NodesExt {
		n1qlPort := ns.Services["n1ql"]
		hostname := ns.Hostname

		if n1qlPort == 0 { // no n1ql service in this node
			continue
		}

		// TODO: check ns.ThisNode also
		if hostname == "" {
			hostname, _ = getHostnameFromURI(c.configStore.URL())
		}
		queryNodeNames = append(queryNodeNames, hostname)
		queryNodes[hostname] = n1qlPort
	}

	c.Lock()
	defer c.Unlock()
	c.queryNodeNames = queryNodeNames
	c.queryNodes = queryNodes
	c.poolSrvRev = poolServices.Rev
	return c.queryNodeNames, nil
}
Пример #8
0
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
}