github.com/matrixorigin/matrixone@v0.7.0/pkg/fileservice/get.go (about) 1 // Copyright 2022 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 fileservice 16 17 import ( 18 "path/filepath" 19 "strings" 20 21 "github.com/matrixorigin/matrixone/pkg/common/moerr" 22 ) 23 24 func Get[T any](fs FileService, name string) (res T, err error) { 25 lowerName := strings.ToLower(name) 26 if fs, ok := fs.(*FileServices); ok { 27 f, ok := fs.mappings[lowerName] 28 if !ok { 29 err = moerr.NewNoServiceNoCtx(name) 30 return 31 } 32 res, ok = f.(T) 33 if !ok { 34 err = moerr.NewNoServiceNoCtx(name) 35 return 36 } 37 return 38 } 39 var ok bool 40 res, ok = fs.(T) 41 if !ok { 42 err = moerr.NewNoServiceNoCtx(name) 43 return 44 } 45 if !strings.EqualFold(fs.Name(), lowerName) { 46 err = moerr.NewNoServiceNoCtx(name) 47 return 48 } 49 return 50 } 51 52 // GetForETL get or creates a FileService instance for ETL operations 53 // if service part of path is empty, a LocalETLFS will be created 54 // if service part of path is not empty, a ETLFileService typed instance will be extracted from fs argument 55 // if service part of path is argumented, a FileService instance will be created dynamically with those arguments 56 // supported dynamic file service: 57 // s3,<endpoint>,<region>,<bucket>,<key>,<secret>,<prefix> 58 // s3-no-key,<endpoint>,<region>,<bucket>,<prefix> 59 // minio,<endpoint>,<region>,<bucket>,<key>,<secret>,<prefix> 60 // s3-opts,endpoint=<endpoint>,region=<region>,bucket=<bucket>,key=<key>,secret=<secret>,prefix=<prefix>,role-arn=<role arn>,external-id=<external id> 61 // 62 // key value pairs can be in any order 63 func GetForETL(fs FileService, path string) (res ETLFileService, readPath string, err error) { 64 fsPath, err := ParsePath(path) 65 if err != nil { 66 return nil, "", err 67 } 68 69 if fsPath.Service == "" { 70 // no service, create local ETL fs 71 dir, file := filepath.Split(path) 72 res, err = NewLocalETLFS("etl", dir) 73 if err != nil { 74 return nil, "", err 75 } 76 readPath = file 77 78 } else if len(fsPath.ServiceArguments) > 0 { 79 // service with arguments, create dynamically 80 switch fsPath.Service { 81 82 case "s3": 83 arguments := fsPath.ServiceArguments 84 if len(arguments) < 6 { 85 return nil, "", moerr.NewInvalidInputNoCtx("invalid S3 arguments") 86 } 87 endpoint := arguments[0] 88 region := arguments[1] 89 bucket := arguments[2] 90 accessKey := arguments[3] 91 accessSecret := arguments[4] 92 keyPrefix := arguments[5] 93 var name string 94 if len(arguments) > 6 { 95 name = arguments[6] 96 } 97 res, err = newS3FS([]string{ 98 "endpoint=" + endpoint, 99 "region=" + region, 100 "bucket=" + bucket, 101 "key=" + accessKey, 102 "secret=" + accessSecret, 103 "prefix=" + keyPrefix, 104 "name=" + name, 105 }) 106 if err != nil { 107 return 108 } 109 110 case "s3-no-key": 111 arguments := fsPath.ServiceArguments 112 if len(arguments) < 4 { 113 return nil, "", moerr.NewInvalidInputNoCtx("invalid S3 arguments") 114 } 115 endpoint := arguments[0] 116 region := arguments[1] 117 bucket := arguments[2] 118 keyPrefix := arguments[3] 119 var name string 120 if len(arguments) > 4 { 121 name = arguments[4] 122 } 123 res, err = newS3FS([]string{ 124 "endpoint=" + endpoint, 125 "region=" + region, 126 "bucket=" + bucket, 127 "prefix=" + keyPrefix, 128 "name=" + name, 129 }) 130 if err != nil { 131 return 132 } 133 134 case "s3-opts": 135 res, err = newS3FS(fsPath.ServiceArguments) 136 if err != nil { 137 return 138 } 139 140 case "minio": 141 arguments := fsPath.ServiceArguments 142 if len(arguments) < 6 { 143 return nil, "", moerr.NewInvalidInputNoCtx("invalid S3 arguments") 144 } 145 endpoint := arguments[0] 146 region := arguments[1] 147 _ = region 148 bucket := arguments[2] 149 accessKey := arguments[3] 150 accessSecret := arguments[4] 151 keyPrefix := arguments[5] 152 var name string 153 if len(arguments) > 6 { 154 name = arguments[6] 155 } 156 res, err = newS3FS([]string{ 157 "endpoint=" + endpoint, 158 "region=" + region, 159 "bucket=" + bucket, 160 "prefix=" + keyPrefix, 161 "name=" + name, 162 "key=" + accessKey, 163 "secret=" + accessSecret, 164 "is-minio=true", 165 }) 166 if err != nil { 167 return 168 } 169 170 default: 171 err = moerr.NewInvalidInputNoCtx("no such service: %s", fsPath.Service) 172 } 173 174 readPath = fsPath.File 175 176 } else { 177 // get etl fs 178 res, err = Get[ETLFileService](fs, fsPath.Service) 179 if err != nil { 180 return nil, "", err 181 } 182 readPath = path 183 } 184 185 return 186 }