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  }