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)
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
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))
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))
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)
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))
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
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'
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
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()
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)
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)
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
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, } }))
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
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)
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 ''
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))
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
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}))
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()
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)
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)
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')
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')
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)
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, }))
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)
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)
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), }