github.com/mweagle/Sparta@v1.15.0/archetype/event_bridge.go (about)

     1  package archetype
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  	"reflect"
     8  	"runtime"
     9  
    10  	sparta "github.com/mweagle/Sparta"
    11  	"github.com/pkg/errors"
    12  )
    13  
    14  // EventBridge represents a lambda function that responds to CW messages
    15  type EventBridge interface {
    16  	// OnLogMessage when an SNS event occurs. Check the snsEvent field
    17  	// for the specific event
    18  	OnEventBridgeBroadcast(ctx context.Context,
    19  		msg json.RawMessage) (interface{}, error)
    20  }
    21  
    22  // EventBridgeReactorFunc is a free function that adapts a EventBridge
    23  // compliant signature into a function that exposes an OnEvent
    24  // function
    25  type EventBridgeReactorFunc func(ctx context.Context,
    26  	msg json.RawMessage) (interface{}, error)
    27  
    28  // OnEventBridgeBroadcast satisfies the EventBridge interface
    29  func (reactorFunc EventBridgeReactorFunc) OnEventBridgeBroadcast(ctx context.Context,
    30  	msg json.RawMessage) (interface{}, error) {
    31  	return reactorFunc(ctx, msg)
    32  }
    33  
    34  // ReactorName provides the name of the reactor func
    35  func (reactorFunc EventBridgeReactorFunc) ReactorName() string {
    36  	return runtime.FuncForPC(reflect.ValueOf(reactorFunc).Pointer()).Name()
    37  }
    38  
    39  // Standardized event bridge reactor ctor
    40  func newEventBridgeEventReactor(reactor EventBridge,
    41  	eventPattern map[string]interface{},
    42  	scheduleExpression string,
    43  	additionalLambdaPermissions []sparta.IAMRolePrivilege) (*sparta.LambdaAWSInfo, error) {
    44  
    45  	reactorLambda := func(ctx context.Context, msg json.RawMessage) (interface{}, error) {
    46  		return reactor.OnEventBridgeBroadcast(ctx, msg)
    47  	}
    48  
    49  	lambdaFn, lambdaFnErr := sparta.NewAWSLambda(reactorName(reactor),
    50  		reactorLambda,
    51  		sparta.IAMRoleDefinition{})
    52  	if lambdaFnErr != nil {
    53  		return nil, errors.Wrapf(lambdaFnErr, "attempting to create reactor")
    54  	}
    55  	if len(additionalLambdaPermissions) != 0 {
    56  		lambdaFn.RoleDefinition.Privileges = additionalLambdaPermissions
    57  	}
    58  
    59  	eventBridgePermission := sparta.EventBridgePermission{}
    60  	eventBridgePermission.Rule = &sparta.EventBridgeRule{
    61  		Description:        fmt.Sprintf("EventBridge rule for %s", lambdaFn.LogicalResourceName()),
    62  		EventPattern:       eventPattern,
    63  		ScheduleExpression: scheduleExpression,
    64  	}
    65  	lambdaFn.Permissions = append(lambdaFn.Permissions, eventBridgePermission)
    66  	return lambdaFn, nil
    67  }
    68  
    69  // NewEventBridgeEventReactor returns an EventBridge reactor function
    70  // that responds to events (as opposed to schedules)
    71  func NewEventBridgeEventReactor(reactor EventBridge,
    72  	eventPattern map[string]interface{},
    73  	additionalLambdaPermissions []sparta.IAMRolePrivilege) (*sparta.LambdaAWSInfo, error) {
    74  
    75  	if len(eventPattern) <= 0 {
    76  		return nil, errors.Errorf("EventBridge eventPattern map must not be empty")
    77  	}
    78  	return newEventBridgeEventReactor(reactor,
    79  		eventPattern,
    80  		"",
    81  		additionalLambdaPermissions)
    82  }
    83  
    84  // NewEventBridgeScheduledReactor returns an EventBridge reactor function
    85  // that responds to events (as opposed to schedules)
    86  func NewEventBridgeScheduledReactor(reactor EventBridge,
    87  	scheduleExpression string,
    88  	additionalLambdaPermissions []sparta.IAMRolePrivilege) (*sparta.LambdaAWSInfo, error) {
    89  
    90  	if len(scheduleExpression) <= 0 {
    91  		return nil, errors.Errorf("EventBridge scheduleExpression must not be empty")
    92  	}
    93  	return newEventBridgeEventReactor(reactor,
    94  		nil,
    95  		scheduleExpression,
    96  		additionalLambdaPermissions)
    97  }