コード例 #1
0
def invoke_action(req,
                  pub_client_id,
                  send_attrs=('id', 'pub_client_id', 'request_data',
                              'timeout')):

    try:
        request = {'cluster_id': req.zato.cluster_id}

        for name in send_attrs:
            request[name] = req.POST.get(name, '')

        response = req.zato.client.invoke('zato.channel.web-socket.invoke-wsx',
                                          request)

        if response.ok:
            response_data = response.data['response_data']
            if isinstance(response_data, dict):
                response_data = dict(response_data)
            return HttpResponse(dumps(response_data),
                                content_type='application/javascript')
        else:
            raise Exception(response.details)
    except Exception:
        msg = 'Caught an exception, e:`{}`'.format(format_exc())
        logger.error(msg)
        return HttpResponseServerError(msg)
コード例 #2
0
ファイル: outgoing.py プロジェクト: dangnammta/zato
    def http_request(self,
                     method,
                     cid,
                     data='',
                     params=None,
                     _has_debug=has_debug,
                     *args,
                     **kwargs):
        self._enforce_is_active()

        # We never touch strings/unicode because apparently the user already serialized outgoing data
        needs_serialize = not isinstance(data, basestring)

        if needs_serialize:
            if self.config['data_format'] == DATA_FORMAT.JSON:
                data = dumps(data)
            elif data and self.config['data_format'] == DATA_FORMAT.XML:
                data = tostring(data)

        headers = self._create_headers(cid, kwargs.pop('headers', {}))
        if self.config['transport'] == 'soap':
            data, headers = self._soap_data(data, headers)

        params = params or {}

        if self.path_params:
            address, qs_params = self.format_address(cid, params)
        else:
            address, qs_params = self.address, dict(params)

        if isinstance(data, unicode):
            data = data.encode('utf-8')

        logger.info(
            'CID:`%s`, address:`%s`, qs:`%s`, auth_user:`%s`, kwargs:`%s`',
            cid, address, qs_params, self.username, kwargs)

        response = self.invoke_http(cid,
                                    method,
                                    address,
                                    data,
                                    headers, {},
                                    params=qs_params,
                                    *args,
                                    **kwargs)

        if _has_debug:
            logger.debug('CID:`%s`, response:`%s`', cid, response.text)

        if needs_serialize:

            if self.config['data_format'] == DATA_FORMAT.JSON:
                response.data = loads(response.text)

            elif self.config['data_format'] == DATA_FORMAT.XML:
                if response.text and response.headers.get('Content-Type') in (
                        'application/xml', 'text/xml'):
                    response.data = fromstring(response.text)

        return response
コード例 #3
0
ファイル: sql.py プロジェクト: johny-mnemonik/zato
def set_instance_opaque_attrs(instance, input, skip=None, only=None, _zato_skip=_zato_opaque_skip_attrs):
    """ Given an SQLAlchemy object instance and incoming SimpleIO-based input,
    populates all opaque values of that instance.
    """
    only = only or []
    instance_opaque_attrs = None
    instance_attrs = set(instance.asdict())
    input_attrs = set(input)

    if only:
        input_attrs = set([elem for elem in input_attrs if elem in only])
        instance_attrs = set([elem for elem in instance_attrs if elem not in only])

    # Any extra input attributes will be treated as opaque ones
    input_opaque_attrs = input_attrs - instance_attrs

    # Skip attributes related to pagination
    for name in chain(skip or [], _zato_skip):
        input_opaque_attrs.discard(name)

    # Prepare generic attributes for instance
    if GENERIC.ATTR_NAME in instance_attrs:
        instance_opaque_attrs = getattr(instance, GENERIC.ATTR_NAME)
        if instance_opaque_attrs:
            instance_opaque_attrs = loads(instance_opaque_attrs)
        else:
            instance_opaque_attrs = {}

        for name in input_opaque_attrs:
            instance_opaque_attrs[name] = input[name]

    # Set generic attributes for instance
    if instance_opaque_attrs is not None:
        setattr(instance, GENERIC.ATTR_NAME, dumps(instance_opaque_attrs))
