github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/cdc/model/http_model.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 model 15 16 import ( 17 "encoding/json" 18 "sync/atomic" 19 "time" 20 21 "github.com/pingcap/tiflow/pkg/config" 22 cerror "github.com/pingcap/tiflow/pkg/errors" 23 ) 24 25 const timeFormat = `"2006-01-02 15:04:05.000"` 26 27 // JSONTime used to wrap time into json format 28 type JSONTime time.Time 29 30 // MarshalJSON used to specify the time format 31 func (t JSONTime) MarshalJSON() ([]byte, error) { 32 stamp := time.Time(t).Format(timeFormat) 33 return []byte(stamp), nil 34 } 35 36 // UnmarshalJSON is used to parse time.Time from bytes. The builtin json.Unmarshal function cannot unmarshal 37 // a date string formatted as "2006-01-02 15:04:05.000", so we must implement a customized unmarshal function. 38 func (t *JSONTime) UnmarshalJSON(data []byte) error { 39 tm, err := time.Parse(timeFormat, string(data)) 40 if err != nil { 41 return err 42 } 43 44 *t = JSONTime(tm) 45 return nil 46 } 47 48 // HTTPError of cdc http api 49 type HTTPError struct { 50 Error string `json:"error_msg"` 51 Code string `json:"error_code"` 52 } 53 54 // NewHTTPError wrap a err into HTTPError 55 func NewHTTPError(err error) HTTPError { 56 errCode, _ := cerror.RFCCode(err) 57 return HTTPError{ 58 Error: err.Error(), 59 Code: string(errCode), 60 } 61 } 62 63 // Liveness is the liveness status of a capture. 64 // Liveness can only be changed from alive to stopping, and no way back. 65 type Liveness int32 66 67 const ( 68 // LivenessCaptureAlive means the capture is alive, and ready to serve. 69 LivenessCaptureAlive Liveness = 0 70 // LivenessCaptureStopping means the capture is in the process of graceful shutdown. 71 LivenessCaptureStopping Liveness = 1 72 ) 73 74 // Store the given liveness. Returns true if it success. 75 func (l *Liveness) Store(v Liveness) bool { 76 return atomic.CompareAndSwapInt32( 77 (*int32)(l), int32(LivenessCaptureAlive), int32(v)) 78 } 79 80 // Load the liveness. 81 func (l *Liveness) Load() Liveness { 82 return Liveness(atomic.LoadInt32((*int32)(l))) 83 } 84 85 func (l *Liveness) String() string { 86 switch *l { 87 case LivenessCaptureAlive: 88 return "Alive" 89 case LivenessCaptureStopping: 90 return "Stopping" 91 default: 92 return "unknown" 93 } 94 } 95 96 // ServerStatus holds some common information of a server 97 type ServerStatus struct { 98 Version string `json:"version"` 99 GitHash string `json:"git_hash"` 100 ID string `json:"id"` 101 ClusterID string `json:"cluster_id"` 102 Pid int `json:"pid"` 103 IsOwner bool `json:"is_owner"` 104 Liveness Liveness `json:"liveness"` 105 } 106 107 // ChangefeedCommonInfo holds some common usage information of a changefeed 108 type ChangefeedCommonInfo struct { 109 UpstreamID uint64 `json:"upstream_id"` 110 Namespace string `json:"namespace"` 111 ID string `json:"id"` 112 FeedState FeedState `json:"state"` 113 CheckpointTSO uint64 `json:"checkpoint_tso"` 114 CheckpointTime JSONTime `json:"checkpoint_time"` 115 RunningError *RunningError `json:"error"` 116 } 117 118 // MarshalJSON use to marshal ChangefeedCommonInfo 119 func (c ChangefeedCommonInfo) MarshalJSON() ([]byte, error) { 120 // alias the original type to prevent recursive call of MarshalJSON 121 type Alias ChangefeedCommonInfo 122 if c.FeedState == StateNormal { 123 c.RunningError = nil 124 } 125 return json.Marshal(struct { 126 Alias 127 }{ 128 Alias: Alias(c), 129 }) 130 } 131 132 // ChangefeedDetail holds detail info of a changefeed 133 type ChangefeedDetail struct { 134 UpstreamID uint64 `json:"upstream_id"` 135 Namespace string `json:"namespace"` 136 ID string `json:"id"` 137 SinkURI string `json:"sink_uri"` 138 CreateTime JSONTime `json:"create_time"` 139 StartTs uint64 `json:"start_ts"` 140 ResolvedTs uint64 `json:"resolved_ts"` 141 TargetTs uint64 `json:"target_ts"` 142 CheckpointTSO uint64 `json:"checkpoint_tso"` 143 CheckpointTime JSONTime `json:"checkpoint_time"` 144 Engine SortEngine `json:"sort_engine,omitempty"` 145 FeedState FeedState `json:"state"` 146 RunningError *RunningError `json:"error"` 147 ErrorHis []int64 `json:"error_history"` 148 CreatorVersion string `json:"creator_version"` 149 TaskStatus []CaptureTaskStatus `json:"task_status,omitempty"` 150 } 151 152 // MarshalJSON use to marshal ChangefeedDetail 153 func (c ChangefeedDetail) MarshalJSON() ([]byte, error) { 154 // alias the original type to prevent recursive call of MarshalJSON 155 type Alias ChangefeedDetail 156 if c.FeedState == StateNormal { 157 c.RunningError = nil 158 } 159 return json.Marshal(struct { 160 Alias 161 }{ 162 Alias: Alias(c), 163 }) 164 } 165 166 // ChangefeedConfig use to create a changefeed 167 type ChangefeedConfig struct { 168 Namespace string `json:"namespace"` 169 ID string `json:"changefeed_id"` 170 StartTS uint64 `json:"start_ts"` 171 TargetTS uint64 `json:"target_ts"` 172 SinkURI string `json:"sink_uri"` 173 // timezone used when checking sink uri 174 TimeZone string `json:"timezone" default:"system"` 175 // if true, force to replicate some ineligible tables 176 ForceReplicate bool `json:"force_replicate" default:"false"` 177 IgnoreIneligibleTable bool `json:"ignore_ineligible_table" default:"false"` 178 FilterRules []string `json:"filter_rules"` 179 IgnoreTxnStartTs []uint64 `json:"ignore_txn_start_ts"` 180 MounterWorkerNum int `json:"mounter_worker_num" default:"16"` 181 SinkConfig *config.SinkConfig `json:"sink_config"` 182 } 183 184 // ProcessorCommonInfo holds the common info of a processor 185 type ProcessorCommonInfo struct { 186 Namespace string `json:"namespace"` 187 CfID string `json:"changefeed_id"` 188 CaptureID string `json:"capture_id"` 189 } 190 191 // ProcessorDetail holds the detail info of a processor 192 type ProcessorDetail struct { 193 // All table ids that this processor are replicating. 194 Tables []int64 `json:"table_ids"` 195 } 196 197 // CaptureTaskStatus holds TaskStatus of a capture 198 type CaptureTaskStatus struct { 199 CaptureID string `json:"capture_id"` 200 // Table list, containing tables that processor should process 201 Tables []int64 `json:"table_ids,omitempty"` 202 Operation map[TableID]*TableOperation `json:"table_operations,omitempty"` 203 } 204 205 // Capture holds common information of a capture in cdc 206 type Capture struct { 207 ID string `json:"id"` 208 IsOwner bool `json:"is_owner"` 209 AdvertiseAddr string `json:"address"` 210 ClusterID string `json:"cluster_id"` 211 } 212 213 // DrainCaptureRequest is request for manual `DrainCapture` 214 type DrainCaptureRequest struct { 215 CaptureID string `json:"capture_id"` 216 } 217 218 // DrainCaptureResp is response for manual `DrainCapture` 219 type DrainCaptureResp struct { 220 CurrentTableCount int `json:"current_table_count"` 221 } 222 223 // MoveTableReq is the request for `MoveTable` 224 type MoveTableReq struct { 225 CaptureID string `json:"capture_id"` 226 TableID int64 `json:"table_id"` 227 }