1//go:build example
2// +build example
3
4package main
5
6import (
7	"log"
8	"net/url"
9	"os"
10
11	"github.com/aws/aws-sdk-go/aws"
12	"github.com/aws/aws-sdk-go/aws/session"
13	"github.com/aws/aws-sdk-go/service/s3"
14)
15
16type client struct {
17	s3Client *s3.S3
18	bucket   *string
19}
20
21// concatenate will contenate key1's object to key2's object under the key testKey
22func (c *client) concatenate(key1, key2, key3 string, uploadID *string) (*string, *string, error) {
23	// The first part to be uploaded which is represented as part number 1
24	foo, err := c.s3Client.UploadPartCopy(&s3.UploadPartCopyInput{
25		Bucket:     c.bucket,
26		CopySource: aws.String(url.QueryEscape(*c.bucket + "/" + key1)),
27		PartNumber: aws.Int64(1),
28		Key:        &key3,
29		UploadId:   uploadID,
30	})
31	if err != nil {
32		return nil, nil, err
33	}
34
35	// The second part that is going to be appended to the newly created testKey
36	// object.
37	bar, err := c.s3Client.UploadPartCopy(&s3.UploadPartCopyInput{
38		Bucket:     c.bucket,
39		CopySource: aws.String(url.QueryEscape(*c.bucket + "/" + key2)),
40		PartNumber: aws.Int64(2),
41		Key:        &key3,
42		UploadId:   uploadID,
43	})
44	if err != nil {
45		return nil, nil, err
46	}
47	// The ETags are needed to complete the process
48	return foo.CopyPartResult.ETag, bar.CopyPartResult.ETag, nil
49}
50
51func main() {
52	if len(os.Args) < 4 {
53		log.Println("USAGE ERROR: AWS_REGION=us-east-1 go run concatenateObjects.go <bucket> <key for object 1> <key for object 2> <key for output>")
54		return
55	}
56
57	bucket := os.Args[1]
58	key1 := os.Args[2]
59	key2 := os.Args[3]
60	key3 := os.Args[4]
61	sess := session.New(&aws.Config{})
62	svc := s3.New(sess)
63
64	c := client{svc, &bucket}
65
66	// We let the service know that we want to do a multipart upload
67	output, err := c.s3Client.CreateMultipartUpload(&s3.CreateMultipartUploadInput{
68		Bucket: &bucket,
69		Key:    &key3,
70	})
71
72	if err != nil {
73		log.Println("ERROR:", err)
74		return
75	}
76
77	foo, bar, err := c.concatenate(key1, key2, key3, output.UploadId)
78	if err != nil {
79		log.Println("ERROR:", err)
80		return
81	}
82
83	// We finally complete the multipart upload.
84	_, err = c.s3Client.CompleteMultipartUpload(&s3.CompleteMultipartUploadInput{
85		Bucket:   &bucket,
86		Key:      &key3,
87		UploadId: output.UploadId,
88		MultipartUpload: &s3.CompletedMultipartUpload{
89			Parts: []*s3.CompletedPart{
90				{
91					ETag:       foo,
92					PartNumber: aws.Int64(1),
93				},
94				{
95					ETag:       bar,
96					PartNumber: aws.Int64(2),
97				},
98			},
99		},
100	})
101	if err != nil {
102		log.Println("ERROR:", err)
103		return
104	}
105}
106