github.com/argoproj/argo-events@v1.9.1/eventsources/sources/emitter/start.go (about) 1 /* 2 Copyright 2018 BlackRock, Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package emitter 18 19 import ( 20 "context" 21 "encoding/json" 22 "fmt" 23 "time" 24 25 emitter "github.com/emitter-io/go/v2" 26 "go.uber.org/zap" 27 28 "github.com/argoproj/argo-events/common" 29 "github.com/argoproj/argo-events/common/logging" 30 eventsourcecommon "github.com/argoproj/argo-events/eventsources/common" 31 "github.com/argoproj/argo-events/eventsources/sources" 32 metrics "github.com/argoproj/argo-events/metrics" 33 apicommon "github.com/argoproj/argo-events/pkg/apis/common" 34 "github.com/argoproj/argo-events/pkg/apis/events" 35 "github.com/argoproj/argo-events/pkg/apis/eventsource/v1alpha1" 36 ) 37 38 // EventListener implements Eventing for Emitter event source 39 type EventListener struct { 40 EventSourceName string 41 EventName string 42 EmitterEventSource v1alpha1.EmitterEventSource 43 Metrics *metrics.Metrics 44 } 45 46 // GetEventSourceName returns name of event source 47 func (el *EventListener) GetEventSourceName() string { 48 return el.EventSourceName 49 } 50 51 // GetEventName returns name of event 52 func (el *EventListener) GetEventName() string { 53 return el.EventName 54 } 55 56 // GetEventSourceType return type of event server 57 func (el *EventListener) GetEventSourceType() apicommon.EventSourceType { 58 return apicommon.EmitterEvent 59 } 60 61 // StartListening starts listening events 62 func (el *EventListener) StartListening(ctx context.Context, dispatch func([]byte, ...eventsourcecommon.Option) error) error { 63 log := logging.FromContext(ctx). 64 With(logging.LabelEventSourceType, el.GetEventSourceType(), logging.LabelEventName, el.GetEventName()) 65 log.Info("started processing the Emitter event source...") 66 defer sources.Recover(el.GetEventName()) 67 68 emitterEventSource := &el.EmitterEventSource 69 70 var options []func(client *emitter.Client) 71 if emitterEventSource.TLS != nil { 72 tlsConfig, err := common.GetTLSConfig(emitterEventSource.TLS) 73 if err != nil { 74 return fmt.Errorf("failed to get the tls configuration, %w", err) 75 } 76 options = append(options, emitter.WithTLSConfig(tlsConfig)) 77 } 78 options = append(options, emitter.WithBrokers(emitterEventSource.Broker), emitter.WithAutoReconnect(true)) 79 80 if emitterEventSource.Username != nil { 81 username, err := common.GetSecretFromVolume(emitterEventSource.Username) 82 if err != nil { 83 return fmt.Errorf("failed to retrieve the username from %s, %w", emitterEventSource.Username.Name, err) 84 } 85 options = append(options, emitter.WithUsername(username)) 86 } 87 88 if emitterEventSource.Password != nil { 89 password, err := common.GetSecretFromVolume(emitterEventSource.Password) 90 if err != nil { 91 return fmt.Errorf("failed to retrieve the password from %s, %w", emitterEventSource.Password.Name, err) 92 } 93 options = append(options, emitter.WithPassword(password)) 94 } 95 96 if emitterEventSource.JSONBody { 97 log.Info("assuming all events have a json body...") 98 } 99 100 log.Infow("creating a client", zap.Any("channelName", emitterEventSource.ChannelName)) 101 client := emitter.NewClient(options...) 102 103 if err := common.DoWithRetry(emitterEventSource.ConnectionBackoff, func() error { 104 if err := client.Connect(); err != nil { 105 return err 106 } 107 return nil 108 }); err != nil { 109 return fmt.Errorf("failed to connect to %s, %w", emitterEventSource.Broker, err) 110 } 111 112 if err := client.Subscribe(emitterEventSource.ChannelKey, emitterEventSource.ChannelName, func(_ *emitter.Client, message emitter.Message) { 113 defer func(start time.Time) { 114 el.Metrics.EventProcessingDuration(el.GetEventSourceName(), el.GetEventName(), float64(time.Since(start)/time.Millisecond)) 115 }(time.Now()) 116 117 body := message.Payload() 118 event := &events.EmitterEventData{ 119 Topic: message.Topic(), 120 Body: body, 121 Metadata: emitterEventSource.Metadata, 122 } 123 if emitterEventSource.JSONBody { 124 event.Body = (*json.RawMessage)(&body) 125 } 126 eventBytes, err := json.Marshal(event) 127 128 if err != nil { 129 log.Errorw("failed to marshal the event data", zap.Error(err)) 130 el.Metrics.EventProcessingFailed(el.GetEventSourceName(), el.GetEventName()) 131 return 132 } 133 log.Info("dispatching event on data channel...") 134 if err = dispatch(eventBytes); err != nil { 135 log.Errorw("failed to dispatch event", zap.Error(err)) 136 el.Metrics.EventProcessingFailed(el.GetEventSourceName(), el.GetEventName()) 137 } 138 }); err != nil { 139 return fmt.Errorf("failed to subscribe to channel %s, %w", emitterEventSource.ChannelName, err) 140 } 141 142 <-ctx.Done() 143 144 log.Infow("event source stopped, unsubscribe the channel", zap.Any("channelName", emitterEventSource.ChannelName)) 145 146 if err := client.Unsubscribe(emitterEventSource.ChannelKey, emitterEventSource.ChannelName); err != nil { 147 log.Errorw("failed to unsubscribe", zap.Any("channelName", emitterEventSource.ChannelName), zap.Error(err)) 148 } 149 150 return nil 151 }