github.com/argoproj/argo-events@v1.9.1/eventsources/eventing.go (about) 1 package eventsources 2 3 import ( 4 "context" 5 "crypto/rand" 6 "encoding/json" 7 "fmt" 8 "math/big" 9 "strings" 10 "sync" 11 "time" 12 13 cloudevents "github.com/cloudevents/sdk-go/v2" 14 "github.com/google/uuid" 15 "go.uber.org/zap" 16 17 "github.com/argoproj/argo-events/common" 18 "github.com/argoproj/argo-events/common/expr" 19 "github.com/argoproj/argo-events/common/leaderelection" 20 "github.com/argoproj/argo-events/common/logging" 21 "github.com/argoproj/argo-events/eventbus" 22 eventbuscommon "github.com/argoproj/argo-events/eventbus/common" 23 eventsourcecommon "github.com/argoproj/argo-events/eventsources/common" 24 "github.com/argoproj/argo-events/eventsources/sources/amqp" 25 "github.com/argoproj/argo-events/eventsources/sources/awssns" 26 "github.com/argoproj/argo-events/eventsources/sources/awssqs" 27 "github.com/argoproj/argo-events/eventsources/sources/azureeventshub" 28 "github.com/argoproj/argo-events/eventsources/sources/azurequeuestorage" 29 "github.com/argoproj/argo-events/eventsources/sources/azureservicebus" 30 "github.com/argoproj/argo-events/eventsources/sources/bitbucket" 31 "github.com/argoproj/argo-events/eventsources/sources/bitbucketserver" 32 "github.com/argoproj/argo-events/eventsources/sources/calendar" 33 "github.com/argoproj/argo-events/eventsources/sources/emitter" 34 "github.com/argoproj/argo-events/eventsources/sources/file" 35 "github.com/argoproj/argo-events/eventsources/sources/gcppubsub" 36 "github.com/argoproj/argo-events/eventsources/sources/generic" 37 "github.com/argoproj/argo-events/eventsources/sources/gerrit" 38 "github.com/argoproj/argo-events/eventsources/sources/github" 39 "github.com/argoproj/argo-events/eventsources/sources/gitlab" 40 "github.com/argoproj/argo-events/eventsources/sources/hdfs" 41 "github.com/argoproj/argo-events/eventsources/sources/kafka" 42 "github.com/argoproj/argo-events/eventsources/sources/minio" 43 "github.com/argoproj/argo-events/eventsources/sources/mqtt" 44 "github.com/argoproj/argo-events/eventsources/sources/nats" 45 "github.com/argoproj/argo-events/eventsources/sources/nsq" 46 "github.com/argoproj/argo-events/eventsources/sources/pulsar" 47 "github.com/argoproj/argo-events/eventsources/sources/redis" 48 redisstream "github.com/argoproj/argo-events/eventsources/sources/redis_stream" 49 "github.com/argoproj/argo-events/eventsources/sources/resource" 50 "github.com/argoproj/argo-events/eventsources/sources/sftp" 51 "github.com/argoproj/argo-events/eventsources/sources/slack" 52 "github.com/argoproj/argo-events/eventsources/sources/storagegrid" 53 "github.com/argoproj/argo-events/eventsources/sources/stripe" 54 "github.com/argoproj/argo-events/eventsources/sources/webhook" 55 eventsourcemetrics "github.com/argoproj/argo-events/metrics" 56 apicommon "github.com/argoproj/argo-events/pkg/apis/common" 57 eventbusv1alpha1 "github.com/argoproj/argo-events/pkg/apis/eventbus/v1alpha1" 58 "github.com/argoproj/argo-events/pkg/apis/eventsource/v1alpha1" 59 ) 60 61 // EventingServer is the server API for Eventing service. 62 type EventingServer interface { 63 64 // ValidateEventSource validates an event source. 65 ValidateEventSource(context.Context) error 66 67 GetEventSourceName() string 68 69 GetEventName() string 70 71 GetEventSourceType() apicommon.EventSourceType 72 73 // Function to start listening events. 74 StartListening(ctx context.Context, dispatch func([]byte, ...eventsourcecommon.Option) error) error 75 } 76 77 // GetEventingServers returns the mapping of event source type and list of eventing servers 78 func GetEventingServers(eventSource *v1alpha1.EventSource, metrics *eventsourcemetrics.Metrics) (map[apicommon.EventSourceType][]EventingServer, map[string]*v1alpha1.EventSourceFilter) { 79 result := make(map[apicommon.EventSourceType][]EventingServer) 80 filters := make(map[string]*v1alpha1.EventSourceFilter) 81 if len(eventSource.Spec.AMQP) != 0 { 82 servers := []EventingServer{} 83 for k, v := range eventSource.Spec.AMQP { 84 if v.Filter != nil { 85 filters[k] = v.Filter 86 } 87 servers = append(servers, &amqp.EventListener{EventSourceName: eventSource.Name, EventName: k, AMQPEventSource: v, Metrics: metrics}) 88 } 89 result[apicommon.AMQPEvent] = servers 90 } 91 if len(eventSource.Spec.AzureEventsHub) != 0 { 92 servers := []EventingServer{} 93 for k, v := range eventSource.Spec.AzureEventsHub { 94 if v.Filter != nil { 95 filters[k] = v.Filter 96 } 97 servers = append(servers, &azureeventshub.EventListener{EventSourceName: eventSource.Name, EventName: k, AzureEventsHubEventSource: v, Metrics: metrics}) 98 } 99 result[apicommon.AzureEventsHub] = servers 100 } 101 if len(eventSource.Spec.AzureQueueStorage) != 0 { 102 servers := []EventingServer{} 103 for k, v := range eventSource.Spec.AzureQueueStorage { 104 if v.Filter != nil { 105 filters[k] = v.Filter 106 } 107 servers = append(servers, &azurequeuestorage.EventListener{EventSourceName: eventSource.Name, EventName: k, AzureQueueStorageEventSource: v, Metrics: metrics}) 108 } 109 result[apicommon.AzureQueueStorage] = servers 110 } 111 if len(eventSource.Spec.AzureServiceBus) != 0 { 112 servers := []EventingServer{} 113 for k, v := range eventSource.Spec.AzureServiceBus { 114 if v.Filter != nil { 115 filters[k] = v.Filter 116 } 117 servers = append(servers, &azureservicebus.EventListener{EventSourceName: eventSource.Name, EventName: k, AzureServiceBusEventSource: v, Metrics: metrics}) 118 } 119 result[apicommon.AzureServiceBus] = servers 120 } 121 if len(eventSource.Spec.Bitbucket) != 0 { 122 servers := []EventingServer{} 123 for k, v := range eventSource.Spec.Bitbucket { 124 if v.Filter != nil { 125 filters[k] = v.Filter 126 } 127 servers = append(servers, &bitbucket.EventListener{EventSourceName: eventSource.Name, EventName: k, BitbucketEventSource: v, Metrics: metrics}) 128 } 129 result[apicommon.BitbucketEvent] = servers 130 } 131 if len(eventSource.Spec.BitbucketServer) != 0 { 132 servers := []EventingServer{} 133 for k, v := range eventSource.Spec.BitbucketServer { 134 if v.Filter != nil { 135 filters[k] = v.Filter 136 } 137 servers = append(servers, &bitbucketserver.EventListener{EventSourceName: eventSource.Name, EventName: k, BitbucketServerEventSource: v, Metrics: metrics}) 138 } 139 result[apicommon.BitbucketServerEvent] = servers 140 } 141 if len(eventSource.Spec.Calendar) != 0 { 142 servers := []EventingServer{} 143 for k, v := range eventSource.Spec.Calendar { 144 if v.Filter != nil { 145 filters[k] = v.Filter 146 } 147 servers = append(servers, &calendar.EventListener{EventSourceName: eventSource.Name, EventName: k, CalendarEventSource: v, Namespace: eventSource.Namespace, Metrics: metrics}) 148 } 149 result[apicommon.CalendarEvent] = servers 150 } 151 if len(eventSource.Spec.Emitter) != 0 { 152 servers := []EventingServer{} 153 for k, v := range eventSource.Spec.Emitter { 154 if v.Filter != nil { 155 filters[k] = v.Filter 156 } 157 servers = append(servers, &emitter.EventListener{EventSourceName: eventSource.Name, EventName: k, EmitterEventSource: v, Metrics: metrics}) 158 } 159 result[apicommon.EmitterEvent] = servers 160 } 161 if len(eventSource.Spec.File) != 0 { 162 servers := []EventingServer{} 163 for k, v := range eventSource.Spec.File { 164 if v.Filter != nil { 165 filters[k] = v.Filter 166 } 167 servers = append(servers, &file.EventListener{EventSourceName: eventSource.Name, EventName: k, FileEventSource: v, Metrics: metrics}) 168 } 169 result[apicommon.FileEvent] = servers 170 } 171 if len(eventSource.Spec.SFTP) != 0 { 172 servers := []EventingServer{} 173 for k, v := range eventSource.Spec.SFTP { 174 if v.Filter != nil { 175 filters[k] = v.Filter 176 } 177 servers = append(servers, &sftp.EventListener{EventSourceName: eventSource.Name, EventName: k, SFTPEventSource: v, Metrics: metrics}) 178 } 179 result[apicommon.SFTPEvent] = servers 180 } 181 if len(eventSource.Spec.Gerrit) != 0 { 182 servers := []EventingServer{} 183 for k, v := range eventSource.Spec.Gerrit { 184 if v.Filter != nil { 185 filters[k] = v.Filter 186 } 187 servers = append(servers, &gerrit.EventListener{EventSourceName: eventSource.Name, EventName: k, GerritEventSource: v, Metrics: metrics}) 188 } 189 result[apicommon.GerritEvent] = servers 190 } 191 if len(eventSource.Spec.Github) != 0 { 192 servers := []EventingServer{} 193 for k, v := range eventSource.Spec.Github { 194 if v.Filter != nil { 195 filters[k] = v.Filter 196 } 197 servers = append(servers, &github.EventListener{EventSourceName: eventSource.Name, EventName: k, GithubEventSource: v, Metrics: metrics}) 198 } 199 result[apicommon.GithubEvent] = servers 200 } 201 if len(eventSource.Spec.Gitlab) != 0 { 202 servers := []EventingServer{} 203 for k, v := range eventSource.Spec.Gitlab { 204 if v.Filter != nil { 205 filters[k] = v.Filter 206 } 207 servers = append(servers, &gitlab.EventListener{EventSourceName: eventSource.Name, EventName: k, GitlabEventSource: v, Metrics: metrics}) 208 } 209 result[apicommon.GitlabEvent] = servers 210 } 211 if len(eventSource.Spec.HDFS) != 0 { 212 servers := []EventingServer{} 213 for k, v := range eventSource.Spec.HDFS { 214 if v.Filter != nil { 215 filters[k] = v.Filter 216 } 217 servers = append(servers, &hdfs.EventListener{EventSourceName: eventSource.Name, EventName: k, HDFSEventSource: v, Metrics: metrics}) 218 } 219 result[apicommon.HDFSEvent] = servers 220 } 221 if len(eventSource.Spec.Kafka) != 0 { 222 servers := []EventingServer{} 223 for k, v := range eventSource.Spec.Kafka { 224 if v.Filter != nil { 225 filters[k] = v.Filter 226 } 227 servers = append(servers, &kafka.EventListener{EventSourceName: eventSource.Name, EventName: k, KafkaEventSource: v, Metrics: metrics}) 228 } 229 result[apicommon.KafkaEvent] = servers 230 } 231 if len(eventSource.Spec.MQTT) != 0 { 232 servers := []EventingServer{} 233 for k, v := range eventSource.Spec.MQTT { 234 if v.Filter != nil { 235 filters[k] = v.Filter 236 } 237 servers = append(servers, &mqtt.EventListener{EventSourceName: eventSource.Name, EventName: k, MQTTEventSource: v, Metrics: metrics}) 238 } 239 result[apicommon.MQTTEvent] = servers 240 } 241 if len(eventSource.Spec.Minio) != 0 { 242 servers := []EventingServer{} 243 for k, v := range eventSource.Spec.Minio { 244 servers = append(servers, &minio.EventListener{EventSourceName: eventSource.Name, EventName: k, MinioEventSource: v, Metrics: metrics}) 245 } 246 result[apicommon.MinioEvent] = servers 247 } 248 if len(eventSource.Spec.NATS) != 0 { 249 servers := []EventingServer{} 250 for k, v := range eventSource.Spec.NATS { 251 if v.Filter != nil { 252 filters[k] = v.Filter 253 } 254 servers = append(servers, &nats.EventListener{EventSourceName: eventSource.Name, EventName: k, NATSEventSource: v, Metrics: metrics}) 255 } 256 result[apicommon.NATSEvent] = servers 257 } 258 if len(eventSource.Spec.NSQ) != 0 { 259 servers := []EventingServer{} 260 for k, v := range eventSource.Spec.NSQ { 261 if v.Filter != nil { 262 filters[k] = v.Filter 263 } 264 servers = append(servers, &nsq.EventListener{EventSourceName: eventSource.Name, EventName: k, NSQEventSource: v, Metrics: metrics}) 265 } 266 result[apicommon.NSQEvent] = servers 267 } 268 if len(eventSource.Spec.PubSub) != 0 { 269 servers := []EventingServer{} 270 for k, v := range eventSource.Spec.PubSub { 271 if v.Filter != nil { 272 filters[k] = v.Filter 273 } 274 servers = append(servers, &gcppubsub.EventListener{EventSourceName: eventSource.Name, EventName: k, PubSubEventSource: v, Metrics: metrics}) 275 } 276 result[apicommon.PubSubEvent] = servers 277 } 278 if len(eventSource.Spec.Redis) != 0 { 279 servers := []EventingServer{} 280 for k, v := range eventSource.Spec.Redis { 281 if v.Filter != nil { 282 filters[k] = v.Filter 283 } 284 servers = append(servers, &redis.EventListener{EventSourceName: eventSource.Name, EventName: k, RedisEventSource: v, Metrics: metrics}) 285 } 286 result[apicommon.RedisEvent] = servers 287 } 288 if len(eventSource.Spec.RedisStream) != 0 { 289 servers := []EventingServer{} 290 for k, v := range eventSource.Spec.RedisStream { 291 if v.Filter != nil { 292 filters[k] = v.Filter 293 } 294 servers = append(servers, &redisstream.EventListener{EventSourceName: eventSource.Name, EventName: k, EventSource: v, Metrics: metrics}) 295 } 296 result[apicommon.RedisStreamEvent] = servers 297 } 298 if len(eventSource.Spec.SNS) != 0 { 299 servers := []EventingServer{} 300 for k, v := range eventSource.Spec.SNS { 301 if v.Filter != nil { 302 filters[k] = v.Filter 303 } 304 servers = append(servers, &awssns.EventListener{EventSourceName: eventSource.Name, EventName: k, SNSEventSource: v, Metrics: metrics}) 305 } 306 result[apicommon.SNSEvent] = servers 307 } 308 if len(eventSource.Spec.SQS) != 0 { 309 servers := []EventingServer{} 310 for k, v := range eventSource.Spec.SQS { 311 if v.Filter != nil { 312 filters[k] = v.Filter 313 } 314 servers = append(servers, &awssqs.EventListener{EventSourceName: eventSource.Name, EventName: k, SQSEventSource: v, Metrics: metrics}) 315 } 316 result[apicommon.SQSEvent] = servers 317 } 318 if len(eventSource.Spec.Slack) != 0 { 319 servers := []EventingServer{} 320 for k, v := range eventSource.Spec.Slack { 321 if v.Filter != nil { 322 filters[k] = v.Filter 323 } 324 servers = append(servers, &slack.EventListener{EventSourceName: eventSource.Name, EventName: k, SlackEventSource: v, Metrics: metrics}) 325 } 326 result[apicommon.SlackEvent] = servers 327 } 328 if len(eventSource.Spec.StorageGrid) != 0 { 329 servers := []EventingServer{} 330 for k, v := range eventSource.Spec.StorageGrid { 331 servers = append(servers, &storagegrid.EventListener{EventSourceName: eventSource.Name, EventName: k, StorageGridEventSource: v, Metrics: metrics}) 332 } 333 result[apicommon.StorageGridEvent] = servers 334 } 335 if len(eventSource.Spec.Stripe) != 0 { 336 servers := []EventingServer{} 337 for k, v := range eventSource.Spec.Stripe { 338 servers = append(servers, &stripe.EventListener{EventSourceName: eventSource.Name, EventName: k, StripeEventSource: v, Metrics: metrics}) 339 } 340 result[apicommon.StripeEvent] = servers 341 } 342 if len(eventSource.Spec.Webhook) != 0 { 343 servers := []EventingServer{} 344 for k, v := range eventSource.Spec.Webhook { 345 if v.Filter != nil { 346 filters[k] = v.Filter 347 } 348 servers = append(servers, &webhook.EventListener{EventSourceName: eventSource.Name, EventName: k, Webhook: v, Metrics: metrics}) 349 } 350 result[apicommon.WebhookEvent] = servers 351 } 352 if len(eventSource.Spec.Resource) != 0 { 353 servers := []EventingServer{} 354 for k, v := range eventSource.Spec.Resource { 355 servers = append(servers, &resource.EventListener{EventSourceName: eventSource.Name, EventName: k, ResourceEventSource: v, Metrics: metrics}) 356 } 357 result[apicommon.ResourceEvent] = servers 358 } 359 if len(eventSource.Spec.Pulsar) != 0 { 360 servers := []EventingServer{} 361 for k, v := range eventSource.Spec.Pulsar { 362 if v.Filter != nil { 363 filters[k] = v.Filter 364 } 365 servers = append(servers, &pulsar.EventListener{EventSourceName: eventSource.Name, EventName: k, PulsarEventSource: v, Metrics: metrics}) 366 } 367 result[apicommon.PulsarEvent] = servers 368 } 369 if len(eventSource.Spec.Generic) != 0 { 370 servers := []EventingServer{} 371 for k, v := range eventSource.Spec.Generic { 372 if v.Filter != nil { 373 filters[k] = v.Filter 374 } 375 servers = append(servers, &generic.EventListener{EventSourceName: eventSource.Name, EventName: k, GenericEventSource: v, Metrics: metrics}) 376 } 377 result[apicommon.GenericEvent] = servers 378 } 379 return result, filters 380 } 381 382 // EventSourceAdaptor is the adaptor for eventsource service 383 type EventSourceAdaptor struct { 384 eventSource *v1alpha1.EventSource 385 eventBusConfig *eventbusv1alpha1.BusConfig 386 eventBusSubject string 387 hostname string 388 389 eventBusConn eventbuscommon.EventSourceConnection 390 391 metrics *eventsourcemetrics.Metrics 392 } 393 394 // NewEventSourceAdaptor returns a new EventSourceAdaptor 395 func NewEventSourceAdaptor(eventSource *v1alpha1.EventSource, eventBusConfig *eventbusv1alpha1.BusConfig, eventBusSubject, hostname string, metrics *eventsourcemetrics.Metrics) *EventSourceAdaptor { 396 return &EventSourceAdaptor{ 397 eventSource: eventSource, 398 eventBusConfig: eventBusConfig, 399 eventBusSubject: eventBusSubject, 400 hostname: hostname, 401 metrics: metrics, 402 } 403 } 404 405 // Start function 406 func (e *EventSourceAdaptor) Start(ctx context.Context) error { 407 log := logging.FromContext(ctx) 408 409 recreateTypes := make(map[apicommon.EventSourceType]bool) 410 for _, esType := range apicommon.RecreateStrategyEventSources { 411 recreateTypes[esType] = true 412 } 413 isRecreateType := false 414 servers, filters := GetEventingServers(e.eventSource, e.metrics) 415 for k := range servers { 416 if _, ok := recreateTypes[k]; ok { 417 isRecreateType = true 418 } 419 // This is based on the presumption that all the events in one 420 // EventSource object use the same type of deployment strategy 421 break 422 } 423 424 if !isRecreateType { 425 return e.run(ctx, servers, filters) 426 } 427 428 clusterName := fmt.Sprintf("%s-eventsource-%s", e.eventSource.Namespace, e.eventSource.Name) 429 replicas := int(e.eventSource.Spec.GetReplicas()) 430 leasename := fmt.Sprintf("eventsource-%s", e.eventSource.Name) 431 432 elector, err := leaderelection.NewElector(ctx, *e.eventBusConfig, clusterName, replicas, e.eventSource.Namespace, leasename, e.hostname) 433 if err != nil { 434 log.Errorw("failed to get an elector", zap.Error(err)) 435 return err 436 } 437 438 elector.RunOrDie(ctx, leaderelection.LeaderCallbacks{ 439 OnStartedLeading: func(ctx context.Context) { 440 if err := e.run(ctx, servers, filters); err != nil { 441 log.Fatalw("failed to start", zap.Error(err)) 442 } 443 }, 444 OnStoppedLeading: func() { 445 log.Fatalf("leader lost: %s", e.hostname) 446 }, 447 }) 448 449 return nil 450 } 451 452 func (e *EventSourceAdaptor) run(ctx context.Context, servers map[apicommon.EventSourceType][]EventingServer, filters map[string]*v1alpha1.EventSourceFilter) error { 453 logger := logging.FromContext(ctx) 454 logger.Info("Starting event source server...") 455 clientID := generateClientID(e.hostname) 456 driver, err := eventbus.GetEventSourceDriver(ctx, *e.eventBusConfig, e.eventSource.Name, e.eventBusSubject) 457 if err != nil { 458 logger.Errorw("failed to get eventbus driver", zap.Error(err)) 459 return err 460 } 461 if err = common.DoWithRetry(&common.DefaultBackoff, func() error { 462 err = driver.Initialize() 463 if err != nil { 464 return err 465 } 466 e.eventBusConn, err = driver.Connect(clientID) 467 return err 468 }); err != nil { 469 logger.Errorw("failed to connect to eventbus", zap.Error(err)) 470 return err 471 } 472 defer e.eventBusConn.Close() 473 474 ctx, cancel := context.WithCancel(ctx) 475 connWG := &sync.WaitGroup{} 476 477 // Daemon to reconnect 478 connWG.Add(1) 479 go func() { 480 defer connWG.Done() 481 logger.Info("starting eventbus connection daemon...") 482 ticker := time.NewTicker(5 * time.Second) 483 defer ticker.Stop() 484 for { 485 select { 486 case <-ctx.Done(): 487 logger.Info("exiting eventbus connection daemon...") 488 return 489 case <-ticker.C: 490 if e.eventBusConn == nil || e.eventBusConn.IsClosed() { 491 logger.Info("NATS connection lost, reconnecting...") 492 // Regenerate the client ID to avoid the issue that NAT server still thinks the client is alive. 493 clientID := generateClientID(e.hostname) 494 driver, err := eventbus.GetEventSourceDriver(ctx, *e.eventBusConfig, e.eventSource.Name, e.eventBusSubject) 495 if err != nil { 496 logger.Errorw("failed to get eventbus driver during reconnection", zap.Error(err)) 497 continue 498 } 499 e.eventBusConn, err = driver.Connect(clientID) 500 if err != nil { 501 logger.Errorw("failed to reconnect to eventbus", zap.Error(err)) 502 continue 503 } 504 logger.Info("reconnected to eventbus successfully") 505 } 506 } 507 } 508 }() 509 510 wg := &sync.WaitGroup{} 511 for _, ss := range servers { 512 for _, server := range ss { 513 // Validation has been done in eventsource-controller, it's harmless to do it again here. 514 err := server.ValidateEventSource(ctx) 515 if err != nil { 516 logger.Errorw("Validation failed", zap.Error(err), zap.Any(logging.LabelEventName, 517 server.GetEventName()), zap.Any(logging.LabelEventSourceType, server.GetEventSourceType())) 518 // Continue starting other event services instead of failing all of them 519 continue 520 } 521 wg.Add(1) 522 go func(s EventingServer) { 523 defer wg.Done() 524 e.metrics.IncRunningServices(s.GetEventSourceName()) 525 defer e.metrics.DecRunningServices(s.GetEventSourceName()) 526 duration := apicommon.FromString("1s") 527 factor := apicommon.NewAmount("1") 528 jitter := apicommon.NewAmount("30") 529 backoff := apicommon.Backoff{ 530 Steps: 10, 531 Duration: &duration, 532 Factor: &factor, 533 Jitter: &jitter, 534 } 535 if err = common.DoWithRetry(&backoff, func() error { 536 return s.StartListening(ctx, func(data []byte, opts ...eventsourcecommon.Option) error { 537 if filter, ok := filters[s.GetEventName()]; ok { 538 proceed, err := filterEvent(data, filter) 539 if err != nil { 540 logger.Errorw("Failed to filter event", zap.Error(err)) 541 return nil 542 } 543 if !proceed { 544 logger.Info("Filter condition not met, skip dispatching") 545 return nil 546 } 547 } 548 549 event := cloudevents.NewEvent() 550 event.SetID(fmt.Sprintf("%x", uuid.New())) 551 event.SetType(string(s.GetEventSourceType())) 552 event.SetSource(s.GetEventSourceName()) 553 event.SetSubject(s.GetEventName()) 554 event.SetTime(time.Now()) 555 for _, opt := range opts { 556 err := opt(&event) 557 if err != nil { 558 return err 559 } 560 } 561 err := event.SetData(cloudevents.ApplicationJSON, data) 562 if err != nil { 563 return err 564 } 565 eventBody, err := json.Marshal(event) 566 if err != nil { 567 return err 568 } 569 570 if e.eventBusConn == nil || e.eventBusConn.IsClosed() { 571 return eventbuscommon.NewEventBusError(fmt.Errorf("failed to publish event, eventbus connection closed")) 572 } 573 574 msg := eventbuscommon.Message{ 575 MsgHeader: eventbuscommon.MsgHeader{ 576 EventSourceName: s.GetEventSourceName(), 577 EventName: s.GetEventName(), 578 ID: event.ID(), 579 }, 580 Body: eventBody, 581 } 582 583 if err = common.DoWithRetry(&common.DefaultBackoff, func() error { 584 return e.eventBusConn.Publish(ctx, msg) 585 }); err != nil { 586 logger.Errorw("Failed to publish an event", zap.Error(err), zap.String(logging.LabelEventName, 587 s.GetEventName()), zap.Any(logging.LabelEventSourceType, s.GetEventSourceType())) 588 e.metrics.EventSentFailed(s.GetEventSourceName(), s.GetEventName()) 589 return eventbuscommon.NewEventBusError(err) 590 } 591 logger.Infow("Succeeded to publish an event", zap.String(logging.LabelEventName, 592 s.GetEventName()), zap.Any(logging.LabelEventSourceType, s.GetEventSourceType()), zap.String("eventID", event.ID())) 593 e.metrics.EventSent(s.GetEventSourceName(), s.GetEventName()) 594 return nil 595 }) 596 }); err != nil { 597 logger.Errorw("Failed to start listening eventsource", zap.Any(logging.LabelEventSourceType, 598 s.GetEventSourceType()), zap.Any(logging.LabelEventName, s.GetEventName()), zap.Error(err)) 599 } 600 }(server) 601 } 602 } 603 logger.Info("Eventing server started.") 604 605 eventServersWGDone := make(chan bool) 606 go func() { 607 wg.Wait() 608 close(eventServersWGDone) 609 }() 610 611 for { 612 select { 613 case <-ctx.Done(): 614 logger.Info("Shutting down...") 615 cancel() 616 <-eventServersWGDone 617 connWG.Wait() 618 return nil 619 case <-eventServersWGDone: 620 logger.Error("Erroring out, no active event server running") 621 cancel() 622 connWG.Wait() 623 return fmt.Errorf("no active event server running") 624 } 625 } 626 } 627 628 func generateClientID(hostname string) string { 629 randomNum, _ := rand.Int(rand.Reader, big.NewInt(int64(1000))) 630 clientID := fmt.Sprintf("client-%s-%v", strings.ReplaceAll(hostname, ".", "_"), randomNum.Int64()) 631 return clientID 632 } 633 634 func filterEvent(data []byte, filter *v1alpha1.EventSourceFilter) (bool, error) { 635 dataMap := make(map[string]interface{}) 636 err := json.Unmarshal(data, &dataMap) 637 if err != nil { 638 return false, fmt.Errorf("failed to unmarshal data, %w", err) 639 } 640 641 params := make(map[string]interface{}) 642 for key, value := range dataMap { 643 params[strings.ReplaceAll(key, "-", "_")] = value 644 } 645 env := expr.GetFuncMap(params) 646 return expr.EvalBool(filter.Expression, env) 647 }