github.com/pingcap/ticdc@v0.0.0-20220526033649-485a10ef2652/pkg/etcd/etcdkey.go (about) 1 // Copyright 2021 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package etcd 15 16 import ( 17 "log" 18 "strings" 19 20 cerror "github.com/pingcap/ticdc/pkg/errors" 21 ) 22 23 const ( 24 etcdKeyBase = "/tidb/cdc" 25 ownerKey = "/owner" 26 captureKey = "/capture" 27 28 taskKey = "/task" 29 taskWorkloadKey = taskKey + "/workload" 30 taskStatusKey = taskKey + "/status" 31 taskPositionKey = taskKey + "/position" 32 33 changefeedInfoKey = "/changefeed/info" 34 jobKey = "/job" 35 ) 36 37 // CDCKeyType is the type of etcd key 38 type CDCKeyType = int 39 40 // the types of etcd key 41 const ( 42 CDCKeyTypeUnknown CDCKeyType = iota 43 CDCKeyTypeOwner 44 CDCKeyTypeCapture 45 CDCKeyTypeChangefeedInfo 46 CDCKeyTypeChangeFeedStatus 47 CDCKeyTypeTaskPosition 48 CDCKeyTypeTaskStatus 49 CDCKeyTypeTaskWorkload 50 ) 51 52 // CDCKey represents a etcd key which is defined by TiCDC 53 /* 54 Usage: 55 we can parse a raw etcd key: 56 ``` 57 k := new(CDCKey) 58 rawKey := "/tidb/cdc/changefeed/info/test/changefeed" 59 err := k.Parse(rawKey) 60 c.Assert(k, check.DeepEquals, &CDCKey{ 61 Tp: CDCKeyTypeChangefeedInfo, 62 ChangefeedID: "test/changefeed", 63 }) 64 ``` 65 66 and we can generate a raw key from CDCKey 67 ``` 68 k := &CDCKey{ 69 Tp: CDCKeyTypeChangefeedInfo, 70 ChangefeedID: "test/changefeed", 71 } 72 c.Assert(k.String(), check.Equals, "/tidb/cdc/changefeed/info/test/changefeed") 73 ``` 74 75 */ 76 type CDCKey struct { 77 Tp CDCKeyType 78 ChangefeedID string 79 CaptureID string 80 OwnerLeaseID string 81 } 82 83 // Parse parses the given etcd key 84 func (k *CDCKey) Parse(key string) error { 85 if !strings.HasPrefix(key, etcdKeyBase) { 86 return cerror.ErrInvalidEtcdKey.GenWithStackByArgs(key) 87 } 88 key = key[len(etcdKeyBase):] 89 switch { 90 case strings.HasPrefix(key, ownerKey): 91 k.Tp = CDCKeyTypeOwner 92 k.CaptureID = "" 93 k.ChangefeedID = "" 94 key = key[len(ownerKey):] 95 if len(key) > 0 { 96 key = key[1:] 97 } 98 k.OwnerLeaseID = key 99 case strings.HasPrefix(key, captureKey): 100 k.Tp = CDCKeyTypeCapture 101 k.CaptureID = key[len(captureKey)+1:] 102 k.ChangefeedID = "" 103 k.OwnerLeaseID = "" 104 case strings.HasPrefix(key, changefeedInfoKey): 105 k.Tp = CDCKeyTypeChangefeedInfo 106 k.CaptureID = "" 107 k.ChangefeedID = key[len(changefeedInfoKey)+1:] 108 k.OwnerLeaseID = "" 109 case strings.HasPrefix(key, jobKey): 110 k.Tp = CDCKeyTypeChangeFeedStatus 111 k.CaptureID = "" 112 k.ChangefeedID = key[len(jobKey)+1:] 113 k.OwnerLeaseID = "" 114 case strings.HasPrefix(key, taskStatusKey): 115 splitKey := strings.SplitN(key[len(taskStatusKey)+1:], "/", 2) 116 if len(splitKey) != 2 { 117 return cerror.ErrInvalidEtcdKey.GenWithStackByArgs(key) 118 } 119 k.Tp = CDCKeyTypeTaskStatus 120 k.CaptureID = splitKey[0] 121 k.ChangefeedID = splitKey[1] 122 k.OwnerLeaseID = "" 123 case strings.HasPrefix(key, taskPositionKey): 124 splitKey := strings.SplitN(key[len(taskPositionKey)+1:], "/", 2) 125 if len(splitKey) != 2 { 126 return cerror.ErrInvalidEtcdKey.GenWithStackByArgs(key) 127 } 128 k.Tp = CDCKeyTypeTaskPosition 129 k.CaptureID = splitKey[0] 130 k.ChangefeedID = splitKey[1] 131 k.OwnerLeaseID = "" 132 case strings.HasPrefix(key, taskWorkloadKey): 133 splitKey := strings.SplitN(key[len(taskWorkloadKey)+1:], "/", 2) 134 if len(splitKey) != 2 { 135 return cerror.ErrInvalidEtcdKey.GenWithStackByArgs(key) 136 } 137 k.Tp = CDCKeyTypeTaskWorkload 138 k.CaptureID = splitKey[0] 139 k.ChangefeedID = splitKey[1] 140 k.OwnerLeaseID = "" 141 default: 142 return cerror.ErrInvalidEtcdKey.GenWithStackByArgs(key) 143 } 144 return nil 145 } 146 147 func (k *CDCKey) String() string { 148 switch k.Tp { 149 case CDCKeyTypeOwner: 150 if len(k.OwnerLeaseID) == 0 { 151 return etcdKeyBase + ownerKey 152 } 153 return etcdKeyBase + ownerKey + "/" + k.OwnerLeaseID 154 case CDCKeyTypeCapture: 155 return etcdKeyBase + captureKey + "/" + k.CaptureID 156 case CDCKeyTypeChangefeedInfo: 157 return etcdKeyBase + changefeedInfoKey + "/" + k.ChangefeedID 158 case CDCKeyTypeChangeFeedStatus: 159 return etcdKeyBase + jobKey + "/" + k.ChangefeedID 160 case CDCKeyTypeTaskPosition: 161 return etcdKeyBase + taskPositionKey + "/" + k.CaptureID + "/" + k.ChangefeedID 162 case CDCKeyTypeTaskStatus: 163 return etcdKeyBase + taskStatusKey + "/" + k.CaptureID + "/" + k.ChangefeedID 164 case CDCKeyTypeTaskWorkload: 165 return etcdKeyBase + taskWorkloadKey + "/" + k.CaptureID + "/" + k.ChangefeedID 166 } 167 log.Panic("unreachable") 168 return "" 169 }