|
| 1 | +package endpoints |
| 2 | + |
| 3 | +// TODO: The API is not yet implemented. |
| 4 | + |
| 5 | +import ( |
| 6 | + "context" |
| 7 | + "fmt" |
| 8 | + |
| 9 | + "go.etcd.io/etcd/clientv3" |
| 10 | + "go.etcd.io/etcd/clientv3/naming/endpoints/internal" |
| 11 | +) |
| 12 | + |
| 13 | +type endpointManager struct { |
| 14 | + // TODO: To be implemented, tracked by: https://github.com/etcd-io/etcd/issues/12652 |
| 15 | +} |
| 16 | + |
| 17 | +func NewManager(client *clientv3.Client, target string) (Manager, error) { |
| 18 | + // To be implemented (https://github.com/etcd-io/etcd/issues/12652) |
| 19 | + return nil, fmt.Errorf("Not implemented yet") |
| 20 | +} |
| 21 | + |
| 22 | +func (m *endpointManager) Update(ctx context.Context, updates []*UpdateWithOpts) error { |
| 23 | + // TODO: For loop in a single transaction: |
| 24 | + internalUpdate := &internal.Update{} // translate UpdateWithOpts into json format. |
| 25 | + switch internalUpdate.Op { |
| 26 | + //case internal.Add: |
| 27 | + // var v []byte |
| 28 | + // if v, err = json.Marshal(internalUpdate); err != nil { |
| 29 | + // return status.Error(codes.InvalidArgument, err.Error()) |
| 30 | + // } |
| 31 | + // _, err = gr.Client.KV.Put(ctx, target+"/"+nm.Addr, string(v), opts...) |
| 32 | + //case internal.Delete: |
| 33 | + // _, err = gr.Client.Delete(ctx, target+"/"+nm.Addr, opts...) |
| 34 | + //default: |
| 35 | + // return status.Error(codes.InvalidArgument, "naming: bad naming op") |
| 36 | + } |
| 37 | + return fmt.Errorf("Not implemented yet") |
| 38 | +} |
| 39 | + |
| 40 | +func (m *endpointManager) AddEndpoint(ctx context.Context, key string, endpoint Endpoint, opts ...clientv3.OpOption) error { |
| 41 | + return m.Update(ctx, []*UpdateWithOpts{NewAddUpdateOpts(key, endpoint, opts...)}) |
| 42 | +} |
| 43 | + |
| 44 | +func (m *endpointManager) DeleteEndpoint(ctx context.Context, key string, opts ...clientv3.OpOption) error { |
| 45 | + return m.Update(ctx, []*UpdateWithOpts{NewDeleteUpdateOpts(key, opts...)}) |
| 46 | +} |
| 47 | + |
| 48 | +func (m *endpointManager) NewWatchChannel(ctx context.Context) (WatchChannel, error) { |
| 49 | + return nil, fmt.Errorf("Not implemented yet") |
| 50 | + |
| 51 | + // TODO: Implementation to be inspired by: |
| 52 | + // Next gets the next set of updates from the etcd resolver. |
| 53 | + //// Calls to Next should be serialized; concurrent calls are not safe since |
| 54 | + //// there is no way to reconcile the update ordering. |
| 55 | + //func (gw *gRPCWatcher) Next() ([]*naming.Update, error) { |
| 56 | + // if gw.wch == nil { |
| 57 | + // // first Next() returns all addresses |
| 58 | + // return gw.firstNext() |
| 59 | + // } |
| 60 | + // if gw.err != nil { |
| 61 | + // return nil, gw.err |
| 62 | + // } |
| 63 | + // |
| 64 | + // // process new events on target/* |
| 65 | + // wr, ok := <-gw.wch |
| 66 | + // if !ok { |
| 67 | + // gw.err = status.Error(codes.Unavailable, ErrWatcherClosed.Error()) |
| 68 | + // return nil, gw.err |
| 69 | + // } |
| 70 | + // if gw.err = wr.Err(); gw.err != nil { |
| 71 | + // return nil, gw.err |
| 72 | + // } |
| 73 | + // |
| 74 | + // updates := make([]*naming.Update, 0, len(wr.Events)) |
| 75 | + // for _, e := range wr.Events { |
| 76 | + // var jupdate naming.Update |
| 77 | + // var err error |
| 78 | + // switch e.Type { |
| 79 | + // case etcd.EventTypePut: |
| 80 | + // err = json.Unmarshal(e.Kv.Value, &jupdate) |
| 81 | + // jupdate.Op = naming.Add |
| 82 | + // case etcd.EventTypeDelete: |
| 83 | + // err = json.Unmarshal(e.PrevKv.Value, &jupdate) |
| 84 | + // jupdate.Op = naming.Delete |
| 85 | + // default: |
| 86 | + // continue |
| 87 | + // } |
| 88 | + // if err == nil { |
| 89 | + // updates = append(updates, &jupdate) |
| 90 | + // } |
| 91 | + // } |
| 92 | + // return updates, nil |
| 93 | + //} |
| 94 | + // |
| 95 | + //func (gw *gRPCWatcher) firstNext() ([]*naming.Update, error) { |
| 96 | + // // Use serialized request so resolution still works if the target etcd |
| 97 | + // // server is partitioned away from the quorum. |
| 98 | + // resp, err := gw.c.Get(gw.ctx, gw.target, etcd.WithPrefix(), etcd.WithSerializable()) |
| 99 | + // if gw.err = err; err != nil { |
| 100 | + // return nil, err |
| 101 | + // } |
| 102 | + // |
| 103 | + // updates := make([]*naming.Update, 0, len(resp.Kvs)) |
| 104 | + // for _, kv := range resp.Kvs { |
| 105 | + // var jupdate naming.Update |
| 106 | + // if err := json.Unmarshal(kv.Value, &jupdate); err != nil { |
| 107 | + // continue |
| 108 | + // } |
| 109 | + // updates = append(updates, &jupdate) |
| 110 | + // } |
| 111 | + // |
| 112 | + // opts := []etcd.OpOption{etcd.WithRev(resp.Header.Revision + 1), etcd.WithPrefix(), etcd.WithPrevKV()} |
| 113 | + // gw.wch = gw.c.Watch(gw.ctx, gw.target, opts...) |
| 114 | + // return updates, nil |
| 115 | + //} |
| 116 | +} |
| 117 | + |
| 118 | +func (m *endpointManager) List(ctx context.Context) (Key2EndpointMap, error) { |
| 119 | + // TODO: Implementation |
| 120 | + return nil, fmt.Errorf("Not implemented yet") |
| 121 | +} |
0 commit comments