github.com/argoproj/argo-events@v1.9.1/eventsources/sources/azureeventshub/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 azureeventshub 18 19 import ( 20 "context" 21 "encoding/json" 22 "fmt" 23 "time" 24 25 eventhub "github.com/Azure/azure-event-hubs-go/v3" 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 azure events hub event source 39 type EventListener struct { 40 EventSourceName string 41 EventName string 42 AzureEventsHubEventSource v1alpha1.AzureEventsHubEventSource 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.AzureEventsHub 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 Azure Events Hub event source...") 66 defer sources.Recover(el.GetEventName()) 67 68 hubEventSource := &el.AzureEventsHubEventSource 69 log.Info("retrieving the shared access key name...") 70 sharedAccessKeyName, err := common.GetSecretFromVolume(hubEventSource.SharedAccessKeyName) 71 if err != nil { 72 return fmt.Errorf("failed to retrieve the shared access key name from secret %s, %w", hubEventSource.SharedAccessKeyName.Name, err) 73 } 74 75 log.Info("retrieving the shared access key...") 76 sharedAccessKey, err := common.GetSecretFromVolume(hubEventSource.SharedAccessKey) 77 if err != nil { 78 return fmt.Errorf("failed to retrieve the shared access key from secret %s, %w", hubEventSource.SharedAccessKey.Name, err) 79 } 80 81 endpoint := fmt.Sprintf("Endpoint=sb://%s/;SharedAccessKeyName=%s;SharedAccessKey=%s;EntityPath=%s", hubEventSource.FQDN, sharedAccessKeyName, sharedAccessKey, hubEventSource.HubName) 82 83 log.Info("connecting to the hub...") 84 hub, err := eventhub.NewHubFromConnectionString(endpoint) 85 if err != nil { 86 return fmt.Errorf("failed to connect to the hub %s, %w", hubEventSource.HubName, err) 87 } 88 89 handler := func(c context.Context, event *eventhub.Event) error { 90 defer func(start time.Time) { 91 el.Metrics.EventProcessingDuration(el.GetEventSourceName(), el.GetEventName(), float64(time.Since(start)/time.Millisecond)) 92 }(time.Now()) 93 94 log.Info("received an event from eventshub...") 95 96 eventData := &events.AzureEventsHubEventData{ 97 Id: event.ID, 98 Body: event.Data, 99 Metadata: hubEventSource.Metadata, 100 } 101 if event.PartitionKey != nil { 102 eventData.PartitionKey = *event.PartitionKey 103 } 104 105 eventBytes, err := json.Marshal(eventData) 106 if err != nil { 107 el.Metrics.EventProcessingFailed(el.GetEventSourceName(), el.GetEventName()) 108 return fmt.Errorf("failed to marshal the event data for event source %s and message id %s, %w", el.GetEventName(), event.ID, err) 109 } 110 111 log.Info("dispatching the event to eventbus...") 112 if err = dispatch(eventBytes); err != nil { 113 el.Metrics.EventProcessingFailed(el.GetEventSourceName(), el.GetEventName()) 114 log.Errorw("failed to dispatch Azure EventHub event", zap.Error(err)) 115 return err 116 } 117 return nil 118 } 119 120 // listen to each partition of the Event Hub 121 log.Info("gathering the hub runtime information...") 122 runtimeInfo, err := hub.GetRuntimeInformation(ctx) 123 if err != nil { 124 return fmt.Errorf("failed to get the hub runtime information for %s, %w", el.GetEventName(), err) 125 } 126 127 if runtimeInfo == nil { 128 return fmt.Errorf("runtime information is not available for %s, %w", el.GetEventName(), err) 129 } 130 131 if runtimeInfo.PartitionIDs == nil { 132 return fmt.Errorf("no partition ids are available for %s, %w", el.GetEventName(), err) 133 } 134 135 log.Info("handling the partitions...") 136 for _, partitionID := range runtimeInfo.PartitionIDs { 137 if _, err := hub.Receive(ctx, partitionID, handler, eventhub.ReceiveWithLatestOffset()); err != nil { 138 return fmt.Errorf("failed to receive events from partition %s, %w", partitionID, err) 139 } 140 } 141 142 <-ctx.Done() 143 log.Info("stopping listener handlers") 144 145 hub.Close(context.Background()) 146 147 return nil 148 }