def handle(self): req = self.request.input with closing(self.odb.session()) as session: # Create the client itself client = self._new_zato_instance_with_cluster( WebSocketClient, self.server.cluster_id) channel = session.query(ChannelWebSocket).\ filter(Cluster.id==self.server.cluster_id).\ filter(ChannelWebSocket.name==req.channel_name).\ one() client.is_internal = req.is_internal client.pub_client_id = req.pub_client_id client.ext_client_id = req.ext_client_id client.ext_client_name = req.get('ext_client_name', '').encode('utf8') client.local_address = req.local_address client.peer_address = req.peer_address client.peer_fqdn = req.peer_fqdn client.connection_time = parse(req.connection_time) client.last_seen = parse(req.last_seen) client.server_proc_pid = self.server.pid client.channel_id = channel.id client.server_id = self.server.id client.server_name = self.server.name # Opaque attributes set_instance_opaque_attrs(client, req, ['channel_name']) session.add(client) session.commit() self.response.payload.ws_client_id = client.id
def handle(self): # If we have a rate limiting definition, let's check it upfront DefinitionParser.check_definition_from_input(self.request.input) input = self.request.input input.password = uuid4().hex input.secret = Fernet.generate_key() with closing(self.odb.session()) as session: try: # Let's see if we already have a definition of that name before committing # any stuff into the database. existing_one = session.query(JWT).\ filter(Cluster.id==input.cluster_id).\ filter(JWT.name==input.name).first() if existing_one: raise Exception( 'JWT definition `{}` already exists on this cluster'. format(input.name)) item = self._new_zato_instance_with_cluster(JWT) item.name = input.name item.is_active = input.is_active item.username = input.username item.password = input.password item.secret = input.secret item.ttl = input.ttl item.cluster_id = input.cluster_id set_instance_opaque_attrs(item, input) session.add(item) session.commit() except Exception: self.logger.error('Could not create a JWT definition, e:`%s`', format_exc()) session.rollback() raise else: input.id = item.id input.action = SECURITY.JWT_CREATE.value input.sec_type = SEC_DEF_TYPE.JWT self.broker_client.publish(input) self.response.payload.id = item.id self.response.payload.name = item.name
def handle(self): input = self.request.input with closing(self.odb.session()) as session: existing_one = session.query(OutgoingFTP.id).\ filter(OutgoingFTP.cluster_id==input.cluster_id).\ filter(OutgoingFTP.name==input.name).\ filter(OutgoingFTP.id!=input.id).\ first() if existing_one: raise Exception( 'Outgoing FTP connection `{}` already exists'.format( input.name)) try: item = session.query(OutgoingFTP).filter_by(id=input.id).one() old_name = item.name item.name = input.name item.is_active = input.is_active item.cluster_id = input.cluster_id item.dircache = input.dircache item.host = input.host item.port = input.port item.user = input.user item.acct = input.acct item.timeout = input.timeout or None input.password = item.password input.old_name = old_name # Opaque attributes set_instance_opaque_attrs(item, input) session.add(item) session.commit() self.notify_worker_threads(input) self.response.payload.id = item.id self.response.payload.name = item.name except Exception: self.logger.error( 'Could not update the outgoing FTP connection, e:`{}`', format_exc()) session.rollback() raise
def handle(self): # If we have a rate limiting definition, let's check it upfront DefinitionParser.check_definition_from_input(self.request.input) input = self.request.input with closing(self.odb.session()) as session: try: existing_one = session.query(HTTPBasicAuth).\ filter(Cluster.id==input.cluster_id).\ filter(HTTPBasicAuth.name==input.name).\ filter(HTTPBasicAuth.id!=input.id).\ first() if existing_one: raise Exception( 'HTTP Basic Auth definition `{}` already exists on this cluster' .format(input.name)) definition = session.query(HTTPBasicAuth).filter_by( id=input.id).one() old_name = definition.name set_instance_opaque_attrs(definition, input) definition.name = input.name definition.is_active = input.is_active definition.username = input.username definition.realm = input.realm or None session.add(definition) session.commit() except Exception: self.logger.error( 'Could not update HTTP Basic Auth definition, e:`%s`', format_exc()) session.rollback() raise else: input.action = SECURITY.BASIC_AUTH_EDIT.value input.old_name = old_name input.sec_type = SEC_DEF_TYPE.BASIC_AUTH self.broker_client.publish(input) self.response.payload.id = definition.id self.response.payload.name = definition.name
def handle(self): # If we have a rate limiting definition, let's check it upfront DefinitionParser.check_definition_from_input(self.request.input) input = self.request.input input.password = uuid4().hex with closing(self.odb.session()) as session: try: cluster = session.query(Cluster).filter_by( id=input.cluster_id).first() # Let's see if we already have a definition of that name before committing # any stuff into the database. existing_one = session.query(HTTPBasicAuth).\ filter(Cluster.id==input.cluster_id).\ filter(HTTPBasicAuth.name==input.name).first() if existing_one: raise Exception( 'HTTP Basic Auth definition `{}` already exists in this cluster' .format(input.name)) auth = HTTPBasicAuth(None, input.name, input.is_active, input.username, input.realm or None, input.password, cluster) set_instance_opaque_attrs(auth, input) session.add(auth) session.commit() except Exception: self.logger.error( 'Could not create an HTTP Basic Auth definition, e:`%s`', format_exc()) session.rollback() raise else: input.id = auth.id input.action = SECURITY.BASIC_AUTH_CREATE.value input.sec_type = SEC_DEF_TYPE.BASIC_AUTH self.broker_client.publish(input) self.response.payload.id = auth.id self.response.payload.name = auth.name
def handle(self): input = self.request.input # If we have a rate limiting definition, let's check it upfront DefinitionParser.check_definition_from_input(input) with closing(self.odb.session()) as session: try: service = session.query(Service).filter_by( id=input.id).one() # type: Service service.is_active = input.is_active service.slow_threshold = input.slow_threshold set_instance_opaque_attrs(service, input) # Configure JSON Schema validation if service has a schema assigned by user. class_info = self.server.service_store.get_service_info_by_id( input.id) # type: dict class_ = class_info['service_class'] # type: Service if class_.schema: self.server.service_store.set_up_class_json_schema( class_, input) # Set up rate-limiting each time an object was edited self.server.service_store.set_up_rate_limiting(service.name) session.add(service) session.commit() input.action = SERVICE.EDIT.value input.impl_name = service.impl_name input.name = service.name self.broker_client.publish(input) self.response.payload = service internal_del = is_boolean(self.server.fs_server_config.misc. internal_services_may_be_deleted) self.response.payload.may_be_deleted = internal_del if service.is_internal else True except Exception: self.logger.error('Service could not be updated, e:`%s`', format_exc()) session.rollback() raise
def handle(self): input = self.request.input with closing(self.odb.session()) as session: try: existing_one = session.query(JWT).\ filter(Cluster.id==input.cluster_id).\ filter(JWT.name==input.name).\ filter(JWT.id!=input.id).\ first() if existing_one: raise Exception( 'JWT definition `{}` already exists on this cluster'. format(input.name)) item = session.query(JWT).filter_by(id=input.id).one() old_name = item.name item.name = input.name item.is_active = input.is_active item.username = input.username item.ttl = input.ttl item.cluster_id = input.cluster_id set_instance_opaque_attrs(item, input) session.add(item) session.commit() except Exception: self.logger.error( 'Could not update the JWT definition, e:`%s`', format_exc()) session.rollback() raise else: input.action = SECURITY.JWT_EDIT.value input.old_name = old_name input.sec_type = SEC_DEF_TYPE.JWT self.broker_client.publish(input) self.response.payload.id = item.id self.response.payload.name = item.name
def handle(self): input = self.request.input # If we have a rate limiting definition, let's check it upfront DefinitionParser.check_definition_from_input(input) with closing(self.odb.session()) as session: try: existing_one = session.query(APIKeySecurity).\ filter(Cluster.id==input.cluster_id).\ filter(APIKeySecurity.name==input.name).\ filter(APIKeySecurity.id!=input.id).\ first() if existing_one: raise Exception('API key `{}` already exists in this cluster'.format(input.name)) definition = session.query(APIKeySecurity).filter_by(id=input.id).one() old_name = definition.name set_instance_opaque_attrs(definition, input) definition.name = input.name definition.is_active = input.is_active definition.username = input.username session.add(definition) session.commit() except Exception: self.logger.error('API key could not be updated, e:`{}`', format_exc()) session.rollback() raise else: input.action = SECURITY.APIKEY_EDIT.value input.old_name = old_name input.sec_type = SEC_DEF_TYPE.APIKEY self.broker_client.publish(input) self.response.payload.id = definition.id self.response.payload.name = definition.name
def handle(self): input = self.request.input with closing(self.odb.session()) as session: try: service = session.query(Service).filter_by(id=input.id).one() service.is_active = input.is_active service.slow_threshold = input.slow_threshold set_instance_opaque_attrs(service, input) # Configure JSON Schema validation if service has a schema assigned by user. class_info = self.server.service_store.get_service_class_by_id( input.id) # type: dict class_ = class_info['service_class'] # type: Service if class_.json_schema: self.server.service_store.set_up_class_json_schema( class_, input) session.add(service) session.commit() input.action = SERVICE.EDIT.value input.impl_name = service.impl_name self.broker_client.publish(input) self.response.payload = service internal_del = is_boolean(self.server.fs_server_config.misc. internal_services_may_be_deleted) self.response.payload.may_be_deleted = internal_del if service.is_internal else True except Exception: msg = 'Service could not be updated, e:`{}`'.format( format_exc()) self.logger.error(msg) session.rollback() raise
def handle_impl(self): # type: (Service) input = self.request.input input.update(attrs.initial_input) verb = 'edit' if attrs.is_edit else 'create' old_name = None with closing(self.odb.session()) as session: try: attrs._meta_session = session if attrs.check_existing_one: # Let's see if we already have an instance of that name before committing # any stuff to the database. However, this is wrapped in an if condition # because certain models don't have the .name attribute. existing_one = session.query(attrs.model).\ filter(Cluster.id==input.cluster_id).\ filter(attrs.model.name==input.name) if attrs.is_edit: existing_one = existing_one.filter( attrs.model.id != input.id) existing_one = existing_one.first() if existing_one and not attrs.is_edit: raise Exception( '{} `{}` already exists in this cluster'. format( attrs.label[0].upper() + attrs.label[1:], input.name)) if attrs.is_edit: instance = session.query( attrs.model).filter_by(id=input.id).one() old_name = instance.name else: instance = self._new_zato_instance_with_cluster( attrs.model) # Update the instance with data received on input, however, # note that this may overwrite some of existing attributes # if they are empty on input. If it's not desired, # set skip_input_params = ['...'] to ignore such input parameters. instance.fromdict(input, exclude=['password'], allow_pk=True) # Invoke a hook that will set any additional opaque attrs # that are required but were possibly not given on input. if attrs.pre_opaque_attrs_hook: attrs.pre_opaque_attrs_hook(self, input, instance, attrs) # Populate all the opaque attrs now set_instance_opaque_attrs(instance, input) # Now that we have an instance which is known not to be a duplicate # we can possibly invoke a customization function before we commit # anything to the database. if attrs.instance_hook: attrs.instance_hook(self, input, instance, attrs) session.add(instance) session.commit() except Exception: msg = 'Could not {} the object, e:`%s`'.format(verb) logger.error(msg, format_exc()) session.rollback() raise else: if attrs.def_needed: def_ = session.query( attrs.def_needed).filter_by(id=input.def_id).one() input.def_name = def_.name action = getattr( attrs.broker_message, attrs.broker_message_prefix + verb.upper()).value input.id = instance.id input.action = action input.old_name = old_name if attrs.broker_message_hook: attrs.broker_message_hook(self, input, instance, attrs, 'create_edit') self.broker_client.publish(input) for name in chain(attrs.create_edit_rewrite, self.SimpleIO.output_required): value = getattr(instance, name, singleton) if value is singleton: value = input[name] setattr(self.response.payload, name, value) if attrs.response_hook: attrs.response_hook(self, input, instance, attrs, 'create_edit')
def handle(self): # If we have a rate limiting definition, let's check it upfront DefinitionParser.check_definition_from_input(self.request.input) input = self.request.input input.sec_use_rbac = input.get('sec_use_rbac') or (input.security_id == ZATO_SEC_USE_RBAC) input.security_id = input.security_id if input.security_id not in (ZATO_NONE, ZATO_SEC_USE_RBAC) else None input.soap_action = input.soap_action if input.soap_action else '' if input.content_encoding and input.content_encoding != 'gzip': raise Exception('Content encoding must be empty or equal to `gzip`') with closing(self.odb.session()) as session: existing_one = session.query(HTTPSOAP.id).\ filter(HTTPSOAP.cluster_id==input.cluster_id).\ filter(HTTPSOAP.id!=input.id).\ filter(HTTPSOAP.name==input.name).\ filter(HTTPSOAP.connection==input.connection).\ filter(HTTPSOAP.transport==input.transport).\ first() if existing_one: raise Exception('An object of that input.name:`{}` already exists in this cluster ' \ '(input.connection:`{}` input.transport:`{}` input.id:`{}` existing_one.id:`{}`)'.format( input.name, input.connection, input.transport, input.id, existing_one.id)) # Is the service's name correct? service = session.query(Service).\ filter(Cluster.id==input.cluster_id).\ filter(Service.cluster_id==Cluster.id).\ filter(Service.name==input.service).first() if input.connection == CONNECTION.CHANNEL and not service: msg = 'Service `{}` does not exist on this cluster'.format(input.service) self.logger.error(msg) raise Exception(msg) # Will raise exception if the security type doesn't match connection # type and transport sec_info = self._handle_security_info(session, input.security_id, input.connection, input.transport) # TLS data comes in combinations, i.e. certain elements are required only if TLS keys/certs are used self._validate_tls(input, sec_info) try: item = session.query(HTTPSOAP).filter_by(id=input.id).one() opaque = parse_instance_opaque_attr(item) old_name = item.name old_url_path = item.url_path old_soap_action = item.soap_action old_http_method = item.method old_http_accept = opaque.get('http_accept') item.name = input.name item.is_active = input.is_active item.host = input.host item.url_path = input.url_path item.security_id = input.security_id or None # So that SQLite does not reject '' item.connection = input.connection item.transport = input.transport item.cluster_id = input.cluster_id item.method = input.method item.soap_action = input.soap_action item.soap_version = input.soap_version or None item.data_format = input.data_format item.service = service item.ping_method = input.get('ping_method') or DEFAULT_HTTP_PING_METHOD item.pool_size = input.get('pool_size') or DEFAULT_HTTP_POOL_SIZE item.merge_url_params_req = input.get('merge_url_params_req') or False item.url_params_pri = input.get('url_params_pri') or URL_PARAMS_PRIORITY.DEFAULT item.params_pri = input.get('params_pri') or PARAMS_PRIORITY.DEFAULT item.serialization_type = input.get('serialization_type') or HTTP_SOAP_SERIALIZATION_TYPE.DEFAULT.id item.timeout = input.get('timeout') or MISC.DEFAULT_HTTP_TIMEOUT item.has_rbac = input.get('has_rbac') or input.sec_use_rbac or False item.content_type = input.get('content_type') item.sec_use_rbac = input.sec_use_rbac item.cache_id = input.cache_id or None item.cache_expiry = input.cache_expiry item.content_encoding = input.content_encoding sec_tls_ca_cert_id = input.get('sec_tls_ca_cert_id') item.sec_tls_ca_cert_id = sec_tls_ca_cert_id if sec_tls_ca_cert_id and sec_tls_ca_cert_id != ZATO_NONE else None # Opaque attributes set_instance_opaque_attrs(item, input) session.add(item) session.commit() if input.connection == CONNECTION.CHANNEL: input.impl_name = service.impl_name input.service_id = service.id input.service_name = service.name input.merge_url_params_req = item.merge_url_params_req input.url_params_pri = item.url_params_pri input.params_pri = item.params_pri cache = cache_by_id(session, input.cluster_id, item.cache_id) if item.cache_id else None if cache: input.cache_type = cache.cache_type input.cache_name = cache.name else: input.cache_type = None input.cache_name = None else: input.ping_method = item.ping_method input.pool_size = item.pool_size input.is_internal = item.is_internal input.old_name = old_name input.old_url_path = old_url_path input.old_soap_action = old_soap_action input.old_http_method = old_http_method input.old_http_accept = old_http_accept input.update(sec_info) if item.sec_tls_ca_cert_id and item.sec_tls_ca_cert_id != ZATO_NONE: self.add_tls_ca_cert(input, item.sec_tls_ca_cert_id) if input.connection == CONNECTION.CHANNEL: action = CHANNEL.HTTP_SOAP_CREATE_EDIT.value else: action = OUTGOING.HTTP_SOAP_CREATE_EDIT.value self.notify_worker_threads(input, action) self.response.payload.id = item.id self.response.payload.name = item.name except Exception: self.logger.error('Object could not be updated, e:`%s`', format_exc()) session.rollback() raise
def _get_message(self, topic, input, now, pub_pattern_matched, endpoint_id, subscriptions_by_topic, has_wsx_no_server, _initialized=_initialized, _zato_none=ZATO_NONE, _skip=PUBSUB.HOOK_ACTION.SKIP, _default_pri=PUBSUB.PRIORITY.DEFAULT, _opaque_only=PUBSUB.DEFAULT.SK_OPAQUE, _float_str=PUBSUB.FLOAT_STRING_CONVERT): priority = get_priority(self.cid, input) # So as not to send it to SQL if it is a default value anyway = less overhead = better performance if priority == _default_pri: priority = None expiration = get_expiration(self.cid, input) expiration_time = now + (expiration / 1000.0) pub_msg_id = input.get('msg_id', '').encode('utf8') or new_msg_id() # If there is at least one WSX subscriber to this topic which is not connected at the moment, # which means it has no delivery server, we uncoditionally turn this message into a GD one .. if has_wsx_no_server: has_gd = True logger_pubsub.info(_log_turning_gd_msg.format('wsx'), pub_msg_id) # .. otherwise, use input GD value or the default per topic. else: has_gd = input.get('has_gd', _zato_none) if has_gd != _zato_none: if not isinstance(has_gd, bool): raise ValueError( 'Input has_gd is not a bool (found:`{}`)'.format( repr(has_gd))) else: has_gd = topic.has_gd pub_correl_id = input.get('correl_id') in_reply_to = input.get('in_reply_to') ext_client_id = input.get('ext_client_id') mime_type = input.get('mime_type') ext_pub_time = input.get('ext_pub_time') or None if ext_pub_time: ext_pub_time = dt_parse(ext_pub_time) ext_pub_time = datetime_to_ms(ext_pub_time) / 1000.0 pub_correl_id = pub_correl_id.encode('utf8') if pub_correl_id else None in_reply_to = in_reply_to.encode('utf8') if in_reply_to else None ext_client_id = ext_client_id.encode('utf8') if ext_client_id else None mime_type = mime_type.encode('utf8') if mime_type else None reply_to_sk = input.get('reply_to_sk') or [] deliver_to_sk = input.get('deliver_to_sk') or [] user_ctx = input.get('user_ctx') zato_ctx = input.get('zato_ctx') ps_msg = PubSubMessage() ps_msg.topic = topic ps_msg.pub_msg_id = pub_msg_id ps_msg.pub_correl_id = pub_correl_id ps_msg.in_reply_to = in_reply_to # Convert to string to prevent pg8000 from rounding up float values ps_msg.pub_time = _float_str.format(now) ps_msg.ext_pub_time = _float_str.format( ext_pub_time) if ext_pub_time else ext_pub_time ps_msg.delivery_status = _initialized ps_msg.pub_pattern_matched = pub_pattern_matched ps_msg.data = input['data'] ps_msg.mime_type = mime_type ps_msg.priority = priority ps_msg.expiration = expiration ps_msg.expiration_time = expiration_time ps_msg.published_by_id = endpoint_id ps_msg.topic_id = topic.id ps_msg.topic_name = topic.name ps_msg.cluster_id = self.server.cluster_id ps_msg.has_gd = has_gd ps_msg.ext_client_id = ext_client_id ps_msg.group_id = input.get('group_id') or None ps_msg.position_in_group = input.get('position_in_group') or None ps_msg.is_in_sub_queue = bool(subscriptions_by_topic) ps_msg.reply_to_sk = reply_to_sk ps_msg.deliver_to_sk = deliver_to_sk ps_msg.user_ctx = user_ctx ps_msg.zato_ctx = zato_ctx # Opaque attributes - we only need reply to sub_keys to be placed in there # but we do not do it unless we known that any such sub key was actually requested. if reply_to_sk or deliver_to_sk: set_instance_opaque_attrs(ps_msg, input, only=_opaque_only) # If there are any subscriptions for the topic this message was published to, we want to establish # based on what subscription pattern each subscriber will receive the message. for sub in subscriptions_by_topic: ps_msg.sub_pattern_matched[sub.sub_key] = sub.sub_pattern_matched if ps_msg.data: ps_msg.size = len( ps_msg.data.encode('utf8') ) # We need to store the size in bytes rather than Unicode codepoints else: ps_msg.size = 0 # Invoke hook service here because it may want to update data in which case # we need to take it into account below. if topic.before_publish_hook_service_invoker: response = topic.before_publish_hook_service_invoker(topic, ps_msg) # Hook service decided that we should not process this message if response['hook_action'] == _skip: logger_audit.info( 'Skipping message pub_msg_id:`%s`, pub_correl_id:`%s`, ext_client_id:`%s`', ps_msg.pub_msg_id, ps_msg.pub_correl_id, ps_msg.ext_client_id) return # These are needed only for GD messages that are stored in SQL if has_gd: data_prefix, data_prefix_short = self._get_data_prefixes( ps_msg.data) ps_msg.data_prefix = data_prefix ps_msg.data_prefix_short = data_prefix_short return ps_msg
def handle(self): input = self.request.input input.sec_use_rbac = input.security_id == ZATO_SEC_USE_RBAC input.security_id = input.security_id if input.security_id not in ( ZATO_NONE, ZATO_SEC_USE_RBAC) else None input.soap_action = input.soap_action if input.soap_action else '' input.timeout = input.get('timeout') or MISC.DEFAULT_HTTP_TIMEOUT if input.content_encoding and input.content_encoding != 'gzip': raise Exception( 'Content encoding must be empty or equal to `gzip`') with closing(self.odb.session()) as session: existing_one = session.query(HTTPSOAP.id).\ filter(HTTPSOAP.cluster_id==input.cluster_id).\ filter(HTTPSOAP.name==input.name).\ filter(HTTPSOAP.connection==input.connection).\ filter(HTTPSOAP.transport==input.transport).\ first() if existing_one: raise Exception( 'An object of that name `{}` already exists on this cluster' .format(input.name)) # Is the service's name correct? service = session.query(Service).\ filter(Cluster.id==input.cluster_id).\ filter(Service.cluster_id==Cluster.id).\ filter(Service.name==input.service).first() if input.connection == CONNECTION.CHANNEL and not service: msg = 'Service `{}` does not exist on this cluster'.format( input.service) self.logger.error(msg) raise Exception(msg) # Will raise exception if the security type doesn't match connection # type and transport sec_info = self._handle_security_info(session, input.security_id, input.connection, input.transport) # Make sure this combination of channel parameters does not exist already if input.connection == CONNECTION.CHANNEL: self.ensure_channel_is_unique(session, input.url_path, input.soap_action, input.cluster_id) try: item = self._new_zato_instance_with_cluster(HTTPSOAP) item.connection = input.connection item.transport = input.transport item.is_internal = input.is_internal item.name = input.name item.is_active = input.is_active item.host = input.host item.url_path = input.url_path item.method = input.method item.soap_action = input.soap_action item.soap_version = input.soap_version or None item.data_format = input.data_format item.service = service item.ping_method = input.get( 'ping_method') or DEFAULT_HTTP_PING_METHOD item.pool_size = input.get( 'pool_size') or DEFAULT_HTTP_POOL_SIZE item.merge_url_params_req = input.get( 'merge_url_params_req') or True item.url_params_pri = input.get( 'url_params_pri') or URL_PARAMS_PRIORITY.DEFAULT item.params_pri = input.get( 'params_pri') or PARAMS_PRIORITY.DEFAULT item.serialization_type = input.get( 'serialization_type' ) or HTTP_SOAP_SERIALIZATION_TYPE.DEFAULT.id item.timeout = input.timeout item.has_rbac = input.get( 'has_rbac') or input.sec_use_rbac or False item.content_type = input.get('content_type') item.sec_use_rbac = input.sec_use_rbac item.cache_id = input.cache_id or None item.cache_expiry = input.cache_expiry item.content_encoding = input.content_encoding if input.security_id: item.security = get_security_by_id(session, input.security_id) else: input.security_id = None # To ensure that SQLite doesn't reject '' sec_tls_ca_cert_id = input.get('sec_tls_ca_cert_id') item.sec_tls_ca_cert_id = sec_tls_ca_cert_id if sec_tls_ca_cert_id and sec_tls_ca_cert_id != ZATO_NONE else None # Opaque attributes set_instance_opaque_attrs(item, input) session.add(item) session.commit() if input.connection == CONNECTION.CHANNEL: input.impl_name = service.impl_name input.service_id = service.id input.service_name = service.name cache = cache_by_id( session, input.cluster_id, item.cache_id) if item.cache_id else None if cache: input.cache_type = cache.cache_type input.cache_name = cache.name else: input.cache_type = None input.cache_name = None if item.sec_tls_ca_cert_id and item.sec_tls_ca_cert_id != ZATO_NONE: self.add_tls_ca_cert(input, item.sec_tls_ca_cert_id) input.id = item.id input.update(sec_info) if input.connection == CONNECTION.CHANNEL: action = CHANNEL.HTTP_SOAP_CREATE_EDIT.value else: action = OUTGOING.HTTP_SOAP_CREATE_EDIT.value self.notify_worker_threads(input, action) self.response.payload.id = item.id self.response.payload.name = item.name except Exception: msg = 'Could not create the object, e:`{}'.format(format_exc()) self.logger.error(msg) session.rollback() raise
def handle_impl(self): input = self.request.input input.update(attrs.initial_input) verb = 'edit' if attrs.is_edit else 'create' old_name = None with closing(self.odb.session()) as session: try: attrs._meta_session = session if attrs.check_existing_one: # Let's see if we already have an instance of that name before committing # any stuff to the database. However, this is wrapped in an if condition # because certain models don't have the .name attribute. existing_one = session.query(attrs.model).\ filter(Cluster.id==input.cluster_id).\ filter(attrs.model.name==input.name) if attrs.is_edit: existing_one = existing_one.filter( attrs.model.id != input.id) existing_one = existing_one.first() if existing_one and not attrs.is_edit: raise Exception( '{} `{}` already exists in this cluster'. format( attrs.label[0].upper() + attrs.label[1:], input.name)) if attrs.is_edit: instance = session.query( attrs.model).filter_by(id=input.id).one() old_name = instance.name else: instance = self._new_zato_instance_with_cluster( attrs.model) # Update the instance with data received on input, however, # note that this may overwrite some of existing attributes # if they are empty on input. If it's not desired, # set skip_input_params = ['...'] to ignore such input parameters. instance.fromdict(input, exclude=['password'], allow_pk=True) # Populate all the opaque attrs now set_instance_opaque_attrs(instance, input) # Now that we have an instance which is known not to be a duplicate # we can possibly invoke a customization function before we commit # anything to the database. if attrs.instance_hook: attrs.instance_hook(self, input, instance, attrs) session.add(instance) session.commit() except Exception, e: msg = 'Could not {} the object, e:`%s`'.format(verb) logger.error(msg, format_exc(e)) session.rollback() raise else: