1// +build example
2
3package main
4
5import (
6	"fmt"
7	"io"
8	"log"
9	"math/rand"
10	"os"
11	"time"
12
13	"github.com/aws/aws-sdk-go/aws"
14	"github.com/aws/aws-sdk-go/aws/session"
15	"github.com/aws/aws-sdk-go/service/mediastore"
16	"github.com/aws/aws-sdk-go/service/mediastoredata"
17)
18
19func main() {
20	containerName := os.Args[1]
21	objectPath := os.Args[2]
22
23	// Create the SDK's session, and a AWS Elemental MediaStore Data client.
24	sess := session.Must(session.NewSession())
25	dataSvc, err := getMediaStoreDataClient(containerName, sess)
26	if err != nil {
27		log.Fatalf("failed to create client, %v", err)
28	}
29
30	// Create a random reader to simulate a unseekable reader, wrap the reader
31	// in an io.LimitReader to prevent uploading forever.
32	randReader := rand.New(rand.NewSource(0))
33	reader := io.LimitReader(randReader, 1024*1024 /* 1MB */)
34
35	// Wrap the unseekable reader with the SDK's RandSeekCloser. This type will
36	// allow the SDK's to use the nonseekable reader.
37	body := aws.ReadSeekCloser(reader)
38
39	// make the PutObject API call with the nonseekable reader, causing the SDK
40	// to send the request body payload as chunked transfer encoding.
41	_, err = dataSvc.PutObject(&mediastoredata.PutObjectInput{
42		Path: &objectPath,
43		Body: body,
44	})
45	if err != nil {
46		log.Fatalf("failed to upload object, %v", err)
47	}
48
49	fmt.Println("object uploaded")
50}
51
52// getMediaStoreDataClient uses the AWS Elemental MediaStore API to get the
53// endpoint for a container. If the container endpoint can be retrieved a AWS
54// Elemental MediaStore Data client will be created and returned. Otherwise
55// error is returned.
56func getMediaStoreDataClient(containerName string, sess *session.Session) (*mediastoredata.MediaStoreData, error) {
57	endpoint, err := containerEndpoint(containerName, sess)
58	if err != nil {
59		return nil, err
60	}
61
62	dataSvc := mediastoredata.New(sess, &aws.Config{
63		Endpoint: endpoint,
64	})
65
66	return dataSvc, nil
67}
68
69// ContainerEndpoint will attempt to get the endpoint for a container,
70// returning error if the container doesn't exist, or is not active within a
71// timeout.
72func containerEndpoint(name string, sess *session.Session) (*string, error) {
73	for i := 0; i < 3; i++ {
74		ctrlSvc := mediastore.New(sess)
75		descResp, err := ctrlSvc.DescribeContainer(&mediastore.DescribeContainerInput{
76			ContainerName: &name,
77		})
78		if err != nil {
79			return nil, err
80		}
81
82		if status := aws.StringValue(descResp.Container.Status); status != "ACTIVE" {
83			log.Println("waiting for container to be active, ", status)
84			time.Sleep(10 * time.Second)
85			continue
86		}
87
88		return descResp.Container.Endpoint, nil
89	}
90
91	return nil, fmt.Errorf("container is not active")
92}
93