Skip to content

Commit 196ae82

Browse files
[Go] ADR 18: Make clientID a required argument (#563)
1 parent 4e2fded commit 196ae82

File tree

21 files changed

+198
-129
lines changed

21 files changed

+198
-129
lines changed

.github/workflows/ci-go.yml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,21 @@ jobs:
132132

133133
- name: Run counter server
134134
working-directory: ./go/samples/protocol/counter/server
135-
run: AIO_BROKER_HOSTNAME=localhost AIO_BROKER_TCP_PORT=8884 AIO_TLS_CA_FILE=${{ env.CA_FILE_PATH }} AIO_SAT_FILE=${{ env.TOKEN_FILE_PATH }} AIO_MQTT_CLIENT_ID=CounterServer-go go run . &
135+
run: go run . &
136+
env:
137+
AIO_BROKER_HOSTNAME: localhost
138+
AIO_BROKER_TCP_PORT: 8884
139+
AIO_TLS_CA_FILE: ${{ env.CA_FILE_PATH }}
140+
AIO_SAT_FILE: ${{ env.TOKEN_FILE_PATH }}
141+
AIO_MQTT_CLIENT_ID: CounterServer-go
136142

137143
- name: Run counter client
138144
working-directory: ./go/samples/protocol/counter/client
139-
run: AIO_BROKER_HOSTNAME=localhost AIO_BROKER_TCP_PORT=8884 AIO_TLS_CA_FILE=${{ env.CA_FILE_PATH }} AIO_SAT_FILE=${{ env.TOKEN_FILE_PATH }} COUNTER_SERVER_ID=CounterServer-go go run .
145+
run: go run .
146+
env:
147+
AIO_BROKER_HOSTNAME: localhost
148+
AIO_BROKER_TCP_PORT: 8884
149+
AIO_TLS_CA_FILE: ${{ env.CA_FILE_PATH }}
150+
AIO_SAT_FILE: ${{ env.TOKEN_FILE_PATH }}
151+
AIO_MQTT_CLIENT_ID: CounterClient-go
152+
COUNTER_SERVER_ID: CounterServer-go

go/mqtt/API.md

Lines changed: 48 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import "github.com/Azure/iot-operations-sdks/go/mqtt"
77
## Index
88

99
- [func IsTopicFilterMatch\(topicFilter, topicName string\) bool](<#IsTopicFilterMatch>)
10-
- [func SessionClientConfigFromEnv\(\) \(ConnectionProvider, \*SessionClientOptions, error\)](<#SessionClientConfigFromEnv>)
10+
- [func RandomClientID\(\) string](<#RandomClientID>)
1111
- [type Ack](<#Ack>)
1212
- [type ClientState](<#ClientState>)
1313
- [type ClientStateError](<#ClientStateError>)
@@ -26,6 +26,8 @@ import "github.com/Azure/iot-operations-sdks/go/mqtt"
2626
- [func \(e \*DisconnectError\) Error\(\) string](<#DisconnectError.Error>)
2727
- [type DisconnectEvent](<#DisconnectEvent>)
2828
- [type DisconnectEventHandler](<#DisconnectEventHandler>)
29+
- [type Env](<#Env>)
30+
- [func SessionClientConfigFromEnv\(\) \(\*Env, error\)](<#SessionClientConfigFromEnv>)
2931
- [type FatalConnackError](<#FatalConnackError>)
3032
- [func \(e \*FatalConnackError\) Error\(\) string](<#FatalConnackError.Error>)
3133
- [type FatalDisconnectError](<#FatalDisconnectError>)
@@ -43,7 +45,7 @@ import "github.com/Azure/iot-operations-sdks/go/mqtt"
4345
- [type PublishQueueFullError](<#PublishQueueFullError>)
4446
- [func \(\*PublishQueueFullError\) Error\(\) string](<#PublishQueueFullError.Error>)
4547
- [type SessionClient](<#SessionClient>)
46-
- [func NewSessionClient\(connectionProvider ConnectionProvider, opts ...SessionClientOption\) \*SessionClient](<#NewSessionClient>)
48+
- [func NewSessionClient\(clientID string, connectionProvider ConnectionProvider, opts ...SessionClientOption\) \(\*SessionClient, error\)](<#NewSessionClient>)
4749
- [func NewSessionClientFromEnv\(opt ...SessionClientOption\) \(\*SessionClient, error\)](<#NewSessionClientFromEnv>)
4850
- [func \(c \*SessionClient\) ID\(\) string](<#SessionClient.ID>)
4951
- [func \(c \*SessionClient\) Publish\(ctx context.Context, topic string, payload \[\]byte, opts ...PublishOption\) \(\*Ack, error\)](<#SessionClient.Publish>)
@@ -74,7 +76,6 @@ import "github.com/Azure/iot-operations-sdks/go/mqtt"
7476
- [type UsernameProvider](<#UsernameProvider>)
7577
- [func ConstantUsername\(username string\) UsernameProvider](<#ConstantUsername>)
7678
- [type WithCleanStart](<#WithCleanStart>)
77-
- [type WithClientID](<#WithClientID>)
7879
- [type WithConnectUserProperties](<#WithConnectUserProperties>)
7980
- [type WithConnectionTimeout](<#WithConnectionTimeout>)
8081
- [type WithContentType](<#WithContentType>)
@@ -103,14 +104,14 @@ func IsTopicFilterMatch(topicFilter, topicName string) bool
103104

104105
IsTopicFilterMatch checks if a topic name matches a topic filter.
105106

106-
<a name="SessionClientConfigFromEnv"></a>
107-
## func [SessionClientConfigFromEnv](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/env.go#L30>)
107+
<a name="RandomClientID"></a>
108+
## func [RandomClientID](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/random_client_id.go#L23>)
108109

109110
```go
110-
func SessionClientConfigFromEnv() (ConnectionProvider, *SessionClientOptions, error)
111+
func RandomClientID() string
111112
```
112113

113-
SessionClientConfigFromEnv parses a session client configuration from well\-known environment variables. Note that this will only return an error if the environment variables parse incorrectly; it will not return an error if required parameters \(e.g. for the connection provider\) are missing, to allow optional parameters to be specified from environment independently.
114+
RandomClientID generates a random valid MQTT client ID. This should never be used in production \(as it fully invalidates all session guarantees\) but can be useful in testing to prevent parallel tests from conflicting.
114115

115116
<a name="Ack"></a>
116117
## type [Ack](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/alias.go#L30>)
@@ -299,6 +300,28 @@ DisconnectEventHandler is a user\-defined callback function used to respond to d
299300
type DisconnectEventHandler = mqtt.DisconnectEventHandler
300301
```
301302

303+
<a name="Env"></a>
304+
## type [Env](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/env.go#L18-L22>)
305+
306+
Env provides all session client parameters parsed from well\-known environment variables.
307+
308+
```go
309+
type Env struct {
310+
ClientID string
311+
ConnectionProvider ConnectionProvider
312+
*SessionClientOptions
313+
}
314+
```
315+
316+
<a name="SessionClientConfigFromEnv"></a>
317+
### func [SessionClientConfigFromEnv](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/env.go#L40>)
318+
319+
```go
320+
func SessionClientConfigFromEnv() (*Env, error)
321+
```
322+
323+
SessionClientConfigFromEnv parses a session client configuration from well\-known environment variables. Note that this will only return an error if the environment variables parse incorrectly; it will not return an error if required parameters \(e.g. for the connection provider\) are missing, to allow optional parameters to be specified from environment independently.
324+
302325
<a name="FatalConnackError"></a>
303326
## type [FatalConnackError](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/errors.go#L116-L118>)
304327

@@ -450,7 +473,7 @@ func (*PublishQueueFullError) Error() string
450473

451474

452475
<a name="SessionClient"></a>
453-
## type [SessionClient](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client.go#L20-L57>)
476+
## type [SessionClient](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client.go#L20-L58>)
454477

455478
SessionClient implements an MQTT session client supporting MQTT v5 with QoS 0 and QoS 1 support.
456479

@@ -461,16 +484,16 @@ type SessionClient struct {
461484
```
462485

463486
<a name="NewSessionClient"></a>
464-
### func [NewSessionClient](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client.go#L61-L64>)
487+
### func [NewSessionClient](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client.go#L62-L66>)
465488

466489
```go
467-
func NewSessionClient(connectionProvider ConnectionProvider, opts ...SessionClientOption) *SessionClient
490+
func NewSessionClient(clientID string, connectionProvider ConnectionProvider, opts ...SessionClientOption) (*SessionClient, error)
468491
```
469492

470493
NewSessionClient constructs a new session client with user options.
471494

472495
<a name="NewSessionClientFromEnv"></a>
473-
### func [NewSessionClientFromEnv](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/env.go#L134-L136>)
496+
### func [NewSessionClientFromEnv](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/env.go#L145-L147>)
474497

475498
```go
476499
func NewSessionClientFromEnv(opt ...SessionClientOption) (*SessionClient, error)
@@ -479,7 +502,7 @@ func NewSessionClientFromEnv(opt ...SessionClientOption) (*SessionClient, error)
479502
NewSessionClientFromEnv is a shorthand for constructing a session client using SessionClientConfigFromEnv.
480503

481504
<a name="SessionClient.ID"></a>
482-
### func \(\*SessionClient\) [ID](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client.go#L110>)
505+
### func \(\*SessionClient\) [ID](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client.go#L121>)
483506

484507
```go
485508
func (c *SessionClient) ID() string
@@ -580,7 +603,7 @@ type SessionClientOption interface {
580603
```
581604

582605
<a name="WithAuth"></a>
583-
### func [WithAuth](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L143>)
606+
### func [WithAuth](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L134>)
584607

585608
```go
586609
func WithAuth(provider auth.Provider) SessionClientOption
@@ -589,7 +612,7 @@ func WithAuth(provider auth.Provider) SessionClientOption
589612
WithAuth sets the enhanced authentication provider for the session client.
590613

591614
<a name="WithConnectionRetry"></a>
592-
### func [WithConnectionRetry](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L134>)
615+
### func [WithConnectionRetry](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L125>)
593616

594617
```go
595618
func WithConnectionRetry(policy retry.Policy) SessionClientOption
@@ -598,7 +621,7 @@ func WithConnectionRetry(policy retry.Policy) SessionClientOption
598621
WithConnectionRetry sets the connection retry policy for the session client.
599622

600623
<a name="WithLogger"></a>
601-
### func [WithLogger](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L152>)
624+
### func [WithLogger](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L143>)
602625

603626
```go
604627
func WithLogger(log *slog.Logger) SessionClientOption
@@ -607,13 +630,12 @@ func WithLogger(log *slog.Logger) SessionClientOption
607630
WithLogger sets the logger for the session client.
608631

609632
<a name="SessionClientOptions"></a>
610-
## type [SessionClientOptions](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L20-L36>)
633+
## type [SessionClientOptions](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L20-L35>)
611634

612635
SessionClientOptions are the resolved options for the session client.
613636

614637
```go
615638
type SessionClientOptions struct {
616-
ClientID string
617639
CleanStart bool
618640
KeepAlive uint16
619641
SessionExpiry uint32
@@ -632,7 +654,7 @@ type SessionClientOptions struct {
632654
```
633655

634656
<a name="SessionClientOptions.Apply"></a>
635-
### func \(\*SessionClientOptions\) [Apply](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L79-L82>)
657+
### func \(\*SessionClientOptions\) [Apply](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L74-L77>)
636658

637659
```go
638660
func (o *SessionClientOptions) Apply(opts []SessionClientOption, rest ...SessionClientOption)
@@ -749,25 +771,16 @@ func ConstantUsername(username string) UsernameProvider
749771
ConstantUsername is a UsernameProvider implementation that returns an unchanging username. This can be used if the username does not need to be updated between MQTT connections.
750772

751773
<a name="WithCleanStart"></a>
752-
## type [WithCleanStart](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L50>)
774+
## type [WithCleanStart](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L45>)
753775

754776
WithCleanStart sets whether the initial connection will be made without retaining any existing session state. This is by definition set to false for any reconnections.
755777

756778
```go
757779
type WithCleanStart bool
758780
```
759781

760-
<a name="WithClientID"></a>
761-
## type [WithClientID](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L45>)
762-
763-
WithClientID sets the client identifier. If not provided, it will default to a random valid client ID to support session reconnection.
764-
765-
```go
766-
type WithClientID string
767-
```
768-
769782
<a name="WithConnectUserProperties"></a>
770-
## type [WithConnectUserProperties](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L63>)
783+
## type [WithConnectUserProperties](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L58>)
771784

772785
WithConnectUserProperties sets the user properties for the CONNECT packet.
773786

@@ -776,7 +789,7 @@ type WithConnectUserProperties map[string]string
776789
```
777790

778791
<a name="WithConnectionTimeout"></a>
779-
## type [WithConnectionTimeout](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L41>)
792+
## type [WithConnectionTimeout](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L40>)
780793

781794
WithConnectionTimeout sets the connection timeout for a single connection attempt. If a timeout is desired for the entire connection process, it should be specified via the connection retry policy.
782795

@@ -803,7 +816,7 @@ type WithCorrelationData = mqtt.WithCorrelationData
803816
```
804817

805818
<a name="WithKeepAlive"></a>
806-
## type [WithKeepAlive](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L53>)
819+
## type [WithKeepAlive](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L48>)
807820

808821
WithKeepAlive sets the keep\-alive interval \(in seconds\).
809822

@@ -830,7 +843,7 @@ type WithNoLocal = mqtt.WithNoLocal
830843
```
831844

832845
<a name="WithPassword"></a>
833-
## type [WithPassword](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L71>)
846+
## type [WithPassword](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L66>)
834847

835848
WithPassword sets the PasswordProvider that the session client uses to get the password for each connection.
836849

@@ -857,7 +870,7 @@ type WithQoS = mqtt.WithQoS
857870
```
858871

859872
<a name="WithReceiveMaximum"></a>
860-
## type [WithReceiveMaximum](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L59>)
873+
## type [WithReceiveMaximum](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L54>)
861874

862875
WithReceiveMaximum sets the client\-side receive maximum.
863876

@@ -893,7 +906,7 @@ type WithRetainHandling = mqtt.WithRetainHandling
893906
```
894907

895908
<a name="WithSessionExpiry"></a>
896-
## type [WithSessionExpiry](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L56>)
909+
## type [WithSessionExpiry](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L51>)
897910

898911
WithSessionExpiry sets the session expiry interval \(in seconds\).
899912

@@ -911,7 +924,7 @@ type WithUserProperties = mqtt.WithUserProperties
911924
```
912925

913926
<a name="WithUsername"></a>
914-
## type [WithUsername](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L67>)
927+
## type [WithUsername](<https://github.com/Azure/iot-operations-sdks/blob/main/go/mqtt/session_client_options.go#L62>)
915928

916929
WithUsername sets the UsernameProvider that the session client uses to get the username for each connection.
917930

go/mqtt/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ func main() {
3737
ctx := context.Background()
3838

3939
// Create a new session client with the above settings.
40-
client := mqtt.NewSessionClient(
40+
client, _ := mqtt.NewSessionClient(
41+
clientID,
4142
mqtt.TCPConnection(hostname, port),
42-
mqtt.WithClientID(clientID),
4343
)
4444

4545
// Message handlers should be registered before calling Start unless using

go/mqtt/connect.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ func (c *SessionClient) connect(
177177
}
178178

179179
pahoClient := paho.NewClient(paho.ClientConfig{
180-
ClientID: c.options.ClientID,
180+
ClientID: c.clientID,
181181
Session: c.session,
182182
Conn: conn,
183183
AuthHandler: auther,
@@ -322,7 +322,7 @@ func (c *SessionClient) buildConnectPacket(
322322
reconnect bool,
323323
) (*paho.Connect, error) {
324324
packet := &paho.Connect{
325-
ClientID: c.options.ClientID,
325+
ClientID: c.clientID,
326326
CleanStart: !reconnect && c.options.CleanStart,
327327
KeepAlive: c.options.KeepAlive,
328328
Properties: &paho.ConnectProperties{

0 commit comments

Comments
 (0)