Exemplo n.º 1
0
def add_startup_jobs(cluster_id, odb, jobs, stats_enabled):
    """ Adds internal jobs to the ODB. Note that it isn't being added
    directly to the scheduler because we want users to be able to fine-tune the job's
    settings.
    """
    with closing(odb.session()) as session:
        for item in jobs:

            if not stats_enabled and item['name'].startswith('zato.stats'):
                continue

            try:
                service_id = get_service_by_name(session, cluster_id, item['service'])[0]

                now = datetime.utcnow()

                job = Job(None, item['name'], True, 'interval_based', now, item.get('extra', '').encode('utf-8'),
                          cluster_id=cluster_id, service_id=service_id)

                kwargs = {}
                for name in('seconds', 'minutes'):
                    if name in item:
                        kwargs[name] = item[name]

                ib_job = IntervalBasedJob(None, job, **kwargs)

                session.add(job)
                session.add(ib_job)
                session.commit()
            except(IntegrityError, ProgrammingError), e:
                session.rollback()
                logger.debug('Caught an expected error, carrying on anyway, e:[%s]', format_exc(e).decode('utf-8'))
Exemplo n.º 2
0
def add_startup_jobs(cluster_id, odb, stats_jobs):
    """ Adds one of the interval jobs to the ODB. Note that it isn't being added
    directly to the scheduler because we want users to be able to fine-tune the job's
    settings.
    """
    with closing(odb.session()) as session:
        for item in stats_jobs:

            try:
                service_id = get_service_by_name(session, cluster_id, item['service'])[0]

                now = datetime.utcnow().strftime(scheduler_date_time_format)
                job = Job(None, item['name'], True, 'interval_based', now, item.get('extra', '').encode('utf-8'),
                          cluster_id=cluster_id, service_id=service_id)

                kwargs = {}
                for name in('seconds', 'minutes'):
                    if name in item:
                        kwargs[name] = item[name]

                ib_job = IntervalBasedJob(None, job, **kwargs)

                session.add(job)
                session.add(ib_job)
                session.commit()
            except IntegrityError, e:
                session.rollback()
                msg = 'Caught an IntegrityError, carrying on anyway, e:[{}]]'.format(format_exc(e))
                logger.debug(msg)