コード例 #4
0
    def _on_OUTGOING_SFTP_EXECUTE(self,
                                  msg,
                                  is_reconnect=False,
                                  _utcnow=datetime.utcnow):
        out = {}
        connection = self.connections[msg.id]  # type: SFTPConnection
        start_time = _utcnow()

        try:
            result = connection.execute(msg.cid, msg.data,
                                        msg.log_level)  # type: Output
        except ErrorReturnCode as e:
            out['stdout'] = e.stdout
            out['stderr'] = e.stderr
        except Exception as e:
            out['stderr'] = format_exc()
            out['is_ok'] = False
        else:
            out.update(result.to_dict())
        finally:
            out['cid'] = msg.cid
            out['command_no'] = connection.command_no
            out['response_time'] = str(_utcnow() - start_time)

        return Response(data=dumps(out))
コード例 #5
0
    def _handle_attr_call(self, attr):

        try:
            key = self.request.input.key

            # This may be potentially an integer key that we received as string
            # so we need to try to convert it to one.
            try:
                key = int(key)
            except ValueError:
                pass  # That is fine, it was not an integer

            values = attr[key]
        except KeyError:
            raise KeyError('No such key `{}` ({}) among `{}`'.format(
                key, type(key), sorted(attr.keys())))

        values = values if isinstance(values, list) else [values]
        out = [elem.to_dict() for elem in values]
        out.sort(key=itemgetter(*self.request.input.sort_by), reverse=True)

        for item in out:
            for key, value in item.items():
                if isinstance(value, datetime):
                    item[key] = value.isoformat()

        self.response.payload = dumps(out)
コード例 #6
0
    def handle(self, _internal=('zato', 'pub.zato')):

        # Service name is given in URL path
        service_name = self.request.http.params.service_name

        # Make sure the service exists
        if self.server.service_store.has_service(service_name):

            # Depending on HTTP verb used, we may need to look up input in different places
            if self.request.http.method == 'GET':
                payload = self.request.http.GET
            else:
                payload = self.request.raw_request
                payload = loads(payload) if payload else None

            # Invoke the service now
            response = self.invoke(service_name, payload, wsgi_environ={'HTTP_METHOD':self.request.http.method})

            # All internal services wrap their responses in top-level elements that we need to shed here.
            if service_name.startswith(_internal):
                if response:
                    top_level = response.keys()[0]
                    response = response[top_level]

            # Assign response to outgoing payload
            self.response.payload = dumps(response)
            self.response.data_format = 'application/json'

        # No such service as given on input
        else:
            self.response.data_format = 'text/plain'
            raise BadRequest(self.cid, 'No such service `{}`'.format(service_name))
コード例 #7
0
ファイル: impexp.py プロジェクト: whaker/zato
def export(req, cluster_id):
    def _get_last_id(service):
        response = req.zato.client.invoke(service, {})
        if response.has_data:
            return response.data.value

    def _get_last_dict_id():
        return _get_last_id('zato.kvdb.data-dict.dictionary.get-last-id')

    def _get_last_translation_id():
        return _get_last_id('zato.kvdb.data-dict.translation.get-last-id')

    def _get_dict_list():
        for item in req.zato.client.invoke(
                'zato.kvdb.data-dict.dictionary.get-list', {}):
            yield item.id, item.system, item.key, item.value

    def _get_translation_list():
        for item in req.zato.client.invoke(
                'zato.kvdb.data-dict.translation.get-list', {}):
            yield item.id, item.system1, item.key1, item.value1, item.system2, \
                  item.key2, item.value2, item.id1, item.id2

    return_data = {
        'meta': {
            'current_host': current_host(),
            'timestamp_utc': datetime.utcnow().isoformat(),
            'user': req.user.username
        }
    }
    return_data['data'] = {'dict_list': [], 'translation_list': []}

    return_data['data']['last_dict_id'] = _get_last_dict_id()
    return_data['data']['last_translation_id'] = _get_last_translation_id()

    for id, system, key, value in _get_dict_list():
        return_data['data']['dict_list'].append({
            'id': id,
            'system': system,
            'key': key,
            'value': value
        })

    for id, system1, key1, value1, system2, key2, value2, id1, id2 in _get_translation_list(
    ):
        return_data['data']['translation_list'].append({
            translation_name(system1, key1, value1, system2, key2): {
                'id': id,
                'value2': value2,
                'id1': id1,
                'id2': id2
            }
        })

    response = HttpResponse(dumps(return_data, indent=4).encode('bz2'),
                            content_type='application/x-bzip2')
    response['Content-Disposition'] = 'attachment; filename={}'.format(
        'zato-data-dict-export.json.bz2')

    return response
