evcc-io/provider/mqtt/registry.go

68 lines
1.8 KiB
Go

package mqtt
import (
"errors"
"fmt"
"sync"
"github.com/evcc-io/evcc/util"
)
type clientRegistry map[string]*Client
func (r clientRegistry) Add(broker string, client *Client) {
if _, exists := r[broker]; exists {
panic(fmt.Sprintf("cannot register duplicate broker: %s", broker))
}
r[broker] = client
}
func (r clientRegistry) Get(broker string) (*Client, error) {
client, exists := r[broker]
if !exists {
return nil, fmt.Errorf("missing mqtt broker configuration: %s", broker)
}
return client, nil
}
var (
mu sync.Mutex
registry clientRegistry = make(map[string]*Client)
)
// RegisteredClient reuses an registered Mqtt publisher or creates a new one
func RegisteredClient(log *util.Logger, broker, user, password, clientID string, qos byte, insecure bool, caCert, clientCert, clientKey string, opts ...Option) (*Client, error) {
key := fmt.Sprintf("%s.%s:%s", broker, user, password)
mu.Lock()
defer mu.Unlock()
client, err := registry.Get(key)
if err != nil {
if clientID == "" {
clientID = ClientID()
}
if client, err = NewClient(log, broker, user, password, clientID, qos, insecure, caCert, clientCert, clientKey, opts...); err == nil {
registry.Add(key, client)
}
}
return client, err
}
// RegisteredClientOrDefault reuses an registered Mqtt publisher or creates a new one.
// If no publisher is configured, it uses the default instance.
func RegisteredClientOrDefault(log *util.Logger, cc Config) (*Client, error) {
client := Instance
var err error
if cc.Broker != "" {
client, err = RegisteredClient(log, cc.Broker, cc.User, cc.Password, cc.ClientID, 1, cc.Insecure, cc.CaCert, cc.ClientCert, cc.ClientKey)
}
if client == nil && err == nil {
err = errors.New("missing mqtt broker configuration")
}
return client, err
}