def resolve_remote(self, deployables): all_desc_iters = dynops.List() store = GlobalStore(node=self.node) for actor_name, info in deployables.iteritems(): desc_iter = store.global_lookup_iter(info['signature'], info['args'].keys()) all_desc_iters.append((actor_name, desc_iter), trigger_iter=desc_iter) all_desc_iters.final() collect_desc_iter = dynops.Collect(all_desc_iters).set_name("collected_desc") select_iter = dynops.Map(self.select_actor, collect_desc_iter, done=False, priority={k:[] for k in self.deployable['actors'].keys()}, eager=True).set_name("select_actor") select_iter.set_cb(self.deploy_unhandled_actors, select_iter) self.deploy_unhandled_actors(select_iter)
def resolve_remote(self, actor_name, info, cb=None): # FIXME: no list needed since it is only done for one actor all_desc_iters = dynops.List() store = GlobalStore(node=self.node) desc_iter = store.global_lookup_iter(info['signature'], info['args'].keys()) all_desc_iters.append((actor_name, desc_iter), trigger_iter=desc_iter) all_desc_iters.final() collect_desc_iter = dynops.Collect(all_desc_iters).set_name("collected_desc") select_iter = dynops.Map(self.select_actor, collect_desc_iter, done=False, priority={k:[] for k in self.deployable['actors'].keys()}, eager=True).set_name("select_actor") select_iter.set_cb(self.deploy_unhandled_actor, select_iter, cb) self.deploy_unhandled_actor(select_iter, cb)
def _create_signature(actor_type, metadata): # Create the actor signature to be able to look it up in the GlobalStore if neccessary signature_desc = {'is_primitive': True, 'actor_type': actor_type, 'inports': metadata['inputs'], 'outports': metadata['outputs']} return GlobalStore.actor_signature(signature_desc)
def store_complete_requirements(self, actor_id): actor = self.node.am.actors[actor_id] if actor.is_shadow(): # Find requires def _desc_cb(signature, description): _log.debug("REQUIRES BACK %s" % description) requires = None for actor_desc in description: # We get list of possible descriptions back matching the signature # In reality it is only one if 'requires' in actor_desc: requires = actor_desc['requires'] if requires is not None: actor.requires = requires self.node.storage.add_actor_requirements(actor) self._requires_counter += 1 if self._requires_counter >= len(self.deployable['actors']): self._wait_for_all_connections_and_requires() try: GlobalStore(node=self.node).global_signature_lookup( actor._signature, cb=_desc_cb) except: _log.exception("actor instanciate GlobalStore exception") self._requires_counter += 1 else: self._requires_counter += 1 self.node.storage.add_actor_requirements(actor)
def __init__(self, node, request): self.attributes = { "subject": { "actor_signer": self._get_actor_signer }, "action": { "requires": self._get_requires }, "environment": { "current_date": self._get_current_date, "current_time": self._get_current_time } } self.node = node self.request = request self.actorstore = GlobalStore(node=node) self.actor_desc = None
class PolicyInformationPoint(object): def __init__(self, node, request): self.attributes = { "subject": { "actor_signer": self._get_actor_signer }, "action": { "requires": self._get_requires }, "environment": { "current_date": self._get_current_date, "current_time": self._get_current_time } } self.node = node self.request = request self.actorstore = GlobalStore(node=node) self.actor_desc = None def get_attribute_value(self, attribute_type, attribute): """Return the specified attribute if it exists in attributes dictionary""" value = self.attributes[attribute_type][attribute] if hasattr(value, '__call__'): # The value is a function, call the function. func_value = value() # Cache the value (replace function) since same value should be used for future tests when handling this request. self.attributes[attribute_type][attribute] = func_value return func_value return value def _get_actor_signer(self): return self.actor_desc["signer"] def _get_requires(self): return ["runtime"] + self.actor_desc["requires"] def _get_current_date(self): return datetime.now().strftime('%Y-%m-%d') def _get_current_time(self): return datetime.now().strftime('%H:%M') def actor_desc_lookup(self, actorstore_signature, callback): desc_iter = self.actorstore.global_lookup_iter( actorstore_signature, node_id=self.request["resource"]["node_id"]) desc_iter.set_cb(self._set_actor_desc, desc_iter, callback) self._set_actor_desc(desc_iter, callback) def _set_actor_desc(self, desc_iter, callback): while True: try: desc = desc_iter.next() except StopIteration: callback(pip=self) return except dynops.PauseIteration: return self.actor_desc = desc
class PolicyInformationPoint(object): def __init__(self, node, request): self.attributes = { "subject": { "actor_signer": self._get_actor_signer }, "action": { "requires": self._get_requires }, "environment": { "current_date": self._get_current_date, "current_time": self._get_current_time } } self.node = node self.request = request self.actorstore = GlobalStore(node=node) self.actor_desc = None def get_attribute_value(self, attribute_type, attribute): """Return the specified attribute if it exists in attributes dictionary""" value = self.attributes[attribute_type][attribute] if hasattr(value, '__call__'): # The value is a function, call the function. func_value = value() # Cache the value (replace function) since same value should be used for future tests when handling this request. self.attributes[attribute_type][attribute] = func_value return func_value return value def _get_actor_signer(self): return self.actor_desc["signer"] def _get_requires(self): return ["runtime"] + self.actor_desc["requires"] def _get_current_date(self): return datetime.now().strftime('%Y-%m-%d') def _get_current_time(self): return datetime.now().strftime('%H:%M') def actor_desc_lookup(self, actorstore_signature, callback): desc_iter = self.actorstore.global_lookup_iter(actorstore_signature, node_id=self.request["resource"]["node_id"]) desc_iter.set_cb(self._set_actor_desc, desc_iter, callback) self._set_actor_desc(desc_iter, callback) def _set_actor_desc(self, desc_iter, callback): while True: try: desc = desc_iter.next() except StopIteration: callback(pip=self) return except dynops.PauseIteration: return self.actor_desc = desc
def resolve_remote(self, actor_name, info, cb=None): # FIXME: no list needed since it is only done for one actor all_desc_iters = dynops.List() store = GlobalStore(node=self.node) desc_iter = store.global_lookup_iter(info['signature'], info['args'].keys()) all_desc_iters.append((actor_name, desc_iter), trigger_iter=desc_iter) all_desc_iters.final() collect_desc_iter = dynops.Collect(all_desc_iters).set_name( "collected_desc") select_iter = dynops.Map( self.select_actor, collect_desc_iter, done=False, priority={k: [] for k in self.deployable['actors'].keys()}, eager=True).set_name("select_actor") select_iter.set_cb(self.deploy_unhandled_actor, select_iter, cb) self.deploy_unhandled_actor(select_iter, cb)
def add_node(self, node, cb=None): """ Add node to storage """ self.set(prefix="node-", key=node.id, value={"uri": node.external_uri, "control_uri": node.external_control_uri, "authz_server": node.authorization.authz_server_id, "attributes": {'public': node.attributes.get_public(), 'indexed_public': node.attributes.get_indexed_public(as_list=False)}}, cb=cb) self._add_node_index(node) # Store all actors on this node in storage GlobalStore(node=node, security=Security(node) if security_enabled() else None, verify=False).export()
def analyze_structure(self, structure, namespace, argd): """ Analyze a (sub) structure and resolve actor names, arguments, and connections. Parameter argd is a dict with arguments for the structure Returns a dict with port mappings corresponding to the externally visible ports of the structure, i.e. the ports of a component. """ # Check for literals on inports... self.expand_literals(structure, argd) in_mappings = {} out_mappings = {} for actor_name, actor_def in structure['actors'].iteritems(): # Look up actor info, is_actor = self.lookup(actor_def['actor_type']) # Resolve arguments args = self.resolve_arguments(actor_def['args'], argd) qualified_name = namespace + ':' + actor_name if is_actor: # Create the actor signature to be able to look it up in the GlobalStore if neccessary signature_desc = {'is_primitive': True, 'actor_type': actor_def['actor_type'], 'inports': [], 'outports': []} for c in structure['connections']: if actor_name == c['src'] and c['src_port'] not in signature_desc['outports']: signature_desc['outports'].append(c['src_port']) elif actor_name == c['dst'] and c['dst_port'] not in signature_desc['inports']: signature_desc['inports'].append(c['dst_port']) signature = GlobalStore.actor_signature(signature_desc) # Add actor and its arguments to the list of actor instances self.actors[qualified_name] = {'actor_type': actor_def['actor_type'], 'args': args, 'signature': signature, 'signature_desc': signature_desc} else: # Recurse into components # qualified_name constitutes a namespace here comp_in_mapping, comp_out_mapping = self.analyze_structure(info['structure'], qualified_name, args) in_mappings.update(comp_in_mapping) out_mappings.update(comp_out_mapping) export_in_mappings = {} export_out_mappings = {} for c in structure['connections']: in_mapping, out_mapping = self.create_connection(c, namespace, in_mappings, out_mappings) for p in in_mapping: export_in_mappings.setdefault(p, []).extend(in_mapping[p]) export_out_mappings.update(out_mapping) return export_in_mappings, export_out_mappings
def deploy_unhandled_actors(self, comp_name_desc): while True: try: name, desc = comp_name_desc.next() _log.analyze(self.node.id, "+", {'name': name, 'desc': desc}, tb=True) except StopIteration: # Done if self._deploy_cont_done: return self._deploy_cont_done = True self.group_components() _log.analyze(self.node.id, "+ DONE", {'deployable': self.deployable, 'components': self.components}) self._deploy_cont() return except dynops.PauseIteration: return if 'shadow_actor' in desc: _log.analyze(self.node.id, "+ SHADOW ACTOR", {'name': name}) # It was a normal primitive shadow actor, just instanciate req = self.get_req(name) info = self.deployable['actors'][name] actor_id = self.instantiate_primitive(name, info['actor_type'], info['args'], req, info['signature']) if not actor_id: _log.error("Second phase, could not make shadow actor %s!" % info['actor_type']) self.actor_map[name] = actor_id self.node.app_manager.add(self.app_id, actor_id) elif 'shadow_component' in desc: _log.analyze(self.node.id, "+ SHADOW COMPONENT", {'name': name}) # A component that needs to be broken up into individual primitive actors # First get the info and remove the component req = self.get_req(name) info = self.deployable['actors'][name] self.deployable['actors'].pop(name) # Then add the new primitive actors for actor_name, actor_desc in desc['component']['structure']['actors'].iteritems(): args = {k: v[1] if v[0] == 'VALUE' else info['args'][v[1]] for k, v in actor_desc['args'].iteritems()} inports = [c['dst_port'] for c in desc['component']['structure']['connections'] if c['dst'] == actor_name] outports = [c['src_port'] for c in desc['component']['structure']['connections'] if c['src'] == actor_name] sign_desc = {'is_primitive': True, 'actor_type': actor_desc['actor_type'], 'inports': inports[:], 'outports': outports[:]} sign = GlobalStore.actor_signature(sign_desc) self.deployable['actors'][name + ":" + actor_name] = {'args': args, 'actor_type': actor_desc['actor_type'], 'signature_desc': sign_desc, 'signature': sign} # Replace component connections with actor connection # outports comp_outports = [(c['dst_port'], c['src_port']) for c in desc['component']['structure']['connections'] if c['src'] == actor_name and c['dst'] == "."] for c_port, a_port in comp_outports: if (name + "." + c_port) in self.deployable['connections']: self.deployable['connections'][name + ":" + actor_name + "." + a_port] = \ self.deployable['connections'].pop(name + "." + c_port) # inports comp_inports = [(c['src_port'], c['dst_port']) for c in desc['component']['structure']['connections'] if c['dst'] == actor_name and c['src'] == "."] for outport, ports in self.deployable['connections'].iteritems(): for c_inport, a_inport in comp_inports: if (name + "." + c_inport) in ports: ports.remove(name + "." + c_inport) ports.append(name + ":" + actor_name + "." + a_inport) _log.analyze(self.node.id, "+ REPLACED PORTS", {'comp_outports': comp_outports, 'comp_inports': comp_inports, 'actor_name': actor_name, 'connections': self.deployable['connections']}) # Add any new component internal connections (enough with outports) for connection in desc['component']['structure']['connections']: if connection['src'] == actor_name and connection['src_port'] in outports and connection['dst'] != ".": self.deployable['connections'].setdefault( name + ":" + actor_name + "." + connection['src_port'], []).append( name + ":" + connection['dst'] + "." + connection['dst_port']) _log.analyze(self.node.id, "+ ADDED PORTS", {'connections': self.deployable['connections']}) # Instanciate it actor_id = self.instantiate_primitive(name + ":" + actor_name, actor_desc['actor_type'], args, req, sign) if not actor_id: _log.error("Third phase, could not make shadow actor %s!" % info['actor_type']) self.actor_map[name + ":" + actor_name] = actor_id self.node.app_manager.add(self.app_id, actor_id)
def deploy_unhandled_actor(self, comp_name_desc, cb=None): while True: try: name, desc = comp_name_desc.next() _log.analyze(self.node.id, "+", {'name': name, 'desc': desc}, tb=True) except StopIteration: return except dynops.PauseIteration: return if 'shadow_actor' in desc: _log.analyze(self.node.id, "+ SHADOW ACTOR", {'name': name}) # It was a normal primitive shadow actor, just add to list of verified actors. info = self.deployable['actors'][name] info['shadow_actor'] = True self._verified_actors[name] = (info, None) elif 'shadow_component' in desc: _log.analyze(self.node.id, "+ SHADOW COMPONENT", {'name': name}) # A component that needs to be broken up into individual primitive actors # First, get the component requirements and info req = self.get_req(name) info = self.deployable['actors'][name] # Then add the new primitive actors for actor_name, actor_desc in desc['component']['structure']['actors'].iteritems(): args = {k: v[1] if v[0] == 'VALUE' else info['args'][v[1]] for k, v in actor_desc['args'].iteritems()} inports = [c['dst_port'] for c in desc['component']['structure']['connections'] if c['dst'] == actor_name] outports = [c['src_port'] for c in desc['component']['structure']['connections'] if c['src'] == actor_name] sign_desc = {'is_primitive': True, 'actor_type': actor_desc['actor_type'], 'inports': inports[:], 'outports': outports[:]} sign = GlobalStore.actor_signature(sign_desc) self._verified_actors[name + ":" + actor_name] = ({'args': args, 'actor_type': actor_desc['actor_type'], 'signature_desc': sign_desc, 'signature': sign}, None) # Replace component connections with actor connection # outports comp_outports = [(c['dst_port'], c['src_port']) for c in desc['component']['structure']['connections'] if c['src'] == actor_name and c['dst'] == "."] for c_port, a_port in comp_outports: if (name + "." + c_port) in self.deployable['connections']: self.deployable['connections'][name + ":" + actor_name + "." + a_port] = \ self.deployable['connections'].pop(name + "." + c_port) # inports comp_inports = [(c['src_port'], c['dst_port']) for c in desc['component']['structure']['connections'] if c['dst'] == actor_name and c['src'] == "."] for outport, ports in self.deployable['connections'].iteritems(): for c_inport, a_inport in comp_inports: if (name + "." + c_inport) in ports: ports.remove(name + "." + c_inport) ports.append(name + ":" + actor_name + "." + a_inport) _log.analyze(self.node.id, "+ REPLACED PORTS", {'comp_outports': comp_outports, 'comp_inports': comp_inports, 'actor_name': actor_name, 'connections': self.deployable['connections']}) # Add any new component internal connections (enough with outports) for connection in desc['component']['structure']['connections']: if connection['src'] == actor_name and connection['src_port'] in outports and connection['dst'] != ".": self.deployable['connections'].setdefault( name + ":" + actor_name + "." + connection['src_port'], []).append( name + ":" + connection['dst'] + "." + connection['dst_port']) _log.analyze(self.node.id, "+ ADDED PORTS", {'connections': self.deployable['connections']}) self.group_components() if cb: cb()
def deploy_unhandled_actor(self, comp_name_desc, cb=None): while True: try: name, desc = comp_name_desc.next() _log.analyze(self.node.id, "+", { 'name': name, 'desc': desc }, tb=True) except StopIteration: return except dynops.PauseIteration: return if 'shadow_actor' in desc: _log.analyze(self.node.id, "+ SHADOW ACTOR", {'name': name}) # It was a normal primitive shadow actor, just add to list of verified actors. info = self.deployable['actors'][name] info['shadow_actor'] = True self._verified_actors[name] = (info, None) elif 'shadow_component' in desc: _log.analyze(self.node.id, "+ SHADOW COMPONENT", {'name': name}) # A component that needs to be broken up into individual primitive actors # First, get the component requirements and info req = self.get_req(name) info = self.deployable['actors'][name] # Then add the new primitive actors for actor_name, actor_desc in desc['component']['structure'][ 'actors'].iteritems(): args = { k: v[1] if v[0] == 'VALUE' else info['args'][v[1]] for k, v in actor_desc['args'].iteritems() } inports = [ c['dst_port'] for c in desc['component']['structure']['connections'] if c['dst'] == actor_name ] outports = [ c['src_port'] for c in desc['component']['structure']['connections'] if c['src'] == actor_name ] sign_desc = { 'is_primitive': True, 'actor_type': actor_desc['actor_type'], 'inports': inports[:], 'outports': outports[:] } sign = GlobalStore.actor_signature(sign_desc) self._verified_actors[name + ":" + actor_name] = ({ 'args': args, 'actor_type': actor_desc['actor_type'], 'signature_desc': sign_desc, 'signature': sign }, None) # Replace component connections with actor connection # outports comp_outports = [ (c['dst_port'], c['src_port']) for c in desc['component']['structure']['connections'] if c['src'] == actor_name and c['dst'] == "." ] for c_port, a_port in comp_outports: if (name + "." + c_port) in self.deployable['connections']: self.deployable['connections'][name + ":" + actor_name + "." + a_port] = \ self.deployable['connections'].pop(name + "." + c_port) # inports comp_inports = [ (c['src_port'], c['dst_port']) for c in desc['component']['structure']['connections'] if c['dst'] == actor_name and c['src'] == "." ] for outport, ports in self.deployable[ 'connections'].iteritems(): for c_inport, a_inport in comp_inports: if (name + "." + c_inport) in ports: ports.remove(name + "." + c_inport) ports.append(name + ":" + actor_name + "." + a_inport) _log.analyze( self.node.id, "+ REPLACED PORTS", { 'comp_outports': comp_outports, 'comp_inports': comp_inports, 'actor_name': actor_name, 'connections': self.deployable['connections'] }) # Add any new component internal connections (enough with outports) for connection in desc['component']['structure'][ 'connections']: if connection['src'] == actor_name and connection[ 'src_port'] in outports and connection[ 'dst'] != ".": self.deployable['connections'].setdefault( name + ":" + actor_name + "." + connection['src_port'], []).append(name + ":" + connection['dst'] + "." + connection['dst_port']) _log.analyze( self.node.id, "+ ADDED PORTS", {'connections': self.deployable['connections']}) self.group_components() if cb: cb()