func TestManagerIndexControl(t *testing.T) { emptyDir, _ := ioutil.TempDir("./tmp", "test") defer os.RemoveAll(emptyDir) cfg := cbgt.NewCfgMem() m := cbgt.NewManager(cbgt.VERSION, cfg, cbgt.NewUUID(), nil, "", 1, "", ":1000", emptyDir, "some-datasource", nil) if err := m.Start("wanted"); err != nil { t.Errorf("expected Manager.Start() to work, err: %v", err) } sourceParams := "" if err := m.CreateIndex("primary", "default", "123", sourceParams, "bleve", "foo", "", cbgt.PlanParams{}, ""); err != nil { t.Errorf("expected CreateIndex() to work, err: %v", err) } m.Kick("test0") m.PlannerNOOP("test0") err := m.IndexControl("foo", "wrong-uuid", "", "", "") if err == nil { t.Errorf("expected err on wrong UUID") } indexDefs, _, _ := cbgt.CfgGetIndexDefs(cfg) npp := indexDefs.IndexDefs["foo"].PlanParams.NodePlanParams[""] if npp != nil { t.Errorf("expected nil npp") } err = m.IndexControl("foo", "", "", "", "") if err != nil { t.Errorf("expected ok") } indexDefs, _, _ = cbgt.CfgGetIndexDefs(cfg) npp = indexDefs.IndexDefs["foo"].PlanParams.NodePlanParams[""] if npp == nil { t.Errorf("expected npp") } if npp[""] != nil { t.Errorf("expected nil npp.sub") } err = m.IndexControl("foo", "", "disallow", "", "") if err != nil { t.Errorf("expected ok") } indexDefs, _, _ = cbgt.CfgGetIndexDefs(cfg) npp = indexDefs.IndexDefs["foo"].PlanParams.NodePlanParams[""] if npp == nil { t.Errorf("expected npp") } if npp[""] == nil { t.Errorf("expected npp.sub") } if npp[""].CanRead { t.Errorf("expected CanRead false") } if !npp[""].CanWrite { t.Errorf("expected CanWrite") } err = m.IndexControl("foo", "", "", "", "") if err != nil { t.Errorf("expected ok") } indexDefs, _, _ = cbgt.CfgGetIndexDefs(cfg) npp = indexDefs.IndexDefs["foo"].PlanParams.NodePlanParams[""] if npp == nil { t.Errorf("expected npp") } if npp[""] == nil { t.Errorf("expected npp.sub") } if npp[""].CanRead { t.Errorf("expected CanRead false") } if !npp[""].CanWrite { t.Errorf("expected CanWrite") } err = m.IndexControl("foo", "", "", "pause", "") if err != nil { t.Errorf("expected ok") } indexDefs, _, _ = cbgt.CfgGetIndexDefs(cfg) npp = indexDefs.IndexDefs["foo"].PlanParams.NodePlanParams[""] if npp == nil { t.Errorf("expected npp") } if npp[""] == nil { t.Errorf("expected npp.sub") } if npp[""].CanRead { t.Errorf("expected CanRead false") } if npp[""].CanWrite { t.Errorf("expected CanWrite false") } err = m.IndexControl("foo", "", "", "", "") if err != nil { t.Errorf("expected ok") } indexDefs, _, _ = cbgt.CfgGetIndexDefs(cfg) npp = indexDefs.IndexDefs["foo"].PlanParams.NodePlanParams[""] if npp == nil { t.Errorf("expected npp") } if npp[""] == nil { t.Errorf("expected npp.sub") } if npp[""].CanRead { t.Errorf("expected CanRead false") } if npp[""].CanWrite { t.Errorf("expected CanWrite false") } err = m.IndexControl("foo", "", "", "resume", "") if err != nil { t.Errorf("expected ok") } indexDefs, _, _ = cbgt.CfgGetIndexDefs(cfg) npp = indexDefs.IndexDefs["foo"].PlanParams.NodePlanParams[""] if npp == nil { t.Errorf("expected npp") } if npp[""] == nil { t.Errorf("expected npp.sub") } if npp[""].CanRead { t.Errorf("expected CanRead false") } if !npp[""].CanWrite { t.Errorf("expected CanWrite") } err = m.IndexControl("foo", "", "allow", "resume", "") if err != nil { t.Errorf("expected ok") } indexDefs, _, _ = cbgt.CfgGetIndexDefs(cfg) npp = indexDefs.IndexDefs["foo"].PlanParams.NodePlanParams[""] if npp == nil { t.Errorf("expected npp") } if npp[""] != nil { t.Errorf("expected nil npp.sub") } if indexDefs.IndexDefs["foo"].PlanParams.PlanFrozen { t.Errorf("expected not yet frozen") } err = m.IndexControl("foo", "", "", "", "freeze") if err != nil { t.Errorf("expected ok") } indexDefs, _, _ = cbgt.CfgGetIndexDefs(cfg) if !indexDefs.IndexDefs["foo"].PlanParams.PlanFrozen { t.Errorf("expected frozen") } err = m.IndexControl("foo", "", "", "", "unfreeze") if err != nil { t.Errorf("expected ok") } indexDefs, _, _ = cbgt.CfgGetIndexDefs(cfg) if indexDefs.IndexDefs["foo"].PlanParams.PlanFrozen { t.Errorf("expected not frozen") } }
// The indexName/indexUUID is for a user-defined index alias. // // TODO: One day support user-defined aliases for non-bleve indexes. func bleveIndexAliasForUserIndexAlias(mgr *cbgt.Manager, indexName, indexUUID string, ensureCanRead bool, consistencyParams *cbgt.ConsistencyParams, cancelCh <-chan bool) ( bleve.IndexAlias, error) { alias := bleve.NewIndexAlias() indexDefs, _, err := cbgt.CfgGetIndexDefs(mgr.Cfg()) if err != nil { return nil, fmt.Errorf("alias: could not get indexDefs,"+ " indexName: %s, err: %v", indexName, err) } num := 0 var fillAlias func(aliasName, aliasUUID string) error fillAlias = func(aliasName, aliasUUID string) error { aliasDef := indexDefs.IndexDefs[aliasName] if aliasDef == nil { return fmt.Errorf("alias: could not get aliasDef,"+ " aliasName: %s, indexName: %s", aliasName, indexName) } if aliasDef.Type != "alias" { return fmt.Errorf("alias: not alias type: %s,"+ " aliasName: %s, indexName: %s", aliasDef.Type, aliasName, indexName) } if aliasUUID != "" && aliasUUID != aliasDef.UUID { return fmt.Errorf("alias: mismatched aliasUUID: %s,"+ " aliasDef.UUID: %s, aliasName: %s, indexName: %s", aliasUUID, aliasDef.UUID, aliasName, indexName) } params := AliasParams{} err := json.Unmarshal([]byte(aliasDef.Params), ¶ms) if err != nil { return fmt.Errorf("alias: could not parse aliasDef.Params: %s,"+ " aliasName: %s, indexName: %s", aliasDef.Params, aliasName, indexName) } for targetName, targetSpec := range params.Targets { if num > maxAliasTargets { return fmt.Errorf("alias: too many alias targets,"+ " perhaps there's a cycle,"+ " aliasName: %s, indexName: %s", aliasName, indexName) } targetDef := indexDefs.IndexDefs[targetName] if targetDef == nil { return fmt.Errorf("alias: the alias depends upon"+ " a target index that does not exist,"+ " targetName: %q, aliasName: %q", targetName, aliasName) } if targetSpec.IndexUUID != "" && targetSpec.IndexUUID != targetDef.UUID { return fmt.Errorf("alias: mismatched targetSpec.UUID: %s,"+ " targetDef.UUID: %s, targetName: %s,"+ " aliasName: %s, indexName: %s", targetSpec.IndexUUID, targetDef.UUID, targetName, aliasName, indexName) } // TODO: Convert to registered callbacks instead of if-else-if. if targetDef.Type == "alias" { err = fillAlias(targetName, targetSpec.IndexUUID) if err != nil { return err } } else if strings.HasPrefix(targetDef.Type, "bleve") { subAlias, err := bleveIndexAlias(mgr, targetName, targetSpec.IndexUUID, ensureCanRead, consistencyParams, cancelCh) if err != nil { return err } alias.Add(subAlias) num += 1 } else { return fmt.Errorf("alias: unsupported target type: %s,"+ " targetName: %s, aliasName: %s, indexName: %s", targetDef.Type, targetName, aliasName, indexName) } } return nil } err = fillAlias(indexName, indexUUID) if err != nil { return nil, err } return alias, nil }