Exemplo n.º 3
0
def _create_edit(action, payload, logger, session, broker_client):
    """ Creating and updating a job requires a series of very similar steps
    so they've been all put here and depending on the 'action' parameter 
    (be it 'create'/'edit') some additional operations are performed.
    """
    core_params = ['cluster_id', 'name', 'is_active', 'job_type', 'service',
                   'start_date', 'extra']
    params = _get_params(payload, core_params, 'data.', default_value='')
    
    job_type = params['job_type']
    cluster_id = params['cluster_id']
    name = params['name']
    service_name = params['service']
    
    if job_type not in ('one_time', 'interval_based', 'cron_style'):
        msg = 'Unrecognized job type [{0}]'.format(job_type)
        logger.error(msg)
        raise ZatoException(msg)
    
    # For finding out if we don't have a job of that name already defined.
    existing_one_base = session.query(Job).\
        filter(Cluster.id==cluster_id).\
        filter(Job.name==name)
    
    if action == 'create':
        existing_one = existing_one_base.first()
    else:
        edit_params = _get_params(payload, ['id'], 'data.')
        job_id = edit_params['id']
        existing_one = existing_one_base.filter(Job.id != job_id).first()
    
    if existing_one:
        raise Exception('Job [{0}] already exists on this cluster'.format(
            name))
    
    # Is the service's name correct?
    service = session.query(Service).\
        filter(Cluster.id==cluster_id).\
        filter(Service.name==service_name).first()
    
    if not service:
        msg = 'Service [{0}] does not exist on this cluster'.format(service_name)
        logger.error(msg)
        raise Exception(msg)
    
    # We can create/edit a base Job object now and - optionally - another one
    # if the job type's is either interval-based or Cron-style. The base
    # instance will be enough if it's a one-time job.
    
    extra = params['extra'].encode('utf-8')
    is_active = is_boolean(params['is_active'])
    start_date = params['start_date']
    
    
    if action == 'create':
        job = Job(None, name, is_active, job_type, 
                  start_date, extra, 
                  cluster_id=cluster_id, service=service)
    else:
        job = session.query(Job).filter_by(id=job_id).one()
        old_name = job.name
        job.name = name
        job.is_active = is_active
        job.start_date = start_date
        job.service = service
        job.extra = extra
        
    try:
        # Add but don't commit yet.
        session.add(job)

        if job_type == 'interval_based':
            request_params = ['weeks', 'days', 'hours', 'minutes', 'seconds', 'repeats']
            ib_params = _get_params(payload, request_params, 'data.', default_value='')

            if not any(ib_params[key] for key in ('weeks', 'days', 'hours', 'minutes', 'seconds')):
                msg = "At least one of ['weeks', 'days', 'hours', 'minutes', 'seconds'] must be given."
                logger.error(msg)
                raise ZatoException(msg)
            
            if action == 'create':
                ib_job = IntervalBasedJob(None, job)
            else:
                ib_job = session.query(IntervalBasedJob).filter_by(
                    id=job.interval_based.id).one()

            for param, value in ib_params.items():
                if value:
                    setattr(ib_job, param, value)
            
            session.add(ib_job)
            
        elif job_type == 'cron_style':
            cs_params = _get_params(payload, ['cron_definition'], 'data.')
            cron_definition = cs_params['cron_definition'].strip()
            
            if cron_definition.startswith('@'):
                if not cron_definition in PREDEFINED_CRON_DEFINITIONS:
                    msg = ('If using a predefined definition, it must be '
                             'one of {0} instead of [{1}]').format(
                                 sorted(PREDEFINED_CRON_DEFINITIONS), 
                                 cron_definition)
                    logger.error(msg)
                    raise Exception(msg)
                
                cron_definition = PREDEFINED_CRON_DEFINITIONS[cron_definition]
            else:
                splitted = cron_definition.strip().split()
                if not len(splitted) == CRON_EXPRESSION_LEN:
                    msg = ('Expression [{0}] in invalid, it needs to contain '
                           'exactly {1} whitespace-separated fields').format(
                               cron_definition, CRON_EXPRESSION_LEN)
                    logger.error(msg)
                    raise Exception(msg)
                cron_definition = ' '.join(splitted)
            
            if action == 'create':
                cs_job = CronStyleJob(None, job)
            else:
                cs_job = session.query(CronStyleJob).filter_by(
                    id=job.cron_style.id).one()
                
            cs_job.cron_definition = cron_definition
            session.add(cs_job)

        # We can commit it all now.
        session.commit()
        
        # Now send it to the broker, but only if the job is active.
        if is_active:
            msg_action = SCHEDULER.CREATE if action == 'create' else SCHEDULER.EDIT
            msg = {'action': msg_action, 'job_type': job_type,
                   'is_active':is_active, 'start_date':start_date,
                   'extra':extra, 'service': service_name, 'name': name
                   }
            if action == 'edit':
                msg['old_name'] = old_name

            if job_type == 'interval_based':
                for param, value in ib_params.items():
                    msg[param] = int(value) if value else 0
            elif job_type == 'cron_style':
                msg['cron_definition'] = cron_definition
        else:
            msg = {'action': SCHEDULER.DELETE, 'name': name}
            
        broker_client.send_json(msg, MESSAGE_TYPE.TO_SINGLETON)
        
            
    except Exception, e:
        session.rollback()
        msg = 'Could not complete the request, e=[{e}]'.format(e=format_exc(e))
        logger.error(msg)
        
        raise 
