github.com/argoproj/argo-events@v1.9.1/sensors/triggers/azure-event-hubs/azure_event_hubs.go (about)

     1  /*
     2  Copyright 2020 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  package azure_event_hubs
    17  
    18  import (
    19  	"context"
    20  	"encoding/json"
    21  	"fmt"
    22  
    23  	eventhub "github.com/Azure/azure-event-hubs-go/v3"
    24  	"go.uber.org/zap"
    25  
    26  	"github.com/argoproj/argo-events/common"
    27  	"github.com/argoproj/argo-events/common/logging"
    28  	apicommon "github.com/argoproj/argo-events/pkg/apis/common"
    29  	"github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1"
    30  	"github.com/argoproj/argo-events/sensors/triggers"
    31  )
    32  
    33  // AzureEventHubsTrigger describes the trigger to send messages to an Event Hub
    34  type AzureEventHubsTrigger struct {
    35  	// Sensor object
    36  	Sensor *v1alpha1.Sensor
    37  	// Trigger reference
    38  	Trigger *v1alpha1.Trigger
    39  	// Hub refers to Azure Event Hub struct
    40  	Hub *eventhub.Hub
    41  	// Logger to log stuff
    42  	Logger *zap.SugaredLogger
    43  }
    44  
    45  // NewAzureEventHubsTrigger returns a new azure event hubs context.
    46  func NewAzureEventHubsTrigger(sensor *v1alpha1.Sensor, trigger *v1alpha1.Trigger, azureEventHubsClient common.StringKeyedMap[*eventhub.Hub], logger *zap.SugaredLogger) (*AzureEventHubsTrigger, error) {
    47  	azureEventHubsTrigger := trigger.Template.AzureEventHubs
    48  
    49  	hub, ok := azureEventHubsClient.Load(trigger.Template.Name)
    50  
    51  	if !ok {
    52  		// form event hubs connection string in the ff format:
    53  		// Endpoint=sb://namespace.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=superSecret1234=;EntityPath=hubName
    54  		fqdn := azureEventHubsTrigger.FQDN
    55  		hubName := azureEventHubsTrigger.HubName
    56  
    57  		sharedAccessKeyName, err := common.GetSecretFromVolume(azureEventHubsTrigger.SharedAccessKeyName)
    58  		if err != nil {
    59  			return nil, err
    60  		}
    61  		sharedAccessKey, err := common.GetSecretFromVolume(azureEventHubsTrigger.SharedAccessKey)
    62  		if err != nil {
    63  			return nil, err
    64  		}
    65  
    66  		logger.Debug("generating connection string")
    67  		connStr := fmt.Sprintf("Endpoint=sb://%s/;SharedAccessKeyName=%s;SharedAccessKey=%s;EntityPath=%s", fqdn, sharedAccessKeyName, sharedAccessKey, hubName)
    68  		logger.Debug("connection string: ", connStr)
    69  
    70  		hub, err = eventhub.NewHubFromConnectionString(connStr)
    71  		if err != nil {
    72  			return nil, err
    73  		}
    74  
    75  		azureEventHubsClient.Store(trigger.Template.Name, hub)
    76  	}
    77  
    78  	return &AzureEventHubsTrigger{
    79  		Sensor:  sensor,
    80  		Trigger: trigger,
    81  		Hub:     hub,
    82  		Logger:  logger.With(logging.LabelTriggerType, apicommon.AzureEventHubsTrigger),
    83  	}, nil
    84  }
    85  
    86  // GetTriggerType returns the type of the trigger
    87  func (t *AzureEventHubsTrigger) GetTriggerType() apicommon.TriggerType {
    88  	return apicommon.AzureEventHubsTrigger
    89  }
    90  
    91  // FetchResource fetches the trigger. As the Azure Event Hubs trigger is simply a Hub client, there
    92  // is no need to fetch any resource from external source
    93  func (t *AzureEventHubsTrigger) FetchResource(ctx context.Context) (interface{}, error) {
    94  	return t.Trigger.Template.AzureEventHubs, nil
    95  }
    96  
    97  // ApplyResourceParameters applies parameters to the trigger resource
    98  func (t *AzureEventHubsTrigger) ApplyResourceParameters(events map[string]*v1alpha1.Event, resource interface{}) (interface{}, error) {
    99  	fetchedResource, ok := resource.(*v1alpha1.AzureEventHubsTrigger)
   100  	if !ok {
   101  		return nil, fmt.Errorf("failed to interpret the fetched trigger resource")
   102  	}
   103  
   104  	resourceBytes, err := json.Marshal(fetchedResource)
   105  	if err != nil {
   106  		return nil, fmt.Errorf("failed to marshal the azure event hubs trigger resource, %w", err)
   107  	}
   108  	parameters := fetchedResource.Parameters
   109  	if parameters != nil {
   110  		updatedResourceBytes, err := triggers.ApplyParams(resourceBytes, parameters, events)
   111  		if err != nil {
   112  			return nil, err
   113  		}
   114  		var ht *v1alpha1.AzureEventHubsTrigger
   115  		if err := json.Unmarshal(updatedResourceBytes, &ht); err != nil {
   116  			return nil, fmt.Errorf("failed to unmarshal the updated azure event hubs trigger resource after applying resource parameters, %w", err)
   117  		}
   118  		return ht, nil
   119  	}
   120  	return resource, nil
   121  }
   122  
   123  // Execute executes the trigger
   124  func (t *AzureEventHubsTrigger) Execute(ctx context.Context, events map[string]*v1alpha1.Event, resource interface{}) (interface{}, error) {
   125  	trigger, ok := resource.(*v1alpha1.AzureEventHubsTrigger)
   126  	if !ok {
   127  		return nil, fmt.Errorf("failed to interpret the trigger resource")
   128  	}
   129  
   130  	if trigger.Payload == nil {
   131  		return nil, fmt.Errorf("payload parameters are not specified")
   132  	}
   133  
   134  	payload, err := triggers.ConstructPayload(events, trigger.Payload)
   135  	if err != nil {
   136  		return nil, err
   137  	}
   138  
   139  	if err := t.Hub.Send(ctx, eventhub.NewEvent(payload)); err != nil {
   140  		return nil, err
   141  	}
   142  	t.Logger.Info("successfully sent an event to Azure Event Hubs")
   143  
   144  	return nil, nil
   145  }
   146  
   147  // ApplyPolicy applies policy on the trigger
   148  func (t *AzureEventHubsTrigger) ApplyPolicy(ctx context.Context, resource interface{}) error {
   149  	return nil
   150  }