Example #1
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
}
Example #2
0
func (z *zkCluster) RemoveQueryNode(n clustering.QueryNode) (clustering.QueryNode, errors.Error) {
	return z.RemoveQueryNodeByName(n.Name())
}