Exemplo n.º 4
0
def _create_edit(action, cid, input, payload, logger, session, broker_client,
                 response):
    """ Creating and updating a job requires a series of very similar steps
    so they've been all put here and depending on the 'action' parameter
    (be it 'create'/'edit') some additional operations are performed.
    """
    job_type = input.job_type
    cluster_id = input.cluster_id
    name = input.name
    service_name = input.service

    if job_type not in (SCHEDULER.JOB_TYPE.ONE_TIME,
                        SCHEDULER.JOB_TYPE.INTERVAL_BASED,
                        SCHEDULER.JOB_TYPE.CRON_STYLE):
        msg = 'Unrecognized job type [{0}]'.format(job_type)
        logger.error(msg)
        raise ZatoException(cid, msg)

    # For finding out if we don't have a job of that name already defined.
    existing_one_base = session.query(Job).\
        filter(Cluster.id==cluster_id).\
        filter(Job.name==name)

    if action == 'create':
        existing_one = existing_one_base.first()
    else:
        job_id = input.id
        existing_one = existing_one_base.filter(Job.id != job_id).first()

    if existing_one:
        raise ZatoException(
            cid, 'Job [{0}] already exists on this cluster'.format(name))

    # Is the service's name correct?
    service = session.query(Service).\
        filter(Cluster.id==cluster_id).\
        filter(Service.cluster_id==Cluster.id).\
        filter(Service.name==service_name).first()

    if not service:
        msg = 'Service [{0}] does not exist on this cluster'.format(
            service_name)
        logger.error(msg)
        raise ZatoException(cid, msg)

    # We can create/edit a base Job object now and - optionally - another one
    # if the job type's is either interval-based or Cron-style. The base
    # instance will be enough if it's a one-time job.

    extra = input.extra.encode('utf-8')
    is_active = input.is_active
    start_date = parse(input.start_date)

    if action == 'create':
        job = Job(None,
                  name,
                  is_active,
                  job_type,
                  start_date,
                  extra,
                  cluster_id=cluster_id,
                  service=service)
    else:
        job = session.query(Job).filter_by(id=job_id).one()
        old_name = job.name
        job.name = name
        job.is_active = is_active
        job.start_date = start_date
        job.service = service
        job.extra = extra

    try:
        # Add but don't commit yet.
        session.add(job)

        if job_type == SCHEDULER.JOB_TYPE.INTERVAL_BASED:
            ib_params = ('weeks', 'days', 'hours', 'minutes', 'seconds')
            if not any(input[key] for key in ib_params):
                msg = "At least one of ['weeks', 'days', 'hours', 'minutes', 'seconds'] must be given"
                logger.error(msg)
                raise ZatoException(cid, msg)

            if action == 'create':
                ib_job = IntervalBasedJob(None, job)
            else:
                ib_job = session.query(IntervalBasedJob).filter_by(
                    id=job.interval_based.id).one()

            for param in ib_params + ('repeats', ):
                value = input[param] or None
                if value != ZATO_NONE:
                    setattr(ib_job, param, value)

            value = input['repeats'] or None
            if value != ZATO_NONE:
                setattr(ib_job, 'repeats', value)

            session.add(ib_job)

        elif job_type == SCHEDULER.JOB_TYPE.CRON_STYLE:
            cron_definition = input.cron_definition.strip()

            # Just to make sure it's syntactically correct
            CronTab(cron_definition).next()

            if action == 'create':
                cs_job = CronStyleJob(None, job)
            else:
                cs_job = session.query(CronStyleJob).filter_by(
                    id=job.cron_style.id).one()

            cs_job.cron_definition = cron_definition
            session.add(cs_job)

        # We can commit it all now.
        session.commit()

        # Now send it to the broker, but only if the job is active.
        if is_active:
            msg_action = SCHEDULER_MSG.CREATE.value if action == 'create' else SCHEDULER_MSG.EDIT.value
            msg = {
                'action': msg_action,
                'job_type': job_type,
                'is_active': is_active,
                'start_date': start_date.isoformat(),
                'extra': extra,
                'service': service.name,
                'id': job.id,
                'name': name
            }

            if action == 'edit':
                msg['old_name'] = old_name

            if job_type == SCHEDULER.JOB_TYPE.INTERVAL_BASED:
                for param in ib_params + ('repeats', ):
                    value = input[param]
                    msg[param] = int(value) if value else 0

            elif job_type == SCHEDULER.JOB_TYPE.CRON_STYLE:
                msg['cron_definition'] = cron_definition

        else:
            msg = {'action': SCHEDULER_MSG.DELETE.value, 'name': name}

        broker_client.publish(msg, MESSAGE_TYPE.TO_SCHEDULER)

    except Exception, e:
        session.rollback()
        msg = 'Could not complete the request, e:[{e}]'.format(e=format_exc(e))
        logger.error(msg)
        raise
