diff --git a/moto/events/__init__.py b/moto/events/__init__.py index 5c93c59c8..8f2730c84 100644 --- a/moto/events/__init__.py +++ b/moto/events/__init__.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals -from .models import events_backend +from .models import events_backends +from ..core.models import base_decorator -events_backends = {"global": events_backend} -mock_events = events_backend.decorator +events_backend = events_backends['us-east-1'] +mock_events = base_decorator(events_backends) diff --git a/moto/events/models.py b/moto/events/models.py index 2422e0b51..6e4a75d07 100644 --- a/moto/events/models.py +++ b/moto/events/models.py @@ -1,6 +1,7 @@ import os import re import json +import boto3 from moto.core.exceptions import JsonRESTError from moto.core import BaseBackend, BaseModel @@ -8,12 +9,15 @@ from moto.core import BaseBackend, BaseModel class Rule(BaseModel): - def _generate_arn(self, name): - return 'arn:aws:events:us-west-2:111111111111:rule/' + name + def _generate_arn(self, name, region_name): + return 'arn:aws:events:{region_name}:111111111111:rule/{name}'.format( + region_name=region_name, + name=name + ) - def __init__(self, name, **kwargs): + def __init__(self, name, region_name, **kwargs): self.name = name - self.arn = kwargs.get('Arn') or self._generate_arn(name) + self.arn = kwargs.get('Arn') or self._generate_arn(name, region_name) self.event_pattern = kwargs.get('EventPattern') self.schedule_exp = kwargs.get('ScheduleExpression') self.state = kwargs.get('State') or 'ENABLED' @@ -55,15 +59,20 @@ class EventsBackend(BaseBackend): ACCOUNT_ID = re.compile(r'^(\d{1,12}|\*)$') STATEMENT_ID = re.compile(r'^[a-zA-Z0-9-_]{1,64}$') - def __init__(self): + def __init__(self, region_name): self.rules = {} # This array tracks the order in which the rules have been added, since # 2.6 doesn't have OrderedDicts. self.rules_order = [] self.next_tokens = {} - + self.region_name = region_name self.permissions = {} + def reset(self): + region_name = self.region_name + self.__dict__ = {} + self.__init__(region_name) + def _get_rule_by_index(self, i): return self.rules.get(self.rules_order[i]) @@ -173,7 +182,7 @@ class EventsBackend(BaseBackend): return return_obj def put_rule(self, name, **kwargs): - rule = Rule(name, **kwargs) + rule = Rule(name, self.region_name, **kwargs) self.rules[rule.name] = rule self.rules_order.append(rule.name) return rule.arn @@ -229,7 +238,7 @@ class EventsBackend(BaseBackend): raise JsonRESTError('ResourceNotFoundException', 'StatementId not found') def describe_event_bus(self): - arn = "arn:aws:events:us-east-1:000000000000:event-bus/default" + arn = "arn:aws:events:{0}:000000000000:event-bus/default".format(self.region_name) statements = [] for statement_id, data in self.permissions.items(): statements.append({ @@ -248,4 +257,5 @@ class EventsBackend(BaseBackend): } -events_backend = EventsBackend() +available_regions = boto3.session.Session().get_available_regions("events") +events_backends = {region: EventsBackend(region) for region in available_regions} diff --git a/moto/events/responses.py b/moto/events/responses.py index f9cb9b5b5..2eb72d342 100644 --- a/moto/events/responses.py +++ b/moto/events/responses.py @@ -2,11 +2,21 @@ import json import re from moto.core.responses import BaseResponse -from moto.events import events_backend +from moto.events import events_backends class EventsHandler(BaseResponse): + @property + def events_backend(self): + """ + Events Backend + + :return: Events Backend object + :rtype: moto.events.models.EventsBackend + """ + return events_backends[self.region] + def _generate_rule_dict(self, rule): return { 'Name': rule.name, @@ -40,7 +50,7 @@ class EventsHandler(BaseResponse): if not name: return self.error('ValidationException', 'Parameter Name is required.') - events_backend.delete_rule(name) + self.events_backend.delete_rule(name) return '', self.response_headers @@ -50,7 +60,7 @@ class EventsHandler(BaseResponse): if not name: return self.error('ValidationException', 'Parameter Name is required.') - rule = events_backend.describe_rule(name) + rule = self.events_backend.describe_rule(name) if not rule: return self.error('ResourceNotFoundException', 'Rule test does not exist.') @@ -64,7 +74,7 @@ class EventsHandler(BaseResponse): if not name: return self.error('ValidationException', 'Parameter Name is required.') - if not events_backend.disable_rule(name): + if not self.events_backend.disable_rule(name): return self.error('ResourceNotFoundException', 'Rule ' + name + ' does not exist.') return '', self.response_headers @@ -75,7 +85,7 @@ class EventsHandler(BaseResponse): if not name: return self.error('ValidationException', 'Parameter Name is required.') - if not events_backend.enable_rule(name): + if not self.events_backend.enable_rule(name): return self.error('ResourceNotFoundException', 'Rule ' + name + ' does not exist.') return '', self.response_headers @@ -91,7 +101,7 @@ class EventsHandler(BaseResponse): if not target_arn: return self.error('ValidationException', 'Parameter TargetArn is required.') - rule_names = events_backend.list_rule_names_by_target( + rule_names = self.events_backend.list_rule_names_by_target( target_arn, next_token, limit) return json.dumps(rule_names), self.response_headers @@ -101,7 +111,7 @@ class EventsHandler(BaseResponse): next_token = self._get_param('NextToken') limit = self._get_param('Limit') - rules = events_backend.list_rules(prefix, next_token, limit) + rules = self.events_backend.list_rules(prefix, next_token, limit) rules_obj = {'Rules': []} for rule in rules['Rules']: @@ -121,7 +131,7 @@ class EventsHandler(BaseResponse): return self.error('ValidationException', 'Parameter Rule is required.') try: - targets = events_backend.list_targets_by_rule( + targets = self.events_backend.list_targets_by_rule( rule_name, next_token, limit) except KeyError: return self.error('ResourceNotFoundException', 'Rule ' + rule_name + ' does not exist.') @@ -131,7 +141,7 @@ class EventsHandler(BaseResponse): def put_events(self): events = self._get_param('Entries') - failed_entries = events_backend.put_events(events) + failed_entries = self.events_backend.put_events(events) if failed_entries: return json.dumps({ @@ -165,7 +175,7 @@ class EventsHandler(BaseResponse): re.match('^rate\(\d*\s(minute|minutes|hour|hours|day|days)\)', sched_exp)): return self.error('ValidationException', 'Parameter ScheduleExpression is not valid.') - rule_arn = events_backend.put_rule( + rule_arn = self.events_backend.put_rule( name, ScheduleExpression=sched_exp, EventPattern=event_pattern, @@ -186,7 +196,7 @@ class EventsHandler(BaseResponse): if not targets: return self.error('ValidationException', 'Parameter Targets is required.') - if not events_backend.put_targets(rule_name, targets): + if not self.events_backend.put_targets(rule_name, targets): return self.error('ResourceNotFoundException', 'Rule ' + rule_name + ' does not exist.') return '', self.response_headers @@ -201,7 +211,7 @@ class EventsHandler(BaseResponse): if not ids: return self.error('ValidationException', 'Parameter Ids is required.') - if not events_backend.remove_targets(rule_name, ids): + if not self.events_backend.remove_targets(rule_name, ids): return self.error('ResourceNotFoundException', 'Rule ' + rule_name + ' does not exist.') return '', self.response_headers @@ -214,16 +224,16 @@ class EventsHandler(BaseResponse): principal = self._get_param('Principal') statement_id = self._get_param('StatementId') - events_backend.put_permission(action, principal, statement_id) + self.events_backend.put_permission(action, principal, statement_id) return '' def remove_permission(self): statement_id = self._get_param('StatementId') - events_backend.remove_permission(statement_id) + self.events_backend.remove_permission(statement_id) return '' def describe_event_bus(self): - return json.dumps(events_backend.describe_event_bus()) + return json.dumps(self.events_backend.describe_event_bus()) diff --git a/tests/test_events/test_events.py b/tests/test_events/test_events.py index a9d90ec32..e9e1d12c9 100644 --- a/tests/test_events/test_events.py +++ b/tests/test_events/test_events.py @@ -87,7 +87,7 @@ def test_describe_rule(): assert(response is not None) assert(response.get('Name') == rule_name) - assert(response.get('Arn') is not None) + assert(response.get('Arn') == 'arn:aws:events:us-west-2:111111111111:rule/{0}'.format(rule_name)) @mock_events