コード例 #8
0
ファイル: http_soap.py プロジェクト: lukeplus/zato
 def handle(self):
     response = {}
     response['url_sec'] = sorted(self.worker_store.request_handler.security.url_sec.items())
     response['plain_http_handler.http_soap'] = sorted(self.worker_store.request_handler.plain_http_handler.http_soap.items())
     response['soap_handler.http_soap'] = sorted(self.worker_store.request_handler.soap_handler.http_soap.items())
     self.response.payload = dumps(response, sort_keys=True, indent=4)
     self.response.content_type = 'application/json'
コード例 #9
0
ファイル: ipc.py プロジェクト: whaker/zato
    def start_connector(self, ipc_tcp_start_port, timeout=5):
        """ Starts an HTTP server acting as an connector process. Its port will be greater than ipc_tcp_start_port,
        which is the starting point to find a free port from.
        """
        if self.check_enabled:
            self._check_enabled()

        self.ipc_tcp_port = get_free_port(ipc_tcp_start_port)
        logger.info('Starting {} connector for server `%s` on `%s`'.format(self.connector_name),
            self.server.name, self.ipc_tcp_port)

        # Credentials for both servers and connectors
        username, password = self.get_credentials()

        # Employ IPC to exchange subprocess startup configuration
        self.server.connector_config_ipc.set_config(self.ipc_config_name, dumps({
            'port': self.ipc_tcp_port,
            'username': username,
            'password': password,
            'server_port': self.server.port,
            'server_name': self.server.name,
            'server_path': '/zato/internal/callback/{}'.format(self.callback_suffix),
            'base_dir': self.server.base_dir,
            'needs_pidfile': not self.server.has_fg,
            'pidfile_suffix': self.pidfile_suffix,
            'logging_conf_path': self.server.logging_conf_path
        }))

        # Start connector in a sub-process
        start_python_process('{} connector'.format(self.connector_name), False, self.connector_module, '', extra_options={
            'deployment_key': self.server.deployment_key,
            'shmem_size': self.server.shmem_size
        })

        # Wait up to timeout seconds for the connector to start as indicated by its responding to a PING request
        now = datetime.utcnow()
        warn_after = now + timedelta(seconds=3)
        should_warn = False
        until = now + timedelta(seconds=timeout)
        is_ok = False
        address = address_pattern.format(self.ipc_tcp_port, 'ping')
        auth = self.get_credentials()

        while not is_ok or now >= until:
            if not should_warn:
                if now >= warn_after:
                    should_warn = True
            is_ok = self._ping_connector(address, auth, should_warn)
            if is_ok:
                break
            else:
                sleep(2)
                now = datetime.utcnow()

        if not is_ok:
            logger.warn('{} connector (%s) could not be started after %s'.format(self.connector_name), address, timeout)
        else:
            return is_ok
