def generate_notifications_for_incident(incident): now = timezone.make_aware(datetime.now(), timezone.get_current_timezone()) duty_officers = [] # if incident has been escalated, notify according to the escalated service's escalation rule if hasattr(incident, 'service_to_escalate_to') and incident.service_to_escalate_to is not None: print "escalation rule in place to " + incident.service_to_escalate_to.name duty_officers = get_escalation_for_service(incident.service_to_escalate_to) with transaction.atomic(): incident.description = "[escalated] " + incident.description incident.save() else: duty_officers = get_escalation_for_service(incident.service_key) current_time = now notifications = [] group_index = {} user_method_index = {} for officer_index, duty_officer in enumerate(duty_officers): if incident.event_type == Incident.RESOLVE and not duty_officer.profile.send_resolve_enabled: print "Skipping notification for %s because type is RESOLVE and user %s has send_resolve_enabled OFF" % (incident.incident_key, duty_officer.username) continue index = 0 if hasattr(duty_officer ,'came_from_group' ): if not duty_officer.came_from_group in group_index: group_index[duty_officer.came_from_group] = officer_index index = group_index[duty_officer.came_from_group] else: index = officer_index escalation_time = incident.service_key.escalate_after * (index + 1) escalate_at = current_time + timedelta(minutes=escalation_time) user_method_index[duty_officer.username] = 0 methods = duty_officer.notification_methods.order_by('position').all() for method in methods: notification_time = incident.service_key.retry * user_method_index[duty_officer.username] + incident.service_key.escalate_after * index notify_at = current_time + timedelta(minutes=notification_time) if notify_at < escalate_at: notification = ScheduledNotification() notification.incident = incident notification.user_to_notify = duty_officer notification.notifier = method.method notification.send_at = notify_at uri = settings.BASE_URL + "/incidents/details/" + str(incident.id) notification.message = incident.description + ". Handle at: " + uri + " Details: " + incident.details notifications.append(notification) print "[%s] Notify %s about %s at %s with method: %s" % (notification.incident.event_type, duty_officer.username, notification.incident.incident_key, notify_at, notification.notifier) else: break user_method_index[duty_officer.username] += 1 # todo: error handling return notifications
def test_get_escalation_fails_with_no_recurrence_after_event_end(self): event = Event( start=timezone.now() - timedelta(days=2), end=timezone.now() - timedelta(days=1), title='{username},{username}'.format(username=self.username), calendar=self.cal, ) event.save() try: events = get_escalation_for_service(self.service) self.assertEqual(0, len(events)) finally: event.delete()
def test_get_escalation_fails_with_no_recurrence_after_event_end(self): event = Event( start = timezone.now() - timedelta(days=2), end = timezone.now() - timedelta(days=1), title = '{username},{username}'.format(username=self.username), calendar = self.cal, ) event.save() try: events = get_escalation_for_service(self.service) self.assertEqual(0, len(events)) finally: event.delete()
def test_get_escalation_returns_empty_for_muted_services(self): event = Event( start=timezone.now() - timedelta(days=1), end=timezone.now() + timedelta(days=1), title='{username},{username}'.format(username=self.username), calendar=self.cal, ) event.save() self.service.notifications_disabled = True try: events = get_escalation_for_service(self.service) self.assertEqual(0, len(events)) finally: event.delete()
def test_get_escalation_returns_empty_for_muted_services(self): event = Event( start = timezone.now() - timedelta(days=1), end = timezone.now() + timedelta(days=1), title = '{username},{username}'.format(username=self.username), calendar = self.cal, ) event.save() self.service.notifications_disabled = True try: events = get_escalation_for_service(self.service) self.assertEqual(0, len(events)) finally: event.delete()
def test_get_escalation_works_when_recurrance_is_now(self): rule = Rule( name=random_string(), description=random_string(), frequency='WEEKLY', ) rule.save() # Active last week at this time, recurring now event = Event( start=timezone.now() - timedelta(days=7, hours=5), end=timezone.now() + timedelta(hours=4) - timedelta(days=7), title='{username},{username}'.format(username=self.username), calendar=self.cal, rule=rule, ) event.save() events = get_escalation_for_service(self.service) self.assertEqual(2, len(events))
def test_get_escalation_empty_when_recurrance_is_not_now(self): rule = Rule( name=random_string(), description=random_string(), frequency='WEEKLY', ) rule.save() # Active yesterday, and 1 week from now, but not today event = Event( start=timezone.now() - timedelta(days=2), end=timezone.now() - timedelta(days=1), title='{username},{username}'.format(username=self.username), calendar=self.cal, rule=rule, ) event.save() events = get_escalation_for_service(self.service) self.assertEqual(0, len(events))
def test_get_escalation_works_when_recurrance_is_now(self): rule = Rule( name=random_string(), description=random_string(), frequency='WEEKLY', ) rule.save() # Active last week at this time, recurring now event = Event( start = timezone.now() - timedelta(days=7, hours=5), end = timezone.now() + timedelta(hours=4) - timedelta(days=7), title = '{username},{username}'.format(username=self.username), calendar = self.cal, rule = rule, ) event.save() events = get_escalation_for_service(self.service) self.assertEqual(2, len(events))
def test_get_escalation_empty_when_recurrance_is_not_now(self): rule = Rule( name=random_string(), description=random_string(), frequency='WEEKLY', ) rule.save() # Active yesterday, and 1 week from now, but not today event = Event( start = timezone.now() - timedelta(days=2), end = timezone.now() - timedelta(days=1), title = '{username},{username}'.format(username=self.username), calendar = self.cal, rule = rule, ) event.save() events = get_escalation_for_service(self.service) self.assertEqual(0, len(events))
def generate_notifications_for_incident(incident): now = timezone.make_aware(datetime.now(), timezone.get_current_timezone()) duty_officers = get_escalation_for_service(incident.service_key) current_time = now notifications = [] for officer_index, duty_officer in enumerate(duty_officers): escalation_time = incident.service_key.escalate_after * ( officer_index + 1) escalate_at = current_time + timedelta(minutes=escalation_time) methods = duty_officer.notification_methods.order_by( 'position').all() method_index = 0 for method in methods: notification_time = incident.service_key.retry * method_index + incident.service_key.escalate_after * officer_index notify_at = current_time + timedelta(minutes=notification_time) if notify_at < escalate_at: notification = ScheduledNotification() notification.incident = incident notification.user_to_notify = duty_officer notification.notifier = method.method notification.send_at = notify_at uri = settings.BASE_URL + "/incidents/details/" + str( incident.id) notification.message = "A Service is experiencing a problem: " + incident.incident_key + " " + incident.description + ". Handle at: " + uri + " Details: " + str( incident.details) notifications.append(notification) print "Notify %s at %s with method: %s" % ( duty_officer.username, notify_at, notification.notifier) else: break method_index += 1 # todo: error handling return notifications
def generate_notifications_for_incident(incident): now = timezone.make_aware(datetime.now(), timezone.get_current_timezone()) duty_officers = get_escalation_for_service(incident.service_key) current_time = now notifications = [] for officer_index, duty_officer in enumerate(duty_officers): escalation_time = incident.service_key.escalate_after * (officer_index + 1) escalate_at = current_time + timedelta(minutes=escalation_time) methods = duty_officer.notification_methods.order_by('position').all() method_index = 0 for method in methods: notification_time = incident.service_key.retry * method_index + incident.service_key.escalate_after * officer_index notify_at = current_time + timedelta(minutes=notification_time) if notify_at < escalate_at: notification = ScheduledNotification() notification.incident = incident notification.user_to_notify = duty_officer notification.notifier = method.method notification.send_at = notify_at uri = settings.BASE_URL + "/incidents/details/" + str(incident.id) notification.message = "A Service is experiencing a problem: {} {}. Handle at: {}. Details: {}".format(incident.incident_key, incident.description, uri, incident.details) notifications.append(notification) print("Notify {} at {} with method: {}".format(duty_officer.username, notify_at, notification.notifier)) else: break method_index += 1 # todo: error handling return notifications