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 }