Exemplo n.º 5
0
def index(req):
    try:
        jobs = []

        # Build a list of schedulers for a given Zato cluster.
        if req.zato.cluster_id and req.method == 'GET':

            # We have a server to pick the schedulers from, try to invoke it now.
            response = req.zato.client.invoke(
                'zato.scheduler.job.get-list',
                {'cluster_id': req.zato.cluster_id})

            if response.has_data:
                for job_elem in response.data:

                    id = job_elem.id
                    name = job_elem.name
                    is_active = job_elem.is_active
                    job_type = job_elem.job_type
                    start_date = job_elem.start_date
                    service_name = job_elem.service_name
                    extra = job_elem.extra
                    job_type_friendly = job_type_friendly_names[job_type]

                    job = Job(id,
                              name,
                              is_active,
                              job_type,
                              from_utc_to_user(start_date + '+00:00',
                                               req.zato.user_profile),
                              extra,
                              service_name=service_name,
                              job_type_friendly=job_type_friendly)

                    if job_type == SCHEDULER.JOB_TYPE.ONE_TIME:
                        definition_text = _one_time_job_def(
                            req.zato.user_profile, start_date)

                    elif job_type == SCHEDULER.JOB_TYPE.INTERVAL_BASED:
                        definition_text = _interval_based_job_def(
                            req.zato.user_profile,
                            _get_start_date(job_elem.start_date),
                            job_elem.repeats, job_elem.weeks, job_elem.days,
                            job_elem.hours, job_elem.minutes, job_elem.seconds)

                        weeks = job_elem.weeks or ''
                        days = job_elem.days or ''
                        hours = job_elem.hours or ''
                        minutes = job_elem.minutes or ''
                        seconds = job_elem.seconds or ''
                        repeats = job_elem.repeats or ''

                        ib_job = IntervalBasedJob(None, None, weeks, days,
                                                  hours, minutes, seconds,
                                                  repeats)
                        job.interval_based = ib_job

                    elif job_type == SCHEDULER.JOB_TYPE.CRON_STYLE:
                        cron_definition = job_elem.cron_definition or ''
                        definition_text = _cron_style_job_def(
                            req.zato.user_profile, start_date, cron_definition)

                        cs_job = CronStyleJob(None, None, cron_definition)
                        job.cron_style = cs_job

                    else:
                        msg = 'Unrecognized job type, name:[{0}], type:[{1}]'.format(
                            name, job_type)
                        logger.error(msg)
                        raise ZatoException(msg)

                    job.definition_text = definition_text
                    jobs.append(job)
            else:
                logger.info('No jobs found, response:[{}]'.format(response))

        if req.method == 'POST':

            action = req.POST.get('zato_action', '')
            if not action:
                msg = 'req.POST contains no [zato_action] parameter.'
                logger.error(msg)
                return HttpResponseServerError(msg)

            job_type = req.POST.get('job_type', '')
            if action != 'execute' and not job_type:
                msg = 'req.POST contains no [job_type] parameter.'
                logger.error(msg)
                return HttpResponseServerError(msg)

            job_name = req.POST['{0}-{1}-name'.format(action, job_type)]

            # Try to match the action and a job type with an action handler..
            handler_name = '_' + action
            if action != 'execute':
                handler_name += '_' + job_type

            handler = globals().get(handler_name)
            if not handler:
                msg = ('No handler found for action [{0}], job_type:[{1}], '
                       'req.POST:[{2}], req.GET:[{3}].'.format(
                           action, job_type, pprint(req.POST),
                           pprint(req.GET)))

                logger.error(msg)
                return HttpResponseServerError(msg)

            # .. invoke the action handler.
            try:
                response = handler(req.zato.client, req.zato.user_profile,
                                   req.zato.cluster, req.POST)
                response = response if response else ''
                if response:
                    response['message'] = _get_success_message(
                        action, job_type, job_name)
                    response = dumps(response)
                return HttpResponse(response,
                                    content_type='application/javascript')
            except Exception, e:
                msg = ('Could not invoke action [%s], job_type:[%s], e:[%s]'
                       'req.POST:[%s], req.GET:[%s]') % (
                           action, job_type, format_exc(), pprint(
                               req.POST), pprint(req.GET))

                logger.error(msg)
                return HttpResponseServerError(msg)

        return_data = {
            'zato_clusters':
            req.zato.clusters,
            'cluster_id':
            req.zato.cluster_id,
            'choose_cluster_form':
            req.zato.choose_cluster_form,
            'jobs':
            jobs,
            'friendly_names':
            job_type_friendly_names.items(),
            'create_one_time_form':
            OneTimeSchedulerJobForm(create_one_time_prefix, req),
            'create_interval_based_form':
            IntervalBasedSchedulerJobForm(create_interval_based_prefix, req),
            'create_cron_style_form':
            CronStyleSchedulerJobForm(create_cron_style_prefix, req),
            'edit_one_time_form':
            OneTimeSchedulerJobForm(edit_one_time_prefix, req),
            'edit_interval_based_form':
            IntervalBasedSchedulerJobForm(edit_interval_based_prefix, req),
            'edit_cron_style_form':
            CronStyleSchedulerJobForm(edit_cron_style_prefix, req),
            'sample_dt':
            get_sample_dt(req.zato.user_profile),
        }

        return_data.update(get_js_dt_format(req.zato.user_profile))

        return TemplateResponse(req, 'zato/scheduler.html', return_data)
