Merge pull request #162 from CGenie/cgenie/graph-db-hash-type

signals: add optional hash tagging parameter
This commit is contained in:
Jędrzej Nowak 2015-09-16 16:14:08 +02:00
commit ddac477240
3 changed files with 67 additions and 8 deletions

View File

@ -103,6 +103,10 @@ def connect_single(emitter, src, receiver, dst):
def connect_multi(emitter, src, receiver, dst):
receiver_input_name, receiver_input_key = dst.split(':')
if '|' in receiver_input_key:
receiver_input_key, receiver_input_tag = receiver_input_key.split('|')
else:
receiver_input_tag = None
emitter_input = emitter.resource_inputs()[src]
receiver_input = receiver.resource_inputs()[receiver_input_name]
@ -113,11 +117,16 @@ def connect_multi(emitter, src, receiver, dst):
'Receiver input {} must be a hash or a list of hashes'.format(receiver_input_name)
)
log.debug('Connecting {}::{} -> {}::{}[{}]'.format(
log.debug('Connecting {}::{} -> {}::{}[{}], tag={}'.format(
emitter.name, emitter_input.name, receiver.name, receiver_input.name,
receiver_input_key
receiver_input_key,
receiver_input_tag
))
emitter_input.receivers.add_hash(receiver_input, receiver_input_key)
emitter_input.receivers.add_hash(
receiver_input,
receiver_input_key,
tag=receiver_input_tag
)
def disconnect_receiver_by_input(receiver, input_name):

View File

@ -123,7 +123,7 @@ class DBRelatedField(object):
type_=self.relation_type
)
def add_hash(self, destination_db_object, destination_key):
def add_hash(self, destination_db_object, destination_key, tag=None):
if not isinstance(destination_db_object, self.destination_db_class):
raise errors.SolarError(
'Object {} is of incompatible type {}.'.format(
@ -134,7 +134,7 @@ class DBRelatedField(object):
db.get_or_create_relation(
self.source_db_object._db_node,
destination_db_object._db_node,
properties={'destination_key': destination_key},
properties={'destination_key': destination_key, 'tag': tag},
type_=self.relation_type
)
@ -392,16 +392,19 @@ class DBResourceInput(DBObject):
return [i.backtrack_value() for i in inputs]
# NOTE: we return a list of values, but we need to group them
# by resource name, hence this dict here
# hence this dict here
# NOTE: grouping is done by resource.name by default, but this
# can be overwritten by the 'tag' property in relation
ret = {}
for r in relations:
source = source_class(**r.start_node.properties)
ret.setdefault(source.resource.name, {})
tag = r.properties['tag'] or source.resource.name
ret.setdefault(tag, {})
key = r.properties['destination_key']
value = source.backtrack_value()
ret[source.resource.name].update({key: value})
ret[tag].update({key: value})
return ret.values()
elif self.is_hash:

View File

@ -654,3 +654,50 @@ input:
{'ip': sample.args['ip']},
receiver.args['server'],
)
def test_hash_input_multiple_resources_with_tag_connect(self):
sample_meta_dir = self.make_resource_meta("""
id: sample
handler: ansible
version: 1.0.0
input:
ip:
schema: str!
value:
port:
schema: int!
value:
""")
receiver_meta_dir = self.make_resource_meta("""
id: receiver
handler: ansible
version: 1.0.0
input:
server:
schema: [{ip: str!, port: int!}]
""")
sample1 = self.create_resource(
'sample1', sample_meta_dir, args={'ip': '10.0.0.1', 'port': 5000}
)
sample2 = self.create_resource(
'sample2', sample_meta_dir, args={'ip': '10.0.0.2', 'port': 5001}
)
receiver = self.create_resource(
'receiver', receiver_meta_dir
)
xs.connect(sample1, receiver, mapping={'ip': 'server:ip'})
xs.connect(sample2, receiver, mapping={'port': 'server:port|sample1'})
self.assertItemsEqual(
[{'ip': sample1.args['ip'], 'port': sample2.args['port']}],
receiver.args['server'],
)
sample3 = self.create_resource(
'sample3', sample_meta_dir, args={'ip': '10.0.0.3', 'port': 5002}
)
xs.connect(sample3, receiver, mapping={'ip': 'server:ip', 'port': 'server:port'})
self.assertItemsEqual(
[{'ip': sample1.args['ip'], 'port': sample2.args['port']},
{'ip': sample3.args['ip'], 'port': sample3.args['port']}],
receiver.args['server'],
)