def test_response_received(self): publish_urn = 'rho:instances.owner' payload = StoragePayload() payload.add_type(FOAF.Person, RHO.Owner) promise = self.rdf_publisher.send_out_request(payload) args, kwargs = self.roster_plugin.send_message.call_args payload = kwargs['payload'] thread_id = kwargs['thread_id'] response_payload = ResultCollectionPayload() response_payload.append(ResultPayload(about=publish_urn, types=[FOAF.Person, RHO.Owner])) self.rdf_publisher._send_message(RDFStanzaType.RESPONSE, response_payload, thread_id) response_args, response_kwargs = self.roster_plugin.send_message.call_args payload = response_kwargs['payload'] response_message = Message() response_message.append(payload) response_message['thread'] = response_kwargs['thread_id'] with mock.patch.object(promise, attribute='resolved') as mock_promise_resolve: self.rdf_publisher._receive_message(response_message) self.assertEqual(1, mock_promise_resolve.call_count) args, kwargs = mock_promise_resolve.call_args result = [rdf.about for rdf in args[0].results] self.assertEqual(result, [publish_urn])
def _create_interval(self, session, form_payload): """ Convert the form payload into a storage payload for creating a new interval. :param session: :param form_payload: :return: """ def _translate_search_to_about(result): if result.results: return result.results[0].about raise RuntimeError('Interval was not created.') # Handle the creation of the interval. create_interval_payload = StoragePayload() create_interval_payload.add_type(TIMELINE.Interval) if 'event_start' in form_payload.get_values(): create_interval_payload.add_property(TIMELINE.start, form_payload.get_values()['event_start']) if 'event_stop' in form_payload.get_values(): create_interval_payload.add_property(TIMELINE.end, form_payload.get_values()['event_stop']) creator = self._representation_manager.representation_uri if creator: create_interval_payload.add_property(DCTERMS.creator, creator) promise = self._storage_client.create_node(create_interval_payload) promise = promise.then(_translate_search_to_about) promise = promise.then(self._scheduler.generate_promise_handler(self._update_session, session, 'interval')) return promise
def test_basic_creation(self): message = self.Message() payload = StoragePayload() payload.about = 'urn:rho:instance:owner' payload.add_type(FOAF.Person, RHO.Owner) rdf = RDFStanza() rdf['type'] = RDFStanzaType.CREATE.value rdf.append(payload.populate_payload()) message.append(rdf) self.check(message, """ <message> <rdf xmlns="urn:rho:rdf" type="create"> <x xmlns="jabber:x:data" type="form"> <field var="%s" type="text-single"> <value>%s</value> </field> <field var="%s" type="list-multi"> <value>%s</value> <value>%s</value> </field> </x> </rdf> </message> """ % (str(RDF.about), payload.about, str(RDF.type), str(FOAF.Person), str(RHO.Owner), ), use_values=False)
def test_send_request(self): payload = StoragePayload() payload.add_type(FOAF.Person, RHO.Owner) request_promise = self.rdf_publisher.send_out_request(payload) self.assertIsNotNone(request_promise) self.assertTrue(hasattr(request_promise, 'then')) # Verify the payload request. self.assertEqual(1, self.roster_plugin.send_message.call_count) args, kwargs = self.roster_plugin.send_message.call_args self.assertIn('thread_id', kwargs) self.assertIn('payload', kwargs) # Must have a payload, and a thread_id self.assertIsNotNone(kwargs['thread_id']) self.assertIsNotNone(kwargs['payload']) payload = kwargs['payload'] self.assertEqual(payload['type'], RDFStanzaType.REQUEST.value) self.assertIn(str(FOAF.Person), payload['form'].get_fields()[str(RDF.type)].get_value()) self.assertIn(str(RHO.Owner), payload['form'].get_fields()[str(RDF.type)].get_value())
def test_publish_create(self): publish_urn = 'rho:instances.owner' payload = StoragePayload() payload.add_type(FOAF.Person, RHO.Owner) payload.about = publish_urn self.rdf_publisher.publish_create(payload) self.assertEqual(1, self.roster_plugin.send_message.call_count) args, kwargs = self.roster_plugin.send_message.call_args self.assertIn('thread_id', kwargs) self.assertIn('payload', kwargs) self.assertIsNone(kwargs['thread_id']) self.assertIsNotNone(kwargs['payload']) payload = kwargs['payload'] self.assertEqual(payload['type'], RDFStanzaType.CREATE.value) form = payload['form'] self.assertIsNotNone(form.get_fields()[str(RDF.type)]) values = form.get_fields()[str(RDF.type)].get_value() self.assertIn(str(FOAF.Person), values) self.assertIn(str(RHO.Owner), values) self.assertIsNotNone(form.get_fields()[str(RDF.about)]) values = form.get_fields()[str(RDF.about)].get_value() self.assertEqual(publish_urn, values)
def test_pack_unpacked_payload(self): form = Form() payload = StoragePayload(form) about = "urn:rho:identified_by:asdf" see_also = "urn:rho.value" mbox = "mailto:[email protected]" create_if_missing = True payload.about = about payload.add_type(FOAF.Person) payload.add_property(RDFS.seeAlso, see_also) payload.add_reference(FOAF.mbox, mbox) payload.add_flag(FindFlags.CREATE_IF_MISSING, create_if_missing) content = payload.populate_payload() second_payload = StoragePayload(content) second_content = second_payload.populate_payload() self.assertIsNotNone(second_content) self.assertEqual(second_content.get_fields()[str(RDF.about)].get_value(), about) self.assertEqual(second_content.get_fields()[str(RDFS.seeAlso)].get_value(), [see_also]) self.assertEqual(second_content.get_fields()[str(FOAF.mbox)].get_value(), [mbox]) self.assertEqual(second_content.get_fields()[FindFlags.CREATE_IF_MISSING.var].get_value(), create_if_missing)
def test_get_node(self): self.storage_client._store_found('[email protected]/storage') payload = StoragePayload() payload.about = 'http://www.example.org/instance/01' payload.add_type(FOAF.Person) payload.add_property(FOAF.name, 'Robert') promise = self.storage_client.get_node(payload) def handle_result(result): self.session['result'] = result promise.then(handle_result) self.assertTrue(hasattr(promise, 'then')) self.send(""" <iq type="set" to="[email protected]/storage" id="1"> <command xmlns="http://jabber.org/protocol/commands" node="get_node" action="execute"> <x xmlns="jabber:x:data" type="form"> <field var="http://www.w3.org/1999/02/22-rdf-syntax-ns#about" type="text-single"> <value>http://www.example.org/instance/01</value> </field> <field var="http://www.w3.org/1999/02/22-rdf-syntax-ns#type" type="list-multi"> <value>http://xmlns.com/foaf/0.1/Person</value> </field> <field var="http://xmlns.com/foaf/0.1/name" type="list-multi"> <value>Robert</value> <validate xmlns="http://jabber.org/protocol/xdata-validate" datatype="xs:string" /> </field> </x> </command> </iq> """) self.assertNotIn('result', self.session) self.recv(""" <iq type='result' from='[email protected]/storage' to='tester@localhost/full' id='1'> <command xmlns='http://jabber.org/protocol/commands' sessionid='list:20020923T213616Z-700' node='get_node' status='completed'> %s </command> </iq> """ % payload.populate_payload()) time.sleep(0.2) self.assertIn('result', self.session) result = self.session['result'] self.assertEqual(result.about, 'http://www.example.org/instance/01') self.assertEquals(result.types[0], str(FOAF.Person))
def test_unpack(self): form = Form() payload = StoragePayload(form) about = "urn:rho:identified_by:asdf" see_also = "urn:rho.value" mbox = "mailto:[email protected]" create_if_missing = True payload.about = about payload.add_type(FOAF.Person) payload.add_property(RDFS.seeAlso, see_also) payload.add_reference(FOAF.mbox, mbox) payload.add_flag(FindFlags.CREATE_IF_MISSING, create_if_missing) content = payload.populate_payload() second_payload = StoragePayload(content) self.assertEqual(second_payload.about, about) self.assertIn(str(FOAF.Person), second_payload.types) self.assertEqual(second_payload.properties[str(RDFS.seeAlso)], [see_also]) self.assertEqual(second_payload.references[str(FOAF.mbox)], [mbox]) self.assertEqual(FindFlags.CREATE_IF_MISSING.fetch_from(second_payload.flags), create_if_missing)
def convert_rdf_json_to_storage( definition, store_types=True, store_properties=True, store_bnodes=True, bnode_mappings=None ): """ Convert RDF JSON values into a storage payload. :param definition: dictionary containing the json data. :param store_types: should store the type values of the definition. :param store_properties: should store the property values of the definition. :param store_bnodes: should store the bnodes of the definition. :param bnode_mappings: dictionary containing a translation key for the bnodes. :return: newly created storage payload object. """ if not bnode_mappings: bnode_mappings = {} result = StoragePayload() for node_uri, values in definition.iteritems(): if node_uri == str(RDF.type): if store_types: for value in values: result.add_type(value["value"]) else: for value in values: if store_properties and value["type"] == "literal": result.add_property(node_uri, value["value"]) elif store_bnodes and value["type"] == "bnode": if value["value"] in bnode_mappings: result.add_reference(node_uri, bnode_mappings[value["value"]]) else: logger.error("Couldn't find bnode mapping for: %s" % value["value"]) return result
def _create_event(self, session, form_payload): """ Convert the form payload into a storage payload for creating a new event. :param session: :param form_payload: :return: """ create_event_payload = StoragePayload() create_event_payload.add_type(EVENT.Event) create_event_payload.add_reference(key=EVENT.agent, value=session['owner']) create_event_payload.add_reference(key=DCTERMS.creator, value=self._representation_manager.representation_uri) if 'title' in form_payload.get_values(): create_event_payload.add_property(key=DC.title, value=form_payload.get_values()['title']) if 'description' in form_payload.get_values(): create_event_payload.add_property(key=DC.description, value=form_payload.get_values()['description']) if session['location']: create_event_payload.add_reference(key=EVENT.place, value=session['location']) if session['interval']: create_event_payload.add_reference(key=EVENT.time, value=session['interval']) promise = self._storage_client.create_node(create_event_payload) return promise
def store_results(self, payload, session): """ Store the results into the database. :param payload: :param session: :return: """ logger.info('Payload: %s' % payload) logger.info('Session: %s' % session) storage_session = dict() if 'locations' in payload.get_values(): storage_payload = StoragePayload() storage_payload.about = payload.get_values()['locations'] storage_payload.add_type(WGS_84.SpatialThing) promise = self._get_or_lookup(storage_payload).then( self._scheduler.generate_promise_handler(self._update_session, storage_session, 'location')) else: promise = self._scheduler.defer(lambda: storage_session) promise = promise.then(self._get_owner) promise = promise.then(self._scheduler.generate_promise_handler(self._create_interval, payload)) promise = promise.then(self._scheduler.generate_promise_handler(self._create_event, payload)) promise = promise.then(lambda s: session) session['payload'] = None session['next'] = None session['has_next'] = False return promise
def command_start(self, request, initial_session): """ Provide the configuration details back to the requester and end the command. :param request: :param initial_session: :return: """ storage = StoragePayload() storage.add_type(FOAF.Person, RHO.Owner) promise = self._storage_client.find_nodes(storage) def find_nodes_processor(results): """ Process the results and place the payload into the initial session value. :param results: :return: the initial session value. """ initial_session['payload'] = results.populate_payload() return initial_session # Finish populating the rest of initial_session values. initial_session['next'] = None initial_session['has_next'] = False return promise.then(find_nodes_processor)
def _create_payload(self): update_payload = StoragePayload() update_payload.add_type(FOAF.Agent, RDFS.Resource) update_payload.add_property(RDFS.seeAlso, self.xmpp.get_uri()) update_payload.add_property(FOAF.name, self.xmpp.name) return update_payload
def test_handling(self): payload = StoragePayload() payload.add_type(WGS_84.SpatialThing) self.assertTrue(self.search_handler._process_payload(payload)) payload.add_type(FOAF.Agent) self.assertTrue(self.search_handler._process_payload(payload))
def _publish_update(self, storage_result): publish_payload = StoragePayload() publish_payload.about = storage_result.results[0].about publish_payload.add_type(*storage_result.results[0].types) self._node_id = publish_payload.about self._rdf_publish.publish_update(publish_payload)
def _start(self, event): payload = StoragePayload() payload.add_type(FOAF.Agent, RDFS.Resource) payload.add_property(RDFS.seeAlso, self.xmpp.get_uri()) promise = self._storage_client.find_nodes(payload) node_found_promise = promise.then(self._node_found) node_found_promise.then(self._update_node, self._create_node)
def test_sources_retrieved(self): publish_urn = 'rho:instances.owner' payload = StoragePayload() payload.add_type(FOAF.Person, RHO.Owner) promise = self.rdf_publisher.send_out_request(payload, allow_multiple=True) args, kwargs = self.roster_plugin.send_message.call_args payload = kwargs['payload'] thread_id = kwargs['thread_id'] args, kwargs = self.scheduler_plugin.schedule_task.call_args callback = kwargs['callback'] response_payload = ResultCollectionPayload() response_payload.append(ResultPayload(about=publish_urn, types=[FOAF.Person, RHO.Owner])) search_command_node = 'xmpp:[email protected]/bot?command;node=search_command' rdf_payload = self.rdf_publisher.create_rdf(mtype=RDFStanzaType.SEARCH_RESPONSE, payload=response_payload, source_name='Search Command', source_command=search_command_node) response_message = Message() response_message.append(rdf_payload) response_message['thread'] = thread_id with mock.patch.object(promise, attribute='resolved') as mock_promise_resolve: self.rdf_publisher._receive_message(response_message) mock_promise_resolve.assert_not_called() with mock.patch.object(promise, attribute='resolved') as mock_promise_resolve: callback() self.assertEqual(1, mock_promise_resolve.call_count) args, kwargs = mock_promise_resolve.call_args result_payload = args[0] result = [rdf.about for rdf in result_payload.results] self.assertEqual(result, [publish_urn, ]) self.assertTrue(hasattr(result_payload, 'sources')) sources = list(result_payload.sources) self.assertEqual(1, len(sources)) self.assertEqual('Search Command', sources[0][0]) self.assertEqual('xmpp:[email protected]/bot?command;node=search_command', sources[0][1])
def test_request_data_with_payload(self): foursquare_uri = 'foursquare://venues/4be0b4f0652b0f475f607311' storage_payload = StoragePayload() storage_payload.add_type(WGS_84.SpatialThing) storage_payload.add_property(RDFS.seeAlso, foursquare_uri) result = get_foursquare_venue(storage_payload) self.assertEqual(result, foursquare_uri.split('/')[-1])
def test_retrieve_all(self): publish_urn = 'rho:instances.owner' payload = StoragePayload() payload.add_type(FOAF.Person, RHO.Owner) promise = self.rdf_publisher.send_out_request(payload, allow_multiple=True) args, kwargs = self.roster_plugin.send_message.call_args payload = kwargs['payload'] thread_id = kwargs['thread_id'] args, kwargs = self.scheduler_plugin.schedule_task.call_args callback = kwargs['callback'] response_payload = ResultCollectionPayload() response_payload.append(ResultPayload(about=publish_urn, types=[FOAF.Person, RHO.Owner])) self.rdf_publisher._send_message(RDFStanzaType.RESPONSE, response_payload, thread_id) response_args, response_kwargs = self.roster_plugin.send_message.call_args payload = response_kwargs['payload'] response_message = Message() response_message.append(payload) response_message['thread'] = response_kwargs['thread_id'] with mock.patch.object(promise, attribute='resolved') as mock_promise_resolve: self.rdf_publisher._receive_message(response_message) mock_promise_resolve.assert_not_called() with mock.patch.object(promise, attribute='resolved') as mock_promise_resolve: self.rdf_publisher._receive_message(response_message) mock_promise_resolve.assert_not_called() with mock.patch.object(promise, attribute='resolved') as mock_promise_resolve: callback() self.assertEqual(1, mock_promise_resolve.call_count) args, kwargs = mock_promise_resolve.call_args result = [rdf.about for rdf in args[0].results] self.assertEqual(result, [publish_urn, publish_urn]) # Should not have any sources defined. callback_results = args[0] self.assertFalse(hasattr(callback_results, 'sources'))
def test_timeout_request(self): payload = StoragePayload() payload.add_type(FOAF.Person, RHO.Owner) promise = self.rdf_publisher.send_out_request(payload) args, kwargs = self.scheduler_plugin.schedule_task.call_args callback = kwargs['callback'] with mock.patch.object(target=promise, attribute='resolved') as mocked_method: callback() self.assertEqual(1, mocked_method.call_count) self.assertEqual([], mocked_method.call_args[0][0].results)
def publish_all_results(self, result_collection, created=True): """ Publish all of the results in the collection to the correct type. :param result_collection: collection to publish the results of. :return: """ for res in result_collection.results: publish_payload = StoragePayload() publish_payload.about = res.about publish_payload.add_type(*res.types) if created: self.publish_create(publish_payload) else: self.publish_update(publish_payload)
def test_multiple_responses(self): publish_urn = "rho:instances.owner" payload = StoragePayload() payload.add_type(FOAF.Person, RHO.Owner) promise = self.rdf_publisher.send_out_request(payload, allow_multiple=True) args, kwargs = self.roster_plugin.send_message.call_args payload = kwargs["payload"] thread_id = kwargs["thread_id"] args, kwargs = self.scheduler_plugin.schedule_task.call_args callback = kwargs["callback"] response_payload = ResultCollectionPayload() response_payload.append(ResultPayload(about=publish_urn, types=[FOAF.Person, RHO.Owner])) self.rdf_publisher._send_message(RDFStanzaType.RESPONSE, response_payload, thread_id) response_args, response_kwargs = self.roster_plugin.send_message.call_args payload = response_kwargs["payload"] response_message = Message() response_message.append(payload) response_message["thread"] = response_kwargs["thread_id"] with mock.patch.object(promise, attribute="resolved") as mock_promise_resolve: self.rdf_publisher._receive_message(response_message) mock_promise_resolve.assert_not_called() with mock.patch.object(promise, attribute="resolved") as mock_promise_resolve: self.rdf_publisher._receive_message(response_message) mock_promise_resolve.assert_not_called() with mock.patch.object(promise, attribute="resolved") as mock_promise_resolve: callback() self.assertEqual(1, mock_promise_resolve.call_count) args, kwargs = mock_promise_resolve.call_args result = [rdf.about for rdf in args[0].results] self.assertEqual(result, [publish_urn, publish_urn])
def command_start(self, request, initial_session): """ Provide the configuration details back to the requester and end the command. :param request: :param initial_session: :return: """ form = self._forms.make_form() form.add_field(var='title', label='Title', ftype='text-single') form.add_field(var='description', label='Description', ftype='text-multi') form.add_field(var='event_start', label='Start Time', ftype='text-single') form.add_field(var='event_stop', label='Stop Time', ftype='text-single') initial_session['payload'] = form initial_session['next'] = self.store_results initial_session['has_next'] = False def handle_results_from_search(results): options = [] results.results.sort(cmp=lambda x, y: cmp(x.get_column(str(GRAPH.degree))[0], y.get_column(str(GRAPH.degree))[0]), reverse=True) for result in results.results: options.append({'value': result.about, 'label': result.get_column(str(SCHEMA.name))[0]}) options = options[:10] location_field = form.add_field(var='locations', label='Location', ftype='list-single', options=options) if hasattr(results, 'sources'): for source in results.sources: source_stanza = RDFSourceStanza() source_stanza['name'] = source[0] source_stanza['command'] = source[1] location_field.append(source_stanza) return initial_session payload = StoragePayload() payload.add_type(WGS_84.SpatialThing) return self._rdf_publish.send_out_search(payload, timeout=2.0).then(handle_results_from_search)
def _process_lookup_result(self, result, payload): """ This will split the promise chain in two. If the result returns a value, then the promise will drop off. If the result doesn't exist, then do an rdf publish and return the result of that. :param result: the result of the get_command. :param payload: the payload that was used to look up the data. :return: a value or a promise that will return the value. """ if result.about: return result.about location_request = StoragePayload() location_request.add_type(*payload.types) location_request.add_property(RDFS.seeAlso, payload.about) promise = self._rdf_publish.send_out_request(location_request) promise.then(self._lookup_handler) return promise
def test_empty_handle_request(self): payload = StoragePayload() payload.add_type(FOAF.Person, RHO.Owner) self.rdf_publisher.send_out_request(payload) # Verify the payload request. self.assertEqual(1, self.roster_plugin.send_message.call_count) args, kwargs = self.roster_plugin.send_message.call_args payload = kwargs['payload'] message = Message() message.append(payload) message['thread'] = kwargs['thread_id'] # Test empty request. self.rdf_publisher._receive_message(message)
def command_start(self, iq, initial_session): """ Starting point for creating a new node. :param iq: :param initial_session: :return: """ if not initial_session['payload']: initial_session['notes'] = [('error', 'Cannot execute without a payload')] else: logger.info('Get Node iq: %s' % iq) logger.info('Initial_session: %s' % initial_session) payload = StoragePayload(initial_session['payload']) logger.debug('about: %s' % payload.about) node = self._command_handler.get_node(payload.about, create=False) if node: result_payload = StoragePayload() result_payload.about = node.uri # Get the types into place. for label in node.labels: result_payload.add_type(label) # Gather up all of the references for relationship in node.match_outgoing(): result_payload.add_reference(relationship.type, relationship.end_node.uri) # Gather up all of the properties for key, value in node.properties.iteritems(): if isinstance(value, list): for val in value: result_payload.add_property(key, val) else: result_payload.add_property(key, value) initial_session['payload'] = result_payload.populate_payload() return initial_session
def _get_owner(self, session): """ Fetch the owner of the system from the framework. :param session: :return: """ def _translate_search_to_about(result): if result.results: return result.results[0].about raise RuntimeError('Owner could not be found') search_payload = StoragePayload() search_payload.add_type(RHO.Owner, FOAF.Person) promise = self._rdf_publish.send_out_request(search_payload) promise = promise.then(_translate_search_to_about) promise = promise.then(self._scheduler.generate_promise_handler(self._update_session, session, 'owner')) return promise
def test_no_result(self): payload = StoragePayload() payload.add_type(FOAF.Person, RHO.Owner) self.rdf_publisher.send_out_request(payload) # Verify the payload request. self.assertEqual(1, self.roster_plugin.send_message.call_count) args, kwargs = self.roster_plugin.send_message.call_args payload = kwargs['payload'] message = Message() message.append(payload) message['thread'] = kwargs['thread_id'] handler_mock = mock.Mock(return_value=None) self.rdf_publisher.add_request_handler(handler_mock) self.rdf_publisher._receive_message(message)
def _get_owner(self, session): """ Look up the owner information from one of the other bots in the channel. :param session: session variable :return: """ logger.debug('Getting the owner information from other bot') payload = StoragePayload() payload.add_type(FOAF.Person, RHO.Owner) def set_owner_session(owner): logger.info('Configuring session owner') if owner.results: session['owner'] = owner.results[0].about else: raise RuntimeError('No owners defined') return session return self._rdf_publish.send_out_request(payload).then(set_owner_session)
def _update_node(self, node_identifier, start_time, end_time): """ Update the node and schedule the publishing of the update method. :param start_time: :param end_time: :return: """ payload = StoragePayload() payload.about = node_identifier payload.add_type(TIMELINE.Interval) if start_time: payload.add_property(TIMELINE.start, start_time) if end_time: payload.add_property(TIMELINE.end, end_time) promise = self._storage_client.update_node(payload) promise.then(self._scheduler.generate_promise_handler(self._rdf_publish.publish_all_results, created=False)) return promise.then(self._handle_result)