// newCbqClient create cbq-cluster client. func newCbqClient(cluster string) (*cbqClient, error) { clusterUrl, err := common.ClusterAuthUrl(cluster) if err != nil { return nil, err } cinfo, err := common.NewClusterInfoCache(clusterUrl, "default" /*pooln*/) if err != nil { return nil, err } if err = cinfo.Fetch(); err != nil { return nil, err } nodes := cinfo.GetNodesByServiceType("indexAdmin") if l := len(nodes); l < 1 { err := fmt.Errorf("cinfo.GetNodesByServiceType() returns %d nodes", l) return nil, err } adminport, err := cinfo.GetServiceAddress(nodes[0], "indexAdmin") if err != nil { return nil, err } queryport, err := cinfo.GetServiceAddress(nodes[0], "indexScan") if err != nil { return nil, err } b := &cbqClient{ adminport: "http://" + adminport, queryport: queryport, httpc: http.DefaultClient, } b.logPrefix = fmt.Sprintf("[cbqClient %v]", b.adminport) return b, nil }
func ValidateBucket(cluster, bucket string, uuids []string) bool { var cinfo *common.ClusterInfoCache url, err := common.ClusterAuthUrl(cluster) if err == nil { cinfo, err = common.NewClusterInfoCache(url, DEFAULT_POOL) } if err != nil { logging.Fatalf("Indexer::Fail to init ClusterInfoCache : %v", err) common.CrashOnError(err) } cinfo.Lock() defer cinfo.Unlock() if err := cinfo.Fetch(); err != nil { logging.Errorf("Indexer::Fail to init ClusterInfoCache : %v", err) common.CrashOnError(err) } if nids, err := cinfo.GetNodesByBucket(bucket); err == nil && len(nids) != 0 { // verify UUID currentUUID := cinfo.GetBucketUUID(bucket) for _, uuid := range uuids { if uuid != currentUUID { return false } } return true } else { logging.Fatalf("Indexer::Error Fetching Bucket Info: %v Nids: %v", err, nids) return false } }
func NewKVSender(supvCmdch MsgChannel, supvRespch MsgChannel, config c.Config) (KVSender, Message) { var cinfo *c.ClusterInfoCache url, err := c.ClusterAuthUrl(config["clusterAddr"].String()) if err == nil { cinfo, err = c.NewClusterInfoCache(url, DEFAULT_POOL) } if err != nil { panic("Unable to initialize cluster_info - " + err.Error()) } //Init the kvSender struct k := &kvSender{ supvCmdch: supvCmdch, supvRespch: supvRespch, cInfoCache: cinfo, config: config, } k.cInfoCache.SetMaxRetries(MAX_CLUSTER_FETCH_RETRY) k.cInfoCache.SetLogPrefix("KVSender: ") //start kvsender loop which listens to commands from its supervisor go k.run() return k, &MsgSuccess{} }
// get cluster info and refresh ns-server data. func getClusterInfo( cluster string, pooln string) (*c.ClusterInfoCache, errors.Error) { clusterURL, err := c.ClusterAuthUrl(cluster) if err != nil { return nil, errors.NewError(err, fmt.Sprintf("ClusterAuthUrl() failed")) } cinfo, err := c.NewClusterInfoCache(clusterURL, pooln) if err != nil { return nil, errors.NewError(err, fmt.Sprintf("ClusterInfo() failed")) } if err := cinfo.Fetch(); err != nil { msg := fmt.Sprintf("Fetch ClusterInfo() failed") return nil, errors.NewError(err, msg) } return cinfo, nil }
func (b *metadataClient) watchClusterChanges() { selfRestart := func() { time.Sleep(time.Duration(b.servicesNotifierRetryTm) * time.Millisecond) go b.watchClusterChanges() } clusterURL, err := common.ClusterAuthUrl(b.cluster) if err != nil { logging.Errorf("common.ClusterAuthUrl(): %v\n", err) selfRestart() return } scn, err := common.NewServicesChangeNotifier(clusterURL, "default") if err != nil { logging.Errorf("common.NewServicesChangeNotifier(): %v\n", err) selfRestart() return } defer scn.Close() // For observing node services config ch := scn.GetNotifyCh() for { b.Refresh() select { case _, ok := <-ch: if !ok { selfRestart() return } else if err := b.updateIndexerList(false); err != nil { logging.Errorf("updateIndexerList(): %v\n", err) selfRestart() return } case <-b.finch: return } } }
func GetIndexerNodesHttpAddresses(hostaddress string) ([]string, error) { clusterURL, err := c.ClusterAuthUrl(hostaddress) if err != nil { return nil, err } cinfo, err := c.NewClusterInfoCache(clusterURL, "default") if err != nil { return nil, err } if err := cinfo.Fetch(); err != nil { return nil, err } node_ids := cinfo.GetNodesByServiceType(c.INDEX_HTTP_SERVICE) indexNodes := []string{} for _, node_id := range node_ids { addr, _ := cinfo.GetServiceAddress(node_id, c.INDEX_HTTP_SERVICE) indexNodes = append(indexNodes, addr) } return indexNodes, nil }
// update 2i cluster information, // IMPORTANT: make sure to call Refresh() after calling updateIndexerList() func (b *metadataClient) updateIndexerList(discardExisting bool) error { clusterURL, err := common.ClusterAuthUrl(b.cluster) if err != nil { return err } cinfo, err := common.NewClusterInfoCache(clusterURL, "default") if err != nil { return err } if err := cinfo.Fetch(); err != nil { return err } // populate indexers' adminport and queryport adminports, err := getIndexerAdminports(cinfo) if err != nil { return err } fmsg := "Refreshing indexer list due to cluster changes or auto-refresh." logging.Infof(fmsg) logging.Infof("Refreshed Indexer List: %v", adminports) b.rw.Lock() defer b.rw.Unlock() if discardExisting { for _, indexerID := range b.adminports { b.mdClient.UnwatchMetadata(indexerID) } b.adminports = nil } // watch all indexers m := make(map[string]common.IndexerId) for _, adminport := range adminports { // add new indexer-nodes if any if indexerID, ok := b.adminports[adminport]; !ok { // This adminport is provided by cluster manager. Meta client will // honor cluster manager to treat this adminport as a healthy node. // If the indexer is unavail during initialization, WatchMetadata() // will return afer timeout. A background watcher will keep // retrying, since it can be tranisent partitioning error. // If retry eventually successful, this callback will be invoked // to update meta_client. The metadata client has to rely on the // cluster manager to send a notification if this node is detected // to be down, such that the metadata client can stop the // background watcher. fn := func(ad string, n_id common.IndexerId, o_id common.IndexerId) { b.updateIndexer(ad, n_id, o_id) } // WatchMetadata will "unwatch" an old metadata watcher which // shares the same indexer Id (but the adminport may be different). indexerID = b.mdClient.WatchMetadata(adminport, fn) m[adminport] = indexerID } else { err = b.mdClient.UpdateServiceAddrForIndexer(indexerID, adminport) m[adminport] = indexerID delete(b.adminports, adminport) } } // delete indexer-nodes that got removed from cluster. for _, indexerID := range b.adminports { // check if the indexerId exists in var "m". In case the // adminport changes for the same index node, there would // be two adminport mapping to the same indexerId, one // in b.adminport (old) and the other in "m" (new). So // make sure not to accidently unwatch the indexer. found := false for _, id := range m { if indexerID == id { found = true } } if !found { b.mdClient.UnwatchMetadata(indexerID) } } b.adminports = m return err }
func NewClustMgrAgent(supvCmdch MsgChannel, supvRespch MsgChannel, cfg common.Config) ( ClustMgrAgent, Message) { //Init the clustMgrAgent struct c := &clustMgrAgent{ supvCmdch: supvCmdch, supvRespch: supvRespch, config: cfg, } var cinfo *common.ClusterInfoCache url, err := common.ClusterAuthUrl(cfg["clusterAddr"].String()) if err == nil { cinfo, err = common.NewClusterInfoCache(url, DEFAULT_POOL) } if err != nil { logging.Errorf("ClustMgrAgent::Fail to init ClusterInfoCache : %v", err) return nil, &MsgError{ err: Error{code: ERROR_CLUSTER_MGR_AGENT_INIT, severity: FATAL, category: CLUSTER_MGR, cause: err}} } cinfo.Lock() defer cinfo.Unlock() if err := cinfo.Fetch(); err != nil { logging.Errorf("ClustMgrAgent::Fail to init ClusterInfoCache : %v", err) return nil, &MsgError{ err: Error{code: ERROR_CLUSTER_MGR_AGENT_INIT, severity: FATAL, category: CLUSTER_MGR, cause: err}} } mgr, err := manager.NewIndexManager(cinfo, cfg) if err != nil { logging.Errorf("ClustMgrAgent::NewClustMgrAgent Error In Init %v", err) return nil, &MsgError{ err: Error{code: ERROR_CLUSTER_MGR_AGENT_INIT, severity: FATAL, category: CLUSTER_MGR, cause: err}} } c.mgr = mgr metaNotifier := NewMetaNotifier(supvRespch, cfg) if metaNotifier == nil { logging.Errorf("ClustMgrAgent::NewClustMgrAgent Error In Init %v", err) return nil, &MsgError{ err: Error{code: ERROR_CLUSTER_MGR_AGENT_INIT, severity: FATAL, category: CLUSTER_MGR}} } mgr.RegisterNotifier(metaNotifier) c.metaNotifier = metaNotifier //start clustMgrAgent loop which listens to commands from its supervisor go c.run() //register with Index Manager for notification of metadata updates return c, &MsgSuccess{} }