github.com/matrixorigin/matrixone@v1.2.0/pkg/stream/connector/options.go (about)

     1  // Copyright 2021 - 2023 Matrix Origin
     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  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package moconnector
    16  
    17  import (
    18  	"context"
    19  	"strconv"
    20  	"strings"
    21  
    22  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    23  )
    24  
    25  const (
    26  	SourceKafka string = "kafka"
    27  	FormatJson  string = "json"
    28  )
    29  
    30  type StmtOpts map[string]string
    31  
    32  type OptType uint16
    33  
    34  const (
    35  	OptTypeString OptType = iota
    36  	OptTypeEnum
    37  	OptTypeInteger
    38  	OptTypeAddress
    39  )
    40  
    41  type OptValidator func(string) bool
    42  
    43  type OptConstraint struct {
    44  	Type      OptType
    45  	Validator OptValidator
    46  }
    47  
    48  var (
    49  	stringOpt = OptConstraint{
    50  		Type: OptTypeString,
    51  		Validator: func(s string) bool {
    52  			return len(s) > 0
    53  		},
    54  	}
    55  
    56  	addressOpt = OptConstraint{
    57  		Type: OptTypeAddress,
    58  		Validator: func(s string) bool {
    59  			ss := strings.Split(s, ":")
    60  			if len(ss) != 2 || len(ss[0]) == 0 || len(ss[1]) == 0 {
    61  				return false
    62  			}
    63  			_, err := strconv.Atoi(ss[1])
    64  			return err == nil
    65  		},
    66  	}
    67  
    68  	integerOpt = OptConstraint{
    69  		Type: OptTypeInteger,
    70  		Validator: func(s string) bool {
    71  			_, err := strconv.Atoi(s)
    72  			return err == nil
    73  		},
    74  	}
    75  )
    76  
    77  func enumOpt(items ...string) OptConstraint {
    78  	tc := OptConstraint{
    79  		Type: OptTypeEnum,
    80  		Validator: func(s string) bool {
    81  			for _, item := range items {
    82  				if item == s {
    83  					return true
    84  				}
    85  			}
    86  			return false
    87  		},
    88  	}
    89  	return tc
    90  }
    91  
    92  const (
    93  	OptConnectorType    = "type"
    94  	OptConnectorServers = "bootstrap.servers"
    95  	OptConnectorTopic   = "topic"
    96  	OptConnectorValue   = "value"
    97  
    98  	OptConnectorSql = "sql"
    99  
   100  	OptConnectorRel       = "relkind"
   101  	OptConnectorPartition = "partition"
   102  
   103  	OptConnectorBufferLimit = "buffer_limit"
   104  	OptConnectorTimeWindow  = "time_window"
   105  )
   106  
   107  var ConnectorOptConstraint = map[string]OptConstraint{
   108  	OptConnectorType:        enumOpt(SourceKafka),
   109  	OptConnectorServers:     addressOpt,
   110  	OptConnectorTopic:       stringOpt,
   111  	OptConnectorValue:       enumOpt(FormatJson),
   112  	OptConnectorSql:         stringOpt,
   113  	OptConnectorRel:         stringOpt,
   114  	OptConnectorPartition:   integerOpt,
   115  	OptConnectorBufferLimit: integerOpt,
   116  	OptConnectorTimeWindow:  integerOpt,
   117  }
   118  
   119  var ConnectorEssentialOpts = map[string]struct{}{
   120  	OptConnectorType: {},
   121  }
   122  
   123  var ConnectorEssentialTypeOpts = map[string]map[string]struct{}{
   124  	"kafka": {
   125  		OptConnectorServers: {},
   126  		OptConnectorTopic:   {},
   127  		OptConnectorValue:   {},
   128  	},
   129  }
   130  
   131  func MakeStmtOpts(ctx context.Context, opts map[string]string) (StmtOpts, error) {
   132  	if opts == nil {
   133  		return StmtOpts{}, nil
   134  	}
   135  	for key := range ConnectorEssentialOpts {
   136  		_, ok := opts[key]
   137  		if !ok {
   138  			return StmtOpts{}, moerr.NewErrLackOption(ctx, key)
   139  		}
   140  	}
   141  	mapCopy := make(StmtOpts, len(opts))
   142  	for key, value := range opts {
   143  		optConstraint, ok := ConnectorOptConstraint[key]
   144  		if !ok {
   145  			return StmtOpts{}, moerr.NewErrUnsupportedOption(ctx, key)
   146  		}
   147  		if optConstraint.Validator != nil && !optConstraint.Validator(value) {
   148  			return StmtOpts{}, moerr.NewErrInvalidValue(ctx, key, value)
   149  		}
   150  		mapCopy[key] = value
   151  	}
   152  	fields := ConnectorEssentialTypeOpts[opts[OptConnectorType]]
   153  	for field := range fields {
   154  		if _, ok := opts[field]; !ok {
   155  			return StmtOpts{}, moerr.NewErrLackOption(ctx, field)
   156  		}
   157  	}
   158  	return mapCopy, nil
   159  }