コード例 #10
0
ファイル: attr.py プロジェクト: DimShadoWWW/zato
    def _update(self,
                session,
                name,
                value=None,
                expiration=None,
                encrypt=False,
                user_id=None,
                needs_commit=True,
                _utcnow=_utcnow):
        """ A low-level implementation of self.update which expects an SQL session on input.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr._update',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr,
                           'name': name,
                           'expiration': expiration,
                           'encrypt': encrypt,
                           'is_super_user': self.is_super_user
                       })

        # Check access permissions to that user's attributes
        self._require_correct_user('_update', user_id)

        now = _utcnow()
        values = {'last_modified': now}

        if value:
            values['value'] = dumps(
                self.encrypt_func(value.encode('utf8')) if encrypt else value)

        if expiration:
            values['expiration_time'] = now + timedelta(seconds=expiration)

        and_condition = [
            AttrModelTable.c.user_id == (user_id or self.user_id),
            AttrModelTable.c.ust == self.ust,
            AttrModelTable.c.name == name,
            AttrModelTable.c.expiration_time > now,
        ]

        if self.ust:
            and_condition.extend([
                AttrModelTable.c.ust == SSOSessionTable.c.ust,
                SSOSessionTable.c.expiration_time > now
            ])

        session.execute(
            AttrModelTableUpdate().\
            values(values).\
            where(and_(*and_condition)))

        if needs_commit:
            session.commit()
コード例 #11
0
ファイル: store.py プロジェクト: johny-mnemonik/zato
    def _store_deployed_services_in_odb(self, session, batch_indexes, to_process, _utcnow=datetime.utcnow):
        """ Looks up all Service objects in ODB, checks if any is not deployed locally and deploys it if it is not.
        """
        # Local objects
        now = _utcnow()
        now_iso = now.isoformat()

        # Get all services already deployed in ODB for comparisons (Service) - it is needed to do it again,
        # in addition to _store_deployed_services_in_odb, because that other method may have added
        # DB-level IDs that we need with our own objects.
        services = self.get_basic_data_services()

        # Same goes for deployed services objects (DeployedService)
        deployed_services = self.get_basic_data_deployed_services()

        # Modules visited may return a service that has been already visited via another module,
        # in which case we need to skip such a duplicate service.
        already_visited = set()

        # Add any missing DeployedService objects from each batch delineated by indexes found
        for start_idx, end_idx in batch_indexes:

            to_add = []
            batch_services = to_process[start_idx:end_idx]

            for service in batch_services: # type: InRAMService

                if service.name in already_visited:
                    continue
                else:
                    already_visited.add(service.name)

                # At this point we wil always have IDs for all Service objects
                service_id = services[service.name]['id']

                # Metadata about this deployment as a JSON object
                class_ = service.service_class
                path = service.source_code_info.path
                deployment_details = dumps(deployment_info('service-store', str(class_), now_iso, path))

                # No such Service object in ODB so we need to store it
                if service.name not in deployed_services:
                    to_add.append({
                        'server_id': self.server.id,
                        'service_id': service_id,
                        'deployment_time': now,
                        'details': deployment_details,
                        'source': service.source_code_info.source,
                        'source_path': service.source_code_info.path,
                        'source_hash': service.source_code_info.hash,
                        'source_hash_method': service.source_code_info.hash_method,
                    })

            # If any services are to be deployed, do it now.
            if to_add:
                self.odb.add_deployed_services(session, to_add)
コード例 #12
0
    def __call__(self,
                 req,
                 initial_input_dict={},
                 initial_return_data={},
                 *args,
                 **kwargs):

        initial_input_dict['payload'] = req.POST.get('payload', None)
        initial_input_dict['args'] = dumps(
            [elem for elem in req.POST.get('args', '').split('\n')])

        initial_input_dict['kwargs'] = {}
        for elem in req.POST.get('kwargs', '').split('\n'):
            k, v = elem.split('=')
            initial_input_dict['kwargs'][k] = v
        initial_input_dict['kwargs'] = dumps(initial_input_dict['kwargs'])

        return super(_Update,
                     self).__call__(req, initial_input_dict,
                                    initial_return_data, *args, **kwargs)
コード例 #13
0
    def to_sql_dict(self, needs_bunch=False, skip=None):
        out = {}
        skip = skip or []
        for name in self.__slots__:
            if name in skip:
                continue
            if name != 'opaque':
                out[name] = getattr(self, name)
            else:
                out[GENERIC.ATTR_NAME] = dumps(self.opaque)

        return bunchify(out) if needs_bunch else out
コード例 #14
0
ファイル: wsx_client.py プロジェクト: Mattlk13/zato
 def serialize(self, _now=datetime.utcnow):
     return dumps(self.enrich({
         'data': {},
         'meta': {
             'action': self.action,
             'id': self.msg_id,
             'timestamp': _now().isoformat(),
             'token': self.token,
             'client_id': self.config.client_id,
             'client_name': self.config.client_name,
         }
     }))
コード例 #15
0
ファイル: __init__.py プロジェクト: dangnammta/zato
    def invoke(self, targets, on_final, on_target=None, cid=None):
        """ Invokes targets collecting their responses, can be both as a whole or individual ones,
        and executes callback(s).
        """
        # Can be user-provided or what our source gave us
        cid = cid or self.cid

        on_final = [on_final] if isinstance(on_final, basestring) else on_final
        on_target = [on_target] if isinstance(on_target,
                                              basestring) else on_target

        on_final = on_final or ''
        on_target = on_target or ''

        # Keep everything under a distributed lock
        with self.source.lock(self.lock_pattern.format(cid)):

            # Store information how many targets there were + info on what to invoke when they complete
            self.source.kvdb.conn.set(self.counter_pattern.format(cid),
                                      len(targets))
            self.source.kvdb.conn.hmset(
                self.data_pattern.format(cid), {
                    'source': self.source.name,
                    'on_final': dumps(on_final),
                    'on_target': dumps(on_target),
                    'req_ts_utc': self.source.time.utcnow()
                })

            # Invoke targets
            for name, payload in targets.items():
                to_json_string = False if isinstance(payload,
                                                     basestring) else True
                self.source.invoke_async(
                    name,
                    payload,
                    self.call_channel,
                    to_json_string=to_json_string,
                    zato_ctx={self.request_ctx_cid_key: cid})

        return cid
コード例 #16
0
ファイル: message.py プロジェクト: whaker/zato
def publish(req, cluster_id, topic_id):

    topic_list = []
    publisher_list = []
    topic_id = int(topic_id)
    initial_topic_name = None
    initial_hook_service_name = None
    select_changer_data = {}

    topic_list_response = req.zato.client.invoke('zato.pubsub.topic.get-list',
                                                 {
                                                     'cluster_id': cluster_id,
                                                     'needs_details': False,
                                                 }).data

    for item in topic_list_response:

        # Initial data for this topic
        if item.id == topic_id:
            initial_topic_name = item.name
            initial_hook_service_name = item.hook_service_name

        # All topics -> hook service names for select changer
        select_changer_data[item.name] = item.hook_service_name or ''

        topic_list.append({
            'id': item.name,
            'name': item.name
        })  # Topics are identified by their name, not ID

    publisher_list_response = req.zato.client.invoke(
        'zato.pubsub.endpoint.get-list', {
            'cluster_id': cluster_id
        }).data
    for item in publisher_list_response:
        for line in (item.topic_patterns or '').splitlines():
            if line.startswith('sub='):
                publisher_list.append({'id': item.id, 'name': item.name})
                break

    return_data = {
        'cluster_id':
        cluster_id,
        'action':
        'publish',
        'form':
        MsgPublishForm(req, dumps(select_changer_data), initial_topic_name,
                       topic_list, initial_hook_service_name, publisher_list)
    }

    return TemplateResponse(req, 'zato/pubsub/message-publish.html',
                            return_data)
コード例 #17
0
    def handle(self):
        payload = self.request.input.get('payload')
        if payload:
            payload = b64decode(payload)
            payload = payload_from_request(self.cid, payload,
                self.request.input.data_format, self.request.input.transport)

        id = self.request.input.get('id')
        name = self.request.input.get('name')
        pid = self.request.input.get('pid') or 0
        all_pids = self.request.input.get('all_pids')
        timeout = self.request.input.get('timeout') or None

        channel = self.request.input.get('channel')
        data_format = self.request.input.get('data_format')
        transport = self.request.input.get('transport')
        expiration = self.request.input.get('expiration') or BROKER.DEFAULT_EXPIRATION

        if name and id:
            raise ZatoException('Cannot accept both id:`{}` and name:`{}`'.format(id, name))

        if self.request.input.get('async'):

            if id:
                impl_name = self.server.service_store.id_to_impl_name[id]
                name = self.server.service_store.service_data(impl_name)['name']

            # If PID is given on input it means we must invoke this particular server process by it ID
            if pid and pid != self.server.pid:
                response = self.server.invoke_by_pid(name, payload, pid)
            else:
                response = self.invoke_async(name, payload, channel, data_format, transport, expiration)

        else:

            # Same as above in async branch, except in async there was no all_pids
            if all_pids:
                args = (name, payload, timeout) if timeout else (name, payload)
                response = dumps(self.server.invoke_all_pids(*args))
            else:
                if pid and pid != self.server.pid:
                    response = self.server.invoke(name, payload, pid=pid, data_format=data_format)
                else:
                    func, id_ = (self.invoke, name) if name else (self.invoke_by_id, id)
                    response = func(id_, payload, channel, data_format, transport, serialize=True)

        if isinstance(response, basestring):
            if response:
                response = response if isinstance(response, bytes) else response.encode('utf8')
                self.response.payload.response = b64encode(response) if response else ''
コード例 #18
0
    def handle(self, _internal=('zato', 'pub.zato')):

        # Service name is given in URL path
        service_name = self.request.http.params.service_name

        # Are we invoking a Zato built-in service or a user-defined one?
        is_internal = service_name.startswith(_internal)  # type: bool

        # Before invoking a service that is potentially internal we need to confirm
        # that our channel can be used for such invocations.
        if is_internal:
            if self.channel.name not in self.server.fs_server_config.misc.service_invoker_allow_internal:
                self.logger.warn(
                    'Service `%s` could not be invoked; channel `%s` not among `%s` (service_invoker_allow_internal)',
                    service_name, self.channel.name, self.server.
                    fs_server_config.misc.service_invoker_allow_internal)
                self.response.data_format = 'text/plain'
                raise BadRequest(self.cid,
                                 'No such service `{}`'.format(service_name))

        # Make sure the service exists
        if self.server.service_store.has_service(service_name):

            # Depending on HTTP verb used, we may need to look up input in different places
            if self.request.http.method == 'GET':
                payload = self.request.http.GET
            else:
                payload = self.request.raw_request
                payload = loads(payload) if payload else None

            # Invoke the service now
            response = self.invoke(
                service_name,
                payload,
                wsgi_environ={'HTTP_METHOD': self.request.http.method})

            # All internal services wrap their responses in top-level elements that we need to shed here ..
            if is_internal and response:
                top_level = list(iterkeys(response))[0]
                response = response[top_level]

            # Assign response to outgoing payload
            self.response.payload = dumps(response)
            self.response.data_format = 'application/json'

        # No such service as given on input
        else:
            self.response.data_format = 'text/plain'
            raise BadRequest(self.cid,
                             'No such service `{}`'.format(service_name))
コード例 #19
0
ファイル: ipc.py プロジェクト: whaker/zato
    def invoke_connector(self, msg, raise_on_error=True, address_pattern=address_pattern):
        if self.check_enabled:
            self._check_enabled()

        address = address_pattern.format(self.ipc_tcp_port, 'api')
        response = post(address, data=dumps(msg), auth=self.get_credentials())

        if not response.ok:
            if raise_on_error:
                raise Exception(response.text)
            else:
                logger.warn('Error message from {} connector `{}`'.format(self.connector_name, response.text))
        else:
            return response
コード例 #20
0
ファイル: impexp.py プロジェクト: whaker/zato
def import_(req, cluster_id):
    try:
        data = req.read()
        data.decode(
            'bz2')  # A preliminary check to weed out files obviously incorrect
        req.zato.client.invoke('zato.kvdb.data-dict.impexp.import',
                               {'data': b64encode(data)})
    except Exception:
        msg = 'Could not import the data dictionaries, e:[{}]'.format(
            format_exc())
        logger.error(msg)
        return HttpResponseServerError(msg)
    else:
        return HttpResponse(dumps({'success': True}))
コード例 #21
0
ファイル: attr.py プロジェクト: DimShadoWWW/zato
    def _create(self,
                session,
                name,
                value,
                expiration=None,
                encrypt=False,
                user_id=None,
                needs_commit=True,
                _utcnow=_utcnow):
        """ A low-level implementation of self.create which expects an SQL session on input.
        """
        # Audit comes first
        audit_pii.info(self.cid,
                       'attr._create',
                       self.current_user_id,
                       user_id,
                       extra={
                           'current_app': self.current_app,
                           'remote_addr': self.remote_addr,
                           'name': name,
                           'expiration': expiration,
                           'encrypt': encrypt,
                           'is_super_user': self.is_super_user
                       })

        self._require_correct_user('_create', user_id)

        now = _utcnow()

        attr_model = AttrModel()
        attr_model.user_id = user_id or self.user_id
        attr_model.ust = self.ust
        attr_model._ust_string = self.ust or ''  # Cannot, and will not be, NULL, check the comment in the model for details
        attr_model.is_session_attr = self.is_session_attr
        attr_model.name = name
        attr_model.value = dumps(
            self.encrypt_func(value.encode('utf8')) if encrypt else value)
        attr_model.is_encrypted = encrypt
        attr_model.creation_time = now
        attr_model.last_modified = now

        # Expiration is optional
        attr_model.expiration_time = now + timedelta(
            seconds=expiration) if expiration else _default_expiration

        session.add(attr_model)

        if needs_commit:
            session.commit()
コード例 #22
0
ファイル: connection.py プロジェクト: whaker/zato
    def handle(self):
        out = {'_meta': {}, 'response': []}

        with closing(self.odb.session()) as session:

            search_result = self.get_data(session)
            out['_meta'].update(search_result.to_dict())

            for item in search_result:
                conn = GenericConnection.from_model(item)
                conn_dict = conn.to_dict()
                self._enrich_conn_dict(conn_dict)
                out['response'].append(conn_dict)

        self.response.payload = dumps(out)
コード例 #23
0
ファイル: __init__.py プロジェクト: dangnammta/zato
def upload_to_server(req, cluster_id, service, error_msg_template):
    try:
        input_dict = {
            'cluster_id': cluster_id,
            'payload': b64encode(req.read()),
            'payload_name': req.GET['qqfile']
        }
        req.zato.client.invoke(service, input_dict)

        return HttpResponse(dumps({'success': True}))

    except Exception:
        msg = error_msg_template.format(format_exc())
        logger.error(msg)
        return HttpResponseServerError(msg)
コード例 #24
0
ファイル: wss.py プロジェクト: dangnammta/zato
def _edit_create_response(service_response, action, name, password_type):
    return_data = {
        'id':
        service_response.data.id,
        'message':
        'Successfully {0} the WS-Security definition [{1}]'.format(
            action, name),
        'password_type_raw':
        password_type,
        'password_type':
        ZATO_WSS_PASSWORD_TYPES[password_type]
    }

    return HttpResponse(dumps(return_data),
                        content_type='application/javascript')
コード例 #25
0
ファイル: endpoint.py プロジェクト: myhighland/zato
def endpoint_queue_edit(req):

    sub_id = req.POST['id']
    cluster_id = req.POST['cluster_id']
    endpoint_type = req.POST['endpoint_type']

    # Always available
    request = {
        'id': sub_id,
        'cluster_id': cluster_id,
        'endpoint_type': endpoint_type
    }

    # Need form prefix
    for item in sorted(sub_attrs):
        if item not in ('id', 'cluster_id'):
            key = 'edit-{}'.format(item)
            value = req.POST.get(key)
            request[item] = value

    # Update subscription ..
    req.zato.client.invoke('zato.pubsub.endpoint.update-endpoint-queue',
                           request)

    # .. and read it back - but this time it will include current data about depth.
    service = 'zato.pubsub.endpoint.get-endpoint-queue'
    request = bunchify({
        'id': sub_id,
        'cluster_id': cluster_id,
    })
    service_response = req.zato.client.invoke(service, request).data.response

    service_response.creation_time = from_utc_to_user(
        service_response.creation_time + '+00:00', req.zato.user_profile)

    if service_response.last_interaction_time:
        service_response.last_interaction_time = from_utc_to_user(
            service_response.last_interaction_time + '+00:00',
            req.zato.user_profile)

    response = {}
    response['id'] = sub_id
    response['message'] = 'Subscription updated successfully'
    response.update(**service_response)
    response.update(**request)
    response['name_slug'] = slugify(response['name'])

    return HttpResponse(dumps(response), content_type='application/javascript')
コード例 #26
0
ファイル: __init__.py プロジェクト: dangnammta/zato
def invoke_service_with_json_response(req,
                                      service,
                                      input_dict,
                                      ok_msg,
                                      error_template='',
                                      content_type='application/javascript',
                                      extra=None):
    try:
        req.zato.client.invoke(service, input_dict)
    except Exception as e:
        return HttpResponseServerError(e.message, content_type=content_type)
    else:
        response = {'msg': ok_msg}
        response.update(extra or {})
        response = dumps(response)
        return HttpResponse(response, content_type=content_type)
コード例 #27
0
ファイル: message.py プロジェクト: whaker/zato
def publish_action(req):

    try:

        msg_id = req.POST.get('msg_id') or new_msg_id()
        gd = req.POST['gd']

        if gd == PUBSUB.GD_CHOICE.DEFAULT_PER_TOPIC.id:
            has_gd = None
        else:
            has_gd = asbool(gd)

        service_input = {
            'msg_id': msg_id,
            'has_gd': has_gd,
            'skip_pattern_matching': True,
            'endpoint_id': req.POST['publisher_id'],
        }

        for name in ('reply_to_sk', 'deliver_to_sk'):
            value = req.POST.get(name, '')
            if value:
                value = value.split(',')
                value = [elem.strip() for elem in value]
                service_input[name] = value

        for name in ('cluster_id', 'topic_name', 'data'):
            service_input[name] = req.POST[name]

        for name in ('correl_id', 'priority', 'ext_client_id',
                     'position_in_group', 'expiration', 'in_reply_to'):
            service_input[name] = req.POST.get(
                name, None) or None  # Always use None instead of ''

        req.zato.client.invoke('zato.pubsub.publish.publish', service_input)

    except Exception as e:
        message = e.message
        is_ok = False
    else:
        message = 'Successfully published message `{}`'.format(msg_id)
        is_ok = True

    return HttpResponse(dumps({
        'is_ok': is_ok,
        'message': message,
    }))
コード例 #28
0
def _update_many(req, cluster_id, service, success_msg, failure_msg):
    """ A common function for either resubmitting or deleting one or more tasks.
    """
    try:
        for task_id in req.POST.values():
            input_dict = {'task_id': task_id}
            response = req.zato.client.invoke_async(service, input_dict)

            if not response.ok:
                raise Exception(response.details)

        return HttpResponse(dumps({'message': success_msg}))

    except Exception:
        msg = '{}, e:`{}`'.format(failure_msg, format_exc())
        logger.error(msg)
        return HttpResponseServerError(msg)
コード例 #29
0
    def handle(self):

        cluster_id = self.request.input.get('cluster_id')

        include = aslist(self.request.input.include, ',')
        exclude = aslist(self.request.input.exclude, ',')

        include = [elem for elem in include if elem]
        exclude = [elem for elem in exclude if elem]

        api_invoke_path = aslist(self.request.input.api_invoke_path, ',')
        api_invoke_path = [elem for elem in api_invoke_path if elem]

        if not self.request.input.get('return_internal'):
            if 'zato.*' not in exclude:
                exclude.append('zato.*')

        if cluster_id and cluster_id != self.server.cluster_id:
            raise ValueError('Input cluster ID `%s` different than ours `%s`',
                             cluster_id, self.server.cluster_id)

        # Default to Sphinx output unless explicitly overridden
        if isinstance(self.request.input.needs_sphinx, bool):
            needs_sphinx = self.request.input.needs_sphinx
        else:
            needs_sphinx = True

        data = Generator(self.server.service_store.services,
                         self.server.sio_config, include, exclude,
                         self.request.input.query,
                         self.request.input.tags).get_info()

        if needs_sphinx:
            out = self.invoke(
                GetSphinx.get_name(), {
                    'data': data,
                    'needs_api_invoke': self.request.input.needs_api_invoke,
                    'needs_rest_channels':
                    self.request.input.needs_rest_channels,
                    'api_invoke_path': api_invoke_path
                })
        else:
            out = data

        self.response.payload = dumps(out)
コード例 #30
0
ファイル: endpoint.py プロジェクト: myhighland/zato
    def handle(self):

        data_list = Bunch()
        data_list.security_list = []
        data_list.ws_channel_list = []
        data_list.service_list = []

        in_use = Bunch()
        in_use.security_list = []
        in_use.ws_channel_list = []
        in_use.service_list = []

        if self.req.zato.cluster_id:

            # Security definitions
            data_list.security_list = self.get_sec_def_list(
                'basic_auth').def_items

            # WebSockets channels
            data_list.ws_channel_list = self.req.zato.client.invoke(
                'zato.channel.web-socket.get-list', {
                    'cluster_id': self.req.zato.cluster_id
                }).data

            # Services
            data_list.service_list = self.req.zato.client.invoke(
                'zato.service.get-list', {
                    'cluster_id': self.req.zato.cluster_id
                }).data

            # Build a list of IDs that are already used to make fronted warn of this situation.
            # This is also enforced on SQL level by services.
            in_use.security_list = self.get_already_in_use(
                data_list.security_list, 'security_id')
            in_use.ws_channel_list = self.get_already_in_use(
                data_list.ws_channel_list, 'ws_channel_id')
            in_use.service_list = self.get_already_in_use(
                data_list.service_list, 'service_id')

        return {
            'create_form': CreateForm(self.req, data_list),
            'edit_form': EditForm(self.req, data_list, prefix='edit'),
            'in_use': dumps(in_use),
        }