Exemplo n.º 6
0
def index(req):
    try:
        jobs = []

        # Build a list of schedulers for a given Zato cluster.
        if req.zato.cluster_id and req.method == 'GET':

            # We have a server to pick the schedulers from, try to invoke it now.
            response = req.zato.client.invoke('zato.scheduler.job.get-list', {'cluster_id': req.zato.cluster_id})

            if response.has_data:
                for job_elem in response.data:

                    id = job_elem.id
                    name = job_elem.name
                    is_active = job_elem.is_active
                    job_type = job_elem.job_type
                    start_date = job_elem.start_date
                    service_name = job_elem.service_name
                    extra = job_elem.extra
                    job_type_friendly = job_type_friendly_names[job_type]

                    job = Job(id, name, is_active, job_type,
                              from_utc_to_user(start_date+'+00:00', req.zato.user_profile),
                              extra, service_name=service_name,
                              job_type_friendly=job_type_friendly)

                    if job_type == SCHEDULER.JOB_TYPE.ONE_TIME:
                        definition_text=_one_time_job_def(req.zato.user_profile, start_date)

                    elif job_type == SCHEDULER.JOB_TYPE.INTERVAL_BASED:
                        definition_text = _interval_based_job_def(req.zato.user_profile,
                            _get_start_date(job_elem.start_date),
                            job_elem.repeats, job_elem.weeks, job_elem.days,
                            job_elem.hours, job_elem.minutes, job_elem.seconds)

                        weeks = job_elem.weeks or ''
                        days = job_elem.days or ''
                        hours = job_elem.hours or ''
                        minutes = job_elem.minutes or ''
                        seconds = job_elem.seconds or ''
                        repeats = job_elem.repeats or ''

                        ib_job = IntervalBasedJob(None, None, weeks, days, hours, minutes,
                                            seconds, repeats)
                        job.interval_based = ib_job

                    elif job_type == SCHEDULER.JOB_TYPE.CRON_STYLE:
                        cron_definition = job_elem.cron_definition or ''
                        definition_text=_cron_style_job_def(req.zato.user_profile, start_date, cron_definition)

                        cs_job = CronStyleJob(None, None, cron_definition)
                        job.cron_style = cs_job

                    else:
                        msg = 'Unrecognized job type, name:[{0}], type:[{1}]'.format(name, job_type)
                        logger.error(msg)
                        raise ZatoException(msg)

                    job.definition_text = definition_text
                    jobs.append(job)
            else:
                logger.info('No jobs found, response:[{}]'.format(response))

        if req.method == 'POST':

            action = req.POST.get('zato_action', '')
            if not action:
                msg = 'req.POST contains no [zato_action] parameter.'
                logger.error(msg)
                return HttpResponseServerError(msg)

            job_type = req.POST.get('job_type', '')
            if action != 'execute' and not job_type:
                msg = 'req.POST contains no [job_type] parameter.'
                logger.error(msg)
                return HttpResponseServerError(msg)

            job_name = req.POST['{0}-{1}-name'.format(action, job_type)]

            # Try to match the action and a job type with an action handler..
            handler_name = '_' + action
            if action != 'execute':
                handler_name += '_' + job_type

            handler = globals().get(handler_name)
            if not handler:
                msg = ('No handler found for action [{0}], job_type:[{1}], '
                       'req.POST:[{2}], req.GET:[{3}].'.format(action, job_type,
                          pprint(req.POST), pprint(req.GET)))

                logger.error(msg)
                return HttpResponseServerError(msg)

            # .. invoke the action handler.
            try:
                response = handler(req.zato.client, req.zato.user_profile, req.zato.cluster, req.POST)
                response = response if response else ''
                if response:
                    response['message'] = _get_success_message(action, job_type, job_name)
                    response = dumps(response)
                return HttpResponse(response, mimetype='application/javascript')
            except Exception, e:
                msg = ('Could not invoke action [%s], job_type:[%s], e:[%s]'
                       'req.POST:[%s], req.GET:[%s]') % (action, job_type,
                          format_exc(), pprint(req.POST), pprint(req.GET))

                logger.error(msg)
                return HttpResponseServerError(msg)

        return_data = {'zato_clusters':req.zato.clusters,
            'cluster_id':req.zato.cluster_id,
            'choose_cluster_form':req.zato.choose_cluster_form,
            'jobs':jobs,
            'friendly_names':job_type_friendly_names.items(),
            'create_one_time_form':OneTimeSchedulerJobForm(create_one_time_prefix, req),
            'create_interval_based_form':IntervalBasedSchedulerJobForm(create_interval_based_prefix, req),
            'create_cron_style_form':CronStyleSchedulerJobForm(create_cron_style_prefix, req),
            'edit_one_time_form':OneTimeSchedulerJobForm(edit_one_time_prefix, req),
            'edit_interval_based_form':IntervalBasedSchedulerJobForm(edit_interval_based_prefix, req),
            'edit_cron_style_form':CronStyleSchedulerJobForm(edit_cron_style_prefix, req),
            'sample_dt': get_sample_dt(req.zato.user_profile),
            }

        return_data.update(get_js_dt_format(req.zato.user_profile))

        return TemplateResponse(req, 'zato/scheduler.html', return_data)
