// DiffSchemaToArray diffs two schemas and return the schema diffs if there is any. func DiffSchemaToArray(leftName string, left *SchemaDefinition, rightName string, right *SchemaDefinition) (result []string) { er := concurrency.AllErrorRecorder{} DiffSchema(leftName, left, rightName, right, &er) if er.HasErrors() { return er.ErrorStrings() } return nil }
// DiffPermissionsToArray difs two sets of permissions, and returns the difference func DiffPermissionsToArray(leftName string, left *tabletmanagerdatapb.Permissions, rightName string, right *tabletmanagerdatapb.Permissions) (result []string) { er := concurrency.AllErrorRecorder{} DiffPermissions(leftName, left, rightName, right, &er) if er.HasErrors() { return er.ErrorStrings() } return nil }
// DbServingGraph returns the ServingGraph for the given cell. func DbServingGraph(ctx context.Context, ts topo.Server, cell string) (servingGraph *ServingGraph) { servingGraph = &ServingGraph{ Cell: cell, Keyspaces: make(map[string]*KeyspaceNodes), } rec := concurrency.AllErrorRecorder{} keyspaces, err := ts.GetSrvKeyspaceNames(ctx, cell) if err != nil { servingGraph.Errors = append(servingGraph.Errors, fmt.Sprintf("GetSrvKeyspaceNames failed: %v", err)) return } wg := sync.WaitGroup{} servingTypes := []topo.TabletType{topo.TYPE_MASTER, topo.TYPE_REPLICA, topo.TYPE_RDONLY} for _, keyspace := range keyspaces { kn := newKeyspaceNodes() servingGraph.Keyspaces[keyspace] = kn wg.Add(1) go func(keyspace string, kn *KeyspaceNodes) { defer wg.Done() ks, err := ts.GetSrvKeyspace(ctx, cell, keyspace) if err != nil { rec.RecordError(fmt.Errorf("GetSrvKeyspace(%v, %v) failed: %v", cell, keyspace, err)) return } kn.ServedFrom = ks.ServedFrom displayedShards := make(map[string]bool) for _, partitionTabletType := range servingTypes { kp, ok := ks.Partitions[partitionTabletType] if !ok { continue } for _, srvShard := range kp.ShardReferences { shard := srvShard.Name if displayedShards[shard] { continue } displayedShards[shard] = true sn := &ShardNodes{ Name: shard, TabletNodes: make(TabletNodesByType), } kn.ShardNodes = append(kn.ShardNodes, sn) wg.Add(1) go func(shard string, sn *ShardNodes) { defer wg.Done() tabletTypes, err := ts.GetSrvTabletTypesPerShard(ctx, cell, keyspace, shard) if err != nil { rec.RecordError(fmt.Errorf("GetSrvTabletTypesPerShard(%v, %v, %v) failed: %v", cell, keyspace, shard, err)) return } for _, tabletType := range tabletTypes { endPoints, _, err := ts.GetEndPoints(ctx, cell, keyspace, shard, tabletType) if err != nil { rec.RecordError(fmt.Errorf("GetEndPoints(%v, %v, %v, %v) failed: %v", cell, keyspace, shard, tabletType, err)) continue } for _, endPoint := range endPoints.Entries { sn.TabletNodes[tabletType] = append(sn.TabletNodes[tabletType], newTabletNodeFromEndPoint(endPoint, cell)) } } }(shard, sn) } } }(keyspace, kn) } wg.Wait() servingGraph.Errors = rec.ErrorStrings() return }
// DbServingGraph returns the ServingGraph for the given cell. func DbServingGraph(ctx context.Context, ts topo.Server, cell string) (servingGraph *ServingGraph) { servingGraph = &ServingGraph{ Cell: cell, Keyspaces: make(map[string]*KeyspaceNodes), } rec := concurrency.AllErrorRecorder{} keyspaces, err := ts.GetSrvKeyspaceNames(ctx, cell) if err != nil { servingGraph.Errors = append(servingGraph.Errors, fmt.Sprintf("GetSrvKeyspaceNames failed: %v", err)) return } wg := sync.WaitGroup{} servingTypes := []pb.TabletType{pb.TabletType_MASTER, pb.TabletType_REPLICA, pb.TabletType_RDONLY} for _, keyspace := range keyspaces { kn := newKeyspaceNodes() servingGraph.Keyspaces[keyspace] = kn wg.Add(1) go func(keyspace string, kn *KeyspaceNodes) { defer wg.Done() ks, err := ts.GetSrvKeyspace(ctx, cell, keyspace) if err != nil { rec.RecordError(fmt.Errorf("GetSrvKeyspace(%v, %v) failed: %v", cell, keyspace, err)) return } for _, sf := range ks.ServedFrom { kn.ServedFrom[strings.ToLower(sf.TabletType.String())] = sf.Keyspace } displayedShards := make(map[string]bool) for _, partitionTabletType := range servingTypes { kp := topoproto.SrvKeyspaceGetPartition(ks, partitionTabletType) if kp == nil { continue } for _, srvShard := range kp.ShardReferences { shard := srvShard.Name if displayedShards[shard] { continue } displayedShards[shard] = true sn := &ShardNodes{ Name: shard, } kn.ShardNodes = append(kn.ShardNodes, sn) wg.Add(1) go func(shard string, sn *ShardNodes) { defer wg.Done() tabletTypes, err := ts.GetSrvTabletTypesPerShard(ctx, cell, keyspace, shard) if err != nil { rec.RecordError(fmt.Errorf("GetSrvTabletTypesPerShard(%v, %v, %v) failed: %v", cell, keyspace, shard, err)) return } for _, tabletType := range tabletTypes { endPoints, _, err := ts.GetEndPoints(ctx, cell, keyspace, shard, tabletType) if err != nil { rec.RecordError(fmt.Errorf("GetEndPoints(%v, %v, %v, %v) failed: %v", cell, keyspace, shard, tabletType, err)) continue } for _, endPoint := range endPoints.Entries { var tabletNode *TabletNodesByType for _, t := range sn.TabletNodes { if t.TabletType == tabletType { tabletNode = t break } } if tabletNode == nil { tabletNode = &TabletNodesByType{ TabletType: tabletType, } sn.TabletNodes = append(sn.TabletNodes, tabletNode) } tabletNode.Nodes = append(tabletNode.Nodes, newTabletNodeFromEndPoint(endPoint, cell)) } } }(shard, sn) } } }(keyspace, kn) } wg.Wait() servingGraph.Errors = rec.ErrorStrings() return }