Run black on moto & test directories.
This commit is contained in:
parent
c820395dbf
commit
96e5b1993d
507 changed files with 52541 additions and 47814 deletions
|
|
@ -2,6 +2,6 @@ from __future__ import unicode_literals
|
|||
from .models import kinesis_backends
|
||||
from ..core.models import base_decorator, deprecated_base_decorator
|
||||
|
||||
kinesis_backend = kinesis_backends['us-east-1']
|
||||
kinesis_backend = kinesis_backends["us-east-1"]
|
||||
mock_kinesis = base_decorator(kinesis_backends)
|
||||
mock_kinesis_deprecated = deprecated_base_decorator(kinesis_backends)
|
||||
|
|
|
|||
|
|
@ -5,44 +5,38 @@ from werkzeug.exceptions import BadRequest
|
|||
|
||||
|
||||
class ResourceNotFoundError(BadRequest):
|
||||
|
||||
def __init__(self, message):
|
||||
super(ResourceNotFoundError, self).__init__()
|
||||
self.description = json.dumps({
|
||||
"message": message,
|
||||
'__type': 'ResourceNotFoundException',
|
||||
})
|
||||
self.description = json.dumps(
|
||||
{"message": message, "__type": "ResourceNotFoundException"}
|
||||
)
|
||||
|
||||
|
||||
class ResourceInUseError(BadRequest):
|
||||
|
||||
def __init__(self, message):
|
||||
super(ResourceInUseError, self).__init__()
|
||||
self.description = json.dumps({
|
||||
"message": message,
|
||||
'__type': 'ResourceInUseException',
|
||||
})
|
||||
self.description = json.dumps(
|
||||
{"message": message, "__type": "ResourceInUseException"}
|
||||
)
|
||||
|
||||
|
||||
class StreamNotFoundError(ResourceNotFoundError):
|
||||
|
||||
def __init__(self, stream_name):
|
||||
super(StreamNotFoundError, self).__init__(
|
||||
'Stream {0} under account 123456789012 not found.'.format(stream_name))
|
||||
"Stream {0} under account 123456789012 not found.".format(stream_name)
|
||||
)
|
||||
|
||||
|
||||
class ShardNotFoundError(ResourceNotFoundError):
|
||||
|
||||
def __init__(self, shard_id):
|
||||
super(ShardNotFoundError, self).__init__(
|
||||
'Shard {0} under account 123456789012 not found.'.format(shard_id))
|
||||
"Shard {0} under account 123456789012 not found.".format(shard_id)
|
||||
)
|
||||
|
||||
|
||||
class InvalidArgumentError(BadRequest):
|
||||
|
||||
def __init__(self, message):
|
||||
super(InvalidArgumentError, self).__init__()
|
||||
self.description = json.dumps({
|
||||
"message": message,
|
||||
'__type': 'InvalidArgumentException',
|
||||
})
|
||||
self.description = json.dumps(
|
||||
{"message": message, "__type": "InvalidArgumentException"}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -13,9 +13,18 @@ from hashlib import md5
|
|||
from moto.compat import OrderedDict
|
||||
from moto.core import BaseBackend, BaseModel
|
||||
from moto.core.utils import unix_time
|
||||
from .exceptions import StreamNotFoundError, ShardNotFoundError, ResourceInUseError, \
|
||||
ResourceNotFoundError, InvalidArgumentError
|
||||
from .utils import compose_shard_iterator, compose_new_shard_iterator, decompose_shard_iterator
|
||||
from .exceptions import (
|
||||
StreamNotFoundError,
|
||||
ShardNotFoundError,
|
||||
ResourceInUseError,
|
||||
ResourceNotFoundError,
|
||||
InvalidArgumentError,
|
||||
)
|
||||
from .utils import (
|
||||
compose_shard_iterator,
|
||||
compose_new_shard_iterator,
|
||||
decompose_shard_iterator,
|
||||
)
|
||||
|
||||
|
||||
class Record(BaseModel):
|
||||
|
|
@ -32,12 +41,11 @@ class Record(BaseModel):
|
|||
"Data": self.data,
|
||||
"PartitionKey": self.partition_key,
|
||||
"SequenceNumber": str(self.sequence_number),
|
||||
"ApproximateArrivalTimestamp": self.created_at_datetime.isoformat()
|
||||
"ApproximateArrivalTimestamp": self.created_at_datetime.isoformat(),
|
||||
}
|
||||
|
||||
|
||||
class Shard(BaseModel):
|
||||
|
||||
def __init__(self, shard_id, starting_hash, ending_hash):
|
||||
self._shard_id = shard_id
|
||||
self.starting_hash = starting_hash
|
||||
|
|
@ -75,7 +83,8 @@ class Shard(BaseModel):
|
|||
last_sequence_number = 0
|
||||
sequence_number = last_sequence_number + 1
|
||||
self.records[sequence_number] = Record(
|
||||
partition_key, data, sequence_number, explicit_hash_key)
|
||||
partition_key, data, sequence_number, explicit_hash_key
|
||||
)
|
||||
return sequence_number
|
||||
|
||||
def get_min_sequence_number(self):
|
||||
|
|
@ -94,25 +103,31 @@ class Shard(BaseModel):
|
|||
else:
|
||||
# find the last item in the list that was created before
|
||||
# at_timestamp
|
||||
r = next((r for r in reversed(self.records.values()) if r.created_at < at_timestamp), None)
|
||||
r = next(
|
||||
(
|
||||
r
|
||||
for r in reversed(self.records.values())
|
||||
if r.created_at < at_timestamp
|
||||
),
|
||||
None,
|
||||
)
|
||||
return r.sequence_number
|
||||
|
||||
def to_json(self):
|
||||
return {
|
||||
"HashKeyRange": {
|
||||
"EndingHashKey": str(self.ending_hash),
|
||||
"StartingHashKey": str(self.starting_hash)
|
||||
"StartingHashKey": str(self.starting_hash),
|
||||
},
|
||||
"SequenceNumberRange": {
|
||||
"EndingSequenceNumber": self.get_max_sequence_number(),
|
||||
"StartingSequenceNumber": self.get_min_sequence_number(),
|
||||
},
|
||||
"ShardId": self.shard_id
|
||||
"ShardId": self.shard_id,
|
||||
}
|
||||
|
||||
|
||||
class Stream(BaseModel):
|
||||
|
||||
def __init__(self, stream_name, shard_count, region):
|
||||
self.stream_name = stream_name
|
||||
self.shard_count = shard_count
|
||||
|
|
@ -123,10 +138,11 @@ class Stream(BaseModel):
|
|||
self.tags = {}
|
||||
self.status = "ACTIVE"
|
||||
|
||||
step = 2**128 // shard_count
|
||||
hash_ranges = itertools.chain(map(lambda i: (i, i * step, (i + 1) * step),
|
||||
range(shard_count - 1)),
|
||||
[(shard_count - 1, (shard_count - 1) * step, 2**128)])
|
||||
step = 2 ** 128 // shard_count
|
||||
hash_ranges = itertools.chain(
|
||||
map(lambda i: (i, i * step, (i + 1) * step), range(shard_count - 1)),
|
||||
[(shard_count - 1, (shard_count - 1) * step, 2 ** 128)],
|
||||
)
|
||||
for index, start, end in hash_ranges:
|
||||
|
||||
shard = Shard(index, start, end)
|
||||
|
|
@ -137,7 +153,7 @@ class Stream(BaseModel):
|
|||
return "arn:aws:kinesis:{region}:{account_number}:{stream_name}".format(
|
||||
region=self.region,
|
||||
account_number=self.account_number,
|
||||
stream_name=self.stream_name
|
||||
stream_name=self.stream_name,
|
||||
)
|
||||
|
||||
def get_shard(self, shard_id):
|
||||
|
|
@ -158,21 +174,22 @@ class Stream(BaseModel):
|
|||
|
||||
key = int(explicit_hash_key)
|
||||
|
||||
if key >= 2**128:
|
||||
if key >= 2 ** 128:
|
||||
raise InvalidArgumentError("explicit_hash_key")
|
||||
|
||||
else:
|
||||
key = int(md5(partition_key.encode('utf-8')).hexdigest(), 16)
|
||||
key = int(md5(partition_key.encode("utf-8")).hexdigest(), 16)
|
||||
|
||||
for shard in self.shards.values():
|
||||
if shard.starting_hash <= key < shard.ending_hash:
|
||||
return shard
|
||||
|
||||
def put_record(self, partition_key, explicit_hash_key, sequence_number_for_ordering, data):
|
||||
def put_record(
|
||||
self, partition_key, explicit_hash_key, sequence_number_for_ordering, data
|
||||
):
|
||||
shard = self.get_shard_for_key(partition_key, explicit_hash_key)
|
||||
|
||||
sequence_number = shard.put_record(
|
||||
partition_key, data, explicit_hash_key)
|
||||
sequence_number = shard.put_record(partition_key, data, explicit_hash_key)
|
||||
return sequence_number, shard.shard_id
|
||||
|
||||
def to_json(self):
|
||||
|
|
@ -198,64 +215,69 @@ class Stream(BaseModel):
|
|||
}
|
||||
|
||||
@classmethod
|
||||
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
|
||||
properties = cloudformation_json['Properties']
|
||||
region = properties.get('Region', 'us-east-1')
|
||||
shard_count = properties.get('ShardCount', 1)
|
||||
return Stream(properties['Name'], shard_count, region)
|
||||
def create_from_cloudformation_json(
|
||||
cls, resource_name, cloudformation_json, region_name
|
||||
):
|
||||
properties = cloudformation_json["Properties"]
|
||||
region = properties.get("Region", "us-east-1")
|
||||
shard_count = properties.get("ShardCount", 1)
|
||||
return Stream(properties["Name"], shard_count, region)
|
||||
|
||||
|
||||
class FirehoseRecord(BaseModel):
|
||||
|
||||
def __init__(self, record_data):
|
||||
self.record_id = 12345678
|
||||
self.record_data = record_data
|
||||
|
||||
|
||||
class DeliveryStream(BaseModel):
|
||||
|
||||
def __init__(self, stream_name, **stream_kwargs):
|
||||
self.name = stream_name
|
||||
self.redshift_username = stream_kwargs.get('redshift_username')
|
||||
self.redshift_password = stream_kwargs.get('redshift_password')
|
||||
self.redshift_jdbc_url = stream_kwargs.get('redshift_jdbc_url')
|
||||
self.redshift_role_arn = stream_kwargs.get('redshift_role_arn')
|
||||
self.redshift_copy_command = stream_kwargs.get('redshift_copy_command')
|
||||
self.redshift_username = stream_kwargs.get("redshift_username")
|
||||
self.redshift_password = stream_kwargs.get("redshift_password")
|
||||
self.redshift_jdbc_url = stream_kwargs.get("redshift_jdbc_url")
|
||||
self.redshift_role_arn = stream_kwargs.get("redshift_role_arn")
|
||||
self.redshift_copy_command = stream_kwargs.get("redshift_copy_command")
|
||||
|
||||
self.s3_config = stream_kwargs.get('s3_config')
|
||||
self.extended_s3_config = stream_kwargs.get('extended_s3_config')
|
||||
self.s3_config = stream_kwargs.get("s3_config")
|
||||
self.extended_s3_config = stream_kwargs.get("extended_s3_config")
|
||||
|
||||
self.redshift_s3_role_arn = stream_kwargs.get('redshift_s3_role_arn')
|
||||
self.redshift_s3_bucket_arn = stream_kwargs.get(
|
||||
'redshift_s3_bucket_arn')
|
||||
self.redshift_s3_prefix = stream_kwargs.get('redshift_s3_prefix')
|
||||
self.redshift_s3_role_arn = stream_kwargs.get("redshift_s3_role_arn")
|
||||
self.redshift_s3_bucket_arn = stream_kwargs.get("redshift_s3_bucket_arn")
|
||||
self.redshift_s3_prefix = stream_kwargs.get("redshift_s3_prefix")
|
||||
self.redshift_s3_compression_format = stream_kwargs.get(
|
||||
'redshift_s3_compression_format', 'UNCOMPRESSED')
|
||||
"redshift_s3_compression_format", "UNCOMPRESSED"
|
||||
)
|
||||
self.redshift_s3_buffering_hints = stream_kwargs.get(
|
||||
'redshift_s3_buffering_hints')
|
||||
"redshift_s3_buffering_hints"
|
||||
)
|
||||
|
||||
self.records = []
|
||||
self.status = 'ACTIVE'
|
||||
self.status = "ACTIVE"
|
||||
self.created_at = datetime.datetime.utcnow()
|
||||
self.last_updated = datetime.datetime.utcnow()
|
||||
|
||||
@property
|
||||
def arn(self):
|
||||
return 'arn:aws:firehose:us-east-1:123456789012:deliverystream/{0}'.format(self.name)
|
||||
return "arn:aws:firehose:us-east-1:123456789012:deliverystream/{0}".format(
|
||||
self.name
|
||||
)
|
||||
|
||||
def destinations_to_dict(self):
|
||||
if self.s3_config:
|
||||
return [{
|
||||
'DestinationId': 'string',
|
||||
'S3DestinationDescription': self.s3_config,
|
||||
}]
|
||||
return [
|
||||
{"DestinationId": "string", "S3DestinationDescription": self.s3_config}
|
||||
]
|
||||
elif self.extended_s3_config:
|
||||
return [{
|
||||
'DestinationId': 'string',
|
||||
'ExtendedS3DestinationDescription': self.extended_s3_config,
|
||||
}]
|
||||
return [
|
||||
{
|
||||
"DestinationId": "string",
|
||||
"ExtendedS3DestinationDescription": self.extended_s3_config,
|
||||
}
|
||||
]
|
||||
else:
|
||||
return [{
|
||||
return [
|
||||
{
|
||||
"DestinationId": "string",
|
||||
"RedshiftDestinationDescription": {
|
||||
"ClusterJDBCURL": self.redshift_jdbc_url,
|
||||
|
|
@ -266,12 +288,12 @@ class DeliveryStream(BaseModel):
|
|||
"BufferingHints": self.redshift_s3_buffering_hints,
|
||||
"CompressionFormat": self.redshift_s3_compression_format,
|
||||
"Prefix": self.redshift_s3_prefix,
|
||||
"RoleARN": self.redshift_s3_role_arn
|
||||
"RoleARN": self.redshift_s3_role_arn,
|
||||
},
|
||||
"Username": self.redshift_username,
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
|
|
@ -294,7 +316,6 @@ class DeliveryStream(BaseModel):
|
|||
|
||||
|
||||
class KinesisBackend(BaseBackend):
|
||||
|
||||
def __init__(self):
|
||||
self.streams = OrderedDict()
|
||||
self.delivery_streams = {}
|
||||
|
|
@ -323,14 +344,24 @@ class KinesisBackend(BaseBackend):
|
|||
return self.streams.pop(stream_name)
|
||||
raise StreamNotFoundError(stream_name)
|
||||
|
||||
def get_shard_iterator(self, stream_name, shard_id, shard_iterator_type, starting_sequence_number,
|
||||
at_timestamp):
|
||||
def get_shard_iterator(
|
||||
self,
|
||||
stream_name,
|
||||
shard_id,
|
||||
shard_iterator_type,
|
||||
starting_sequence_number,
|
||||
at_timestamp,
|
||||
):
|
||||
# Validate params
|
||||
stream = self.describe_stream(stream_name)
|
||||
shard = stream.get_shard(shard_id)
|
||||
|
||||
shard_iterator = compose_new_shard_iterator(
|
||||
stream_name, shard, shard_iterator_type, starting_sequence_number, at_timestamp
|
||||
stream_name,
|
||||
shard,
|
||||
shard_iterator_type,
|
||||
starting_sequence_number,
|
||||
at_timestamp,
|
||||
)
|
||||
return shard_iterator
|
||||
|
||||
|
|
@ -341,14 +372,24 @@ class KinesisBackend(BaseBackend):
|
|||
stream = self.describe_stream(stream_name)
|
||||
shard = stream.get_shard(shard_id)
|
||||
|
||||
records, last_sequence_id, millis_behind_latest = shard.get_records(last_sequence_id, limit)
|
||||
records, last_sequence_id, millis_behind_latest = shard.get_records(
|
||||
last_sequence_id, limit
|
||||
)
|
||||
|
||||
next_shard_iterator = compose_shard_iterator(
|
||||
stream_name, shard, last_sequence_id)
|
||||
stream_name, shard, last_sequence_id
|
||||
)
|
||||
|
||||
return next_shard_iterator, records, millis_behind_latest
|
||||
|
||||
def put_record(self, stream_name, partition_key, explicit_hash_key, sequence_number_for_ordering, data):
|
||||
def put_record(
|
||||
self,
|
||||
stream_name,
|
||||
partition_key,
|
||||
explicit_hash_key,
|
||||
sequence_number_for_ordering,
|
||||
data,
|
||||
):
|
||||
stream = self.describe_stream(stream_name)
|
||||
|
||||
sequence_number, shard_id = stream.put_record(
|
||||
|
|
@ -360,10 +401,7 @@ class KinesisBackend(BaseBackend):
|
|||
def put_records(self, stream_name, records):
|
||||
stream = self.describe_stream(stream_name)
|
||||
|
||||
response = {
|
||||
"FailedRecordCount": 0,
|
||||
"Records": []
|
||||
}
|
||||
response = {"FailedRecordCount": 0, "Records": []}
|
||||
|
||||
for record in records:
|
||||
partition_key = record.get("PartitionKey")
|
||||
|
|
@ -373,10 +411,9 @@ class KinesisBackend(BaseBackend):
|
|||
sequence_number, shard_id = stream.put_record(
|
||||
partition_key, explicit_hash_key, None, data
|
||||
)
|
||||
response['Records'].append({
|
||||
"SequenceNumber": sequence_number,
|
||||
"ShardId": shard_id
|
||||
})
|
||||
response["Records"].append(
|
||||
{"SequenceNumber": sequence_number, "ShardId": shard_id}
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
|
|
@ -386,18 +423,18 @@ class KinesisBackend(BaseBackend):
|
|||
if shard_to_split not in stream.shards:
|
||||
raise ResourceNotFoundError(shard_to_split)
|
||||
|
||||
if not re.match(r'0|([1-9]\d{0,38})', new_starting_hash_key):
|
||||
if not re.match(r"0|([1-9]\d{0,38})", new_starting_hash_key):
|
||||
raise InvalidArgumentError(new_starting_hash_key)
|
||||
new_starting_hash_key = int(new_starting_hash_key)
|
||||
|
||||
shard = stream.shards[shard_to_split]
|
||||
|
||||
last_id = sorted(stream.shards.values(),
|
||||
key=attrgetter('_shard_id'))[-1]._shard_id
|
||||
last_id = sorted(stream.shards.values(), key=attrgetter("_shard_id"))[
|
||||
-1
|
||||
]._shard_id
|
||||
|
||||
if shard.starting_hash < new_starting_hash_key < shard.ending_hash:
|
||||
new_shard = Shard(
|
||||
last_id + 1, new_starting_hash_key, shard.ending_hash)
|
||||
new_shard = Shard(last_id + 1, new_starting_hash_key, shard.ending_hash)
|
||||
shard.ending_hash = new_starting_hash_key
|
||||
stream.shards[new_shard.shard_id] = new_shard
|
||||
else:
|
||||
|
|
@ -434,10 +471,11 @@ class KinesisBackend(BaseBackend):
|
|||
del stream.shards[shard2.shard_id]
|
||||
for index in shard2.records:
|
||||
record = shard2.records[index]
|
||||
shard1.put_record(record.partition_key,
|
||||
record.data, record.explicit_hash_key)
|
||||
shard1.put_record(
|
||||
record.partition_key, record.data, record.explicit_hash_key
|
||||
)
|
||||
|
||||
''' Firehose '''
|
||||
""" Firehose """
|
||||
|
||||
def create_delivery_stream(self, stream_name, **stream_kwargs):
|
||||
stream = DeliveryStream(stream_name, **stream_kwargs)
|
||||
|
|
@ -461,25 +499,21 @@ class KinesisBackend(BaseBackend):
|
|||
record = stream.put_record(record_data)
|
||||
return record
|
||||
|
||||
def list_tags_for_stream(self, stream_name, exclusive_start_tag_key=None, limit=None):
|
||||
def list_tags_for_stream(
|
||||
self, stream_name, exclusive_start_tag_key=None, limit=None
|
||||
):
|
||||
stream = self.describe_stream(stream_name)
|
||||
|
||||
tags = []
|
||||
result = {
|
||||
'HasMoreTags': False,
|
||||
'Tags': tags
|
||||
}
|
||||
result = {"HasMoreTags": False, "Tags": tags}
|
||||
for key, val in sorted(stream.tags.items(), key=lambda x: x[0]):
|
||||
if limit and len(tags) >= limit:
|
||||
result['HasMoreTags'] = True
|
||||
result["HasMoreTags"] = True
|
||||
break
|
||||
if exclusive_start_tag_key and key < exclusive_start_tag_key:
|
||||
continue
|
||||
|
||||
tags.append({
|
||||
'Key': key,
|
||||
'Value': val
|
||||
})
|
||||
tags.append({"Key": key, "Value": val})
|
||||
|
||||
return result
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ from .models import kinesis_backends
|
|||
|
||||
|
||||
class KinesisResponse(BaseResponse):
|
||||
|
||||
@property
|
||||
def parameters(self):
|
||||
return json.loads(self.body)
|
||||
|
|
@ -18,47 +17,47 @@ class KinesisResponse(BaseResponse):
|
|||
|
||||
@property
|
||||
def is_firehose(self):
|
||||
host = self.headers.get('host') or self.headers['Host']
|
||||
return host.startswith('firehose') or 'firehose' in self.headers.get('Authorization', '')
|
||||
host = self.headers.get("host") or self.headers["Host"]
|
||||
return host.startswith("firehose") or "firehose" in self.headers.get(
|
||||
"Authorization", ""
|
||||
)
|
||||
|
||||
def create_stream(self):
|
||||
stream_name = self.parameters.get('StreamName')
|
||||
shard_count = self.parameters.get('ShardCount')
|
||||
self.kinesis_backend.create_stream(
|
||||
stream_name, shard_count, self.region)
|
||||
stream_name = self.parameters.get("StreamName")
|
||||
shard_count = self.parameters.get("ShardCount")
|
||||
self.kinesis_backend.create_stream(stream_name, shard_count, self.region)
|
||||
return ""
|
||||
|
||||
def describe_stream(self):
|
||||
stream_name = self.parameters.get('StreamName')
|
||||
stream_name = self.parameters.get("StreamName")
|
||||
stream = self.kinesis_backend.describe_stream(stream_name)
|
||||
return json.dumps(stream.to_json())
|
||||
|
||||
def describe_stream_summary(self):
|
||||
stream_name = self.parameters.get('StreamName')
|
||||
stream_name = self.parameters.get("StreamName")
|
||||
stream = self.kinesis_backend.describe_stream_summary(stream_name)
|
||||
return json.dumps(stream.to_json_summary())
|
||||
|
||||
def list_streams(self):
|
||||
streams = self.kinesis_backend.list_streams()
|
||||
stream_names = [stream.stream_name for stream in streams]
|
||||
max_streams = self._get_param('Limit', 10)
|
||||
max_streams = self._get_param("Limit", 10)
|
||||
try:
|
||||
token = self.parameters.get('ExclusiveStartStreamName')
|
||||
token = self.parameters.get("ExclusiveStartStreamName")
|
||||
except ValueError:
|
||||
token = self._get_param('ExclusiveStartStreamName')
|
||||
token = self._get_param("ExclusiveStartStreamName")
|
||||
if token:
|
||||
start = stream_names.index(token) + 1
|
||||
else:
|
||||
start = 0
|
||||
streams_resp = stream_names[start:start + max_streams]
|
||||
streams_resp = stream_names[start : start + max_streams]
|
||||
has_more_streams = False
|
||||
if start + max_streams < len(stream_names):
|
||||
has_more_streams = True
|
||||
|
||||
return json.dumps({
|
||||
"HasMoreStreams": has_more_streams,
|
||||
"StreamNames": streams_resp
|
||||
})
|
||||
return json.dumps(
|
||||
{"HasMoreStreams": has_more_streams, "StreamNames": streams_resp}
|
||||
)
|
||||
|
||||
def delete_stream(self):
|
||||
stream_name = self.parameters.get("StreamName")
|
||||
|
|
@ -69,30 +68,36 @@ class KinesisResponse(BaseResponse):
|
|||
stream_name = self.parameters.get("StreamName")
|
||||
shard_id = self.parameters.get("ShardId")
|
||||
shard_iterator_type = self.parameters.get("ShardIteratorType")
|
||||
starting_sequence_number = self.parameters.get(
|
||||
"StartingSequenceNumber")
|
||||
starting_sequence_number = self.parameters.get("StartingSequenceNumber")
|
||||
at_timestamp = self.parameters.get("Timestamp")
|
||||
|
||||
shard_iterator = self.kinesis_backend.get_shard_iterator(
|
||||
stream_name, shard_id, shard_iterator_type, starting_sequence_number, at_timestamp
|
||||
stream_name,
|
||||
shard_id,
|
||||
shard_iterator_type,
|
||||
starting_sequence_number,
|
||||
at_timestamp,
|
||||
)
|
||||
|
||||
return json.dumps({
|
||||
"ShardIterator": shard_iterator
|
||||
})
|
||||
return json.dumps({"ShardIterator": shard_iterator})
|
||||
|
||||
def get_records(self):
|
||||
shard_iterator = self.parameters.get("ShardIterator")
|
||||
limit = self.parameters.get("Limit")
|
||||
|
||||
next_shard_iterator, records, millis_behind_latest = self.kinesis_backend.get_records(
|
||||
shard_iterator, limit)
|
||||
(
|
||||
next_shard_iterator,
|
||||
records,
|
||||
millis_behind_latest,
|
||||
) = self.kinesis_backend.get_records(shard_iterator, limit)
|
||||
|
||||
return json.dumps({
|
||||
"NextShardIterator": next_shard_iterator,
|
||||
"Records": [record.to_json() for record in records],
|
||||
'MillisBehindLatest': millis_behind_latest
|
||||
})
|
||||
return json.dumps(
|
||||
{
|
||||
"NextShardIterator": next_shard_iterator,
|
||||
"Records": [record.to_json() for record in records],
|
||||
"MillisBehindLatest": millis_behind_latest,
|
||||
}
|
||||
)
|
||||
|
||||
def put_record(self):
|
||||
if self.is_firehose:
|
||||
|
|
@ -100,18 +105,18 @@ class KinesisResponse(BaseResponse):
|
|||
stream_name = self.parameters.get("StreamName")
|
||||
partition_key = self.parameters.get("PartitionKey")
|
||||
explicit_hash_key = self.parameters.get("ExplicitHashKey")
|
||||
sequence_number_for_ordering = self.parameters.get(
|
||||
"SequenceNumberForOrdering")
|
||||
sequence_number_for_ordering = self.parameters.get("SequenceNumberForOrdering")
|
||||
data = self.parameters.get("Data")
|
||||
|
||||
sequence_number, shard_id = self.kinesis_backend.put_record(
|
||||
stream_name, partition_key, explicit_hash_key, sequence_number_for_ordering, data
|
||||
stream_name,
|
||||
partition_key,
|
||||
explicit_hash_key,
|
||||
sequence_number_for_ordering,
|
||||
data,
|
||||
)
|
||||
|
||||
return json.dumps({
|
||||
"SequenceNumber": sequence_number,
|
||||
"ShardId": shard_id,
|
||||
})
|
||||
return json.dumps({"SequenceNumber": sequence_number, "ShardId": shard_id})
|
||||
|
||||
def put_records(self):
|
||||
if self.is_firehose:
|
||||
|
|
@ -119,9 +124,7 @@ class KinesisResponse(BaseResponse):
|
|||
stream_name = self.parameters.get("StreamName")
|
||||
records = self.parameters.get("Records")
|
||||
|
||||
response = self.kinesis_backend.put_records(
|
||||
stream_name, records
|
||||
)
|
||||
response = self.kinesis_backend.put_records(stream_name, records)
|
||||
|
||||
return json.dumps(response)
|
||||
|
||||
|
|
@ -143,42 +146,39 @@ class KinesisResponse(BaseResponse):
|
|||
)
|
||||
return ""
|
||||
|
||||
''' Firehose '''
|
||||
""" Firehose """
|
||||
|
||||
def create_delivery_stream(self):
|
||||
stream_name = self.parameters['DeliveryStreamName']
|
||||
redshift_config = self.parameters.get(
|
||||
'RedshiftDestinationConfiguration')
|
||||
s3_config = self.parameters.get(
|
||||
'S3DestinationConfiguration')
|
||||
extended_s3_config = self.parameters.get(
|
||||
'ExtendedS3DestinationConfiguration')
|
||||
stream_name = self.parameters["DeliveryStreamName"]
|
||||
redshift_config = self.parameters.get("RedshiftDestinationConfiguration")
|
||||
s3_config = self.parameters.get("S3DestinationConfiguration")
|
||||
extended_s3_config = self.parameters.get("ExtendedS3DestinationConfiguration")
|
||||
|
||||
if redshift_config:
|
||||
redshift_s3_config = redshift_config['S3Configuration']
|
||||
redshift_s3_config = redshift_config["S3Configuration"]
|
||||
stream_kwargs = {
|
||||
'redshift_username': redshift_config['Username'],
|
||||
'redshift_password': redshift_config['Password'],
|
||||
'redshift_jdbc_url': redshift_config['ClusterJDBCURL'],
|
||||
'redshift_role_arn': redshift_config['RoleARN'],
|
||||
'redshift_copy_command': redshift_config['CopyCommand'],
|
||||
|
||||
'redshift_s3_role_arn': redshift_s3_config['RoleARN'],
|
||||
'redshift_s3_bucket_arn': redshift_s3_config['BucketARN'],
|
||||
'redshift_s3_prefix': redshift_s3_config['Prefix'],
|
||||
'redshift_s3_compression_format': redshift_s3_config.get('CompressionFormat'),
|
||||
'redshift_s3_buffering_hints': redshift_s3_config['BufferingHints'],
|
||||
"redshift_username": redshift_config["Username"],
|
||||
"redshift_password": redshift_config["Password"],
|
||||
"redshift_jdbc_url": redshift_config["ClusterJDBCURL"],
|
||||
"redshift_role_arn": redshift_config["RoleARN"],
|
||||
"redshift_copy_command": redshift_config["CopyCommand"],
|
||||
"redshift_s3_role_arn": redshift_s3_config["RoleARN"],
|
||||
"redshift_s3_bucket_arn": redshift_s3_config["BucketARN"],
|
||||
"redshift_s3_prefix": redshift_s3_config["Prefix"],
|
||||
"redshift_s3_compression_format": redshift_s3_config.get(
|
||||
"CompressionFormat"
|
||||
),
|
||||
"redshift_s3_buffering_hints": redshift_s3_config["BufferingHints"],
|
||||
}
|
||||
elif s3_config:
|
||||
stream_kwargs = {'s3_config': s3_config}
|
||||
stream_kwargs = {"s3_config": s3_config}
|
||||
elif extended_s3_config:
|
||||
stream_kwargs = {'extended_s3_config': extended_s3_config}
|
||||
stream_kwargs = {"extended_s3_config": extended_s3_config}
|
||||
|
||||
stream = self.kinesis_backend.create_delivery_stream(
|
||||
stream_name, **stream_kwargs)
|
||||
return json.dumps({
|
||||
'DeliveryStreamARN': stream.arn
|
||||
})
|
||||
stream_name, **stream_kwargs
|
||||
)
|
||||
return json.dumps({"DeliveryStreamARN": stream.arn})
|
||||
|
||||
def describe_delivery_stream(self):
|
||||
stream_name = self.parameters["DeliveryStreamName"]
|
||||
|
|
@ -187,60 +187,54 @@ class KinesisResponse(BaseResponse):
|
|||
|
||||
def list_delivery_streams(self):
|
||||
streams = self.kinesis_backend.list_delivery_streams()
|
||||
return json.dumps({
|
||||
"DeliveryStreamNames": [
|
||||
stream.name for stream in streams
|
||||
],
|
||||
"HasMoreDeliveryStreams": False
|
||||
})
|
||||
return json.dumps(
|
||||
{
|
||||
"DeliveryStreamNames": [stream.name for stream in streams],
|
||||
"HasMoreDeliveryStreams": False,
|
||||
}
|
||||
)
|
||||
|
||||
def delete_delivery_stream(self):
|
||||
stream_name = self.parameters['DeliveryStreamName']
|
||||
stream_name = self.parameters["DeliveryStreamName"]
|
||||
self.kinesis_backend.delete_delivery_stream(stream_name)
|
||||
return json.dumps({})
|
||||
|
||||
def firehose_put_record(self):
|
||||
stream_name = self.parameters['DeliveryStreamName']
|
||||
record_data = self.parameters['Record']['Data']
|
||||
stream_name = self.parameters["DeliveryStreamName"]
|
||||
record_data = self.parameters["Record"]["Data"]
|
||||
|
||||
record = self.kinesis_backend.put_firehose_record(
|
||||
stream_name, record_data)
|
||||
return json.dumps({
|
||||
"RecordId": record.record_id,
|
||||
})
|
||||
record = self.kinesis_backend.put_firehose_record(stream_name, record_data)
|
||||
return json.dumps({"RecordId": record.record_id})
|
||||
|
||||
def put_record_batch(self):
|
||||
stream_name = self.parameters['DeliveryStreamName']
|
||||
records = self.parameters['Records']
|
||||
stream_name = self.parameters["DeliveryStreamName"]
|
||||
records = self.parameters["Records"]
|
||||
|
||||
request_responses = []
|
||||
for record in records:
|
||||
record_response = self.kinesis_backend.put_firehose_record(
|
||||
stream_name, record['Data'])
|
||||
request_responses.append({
|
||||
"RecordId": record_response.record_id
|
||||
})
|
||||
return json.dumps({
|
||||
"FailedPutCount": 0,
|
||||
"RequestResponses": request_responses,
|
||||
})
|
||||
stream_name, record["Data"]
|
||||
)
|
||||
request_responses.append({"RecordId": record_response.record_id})
|
||||
return json.dumps({"FailedPutCount": 0, "RequestResponses": request_responses})
|
||||
|
||||
def add_tags_to_stream(self):
|
||||
stream_name = self.parameters.get('StreamName')
|
||||
tags = self.parameters.get('Tags')
|
||||
stream_name = self.parameters.get("StreamName")
|
||||
tags = self.parameters.get("Tags")
|
||||
self.kinesis_backend.add_tags_to_stream(stream_name, tags)
|
||||
return json.dumps({})
|
||||
|
||||
def list_tags_for_stream(self):
|
||||
stream_name = self.parameters.get('StreamName')
|
||||
exclusive_start_tag_key = self.parameters.get('ExclusiveStartTagKey')
|
||||
limit = self.parameters.get('Limit')
|
||||
stream_name = self.parameters.get("StreamName")
|
||||
exclusive_start_tag_key = self.parameters.get("ExclusiveStartTagKey")
|
||||
limit = self.parameters.get("Limit")
|
||||
response = self.kinesis_backend.list_tags_for_stream(
|
||||
stream_name, exclusive_start_tag_key, limit)
|
||||
stream_name, exclusive_start_tag_key, limit
|
||||
)
|
||||
return json.dumps(response)
|
||||
|
||||
def remove_tags_from_stream(self):
|
||||
stream_name = self.parameters.get('StreamName')
|
||||
tag_keys = self.parameters.get('TagKeys')
|
||||
stream_name = self.parameters.get("StreamName")
|
||||
tag_keys = self.parameters.get("TagKeys")
|
||||
self.kinesis_backend.remove_tags_from_stream(stream_name, tag_keys)
|
||||
return json.dumps({})
|
||||
|
|
|
|||
|
|
@ -6,6 +6,4 @@ url_bases = [
|
|||
"https?://firehose.(.+).amazonaws.com",
|
||||
]
|
||||
|
||||
url_paths = {
|
||||
'{0}/$': KinesisResponse.dispatch,
|
||||
}
|
||||
url_paths = {"{0}/$": KinesisResponse.dispatch}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,9 @@ else:
|
|||
raise Exception("Python version is not supported")
|
||||
|
||||
|
||||
def compose_new_shard_iterator(stream_name, shard, shard_iterator_type, starting_sequence_number,
|
||||
at_timestamp):
|
||||
def compose_new_shard_iterator(
|
||||
stream_name, shard, shard_iterator_type, starting_sequence_number, at_timestamp
|
||||
):
|
||||
if shard_iterator_type == "AT_SEQUENCE_NUMBER":
|
||||
last_sequence_id = int(starting_sequence_number) - 1
|
||||
elif shard_iterator_type == "AFTER_SEQUENCE_NUMBER":
|
||||
|
|
@ -28,17 +29,16 @@ def compose_new_shard_iterator(stream_name, shard, shard_iterator_type, starting
|
|||
last_sequence_id = shard.get_sequence_number_at(at_timestamp)
|
||||
else:
|
||||
raise InvalidArgumentError(
|
||||
"Invalid ShardIteratorType: {0}".format(shard_iterator_type))
|
||||
"Invalid ShardIteratorType: {0}".format(shard_iterator_type)
|
||||
)
|
||||
return compose_shard_iterator(stream_name, shard, last_sequence_id)
|
||||
|
||||
|
||||
def compose_shard_iterator(stream_name, shard, last_sequence_id):
|
||||
return encode_method(
|
||||
"{0}:{1}:{2}".format(
|
||||
stream_name,
|
||||
shard.shard_id,
|
||||
last_sequence_id,
|
||||
).encode("utf-8")
|
||||
"{0}:{1}:{2}".format(stream_name, shard.shard_id, last_sequence_id).encode(
|
||||
"utf-8"
|
||||
)
|
||||
).decode("utf-8")
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue