def create(self, request, body): if (body is None or body.get('job') is None or body['job'].get('schedule_id') is None): raise webob.exc.HTTPBadRequest() job = body['job'] try: schedule = self.db_api.schedule_get_by_id(job['schedule_id']) except exception.NotFound: raise webob.exc.HTTPNotFound() # Check integrity of schedule and update next run expected_next_run = job.get('next_run') if expected_next_run: expected_next_run = timeutils.parse_isotime(job.get('next_run')) next_run = api_utils.schedule_to_next_run(schedule, timeutils.utcnow()) try: self.db_api.schedule_test_and_set_next_run(schedule['id'], expected_next_run, next_run) except exception.NotFound: msg = _("Specified next run does not match the current next run" " value. This could mean schedule has either changed" "or has already been scheduled since you last expected.") raise webob.exc.HTTPConflict(explanation=msg) # Update schedule last_scheduled values = {} values['last_scheduled'] = timeutils.utcnow() self.db_api.schedule_update(schedule['id'], values) # Create job values = {} values.update(job) values['tenant'] = schedule['tenant'] values['action'] = schedule['action'] values['status'] = 'QUEUED' job_metadata = [] for metadata in schedule['schedule_metadata']: job_metadata.append({ 'key': metadata['key'], 'value': metadata['value'] }) values['job_metadata'] = job_metadata job_action = values['action'] if not 'timeout' in values: values['timeout'] = api_utils.get_new_timeout_by_action(job_action) values['hard_timeout'] = \ api_utils.get_new_timeout_by_action(job_action) job = self.db_api.job_create(values) utils.serialize_datetimes(job) api_utils.serialize_job_metadata(job) job = {'job': job} utils.generate_notification(None, 'qonos.job.create', job, 'INFO') return job
def create(self, request, body=None): invalid_params = [] if not body: invalid_params.append('request body is empty') elif not 'schedule' in body: invalid_params.append('request body needs "schedule" entity') else: if not body['schedule'].get('tenant'): invalid_params.append('request body needs "tenant" entity') if not body['schedule'].get('action'): invalid_params.append('request body needs "action" entity') if invalid_params: msg = _('The following errors occured with your request: %s') \ % ', '.join(invalid_params) raise webob.exc.HTTPBadRequest(explanation=msg) api_utils.deserialize_schedule_metadata(body['schedule']) values = {} values.update(body['schedule']) values['next_run'] = api_utils.schedule_to_next_run(body['schedule']) schedule = self.db_api.schedule_create(values) utils.serialize_datetimes(schedule) api_utils.serialize_schedule_metadata(schedule) return {'schedule': schedule}
def create(self, request, body=None): invalid_params = [] if not body: invalid_params.append('request body is empty') elif 'schedule' not in body: invalid_params.append('request body needs "schedule" entity') else: if not body['schedule'].get('tenant'): invalid_params.append('request body needs "tenant" entity') if not body['schedule'].get('action'): invalid_params.append('request body needs "action" entity') if invalid_params: msg = _('The following errors occured with your request: %s') \ % ', '.join(invalid_params) raise webob.exc.HTTPBadRequest(explanation=msg) api_utils.deserialize_schedule_metadata(body['schedule']) values = {} values.update(body['schedule']) values['next_run'] = api_utils.schedule_to_next_run(body['schedule']) schedule = self.db_api.schedule_create(values) utils.serialize_datetimes(schedule) api_utils.serialize_schedule_metadata(schedule) return {'schedule': schedule}
def update(self, request, schedule_id, body): if not body: msg = _('The request body must not be empty') raise webob.exc.HTTPBadRequest(explanation=msg) elif not 'schedule' in body: msg = _('The request body must contain a "schedule" entity') raise webob.exc.HTTPBadRequest(explanation=msg) # NOTE(jculp): only raise if a blank tenant is passed # passing no tenant at all is perfectly fine. elif ('tenant' in body['schedule'] and not body['schedule']['tenant'].strip()): msg = _('The request body has not specified a "tenant" entity') raise webob.exc.HTTPBadRequest(explanation=msg) api_utils.deserialize_schedule_metadata(body['schedule']) values = {} values.update(body['schedule']) try: values = api_utils.check_read_only_properties(values) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=unicode(e)) request_next_run = body['schedule'].get('next_run') times = { 'minute': None, 'hour': None, 'month': None, 'day_of_week': None, 'day_of_month': None, } update_schedule_times = False for key in times: if key in values: times[key] = values[key] update_schedule_times = True if update_schedule_times: # NOTE(ameade): We must recalculate the schedules next_run time # since the schedule has changed values.update(times) values['next_run'] = api_utils.schedule_to_next_run(times) elif request_next_run: try: timeutils.parse_isotime(request_next_run) except ValueError as e: msg = _('Invalid "next_run" value. Must be ISO 8601 format') raise webob.exc.HTTPBadRequest(explanation=msg) try: schedule = self.db_api.schedule_update(schedule_id, values) except exception.NotFound: msg = _('Schedule %s could not be found.') % schedule_id raise webob.exc.HTTPNotFound(explanation=msg) utils.serialize_datetimes(schedule) api_utils.serialize_schedule_metadata(schedule) return {'schedule': schedule}
def update(self, request, schedule_id, body): if not body: msg = _('The request body must not be empty') raise webob.exc.HTTPBadRequest(explanation=msg) elif 'schedule' not in body: msg = _('The request body must contain a "schedule" entity') raise webob.exc.HTTPBadRequest(explanation=msg) # NOTE(jculp): only raise if a blank tenant is passed # passing no tenant at all is perfectly fine. elif('tenant' in body['schedule'] and not body['schedule']['tenant'].strip()): msg = _('The request body has not specified a "tenant" entity') raise webob.exc.HTTPBadRequest(explanation=msg) api_utils.deserialize_schedule_metadata(body['schedule']) values = {} values.update(body['schedule']) try: values = api_utils.check_read_only_properties(values) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=unicode(e)) request_next_run = body['schedule'].get('next_run') times = { 'minute': None, 'hour': None, 'month': None, 'day_of_week': None, 'day_of_month': None, } update_schedule_times = False for key in times: if key in values: times[key] = values[key] update_schedule_times = True if update_schedule_times: # NOTE(ameade): We must recalculate the schedules next_run time # since the schedule has changed values.update(times) values['next_run'] = api_utils.schedule_to_next_run(times) elif request_next_run: try: timeutils.parse_isotime(request_next_run) except ValueError as e: msg = _('Invalid "next_run" value. Must be ISO 8601 format') raise webob.exc.HTTPBadRequest(explanation=msg) try: schedule = self.db_api.schedule_update(schedule_id, values) except exception.NotFound: msg = _('Schedule %s could not be found.') % schedule_id raise webob.exc.HTTPNotFound(explanation=msg) utils.serialize_datetimes(schedule) api_utils.serialize_schedule_metadata(schedule) return {'schedule': schedule}
def test_schedule_to_next_run_start_time(self): expected_start_time = timeutils.utcnow() - datetime.timedelta(2) self.called = False def fake_next_datetime(min, h, dom, m, dow, start_time): self.called = True self.assertEqual(min, '*') self.assertEqual(h, '*') self.assertEqual(dom, '*') self.assertEqual(m, '*') self.assertEqual(dow, '*') self.assertEqual(expected_start_time, start_time) self.stubs.Set(utils, 'cron_string_to_next_datetime', fake_next_datetime) api_utils.schedule_to_next_run({}, expected_start_time) self.assertTrue(self.called)
def test_schedule_to_next_run(self): timeutils.set_time_override() self.called = False def fake_next_datetime(min, h, dom, m, dow, start_time): self.called = True self.assertEqual(min, '*') self.assertEqual(h, '*') self.assertEqual(dom, '*') self.assertEqual(m, '*') self.assertEqual(dow, '*') self.assertEqual(timeutils.utcnow(), start_time) self.stubs.Set(utils, 'cron_string_to_next_datetime', fake_next_datetime) api_utils.schedule_to_next_run({}) self.assertTrue(self.called) timeutils.clear_time_override()
def create(self, request, body=None): if (body is None or type(body).__name__ != 'dict' or body.get('schedule') is None): raise webob.exc.HTTPBadRequest() api_utils.deserialize_schedule_metadata(body['schedule']) values = {} values.update(body['schedule']) values['next_run'] = api_utils.schedule_to_next_run(body['schedule']) schedule = self.db_api.schedule_create(values) utils.serialize_datetimes(schedule) api_utils.serialize_schedule_metadata(schedule) return {'schedule': schedule}
def create(self, request, body): if (body is None or body.get('job') is None or body['job'].get('schedule_id') is None): raise webob.exc.HTTPBadRequest() job = body['job'] try: schedule = self.db_api.schedule_get_by_id(job['schedule_id']) except exception.NotFound: raise webob.exc.HTTPNotFound() # Update schedule last_scheduled and next_run values = {} values['next_run'] = api_utils.schedule_to_next_run(schedule) print values['next_run'] values['last_scheduled'] = timeutils.utcnow() self.db_api.schedule_update(schedule['id'], values) # Create job values = {} values.update(job) values['tenant'] = schedule['tenant'] values['action'] = schedule['action'] values['status'] = 'queued' job_metadata = [] for metadata in schedule['schedule_metadata']: job_metadata.append({ 'key': metadata['key'], 'value': metadata['value'] }) values['job_metadata'] = job_metadata now = timeutils.utcnow() job_timeout_seconds = self._job_get_timeout(values['action']) if not 'timeout' in values: values['timeout'] = now +\ datetime.timedelta(seconds=job_timeout_seconds) values['hard_timeout'] = now +\ datetime.timedelta(seconds=job_timeout_seconds) job = self.db_api.job_create(values) utils.serialize_datetimes(job) api_utils.serialize_job_metadata(job) return {'job': job}
def create(self, request, body=None): if not body: msg = _('The request body must not be empty') raise webob.exc.HTTPBadRequest(explanation=msg) if not 'schedule' in body: msg = _('The request body must contain a "schedule" entity') raise webob.exc.HTTPBadRequest(explanation=msg) api_utils.deserialize_schedule_metadata(body['schedule']) values = {} values.update(body['schedule']) values['next_run'] = api_utils.schedule_to_next_run(body['schedule']) schedule = self.db_api.schedule_create(values) utils.serialize_datetimes(schedule) api_utils.serialize_schedule_metadata(schedule) return {'schedule': schedule}
def update(self, request, schedule_id, body): if not body: msg = _('The request body must not be empty') raise webob.exc.HTTPBadRequest(explanation=msg) if not 'schedule' in body: msg = _('The request body must contain a "schedule" entity') raise webob.exc.HTTPBadRequest(explanation=msg) api_utils.deserialize_schedule_metadata(body['schedule']) values = {} values.update(body['schedule']) try: values = api_utils.check_read_only_properties(values) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=unicode(e)) times = { 'minute': None, 'hour': None, 'month': None, 'day_of_week': None, 'day_of_month': None, } update_schedule_times = False for key in times: if key in values: times[key] = values[key] update_schedule_times = True if update_schedule_times: # NOTE(ameade): We must recalculate the schedules next_run time # since the schedule has changed values.update(times) values['next_run'] = api_utils.schedule_to_next_run(times) try: schedule = self.db_api.schedule_update(schedule_id, values) except exception.NotFound: msg = _('Schedule %s could not be found.') % schedule_id raise webob.exc.HTTPNotFound(explanation=msg) utils.serialize_datetimes(schedule) api_utils.serialize_schedule_metadata(schedule) return {'schedule': schedule}
def create(self, request, body): if (body is None or body.get('job') is None or body['job'].get('schedule_id') is None): raise webob.exc.HTTPBadRequest() job = body['job'] try: schedule = self.db_api.schedule_get_by_id(job['schedule_id']) except exception.NotFound: raise webob.exc.HTTPNotFound() # Check integrity of schedule and update next run expected_next_run = job.get('next_run') if expected_next_run: try: expected_next_run = timeutils.parse_isotime(expected_next_run) expected_next_run = expected_next_run.replace(tzinfo=None) except ValueError as e: msg = _('Invalid "next_run" value. Must be ISO 8601 format') raise webob.exc.HTTPBadRequest(explanation=msg) next_run = api_utils.schedule_to_next_run(schedule, timeutils.utcnow()) next_run = next_run.replace(tzinfo=None) try: self.db_api.schedule_test_and_set_next_run(schedule['id'], expected_next_run, next_run) except exception.NotFound: msg = _("Specified next run does not match the current next run" " value. This could mean schedule has either changed" "or has already been scheduled since you last expected.") raise webob.exc.HTTPConflict(explanation=msg) # Update schedule last_scheduled values = {} values['last_scheduled'] = timeutils.utcnow() self.db_api.schedule_update(schedule['id'], values) # Create job values = {} values.update(job) values['tenant'] = schedule['tenant'] values['action'] = schedule['action'] values['status'] = 'QUEUED' job_metadata = [] for metadata in schedule['schedule_metadata']: job_metadata.append({ 'key': metadata['key'], 'value': metadata['value'] }) values['job_metadata'] = job_metadata job_action = values['action'] if not 'timeout' in values: values['timeout'] = api_utils.get_new_timeout_by_action(job_action) values['hard_timeout'] = \ api_utils.get_new_timeout_by_action(job_action) job = self.db_api.job_create(values) utils.serialize_datetimes(job) api_utils.serialize_job_metadata(job) job = {'job': job} utils.generate_notification(None, 'qonos.job.create', job, 'INFO') return job