Repository: seqsense/aws-iot-device-sdk-go
Pull request #194 (2021-01-15 16:26:14)

chore(deps): update alpine docker tag to v3.13
[![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| alpine | final | minor | `3.12` -> `3.13` |

---

### Renovate configuration

:date: **Schedule**: "every weekend" in timezone Asia/Tokyo.

:vertical_traffic_light: **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

:recycle: **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

:no_bell: **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/seqsense/aws-iot-device-sdk-go).

codecov[bot]: # [Codecov](https://codecov.io/gh/seqsense/aws-iot-device-sdk-go/pull/194?src=pr&el=h1) Report
> Merging [#194](https://codecov.io/gh/seqsense/aws-iot-device-sdk-go/pull/194?src=pr&el=desc) (d3234e9) into [master](https://codecov.io/gh/seqsense/aws-iot-device-sdk-go/commit/0cbdc2a364721a74cfeec7251f1d9406738e637c?el=desc) (0cbdc2a) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/seqsense/aws-iot-device-sdk-go/pull/194/graphs/tree.svg?width=650&height=150&src=pr&token=St5U6jzMqv)](https://codecov.io/gh/seqsense/aws-iot-device-sdk-go/pull/194?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master     #194   +/-   ##
=======================================
  Coverage   58.01%   58.01%           
=======================================
  Files          26       26           
  Lines        1229     1229           
=======================================
  Hits          713      713           
  Misses        460      460           
  Partials       56       56           
```



------

[Continue to review full report at Codecov](https://codecov.io/gh/seqsense/aws-iot-device-sdk-go/pull/194?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/seqsense/aws-iot-device-sdk-go/pull/194?src=pr&el=footer). Last update [0cbdc2a...2c38233](https://codecov.io/gh/seqsense/aws-iot-device-sdk-go/pull/194?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/README.md b/README.md
index 2d1b309..3fcb40d 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 # aws-iot-device-sdk-go
 
-[![GoDoc](https://godoc.org/github.com/seqsense/aws-iot-device-sdk-go?status.svg)](http://godoc.org/github.com/seqsense/aws-iot-device-sdk-go) [![Build Status](https://travis-ci.com/seqsense/aws-iot-device-sdk-go.svg?branch=master)](https://travis-ci.com/seqsense/aws-iot-device-sdk-go) [![codecov](https://codecov.io/gh/seqsense/aws-iot-device-sdk-go/branch/master/graph/badge.svg)](https://codecov.io/gh/seqsense/aws-iot-device-sdk-go) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/seqsense/aws-iot-device-sdk-go/blob/master/LICENSE)
+[![Go Reference](https://pkg.go.dev/badge/godoc.org/github.com/seqsense/aws-iot-device-sdk-go.svg)](https://pkg.go.dev/godoc.org/github.com/seqsense/aws-iot-device-sdk-go) ![ci](https://github.com/seqsense/aws-iot-device-sdk-go/workflows/ci/badge.svg) [![codecov](https://codecov.io/gh/seqsense/aws-iot-device-sdk-go/branch/master/graph/badge.svg)](https://codecov.io/gh/seqsense/aws-iot-device-sdk-go) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/seqsense/aws-iot-device-sdk-go/blob/master/LICENSE)
 
-Package awsiotdev implements offline queueing and reconnecting features of MQTT protocol.
+Package awsiotdev implements AWS IoT presigned WebSockets dialer for [github.com/at-wat/mqtt-go](https://github.com/at-wat/mqtt-go), and AWS IoT functionalities.
diff --git a/awsiotdev.go b/awsiotdev.go
index 20cdefc..223509c 100644
--- a/awsiotdev.go
+++ b/awsiotdev.go
@@ -12,13 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// Package awsiotdev implements offline queueing and reconnecting features of MQTT protocol.
+// Package awsiotdev implements AWS IoT presigned WebSockets dialer for github.com/at-wat/mqtt-go, and AWS IoT functionalities.
 package awsiotdev
 
 import (
 	"github.com/at-wat/mqtt-go"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
 )
 
 // Device is an AWS IoT device.
diff --git a/dialer.go b/dialer.go
index d8e1a2c..592b870 100644
--- a/dialer.go
+++ b/dialer.go
@@ -21,8 +21,8 @@ import (
 
 	"github.com/at-wat/mqtt-go"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
-	presigner "github.com/seqsense/aws-iot-device-sdk-go/v4/presigner"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
+	presigner "github.com/seqsense/aws-iot-device-sdk-go/v5/presigner"
 )
 
 type presignDialer struct {
@@ -40,7 +40,7 @@ func NewPresignDialer(sess client.ConfigProvider, endpoint string, opts ...mqtt.
 	}, nil
 }
 
-func (d *presignDialer) Dial() (mqtt.ClientCloser, error) {
+func (d *presignDialer) Dial() (*mqtt.BaseClient, error) {
 	url, err := d.signer.PresignWssNow(d.endpoint)
 	if err != nil {
 		return nil, ioterr.New(err, "presigning wss URL")
diff --git a/examples/jobs/main.go b/examples/jobs/main.go
index 09c906c..49c9ef8 100644
--- a/examples/jobs/main.go
+++ b/examples/jobs/main.go
@@ -21,8 +21,8 @@ import (
 	"time"
 
 	"github.com/at-wat/mqtt-go"
-	"github.com/seqsense/aws-iot-device-sdk-go/v4"
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/jobs"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/jobs"
 )
 
 func main() {
diff --git a/examples/shadow/main.go b/examples/shadow/main.go
index ed8a7e0..cf16291 100644
--- a/examples/shadow/main.go
+++ b/examples/shadow/main.go
@@ -21,16 +21,16 @@ import (
 	"time"
 
 	"github.com/at-wat/mqtt-go"
-	"github.com/seqsense/aws-iot-device-sdk-go/v4"
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/shadow"
+	awsiotdev "github.com/seqsense/aws-iot-device-sdk-go/v5"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/shadow"
 )
 
 func main() {
 	ctx, cancel := context.WithCancel(context.Background())
 	defer cancel()
 
-	if len(os.Args) != 3 {
-		println("usage: shadow AWS_IOT_ENDPOINT THING_NAME")
+	if len(os.Args) != 4 {
+		println("usage: shadow AWS_IOT_ENDPOINT THING_NAME SHADOW_NAME")
 		println("")
 		println("This example updates and deletes AWS IoT Thing Shadow.")
 		println("THING_NAME must be registered to your account of AWS IoT beforehand.")
@@ -43,6 +43,7 @@ func main() {
 	}
 	host := os.Args[1]
 	thingName := os.Args[2]
+	shadowName := os.Args[3]
 
 	for _, file := range []string{
 		"root-CA.crt",
@@ -88,7 +89,7 @@ func main() {
 		panic(err)
 	}
 
-	s, err := shadow.New(ctx, cli)
+	s, err := shadow.New(ctx, cli, shadow.WithName(shadowName))
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/tunnel/main.go b/examples/tunnel/main.go
index d10d6ae..4daa9c0 100644
--- a/examples/tunnel/main.go
+++ b/examples/tunnel/main.go
@@ -23,8 +23,8 @@ import (
 	"time"
 
 	"github.com/at-wat/mqtt-go"
-	"github.com/seqsense/aws-iot-device-sdk-go/v4"
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/tunnel"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/tunnel"
 )
 
 func main() {
diff --git a/go.mod b/go.mod
index e41b60c..4397e88 100644
--- a/go.mod
+++ b/go.mod
@@ -1,12 +1,12 @@
-module github.com/seqsense/aws-iot-device-sdk-go/v4
+module github.com/seqsense/aws-iot-device-sdk-go/v5
 
 require (
-	github.com/at-wat/mqtt-go v0.11.4
-	github.com/aws/aws-sdk-go v1.36.23
+	github.com/at-wat/mqtt-go v0.12.0
+	github.com/aws/aws-sdk-go v1.37.15
 	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/golang/protobuf v1.4.3
-	github.com/google/uuid v1.1.4
-	golang.org/x/net v0.0.0-20201224014010-6772e930b67b
+	github.com/google/uuid v1.2.0
+	golang.org/x/net v0.0.0-20210119194325-5f4716e94777
 	google.golang.org/protobuf v1.25.0
 )
 
diff --git a/go.sum b/go.sum
index 8789513..3f4b002 100644
--- a/go.sum
+++ b/go.sum
@@ -1,9 +1,9 @@
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/at-wat/mqtt-go v0.11.4 h1:tVv+BhsT1SbbdZ9QuBPnPb4iVy7V6hYMenAatQ2z8xY=
-github.com/at-wat/mqtt-go v0.11.4/go.mod h1:NWhjSXyT2oraZmmgomhft0vSLL2DQNrSsRZmG1odl1s=
-github.com/aws/aws-sdk-go v1.36.23 h1:umM44ptMKImsUWLtjGBv/4Ut7Nd99DfqoZDkO0j0/Kc=
-github.com/aws/aws-sdk-go v1.36.23/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
+github.com/at-wat/mqtt-go v0.12.0 h1:FMNOx7ERFt3N8kx/LxSSfGMk5BnlB5cwxjRqrYV6+7A=
+github.com/at-wat/mqtt-go v0.12.0/go.mod h1:b4QTk+HgoReGBw9R652AH0Kqc2OvkLSD7lOgyxWgeQE=
+github.com/aws/aws-sdk-go v1.37.15 h1:W7l7gLLMcYRlg6a+uvf3Zz4jYwdqYzhe5ymqwWoOhp4=
+github.com/aws/aws-sdk-go v1.37.15/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
@@ -32,8 +32,8 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/uuid v1.1.4 h1:0ecGp3skIrHWPNGPJDaBIghfA6Sp7Ruo2Io8eLKzWm0=
-github.com/google/uuid v1.1.4/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
+github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
 github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
 github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
@@ -54,12 +54,10 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 h1:42cLlJJdEh+ySyeUUbEQ5bsTiq8voBeTuweGVkY6Puw=
-golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
 golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw=
-golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
+golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
diff --git a/jobs/jobs.go b/jobs/jobs.go
index 5026d33..3f57eeb 100644
--- a/jobs/jobs.go
+++ b/jobs/jobs.go
@@ -23,8 +23,8 @@ import (
 
 	"github.com/at-wat/mqtt-go"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4"
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
 )
 
 // Jobs is an interface of IoT Jobs.
@@ -86,7 +86,7 @@ func New(ctx context.Context, cli awsiotdev.Device) (Jobs, error) {
 		}
 	}
 
-	err := cli.Subscribe(ctx,
+	_, err := cli.Subscribe(ctx,
 		mqtt.Subscription{Topic: j.topic("notify"), QoS: mqtt.QoS1},
 		mqtt.Subscription{Topic: j.topic("get/#"), QoS: mqtt.QoS1},
 		mqtt.Subscription{Topic: j.topic("+/get/#"), QoS: mqtt.QoS1},
diff --git a/presigner/presign.go b/presigner/presign.go
index 73ec9ea..2c687ad 100644
--- a/presigner/presign.go
+++ b/presigner/presign.go
@@ -31,7 +31,7 @@ import (
 	"github.com/aws/aws-sdk-go/aws/credentials"
 	"github.com/aws/aws-sdk-go/aws/signer/v4"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
 )
 
 // Presigner is an AWS v4 signer wrapper for AWS IoT.
diff --git a/shadow/option.go b/shadow/option.go
new file mode 100644
index 0000000..342c4db
--- /dev/null
+++ b/shadow/option.go
@@ -0,0 +1,31 @@
+// Copyright 2020-2021 SEQSENSE, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package shadow
+
+// Options stores Device Shadow options.
+type Options struct {
+	Name string
+}
+
+// Option is a functional option of UpdateJob.
+type Option func(options *Options) error
+
+// WithName sets shadow name.
+func WithName(name string) Option {
+	return func(o *Options) error {
+		o.Name = name
+		return nil
+	}
+}
diff --git a/shadow/shadow.go b/shadow/shadow.go
index a535502..cb59544 100644
--- a/shadow/shadow.go
+++ b/shadow/shadow.go
@@ -24,8 +24,8 @@ import (
 
 	"github.com/at-wat/mqtt-go"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4"
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
+	awsiotdev "github.com/seqsense/aws-iot-device-sdk-go/v5"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
 )
 
 // Shadow is an interface of Thing Shadow.
@@ -57,6 +57,7 @@ type shadow struct {
 	mqtt.ServeMux
 	cli       mqtt.Client
 	thingName string
+	name      string
 	doc       *ThingDocument
 	mu        sync.Mutex
 	onDelta   func(delta map[string]interface{})
@@ -73,7 +74,11 @@ func (s *shadow) token() string {
 }
 
 func (s *shadow) topic(operation string) string {
-	return "$aws/things/" + s.thingName + "/shadow/" + operation
+	prefix := "$aws/things/" + s.thingName + "/shadow"
+	if s.name != "" {
+		prefix += "/name/" + s.name
+	}
+	return prefix + "/" + operation
 }
 
 func (s *shadow) handleResponse(r interface{}) {
@@ -160,10 +165,17 @@ func (s *shadow) deleteAccepted(msg *mqtt.Message) {
 }
 
 // New creates Thing Shadow interface.
-func New(ctx context.Context, cli awsiotdev.Device) (Shadow, error) {
+func New(ctx context.Context, cli awsiotdev.Device, opt ...Option) (Shadow, error) {
+	opts := &Options{}
+	for _, o := range opt {
+		if err := o(opts); err != nil {
+			return nil, ioterr.New(err, "applying option")
+		}
+	}
 	s := &shadow{
 		cli:       cli,
 		thingName: cli.ThingName(),
+		name:      opts.Name,
 		doc: &ThingDocument{
 			State: ThingState{
 				Desired:  map[string]interface{}{},
@@ -191,7 +203,7 @@ func New(ctx context.Context, cli awsiotdev.Device) (Shadow, error) {
 		}
 	}
 
-	err := cli.Subscribe(ctx,
+	_, err := cli.Subscribe(ctx,
 		mqtt.Subscription{Topic: s.topic("update/delta"), QoS: mqtt.QoS1},
 		mqtt.Subscription{Topic: s.topic("update/accepted"), QoS: mqtt.QoS1},
 		mqtt.Subscription{Topic: s.topic("update/rejected"), QoS: mqtt.QoS1},
diff --git a/shadow/state.go b/shadow/state.go
index 908a3ab..932d3a0 100644
--- a/shadow/state.go
+++ b/shadow/state.go
@@ -19,7 +19,7 @@ import (
 	"errors"
 	"fmt"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
 )
 
 // ErrVersionConflict means thing state update was aborted due to version conflict.
diff --git a/tunnel/cmd/localproxy/main.go b/tunnel/cmd/localproxy/main.go
index 314fe02..aa0d214 100644
--- a/tunnel/cmd/localproxy/main.go
+++ b/tunnel/cmd/localproxy/main.go
@@ -21,7 +21,7 @@ import (
 	"log"
 	"net"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/tunnel"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/tunnel"
 )
 
 var (
diff --git a/tunnel/cmd/secure-tunnel-server/Dockerfile b/tunnel/cmd/secure-tunnel-server/Dockerfile
index 7497e0a..7bcbc88 100644
--- a/tunnel/cmd/secure-tunnel-server/Dockerfile
+++ b/tunnel/cmd/secure-tunnel-server/Dockerfile
@@ -1,5 +1,5 @@
 # =====================
-FROM golang:1.15-alpine3.12 as go-builder
+FROM golang:1.16-alpine3.12 as go-builder
 
 ENV CGO_ENABLED=0
 
@@ -13,7 +13,7 @@ RUN go build -tags netgo -installsuffix netgo
 RUN cp secure-tunnel-server /usr/local/bin/
 
 # =====================
-FROM alpine:3.12
+FROM alpine:3.13
 
 COPY --from=go-builder /usr/local/bin/secure-tunnel-server /usr/local/bin/
 
diff --git a/tunnel/cmd/secure-tunnel-server/main.go b/tunnel/cmd/secure-tunnel-server/main.go
index 8478ab0..a290beb 100644
--- a/tunnel/cmd/secure-tunnel-server/main.go
+++ b/tunnel/cmd/secure-tunnel-server/main.go
@@ -28,8 +28,8 @@ import (
 
 	mqtt "github.com/at-wat/mqtt-go"
 	"github.com/aws/aws-sdk-go/aws/session"
-	awsiot "github.com/seqsense/aws-iot-device-sdk-go/v4"
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/tunnel/server"
+	awsiot "github.com/seqsense/aws-iot-device-sdk-go/v5"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/tunnel/server"
 )
 
 var (
diff --git a/tunnel/destination.go b/tunnel/destination.go
index ae6f7bb..ad7d3e5 100644
--- a/tunnel/destination.go
+++ b/tunnel/destination.go
@@ -19,8 +19,8 @@ import (
 
 	"google.golang.org/protobuf/proto"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/tunnel/msg"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/tunnel/msg"
 )
 
 func proxyDestination(ws io.ReadWriter, dialer Dialer, eh ErrorHandler) error {
diff --git a/tunnel/msg/helper.go b/tunnel/msg/helper.go
index eba4ca7..be02dd3 100644
--- a/tunnel/msg/helper.go
+++ b/tunnel/msg/helper.go
@@ -19,7 +19,7 @@ import (
 
 	"google.golang.org/protobuf/proto"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
 )
 
 // WriteMessage marshals the message and sends to the writer.
diff --git a/tunnel/proxy.go b/tunnel/proxy.go
index 79e58bf..b8f051f 100644
--- a/tunnel/proxy.go
+++ b/tunnel/proxy.go
@@ -24,7 +24,7 @@ import (
 
 	"golang.org/x/net/websocket"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
 )
 
 const (
diff --git a/tunnel/proxyio.go b/tunnel/proxyio.go
index 5083a1a..d88deab 100644
--- a/tunnel/proxyio.go
+++ b/tunnel/proxyio.go
@@ -18,7 +18,7 @@ import (
 	"fmt"
 	"io"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/tunnel/msg"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/tunnel/msg"
 )
 
 func readProxy(ws, conn io.ReadWriter, streamID int32, eh ErrorHandler) {
diff --git a/tunnel/server/api.go b/tunnel/server/api.go
index db660ba..ee6d927 100644
--- a/tunnel/server/api.go
+++ b/tunnel/server/api.go
@@ -27,8 +27,8 @@ import (
 	"github.com/aws/aws-sdk-go/private/protocol/json/jsonutil"
 	ist "github.com/aws/aws-sdk-go/service/iotsecuretunneling"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/tunnel"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/tunnel"
 )
 
 // apiHandler handles iotsecuretunneling API requests.
diff --git a/tunnel/server/notifier.go b/tunnel/server/notifier.go
index e4b1734..1717634 100644
--- a/tunnel/server/notifier.go
+++ b/tunnel/server/notifier.go
@@ -21,8 +21,8 @@ import (
 
 	"github.com/at-wat/mqtt-go"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/tunnel"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/tunnel"
 )
 
 const (
diff --git a/tunnel/server/tunnel.go b/tunnel/server/tunnel.go
index bf44528..f61a0cd 100644
--- a/tunnel/server/tunnel.go
+++ b/tunnel/server/tunnel.go
@@ -24,8 +24,8 @@ import (
 
 	"golang.org/x/net/websocket"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/tunnel"
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/tunnel/msg"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/tunnel"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/tunnel/msg"
 )
 
 // TunnelHandler handles websocket based secure tunneling sessions.
diff --git a/tunnel/source.go b/tunnel/source.go
index 4ae63df..b6c7222 100644
--- a/tunnel/source.go
+++ b/tunnel/source.go
@@ -21,8 +21,8 @@ import (
 
 	"google.golang.org/protobuf/proto"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/tunnel/msg"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/tunnel/msg"
 )
 
 func proxySource(ws io.ReadWriter, listener net.Listener, eh ErrorHandler) error {
diff --git a/tunnel/tunnel.go b/tunnel/tunnel.go
index 5872869..dff0878 100644
--- a/tunnel/tunnel.go
+++ b/tunnel/tunnel.go
@@ -22,8 +22,8 @@ import (
 
 	"github.com/at-wat/mqtt-go"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4"
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
 )
 
 // Tunnel is an interface of secure tunneling.
@@ -79,7 +79,7 @@ func New(ctx context.Context, cli awsiotdev.Device, dialer map[string]Dialer, op
 		return nil, ioterr.New(err, "registering message handler")
 	}
 
-	err := cli.Subscribe(ctx,
+	_, err := cli.Subscribe(ctx,
 		mqtt.Subscription{Topic: t.opts.TopicFunc("notify"), QoS: mqtt.QoS1},
 	)
 	if err != nil {


Test patch:
diff --git a/awsiotdev_test.go b/awsiotdev_test.go
index 701b475..368afd5 100644
--- a/awsiotdev_test.go
+++ b/awsiotdev_test.go
@@ -22,7 +22,7 @@ import (
 
 func TestNew(t *testing.T) {
 	const name = "thing_name1"
-	d, err := New(name, mqtt.DialerFunc(func() (mqtt.ClientCloser, error) {
+	d, err := New(name, mqtt.DialerFunc(func() (*mqtt.BaseClient, error) {
 		return &mqtt.BaseClient{}, nil
 	}))
 	if err != nil {
diff --git a/dialer_test.go b/dialer_test.go
index f538f09..3b98969 100644
--- a/dialer_test.go
+++ b/dialer_test.go
@@ -40,8 +40,8 @@ import (
 	"github.com/aws/aws-sdk-go/aws/client"
 	"github.com/aws/aws-sdk-go/aws/session"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/presigner"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/presigner"
 )
 
 type dummyConfigProvider struct{}
diff --git a/jobs/jobs_test.go b/jobs/jobs_test.go
index 945ac38..73e0139 100644
--- a/jobs/jobs_test.go
+++ b/jobs/jobs_test.go
@@ -25,7 +25,7 @@ import (
 	"github.com/at-wat/mqtt-go"
 	mockmqtt "github.com/at-wat/mqtt-go/mock"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
 )
 
 var errPublish = errors.New("publish failure")
@@ -46,8 +46,8 @@ func TestNew(t *testing.T) {
 		defer cancel()
 
 		cli := &mockDevice{&mockmqtt.Client{
-			SubscribeFn: func(ctx context.Context, subs ...mqtt.Subscription) error {
-				return errDummy
+			SubscribeFn: func(ctx context.Context, subs ...mqtt.Subscription) ([]mqtt.Subscription, error) {
+				return nil, errDummy
 			},
 		}}
 		_, err := New(ctx, cli)
diff --git a/shadow/shadow_test.go b/shadow/shadow_test.go
index 933bbff..d9051d5 100644
--- a/shadow/shadow_test.go
+++ b/shadow/shadow_test.go
@@ -25,7 +25,7 @@ import (
 	"github.com/at-wat/mqtt-go"
 	mockmqtt "github.com/at-wat/mqtt-go/mock"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
 )
 
 type mockDevice struct {
@@ -44,8 +44,8 @@ func TestNew(t *testing.T) {
 		defer cancel()
 
 		cli := &mockDevice{&mockmqtt.Client{
-			SubscribeFn: func(ctx context.Context, subs ...mqtt.Subscription) error {
-				return errDummy
+			SubscribeFn: func(ctx context.Context, subs ...mqtt.Subscription) ([]mqtt.Subscription, error) {
+				return nil, errDummy
 			},
 		}}
 		_, err := New(ctx, cli)
@@ -57,6 +57,44 @@ func TestNew(t *testing.T) {
 			t.Errorf("Expected error: %v, got: %v", errDummy, err)
 		}
 	})
+
+	t.Run("Options", func(t *testing.T) {
+		t.Run("WithName", func(t *testing.T) {
+			ctx, cancel := context.WithTimeout(context.Background(), time.Second)
+			defer cancel()
+
+			cli := &mockDevice{&mockmqtt.Client{}}
+			operation := "foo/bar"
+
+			testCases := map[string]struct {
+				input    string
+				expected string
+			}{
+				"ClassicShadow": {
+					input:    "",
+					expected: "$aws/things/" + cli.ThingName() + "/shadow/" + operation,
+				},
+				"NamedShadow": {
+					input:    "testShadow",
+					expected: "$aws/things/" + cli.ThingName() + "/shadow/name/testShadow/" + operation,
+				},
+			}
+
+			for name, testCase := range testCases {
+				testCase := testCase
+				t.Run(name, func(t *testing.T) {
+					s, err := New(ctx, cli, WithName(testCase.input))
+					if err != nil {
+						t.Fatal(err)
+					}
+					topic := s.(*shadow).topic(operation)
+					if topic != testCase.expected {
+						t.Errorf("Expected topic name: %v, got: %v", testCase.expected, topic)
+					}
+				})
+			}
+		})
+	})
 }
 
 func TestHandlers(t *testing.T) {
diff --git a/shadow/state_test.go b/shadow/state_test.go
index 0c5cc6c..7518b93 100644
--- a/shadow/state_test.go
+++ b/shadow/state_test.go
@@ -21,7 +21,7 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
 )
 
 func TestThingDocument_update(t *testing.T) {
diff --git a/tunnel/msg/helper_test.go b/tunnel/msg/helper_test.go
index e5cf015..9efc2c9 100644
--- a/tunnel/msg/helper_test.go
+++ b/tunnel/msg/helper_test.go
@@ -19,7 +19,7 @@ import (
 	"errors"
 	"testing"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
 )
 
 func TestWriteMessage(t *testing.T) {
diff --git a/tunnel/proxy_test.go b/tunnel/proxy_test.go
index b0bbc6a..ea2b837 100644
--- a/tunnel/proxy_test.go
+++ b/tunnel/proxy_test.go
@@ -24,8 +24,8 @@ import (
 
 	"google.golang.org/protobuf/proto"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/tunnel/msg"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/tunnel/msg"
 )
 
 var (
diff --git a/tunnel/server/api_test.go b/tunnel/server/api_test.go
index eca9ecf..96933a7 100644
--- a/tunnel/server/api_test.go
+++ b/tunnel/server/api_test.go
@@ -30,7 +30,7 @@ import (
 	"github.com/aws/aws-sdk-go/aws/session"
 	ist "github.com/aws/aws-sdk-go/service/iotsecuretunneling"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
 )
 
 func TestAPI(t *testing.T) {
diff --git a/tunnel/tunnel_test.go b/tunnel/tunnel_test.go
index eaf71d9..68407d1 100644
--- a/tunnel/tunnel_test.go
+++ b/tunnel/tunnel_test.go
@@ -24,7 +24,7 @@ import (
 	mqtt "github.com/at-wat/mqtt-go"
 	mockmqtt "github.com/at-wat/mqtt-go/mock"
 
-	"github.com/seqsense/aws-iot-device-sdk-go/v4/internal/ioterr"
+	"github.com/seqsense/aws-iot-device-sdk-go/v5/internal/ioterr"
 )
 
 type mockDevice struct {
@@ -59,8 +59,8 @@ func TestNew(t *testing.T) {
 		defer cancel()
 
 		cli := &mockDevice{&mockmqtt.Client{
-			SubscribeFn: func(ctx context.Context, subs ...mqtt.Subscription) error {
-				return errDummy
+			SubscribeFn: func(ctx context.Context, subs ...mqtt.Subscription) ([]mqtt.Subscription, error) {
+				return nil, errDummy
 			},
 		}}
 		_, err := New(ctx, cli, map[string]Dialer{})