@@ -39,7 +39,7 @@ type MultipartPresignedURL struct {
3939 PartNumber int `json:"partNumber"`
4040}
4141
42- type CompleteMultipartUpload struct {
42+ type CompleteMultipartUploadRequest struct {
4343 UploadID string `json:"UploadID"`
4444 ObjectName string `json:"objectName"`
4545 PartList []Part `json:"partList"`
@@ -165,11 +165,7 @@ func NewUploadsHTTPWrapper(path string) UploadsWrapper {
165165}
166166
167167func (u * UploadsHTTPWrapper ) UploadFileInMultipart (sourcesFile string , featureFlagsWrapper FeatureFlagsWrapper ) (* string , error ) {
168- // calculate file size and compare with 5GB limit
169- fileInfo , err := os .Stat (sourcesFile )
170- if err != nil {
171- return nil , errors .Wrapf (err , "Failed to stat - %s" , sourcesFile )
172- }
168+ fileInfo , _ := os .Stat (sourcesFile )
173169
174170 startMultipartUploadRequest := StartMultipartUploadRequest {}
175171 startMultipartUploadRequest .FileSize = fileInfo .Size ()
@@ -182,14 +178,13 @@ func (u *UploadsHTTPWrapper) UploadFileInMultipart(sourcesFile string, featureFl
182178 return nil , errors .Errorf ("Failed to split ZIP file for multipart upload - %s" , err .Error ())
183179 }
184180
185- // ensure temporary parts are removed when this function returns
186181 defer cleanUpTempParts (partList )
187182
188183 for i , part := range partList {
189184 logger .PrintfIfVerbose ("Part%d created at: %s" , i + 1 , part )
190185 }
191186
192- completeMultipartUpload := & CompleteMultipartUpload {
187+ completeMultipartUploadRequest := & CompleteMultipartUploadRequest {
193188 UploadID : startMultipartUploadResponse .UploadID ,
194189 ObjectName : startMultipartUploadResponse .ObjectName ,
195190 }
@@ -199,64 +194,39 @@ func (u *UploadsHTTPWrapper) UploadFileInMultipart(sourcesFile string, featureFl
199194 for i , partPath := range partList {
200195 partNumber := i + 1
201196
202- // Generate presigned URL
203197 presignedURL , err := getPresignedURLForMultipartUploading (startMultipartUploadResponse , partNumber )
204198 if err != nil {
205- return nil , fmt .Errorf ("failed to get presigned URL for part%d - %s" , partNumber , err .Error ())
199+ return nil , errors .Errorf ("Failed to get presigned URL for part%d - %s" , partNumber , err .Error ())
206200 }
207201
208202 if partNumber == 1 {
209203 presignedURLPart1 = presignedURL
210204 }
211- // Upload part
205+
212206 etag , err := uploadPart (presignedURL , partPath , featureFlagsWrapper )
213207 if err != nil {
214- return nil , fmt .Errorf ("failed to upload part%d - %s" , partNumber , err .Error ())
208+ return nil , errors .Errorf ("Failed to upload part%d - %s" , partNumber , err .Error ())
215209 }
216210
217- // Append part info
218- completeMultipartUpload .PartList = append (completeMultipartUpload .PartList , Part {
211+ completeMultipartUploadRequest .PartList = append (completeMultipartUploadRequest .PartList , Part {
219212 ETag : etag ,
220213 PartNumber : partNumber ,
221214 })
222215 }
223216
224- // call the complete multipart upload API
225- clientTimeout := viper .GetUint (commonParams .ClientTimeoutKey )
226- path := viper .GetString (commonParams .CompleteMultipartUploadPathEnv )
227- jsonBytes , err := json .Marshal (completeMultipartUpload )
217+ err = completeMultipartUpload (* completeMultipartUploadRequest )
228218 if err != nil {
229- return nil , errors .Errorf ("Failed to marshal complete multipart upload request body - %s" , err .Error ())
230- }
231- resp , err := SendHTTPRequest (http .MethodPost , path , bytes .NewBuffer (jsonBytes ), true , clientTimeout )
232- if err != nil {
233- return nil , err
234- }
235- decoder := json .NewDecoder (resp .Body )
236- defer func () {
237- _ = resp .Body .Close ()
238- }()
239- switch resp .StatusCode {
240- case http .StatusNoContent :
241- return & presignedURLPart1 , nil
242- case http .StatusUnauthorized :
243- return nil , errors .New (errorConstants .StatusUnauthorized )
244- default :
245- errorModel := ErrorModel {}
246- err = decoder .Decode (& errorModel )
247- if err != nil {
248- return nil , errors .Errorf ("Parsing error model failed - %s" , err .Error ())
249- }
250- return nil , errors .Errorf ("%d - %s" , errorModel .Code , errorModel .Message )
219+ return nil , errors .Errorf ("Failed to complete multipart upload - %s" , err .Error ())
251220 }
221+ return & presignedURLPart1 , nil
252222}
253223
254224func startMultipartUpload (startMultipartUploadRequest StartMultipartUploadRequest ) (StartMultipartUploadResponse , error ) {
255225 clientTimeout := viper .GetUint (commonParams .ClientTimeoutKey )
256226 path := viper .GetString (commonParams .StartMultiPartUploadPathEnv )
257227 jsonBytes , err := json .Marshal (startMultipartUploadRequest )
258228 if err != nil {
259- return StartMultipartUploadResponse {}, errors . Errorf ( "Failed to marshal start multipart upload request body - %s" , err . Error ())
229+ return StartMultipartUploadResponse {}, err
260230 }
261231 resp , err := SendHTTPRequest (http .MethodPost , path , bytes .NewBuffer (jsonBytes ), true , clientTimeout )
262232 if err != nil {
@@ -271,20 +241,20 @@ func startMultipartUpload(startMultipartUploadRequest StartMultipartUploadReques
271241 startMultipartUpload := StartMultipartUploadResponse {}
272242 err = decoder .Decode (& startMultipartUpload )
273243 if err != nil {
274- return StartMultipartUploadResponse {}, errors . Errorf ( "failed to start the multipart upload - %s " , err . Error ())
244+ return StartMultipartUploadResponse {}, err
275245 }
276246 return startMultipartUpload , nil
277247 case http .StatusBadRequest :
278248 errorModel := ErrorModel {}
279249 err = decoder .Decode (& errorModel )
280250 if err != nil {
281- return StartMultipartUploadResponse {}, errors . Errorf ( "failed to start the multipart upload - %s " , err . Error ())
251+ return StartMultipartUploadResponse {}, err
282252 }
283253 return StartMultipartUploadResponse {}, errors .Errorf (errorModel .Message )
284254 case http .StatusUnauthorized :
285255 return StartMultipartUploadResponse {}, errors .New (errorConstants .StatusUnauthorized )
286256 default :
287- return StartMultipartUploadResponse {}, errors .Errorf ("response status code %d" , resp .StatusCode )
257+ return StartMultipartUploadResponse {}, errors .Errorf ("Response status code %d" , resp .StatusCode )
288258 }
289259}
290260
@@ -299,14 +269,13 @@ func getPresignedURLForMultipartUploading(response StartMultipartUploadResponse,
299269 }
300270 jsonBytes , err := json .Marshal (multipartPresignedURL )
301271 if err != nil {
302- return "" , errors . Errorf ( "Failed to marshal multipart upload presigned URL request body - %s" , err . Error ())
272+ return "" , err
303273 }
304274
305275 resp , err := SendHTTPRequest (http .MethodPost , path , bytes .NewBuffer (jsonBytes ), true , clientTimeout )
306276 if err != nil {
307- return "" , errors . Errorf ( "Invoking HTTP request to get pre-signed URL failed - %s" , err . Error ())
277+ return "" , err
308278 }
309-
310279 defer func () {
311280 _ = resp .Body .Close ()
312281 }()
@@ -318,33 +287,32 @@ func getPresignedURLForMultipartUploading(response StartMultipartUploadResponse,
318287 errorModel := ErrorModel {}
319288 err = decoder .Decode (& errorModel )
320289 if err != nil {
321- return "" , errors . Errorf ( "Parsing error model failed - %s" , err . Error ())
290+ return "" , err
322291 }
323292 return "" , errors .Errorf ("%d - %s" , errorModel .Code , errorModel .Message )
324293
325294 case http .StatusOK :
326295 model := UploadModelMultipart {}
327296 err = decoder .Decode (& model )
328297 if err != nil {
329- return "" , errors . Errorf ( "Parsing upload model failed - %s" , err . Error ())
298+ return "" , err
330299 }
331300 return model .PresignedURL , nil
332301
333302 default :
334- return "" , errors .Errorf ("response status code %d" , resp .StatusCode )
303+ return "" , errors .Errorf ("Response status code %d" , resp .StatusCode )
335304 }
336305}
337306
338307func uploadPart (preSignedURL , sourcesFile string , featureFlagsWrapper FeatureFlagsWrapper ) (string , error ) {
339308 if preSignedURL == "" {
340- return "" , errors .New ("preSignedURL is empty or nil" )
309+ return "" , errors .New ("PreSignedURL is empty or nil" )
341310 }
342311
343312 file , err := os .Open (sourcesFile )
344313 if err != nil {
345- return "" , errors . Errorf ( "Failed to open file for multipart upload %s - %s" , sourcesFile , err . Error ())
314+ return "" , err
346315 }
347- // Close the file later
348316 defer func () {
349317 _ = file .Close ()
350318 }()
@@ -356,13 +324,13 @@ func uploadPart(preSignedURL, sourcesFile string, featureFlagsWrapper FeatureFla
356324
357325 stat , err := file .Stat ()
358326 if err != nil {
359- return "" , errors . Errorf ( "Failed to stat file %s - %s" , sourcesFile , err . Error ())
327+ return "" , err
360328 }
361329 flagResponse , _ := GetSpecificFeatureFlag (featureFlagsWrapper , MinioEnabled )
362330 useAccessToken := flagResponse .Status
363331 resp , err := SendHTTPRequestByFullURLContentLength (http .MethodPut , preSignedURL , file , stat .Size (), useAccessToken , NoTimeout , accessToken , true )
364332 if err != nil {
365- return "" , errors . Errorf ( "Invoking HTTP request to upload file failed - %s" , err . Error ())
333+ return "" , err
366334 }
367335
368336 defer func () {
@@ -380,28 +348,58 @@ func uploadPart(preSignedURL, sourcesFile string, featureFlagsWrapper FeatureFla
380348 _ = resp .Body .Close ()
381349 }()
382350 if err != nil {
383- return "" , errors . Errorf ( "Reading response body failed - %s" , err . Error ())
351+ return "" , err
384352 }
385353 return "" , errors .Errorf ("Bad request while uploading part - %s" , string (body ))
386354 default :
387- return "" , errors .Errorf ("Failed to upload part of multipart - %d" , resp .StatusCode )
355+ return "" , errors .Errorf ("Response status code %d" , resp .StatusCode )
356+ }
357+ }
358+
359+ func completeMultipartUpload (completeMultipartUploadRequest CompleteMultipartUploadRequest ) error {
360+ clientTimeout := viper .GetUint (commonParams .ClientTimeoutKey )
361+ path := viper .GetString (commonParams .CompleteMultipartUploadPathEnv )
362+ jsonBytes , err := json .Marshal (completeMultipartUploadRequest )
363+ if err != nil {
364+ return err
365+ }
366+ resp , err := SendHTTPRequest (http .MethodPost , path , bytes .NewBuffer (jsonBytes ), true , clientTimeout )
367+ if err != nil {
368+ return err
369+ }
370+ decoder := json .NewDecoder (resp .Body )
371+ defer func () {
372+ _ = resp .Body .Close ()
373+ }()
374+ switch resp .StatusCode {
375+ case http .StatusNoContent :
376+ return nil
377+ case http .StatusUnauthorized :
378+ return errors .New (errorConstants .StatusUnauthorized )
379+ default :
380+ errorModel := ErrorModel {}
381+ err = decoder .Decode (& errorModel )
382+ if err != nil {
383+ return err
384+ }
385+ return errors .Errorf ("%d - %s" , errorModel .Code , errorModel .Message )
388386 }
389387}
390388
391389func SplitZipBySizeGB (zipFilePath string ) ([]string , error ) {
392390 partSizeBytes := getPartSizeBytes ()
393391 f , err := os .Open (zipFilePath )
394392 if err != nil {
395- return nil , fmt . Errorf ( "open input - %w" , err )
393+ return nil , err
396394 }
397395 defer closeFileVerbose (f )
398396
399397 stat , err := f .Stat ()
400398 if err != nil {
401- return nil , fmt . Errorf ( "stat input - %w" , err )
399+ return nil , err
402400 }
403401 if stat .Size () == 0 {
404- return nil , fmt . Errorf ( "input file is empty" )
402+ return nil , err
405403 }
406404
407405 partSizes := calculatePartSizes (stat .Size (), partSizeBytes )
@@ -415,19 +413,14 @@ func SplitZipBySizeGB(zipFilePath string) ([]string, error) {
415413}
416414
417415func getPartSizeBytes () int64 {
418- // Get part size in GB from config if config is not provided, default to 2 GB
419416 partChunkSizeStr := viper .GetString (commonParams .MultipartFileSizeKey )
420417 partChunkSizeFloat , err := strconv .ParseFloat (partChunkSizeStr , 64 )
421- // If parsing fails or value is empty, default to 2 GB
422418 if err != nil {
423419 logger .PrintIfVerbose (fmt .Sprintf ("Configured part size '%s' is invalid or empty. Defaulting to 2 GB." , partChunkSizeStr ))
424420 partChunkSizeFloat = 2
425421 }
426- // Truncate to integer
427422 truncatedSize := int64 (partChunkSizeFloat )
428423 if truncatedSize < 1 || truncatedSize > 5 {
429- // Enforce part size to be between 1 GB and 5 GB.
430- // If the configured part size is outside this range, default to 2 GB.
431424 logger .PrintIfVerbose (fmt .Sprintf ("Configured part size %d GB is outside the allowed range (1 – 5 GB). Defaulting to 2 GB." , truncatedSize ))
432425 truncatedSize = 2
433426 }
@@ -458,7 +451,7 @@ func createParts(f *os.File, partSizes []int64) ([]string, error) {
458451 for i , size := range partSizes {
459452 partFile , err := os .CreateTemp ("" , fmt .Sprintf ("cx-part%d-*" , i + 1 ))
460453 if err != nil {
461- return partNames , fmt . Errorf ( "create part%d - %w" , i + 1 , err )
454+ return partNames , err
462455 }
463456 offset := int64 (0 )
464457 for j := 0 ; j < i ; j ++ {
@@ -473,7 +466,7 @@ func createParts(f *os.File, partSizes []int64) ([]string, error) {
473466 if err != nil {
474467 return nil , err
475468 }
476- return partNames , fmt . Errorf ( "seek to part%d - %w" , i + 1 , err )
469+ return partNames , err
477470 }
478471 if _ , err := io .CopyN (partFile , f , size ); err != nil && err != io .EOF {
479472 err := partFile .Close ()
@@ -484,13 +477,13 @@ func createParts(f *os.File, partSizes []int64) ([]string, error) {
484477 if err != nil {
485478 return nil , err
486479 }
487- return partNames , fmt . Errorf ( "copy to part%d - %w" , i + 1 , err )
480+ return partNames , err
488481 }
489482 if err := partFile .Sync (); err != nil {
490- logger . PrintfIfVerbose ( "warning: failed to sync part%d - %v" , i + 1 , err )
483+ return partNames , err
491484 }
492485 if err := partFile .Close (); err != nil {
493- logger . PrintfIfVerbose ( "warning: failed to close part%d - %v" , i + 1 , err )
486+ return partNames , err
494487 }
495488 partNames [i ] = partFile .Name ()
496489 }
@@ -499,7 +492,7 @@ func createParts(f *os.File, partSizes []int64) ([]string, error) {
499492
500493func closeFileVerbose (f * os.File ) {
501494 if err := f .Close (); err != nil {
502- logger .PrintfIfVerbose ("warning : failed to close input file - %v" , err )
495+ logger .PrintfIfVerbose ("Warning : failed to close input file - %v" , err )
503496 }
504497}
505498
0 commit comments