Exemplo n.º 7
0
def _create_edit(action, cid, input, payload, logger, session, broker_client, response):
    """ Creating and updating a job requires a series of very similar steps
    so they've been all put here and depending on the 'action' parameter
    (be it 'create'/'edit') some additional operations are performed.
    """
    job_type = input.job_type
    cluster_id = input.cluster_id
    name = input.name
    service_name = input.service

    if job_type not in(SCHEDULER.JOB_TYPE.ONE_TIME, SCHEDULER.JOB_TYPE.INTERVAL_BASED,
                           SCHEDULER.JOB_TYPE.CRON_STYLE):
        msg = 'Unrecognized job type [{0}]'.format(job_type)
        logger.error(msg)
        raise ZatoException(cid, msg)

    # For finding out if we don't have a job of that name already defined.
    existing_one_base = session.query(Job).\
        filter(Cluster.id==cluster_id).\
        filter(Job.name==name)

    if action == 'create':
        existing_one = existing_one_base.first()
    else:
        job_id = input.id
        existing_one = existing_one_base.filter(Job.id != job_id).first()

    if existing_one:
        raise ZatoException(cid, 'Job [{0}] already exists on this cluster'.format(name))

    # Is the service's name correct?
    service = session.query(Service).\
        filter(Cluster.id==cluster_id).\
        filter(Service.name==service_name).first()

    if not service:
        msg = 'Service [{0}] does not exist on this cluster'.format(service_name)
        logger.error(msg)
        raise ZatoException(cid, msg)

    # We can create/edit a base Job object now and - optionally - another one
    # if the job type's is either interval-based or Cron-style. The base
    # instance will be enough if it's a one-time job.

    extra = input.extra.encode('utf-8')
    is_active = input.is_active
    start_date = parse(input.start_date)

    if action == 'create':
        job = Job(None, name, is_active, job_type, start_date, extra, cluster_id=cluster_id, service=service)
    else:
        job = session.query(Job).filter_by(id=job_id).one()
        old_name = job.name
        job.name = name
        job.is_active = is_active
        job.start_date = start_date
        job.service = service
        job.extra = extra

    try:
        # Add but don't commit yet.
        session.add(job)

        if job_type == SCHEDULER.JOB_TYPE.INTERVAL_BASED:
            ib_params = ('weeks', 'days', 'hours', 'minutes', 'seconds')
            if not any(input[key] for key in ib_params):
                msg = "At least one of ['weeks', 'days', 'hours', 'minutes', 'seconds'] must be given"
                logger.error(msg)
                raise ZatoException(cid, msg)

            if action == 'create':
                ib_job = IntervalBasedJob(None, job)
            else:
                ib_job = session.query(IntervalBasedJob).filter_by(id=job.interval_based.id).one()

            for param in ib_params + ('repeats',):
                value = input[param] or None
                if value != ZATO_NONE:
                    setattr(ib_job, param, value)

            value = input['repeats'] or None
            if value != ZATO_NONE:
                setattr(ib_job, 'repeats', value)

            session.add(ib_job)

        elif job_type == SCHEDULER.JOB_TYPE.CRON_STYLE:
            cron_definition = input.cron_definition.strip()

            # Just to make sure it's syntactically correct
            CronTab(cron_definition).next()

            if action == 'create':
                cs_job = CronStyleJob(None, job)
            else:
                cs_job = session.query(CronStyleJob).filter_by(id=job.cron_style.id).one()

            cs_job.cron_definition = cron_definition
            session.add(cs_job)

        # We can commit it all now.
        session.commit()

        # Now send it to the broker, but only if the job is active.
        if is_active:
            msg_action = SCHEDULER_MSG.CREATE.value if action == 'create' else SCHEDULER_MSG.EDIT.value
            msg = {'action': msg_action, 'job_type': job_type,
                   'is_active':is_active, 'start_date':start_date.isoformat(),
                   'extra':extra, 'service': service.name,
                   'id':job.id, 'name': name
                   }

            if action == 'edit':
                msg['old_name'] = old_name

            if job_type == SCHEDULER.JOB_TYPE.INTERVAL_BASED:
                for param in ib_params + ('repeats',):
                    value = input[param]
                    msg[param] = int(value) if value else 0

            elif job_type == SCHEDULER.JOB_TYPE.CRON_STYLE:
                msg['cron_definition'] = cron_definition

        else:
            msg = {'action': SCHEDULER_MSG.DELETE.value, 'name': name}

        broker_client.publish(msg, MESSAGE_TYPE.TO_SINGLETON)

    except Exception, e:
        session.rollback()
        msg = 'Could not complete the request, e:[{e}]'.format(e=format_exc(e))
        logger.error(msg)
        raise
