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  }