def test_get_rules_from_domain(self): rules = AutomaticUpdateRule.by_domain(self.domain) rules_by_case_type = AutomaticUpdateRule.organize_rules_by_case_type( rules) expected_case_types = [ 'test-case-type', 'test-case-type-2', 'test-case-type-3' ] actual_case_types = rules_by_case_type.keys() self.assertEqual(set(expected_case_types), set(actual_case_types)) expected_rule_ids = [self.rule.pk, self.rule4.pk] actual_rule_ids = [ rule.pk for rule in rules_by_case_type['test-case-type'] ] self.assertEqual(set(expected_rule_ids), set(actual_rule_ids)) expected_rule_ids = [self.rule2.pk, self.rule3.pk] actual_rule_ids = [ rule.pk for rule in rules_by_case_type['test-case-type-2'] ] self.assertEqual(set(expected_rule_ids), set(actual_rule_ids)) expected_rule_ids = [self.rule5.pk] actual_rule_ids = [ rule.pk for rule in rules_by_case_type['test-case-type-3'] ] self.assertEqual(set(expected_rule_ids), set(actual_rule_ids))
def run_case_update_rules_for_domain(domain, now=None): now = now or datetime.utcnow() start_run = datetime.utcnow() all_rules = AutomaticUpdateRule.by_domain(domain) rules_by_case_type = AutomaticUpdateRule.organize_rules_by_case_type(all_rules) for case_type, rules in rules_by_case_type.iteritems(): boundary_date = AutomaticUpdateRule.get_boundary_date(rules, now) case_id_chunks = AutomaticUpdateRule.get_case_ids(domain, case_type, boundary_date) for case_ids in case_id_chunks: for case in CaseAccessors(domain).iter_cases(case_ids): time_elapsed = datetime.utcnow() - start_run if time_elapsed.seconds > HALT_AFTER: notify_error( "Halting rule run for domain %s as it's been running for more than a day." % domain ) return for rule in rules: stop_processing = rule.apply_rule(case, now) if stop_processing: break for rule in rules: rule.last_run = now rule.save()
def _get_rules(self, domain, case_type): domain_rules = self.rules_by_domain.get(domain) if not domain_rules or domain_rules.expired(): rules = AutomaticUpdateRule.by_domain_cached(domain, AutomaticUpdateRule.WORKFLOW_SCHEDULING) domain_rules = CaseRules( datetime.utcnow(), AutomaticUpdateRule.organize_rules_by_case_type(rules) ) self.rules_by_domain[domain] = domain_rules return domain_rules.by_case_type.get(case_type, [])
def test_boundary_date(self): rules = AutomaticUpdateRule.by_domain(self.domain) rules_by_case_type = AutomaticUpdateRule.organize_rules_by_case_type(rules) boundary_date = AutomaticUpdateRule.get_boundary_date( rules_by_case_type['test-case-type'], datetime(2016, 1, 1)) self.assertEqual(boundary_date, datetime(2015, 12, 2)) boundary_date = AutomaticUpdateRule.get_boundary_date( rules_by_case_type['test-case-type-2'], datetime(2016, 1, 1)) self.assertEqual(boundary_date, datetime(2015, 12, 2))
def test_boundary_date(self): rules = AutomaticUpdateRule.by_domain(self.domain) rules_by_case_type = AutomaticUpdateRule.organize_rules_by_case_type( rules) boundary_date = AutomaticUpdateRule.get_boundary_date( rules_by_case_type['test-case-type'], datetime(2016, 1, 1)) self.assertEqual(boundary_date, datetime(2015, 12, 2)) boundary_date = AutomaticUpdateRule.get_boundary_date( rules_by_case_type['test-case-type-2'], datetime(2016, 1, 1)) self.assertEqual(boundary_date, datetime(2015, 12, 2))
def run_case_update_rules_for_domain_and_db(domain, now, run_id, db=None): domain_obj = Domain.get_by_name(domain) max_allowed_updates = domain_obj.auto_case_update_limit or settings.MAX_RULE_UPDATES_IN_ONE_RUN start_run = datetime.utcnow() last_migration_check_time = None cases_checked = 0 case_update_result = CaseRuleActionResult() all_rules = list( AutomaticUpdateRule.by_domain( domain, AutomaticUpdateRule.WORKFLOW_CASE_UPDATE)) rules_by_case_type = AutomaticUpdateRule.organize_rules_by_case_type( all_rules) for case_type, rules in six.iteritems(rules_by_case_type): boundary_date = AutomaticUpdateRule.get_boundary_date(rules, now) case_ids = list( AutomaticUpdateRule.get_case_ids(domain, case_type, boundary_date, db=db)) for case in CaseAccessors(domain).iter_cases(case_ids): migration_in_progress, last_migration_check_time = check_data_migration_in_progress( domain, last_migration_check_time) time_elapsed = datetime.utcnow() - start_run if (time_elapsed.seconds > HALT_AFTER or case_update_result.total_updates >= max_allowed_updates or migration_in_progress): DomainCaseRuleRun.done(run_id, DomainCaseRuleRun.STATUS_HALTED, cases_checked, case_update_result, db=db) notify_error("Halting rule run for domain %s." % domain) return case_update_result.add_result(run_rules_for_case(case, rules, now)) cases_checked += 1 run = DomainCaseRuleRun.done(run_id, DomainCaseRuleRun.STATUS_FINISHED, cases_checked, case_update_result, db=db) if run.status == DomainCaseRuleRun.STATUS_FINISHED: for rule in all_rules: AutomaticUpdateRule.objects.filter(pk=rule.pk).update(last_run=now)
def test_get_rules_from_domain(self): rules = AutomaticUpdateRule.by_domain(self.domain) rules_by_case_type = AutomaticUpdateRule.organize_rules_by_case_type(rules) expected_case_types = ['test-case-type', 'test-case-type-2'] actual_case_types = rules_by_case_type.keys() self.assertEqual(set(expected_case_types), set(actual_case_types)) expected_rule_ids = [self.rule.pk] actual_rule_ids = [rule.pk for rule in rules_by_case_type['test-case-type']] self.assertEqual(set(expected_rule_ids), set(actual_rule_ids)) expected_rule_ids = [self.rule2.pk, self.rule3.pk] actual_rule_ids = [rule.pk for rule in rules_by_case_type['test-case-type-2']] self.assertEqual(set(expected_rule_ids), set(actual_rule_ids))
def run_case_update_rules_for_domain(domain, now=None): domain_obj = Domain.get_by_name(domain) max_allowed_updates = domain_obj.auto_case_update_limit or settings.MAX_RULE_UPDATES_IN_ONE_RUN now = now or datetime.utcnow() start_run = datetime.utcnow() last_migration_check_time = None run_record = DomainCaseRuleRun.objects.create( domain=domain, started_on=start_run, status=DomainCaseRuleRun.STATUS_RUNNING, ) cases_checked = 0 case_update_result = CaseRuleActionResult() all_rules = AutomaticUpdateRule.by_domain( domain, AutomaticUpdateRule.WORKFLOW_CASE_UPDATE) rules_by_case_type = AutomaticUpdateRule.organize_rules_by_case_type( all_rules) for case_type, rules in six.iteritems(rules_by_case_type): boundary_date = AutomaticUpdateRule.get_boundary_date(rules, now) case_ids = list( AutomaticUpdateRule.get_case_ids(domain, case_type, boundary_date)) for case in CaseAccessors(domain).iter_cases(case_ids): migration_in_progress, last_migration_check_time = check_data_migration_in_progress( domain, last_migration_check_time) time_elapsed = datetime.utcnow() - start_run if (time_elapsed.seconds > HALT_AFTER or case_update_result.total_updates >= max_allowed_updates or migration_in_progress): run_record.done(DomainCaseRuleRun.STATUS_HALTED, cases_checked, case_update_result) notify_error("Halting rule run for domain %s." % domain) return case_update_result.add_result(run_rules_for_case(case, rules, now)) cases_checked += 1 for rule in rules: rule.last_run = now rule.save() run_record.done(DomainCaseRuleRun.STATUS_FINISHED, cases_checked, case_update_result)
def run_case_update_rules_for_domain(domain, now=None): now = now or datetime.utcnow() all_rules = AutomaticUpdateRule.by_domain(domain) rules_by_case_type = AutomaticUpdateRule.organize_rules_by_case_type(all_rules) for case_type, rules in rules_by_case_type.iteritems(): boundary_date = AutomaticUpdateRule.get_boundary_date(rules, now) case_ids = AutomaticUpdateRule.get_case_ids(domain, boundary_date, case_type) for doc in iter_docs(CommCareCase.get_db(), case_ids): case = CommCareCase.wrap(doc) for rule in rules: rule.apply_rule(case, now) for rule in rules: rule.last_run = now rule.save()
def run_case_update_rules_for_domain(domain, now=None): now = now or datetime.utcnow() all_rules = AutomaticUpdateRule.by_domain(domain) rules_by_case_type = AutomaticUpdateRule.organize_rules_by_case_type(all_rules) for case_type, rules in rules_by_case_type.iteritems(): boundary_date = AutomaticUpdateRule.get_boundary_date(rules, now) case_ids = AutomaticUpdateRule.get_case_ids(domain, case_type, boundary_date) for case in CaseAccessors(domain).iter_cases(case_ids): for rule in rules: stop_processing = rule.apply_rule(case, now) if stop_processing: break for rule in rules: rule.last_run = now rule.save()
def _sync_case_for_messaging(domain, case_id): try: case = CaseAccessors(domain).get_case(case_id) sms_tasks.clear_case_caches(case) except CaseNotFound: case = None if case is None or case.is_deleted: sms_tasks.delete_phone_numbers_for_owners([case_id]) delete_schedule_instances_for_cases(domain, [case_id]) return if use_phone_entries(): sms_tasks._sync_case_phone_number(case) rules = AutomaticUpdateRule.by_domain_cached(case.domain, AutomaticUpdateRule.WORKFLOW_SCHEDULING) rules_by_case_type = AutomaticUpdateRule.organize_rules_by_case_type(rules) for rule in rules_by_case_type.get(case.type, []): rule.run_rule(case, utcnow())
def run_case_update_rules_for_domain_and_db(domain, now, run_id, db=None): domain_obj = Domain.get_by_name(domain) max_allowed_updates = domain_obj.auto_case_update_limit or settings.MAX_RULE_UPDATES_IN_ONE_RUN start_run = datetime.utcnow() last_migration_check_time = None cases_checked = 0 case_update_result = CaseRuleActionResult() all_rules = list(AutomaticUpdateRule.by_domain(domain, AutomaticUpdateRule.WORKFLOW_CASE_UPDATE)) rules_by_case_type = AutomaticUpdateRule.organize_rules_by_case_type(all_rules) for case_type, rules in six.iteritems(rules_by_case_type): boundary_date = AutomaticUpdateRule.get_boundary_date(rules, now) case_ids = list(AutomaticUpdateRule.get_case_ids(domain, case_type, boundary_date, db=db)) for case in CaseAccessors(domain).iter_cases(case_ids): migration_in_progress, last_migration_check_time = check_data_migration_in_progress(domain, last_migration_check_time) time_elapsed = datetime.utcnow() - start_run if ( time_elapsed.seconds > HALT_AFTER or case_update_result.total_updates >= max_allowed_updates or migration_in_progress ): DomainCaseRuleRun.done(run_id, DomainCaseRuleRun.STATUS_HALTED, cases_checked, case_update_result, db=db) notify_error("Halting rule run for domain %s." % domain) return case_update_result.add_result(run_rules_for_case(case, rules, now)) cases_checked += 1 run = DomainCaseRuleRun.done(run_id, DomainCaseRuleRun.STATUS_FINISHED, cases_checked, case_update_result, db=db) if run.status == DomainCaseRuleRun.STATUS_FINISHED: for rule in all_rules: AutomaticUpdateRule.objects.filter(pk=rule.pk).update(last_run=now)
def run_case_update_rules_for_domain(domain, now=None): now = now or datetime.utcnow() start_run = datetime.utcnow() run_record = DomainCaseRuleRun.objects.create( domain=domain, started_on=start_run, status=DomainCaseRuleRun.STATUS_RUNNING, ) cases_checked = 0 case_update_result = CaseRuleActionResult() all_rules = AutomaticUpdateRule.by_domain(domain) rules_by_case_type = AutomaticUpdateRule.organize_rules_by_case_type(all_rules) for case_type, rules in rules_by_case_type.iteritems(): boundary_date = AutomaticUpdateRule.get_boundary_date(rules, now) case_id_chunks = AutomaticUpdateRule.get_case_ids(domain, case_type, boundary_date) for case_ids in case_id_chunks: for case in CaseAccessors(domain).iter_cases(case_ids): time_elapsed = datetime.utcnow() - start_run if ( time_elapsed.seconds > HALT_AFTER or case_update_result.total_updates >= settings.MAX_RULE_UPDATES_IN_ONE_RUN ): run_record.done(DomainCaseRuleRun.STATUS_HALTED, cases_checked, case_update_result) notify_error("Halting rule run for domain %s." % domain) return case_update_result.add_result(run_rules_for_case(case, rules, now)) cases_checked += 1 for rule in rules: rule.last_run = now rule.save() run_record.done(DomainCaseRuleRun.STATUS_FINISHED, cases_checked, case_update_result)
def run_auto_update_rules_for_case(case): rules = AutomaticUpdateRule.by_domain_cached( case.domain, AutomaticUpdateRule.WORKFLOW_SCHEDULING) rules_by_case_type = AutomaticUpdateRule.organize_rules_by_case_type(rules) for rule in rules_by_case_type.get(case.type, []): rule.run_rule(case, utcnow())
self.retry(exc=e) def _sync_case_for_messaging(domain, case_id): case = CaseAccessors(domain).get_case(case_id) sms_tasks.clear_case_caches(case) if settings.SERVER_ENVIRONMENT not in settings.ICDS_ENVS: sms_tasks._sync_case_phone_number(case) handler_ids = CaseReminderHandler.get_handler_ids_for_case_post_save(case.domain, case.type) if handler_ids: reminders_tasks._process_case_changed_for_case(domain, case, handler_ids) rules = AutomaticUpdateRule.by_domain_cached(case.domain, AutomaticUpdateRule.WORKFLOW_SCHEDULING) rules_by_case_type = AutomaticUpdateRule.organize_rules_by_case_type(rules) for rule in rules_by_case_type.get(case.type, []): rule.run_rule(case, utcnow()) def _get_cached_rule(domain, rule_id): rules = AutomaticUpdateRule.by_domain_cached(domain, AutomaticUpdateRule.WORKFLOW_SCHEDULING) rules = list(filter(lambda rule: rule.pk == rule_id, rules)) if len(rules) != 1: return None return rules[0] def _sync_case_for_messaging_rule(domain, case_id, rule_id):