Exemplo n.º 8
0
def index(req):
    
    try:
        jobs = []
        zato_clusters = req.odb.query(Cluster).order_by('name').all()
        choose_cluster_form = ChooseClusterForm(zato_clusters, req.GET)
        cluster_id = req.GET.get('cluster')
    
        # Build a list of schedulers for a given Zato cluster.
        if cluster_id and req.method == 'GET':
    
            # We have a server to pick the schedulers from, try to invoke it now.
            cluster = req.odb.query(Cluster).filter_by(id=cluster_id).first()
            zato_message = Element('{%s}zato_message' % zato_namespace)
            zato_message.data = Element('data')
            zato_message.data.cluster_id = cluster_id
            _, zato_message, soap_response  = invoke_admin_service(cluster, 
                    'zato:scheduler.job.get-list', zato_message)
            
            if zato_path('data.definition_list.definition').get_from(zato_message) is not None:
                for job_elem in zato_message.data.definition_list.definition:
                    
                    id = job_elem.id.text
                    name = job_elem.name.text
                    is_active = is_boolean(job_elem.is_active.text)
                    job_type = job_elem.job_type.text
                    start_date = job_elem.start_date.text
                    service_name = job_elem.service_name.text
                    extra = job_elem.extra.text if job_elem.extra.text else ''
                    job_type_friendly = job_type_friendly_names[job_type]
                    
                    job = Job(id, name, is_active, job_type, start_date,
                              extra, service_name=service_name, 
                              job_type_friendly=job_type_friendly)
                    
                    if job_type == 'one_time':
                        definition_text=_one_time_job_def(start_date)
                        
                    elif job_type == 'interval_based':
                        definition_text = _interval_based_job_def(
                            _get_start_date(job_elem.start_date, scheduler_date_time_format),
                                job_elem.repeats, job_elem.weeks, job_elem.days,
                                job_elem.hours, job_elem.minutes, job_elem.seconds)
                        
                        weeks = job_elem.weeks.text if job_elem.weeks.text else ''
                        days = job_elem.days.text if job_elem.days.text else ''
                        hours = job_elem.hours.text if job_elem.hours.text else ''
                        minutes = job_elem.minutes.text if job_elem.minutes.text else ''
                        seconds = job_elem.seconds.text if job_elem.seconds.text else ''
                        repeats = job_elem.repeats.text if job_elem.repeats.text else ''
                        
                        ib_job = IntervalBasedJob(None, None, weeks, days, hours, minutes,
                                            seconds, repeats)
                        job.interval_based = ib_job
                        
                    elif job_type == 'cron_style':
                        cron_definition = (job_elem.cron_definition.text if job_elem.cron_definition.text else '')
                        definition_text=_cron_style_job_def(start_date,  cron_definition)
                        
                        cs_job = CronStyleJob(None, None, cron_definition)
                        job.cron_style = cs_job
                        
                    else:
                        msg = 'Unrecognized job type, name=[{0}], type=[{1}]'.format(name, job_type)
                        logger.error(msg)
                        raise ZatoException(msg)
    
                    job.definition_text = definition_text
                    jobs.append(job)
            else:
                logger.info('No jobs found, soap_response=[{0}]'.format(soap_response))
    
        if req.method == 'POST':

            action = req.POST.get('zato_action', '')
            if not action:
                msg = 'req.POST contains no [zato_action] parameter.'
                logger.error(msg)
                return HttpResponseServerError(msg)
    
            job_type = req.POST.get('job_type', '')
            if action != 'execute' and not job_type:
                msg = 'req.POST contains no [job_type] parameter.'
                logger.error(msg)
                return HttpResponseServerError(msg)
    
            
            job_name = req.POST['{0}-{1}-name'.format(action, job_type)]
            cluster = req.odb.query(Cluster).filter_by(id=cluster_id).one()
    
            # Try to match the action and a job type with an action handler..
            handler_name = '_' + action
            if action != 'execute':
                handler_name += '_' + job_type
    
            handler = globals().get(handler_name)
            if not handler:
                msg = ('No handler found for action [{0}], job_type=[{1}], '
                       'req.POST=[{2}], req.GET=[{3}].'.format(action, job_type,
                          pprint(req.POST), pprint(req.GET)))
    
                logger.error(msg)
                return HttpResponseServerError(msg)
    
            # .. invoke the action handler.
            try:
                response = handler(cluster, req.POST)
                response = response if response else ''
                if response:
                    response['message'] = _get_success_message(action, job_type, job_name)
                    response = dumps(response)
                return HttpResponse(response, mimetype='application/javascript')
            except Exception, e:
                msg = ('Could not invoke action [%s], job_type=[%s], e=[%s]'
                       'req.POST=[%s], req.GET=[%s]') % (action, job_type,
                          format_exc(), pprint(req.POST), pprint(req.GET))
    
                logger.error(msg)
                return HttpResponseServerError(msg)
    
        # TODO: Log the data returned here.
        logger.log(TRACE1, 'Returning render_to_response.')
    
        return render_to_response('zato/scheduler.html',
            {'zato_clusters':zato_clusters,
            'cluster_id':cluster_id,
            'choose_cluster_form':choose_cluster_form,
            'jobs':jobs, 
            'cluster_id':cluster_id,
            'friendly_names':job_type_friendly_names.items(),
            'create_one_time_form':OneTimeSchedulerJobForm(prefix=create_one_time_prefix),
            'create_interval_based_form':IntervalBasedSchedulerJobForm(prefix=create_interval_based_prefix),
            'create_cron_style_form':CronStyleSchedulerJobForm(prefix=create_cron_style_prefix),
            'edit_one_time_form':OneTimeSchedulerJobForm(prefix=edit_one_time_prefix),
            'edit_interval_based_form':IntervalBasedSchedulerJobForm(prefix=edit_interval_based_prefix),
            'edit_cron_style_form':CronStyleSchedulerJobForm(prefix=edit_cron_style_prefix),
            }, context_instance=RequestContext(req))