1515import boto3
1616import botocore
1717import logging
18+ from datetime import datetime
1819
1920LOG = logging .getLogger (__name__ )
2021
2122
2223class KinesisSubscriber (object ):
2324 ''' Invokes the lambda function on events from the Kinesis streams '''
2425 def __init__ (self , config , profile_name ,
25- function_name , stream_name , batch_size ):
26+ function_name , stream_name , batch_size ,
27+ starting_position , starting_position_ts = None ):
2628 self ._aws_session = boto3 .session .Session (region_name = config .region ,
2729 profile_name = profile_name )
2830 self ._lambda_client = self ._aws_session .client ('lambda' )
2931 self .function_name = function_name
3032 self .stream_name = stream_name
3133 self .batch_size = batch_size
34+ self .starting_position = starting_position
35+ self .starting_position_ts = starting_position_ts
3236
3337 def subscribe (self ):
3438 ''' Subscribes the lambda to the Kinesis stream '''
3539 try :
3640 LOG .debug ('Creating Kinesis subscription' )
37- self ._lambda_client \
38- .create_event_source_mapping (EventSourceArn = self .stream_name ,
39- FunctionName = self .function_name ,
40- BatchSize = self .batch_size ,
41- StartingPosition = 'TRIM_HORIZON' )
41+ if self .starting_position_ts :
42+ self ._lambda_client \
43+ .create_event_source_mapping (
44+ EventSourceArn = self .stream_name ,
45+ FunctionName = self .function_name ,
46+ BatchSize = self .batch_size ,
47+ StartingPosition = self .starting_position ,
48+ StartingPositionTimestamp = self .starting_position_ts )
49+ else :
50+ self ._lambda_client \
51+ .create_event_source_mapping (
52+ EventSourceArn = self .stream_name ,
53+ FunctionName = self .function_name ,
54+ BatchSize = self .batch_size ,
55+ StartingPosition = self .starting_position )
4256 LOG .debug ('Subscription created' )
4357 except botocore .exceptions .ClientError as ex :
4458 response_code = ex .response ['Error' ]['Code' ]
4559 if response_code == 'ResourceConflictException' :
46- LOG .debug ('Subscription exists' )
60+ LOG .debug ('Subscription exists. Updating ...' )
61+ resp = self ._lambda_client \
62+ .list_event_source_mappings (
63+ FunctionName = self .function_name ,
64+ EventSourceArn = self .stream_name )
65+ uuid = resp ['EventSourceMappings' ][0 ]['UUID' ]
66+ self ._lambda_client \
67+ .update_event_source_mapping (
68+ UUID = uuid ,
69+ FunctionName = self .function_name ,
70+ Enabled = True ,
71+ BatchSize = self .batch_size )
4772 else :
4873 LOG .error ('Subscription failed, error=%s' % str (ex ))
4974 raise ex
@@ -56,6 +81,13 @@ def create_subscriptions(config, profile_name):
5681 function_name = config .name
5782 stream_name = data ['stream' ]
5883 batch_size = data ['batch_size' ]
84+ starting_position = data ['starting_position' ]
85+ starting_position_ts = None
86+ if starting_position == 'AT_TIMESTAMP' :
87+ ts = data .get ('starting_position_timestamp' )
88+ starting_position_ts = datetime .strptime (ts , '%Y-%m-%dT%H:%M:%SZ' )
5989 s = KinesisSubscriber (config , profile_name ,
60- function_name , stream_name , batch_size )
90+ function_name , stream_name , batch_size ,
91+ starting_position ,
92+ starting_position_ts = starting_position_ts )
6193 s .subscribe ()
0 commit comments