예제 #1
0
 def make_subdata_cmd(self,
                      prefix,
                      dataname,
                      seq,
                      lifetime=None,
                      subinfo: SubInfo = None) -> (str, Any):
     """
     make subdata command
     :param prefix: datarn_prefix
     :type prefix: str
     :param dataname: dataname
     :type dataname: str
     :param seq: sequence no.
     :type seq: int
     :param subinfo: subinfo
     :type subinfo: SubInfo
     :return: command, interest_param, app_param
     """
     # make a subdatareq command name with args
     #command = Name.to_str(prefix + "/" + CMD_SUBDATAREQ + dataname + f'/{seq:d}')
     command = prefix + "/" + PSKCmd.commands[
         "CMD_SD"] + dataname + "/" + str(seq)
     # set interest parameter
     i_param = InterestParam()
     i_param.must_be_fresh = True
     i_param.nonce = gen_nonce()
     i_param.lifetime = (lifetime if lifetime else INT_LT_10)
     # make a app_params for subscription
     param = PSKParameters(subinfo=subinfo)
     str_app_param = json.dumps(param, default=serialize)
     return command, i_param, bytes(str_app_param, 'utf-8')
예제 #2
0
 def make_irdel_cmd(self,
                    prefix,
                    dataname,
                    rawpacket: BinaryStr = None) -> (str, Any):
     """
     make irdel command
     :param prefix: ir_prefix
     :type prefix: str
     :param dataname: dataname
     :type dataname: str
     :param rawpacket: raw interest packet
     :type bytes: 
     :return: command, interest_param, app_param
     """
     # make a irmod command name with args
     command = prefix + "/" + PSKCmd.commands["CMD_MD"] + dataname
     # set interest parameter
     i_param = InterestParam()
     i_param.must_be_fresh = True
     i_param.nonce = gen_nonce()
     i_param.lifetime = INT_LT_4
     # make app_param for Infomation Registry (raw interest packet)
     str_rawpacket = rawpacket.decode('utf-8')
     param = PSKParameters(rawpacket=str_rawpacket)
     str_app_param = json.dumps(param, default=serialize)
     return command, i_param, bytes(str_app_param, 'utf-8')
예제 #3
0
 def make_pubdata_cmd(self,
                      prefix,
                      dataname,
                      seq,
                      pubdatainfo: PubDataInfo = None) -> (str, Any):
     """
     make pubdata command
     :param prefix: network_prefix
     :type prefix: str
     :param dataname: dataname for publishing data
     :type dataname: str
     :param seq: sequence no.
     :type seq: int
     :param pubed_data: pubed data
     :type pubed_data: any
     :return: command, interest_param, app_param
     """
     # make a pubdata command name with args
     command = prefix + "/" + PSKCmd.commands[
         "CMD_PD"] + dataname + '/' + str(seq)
     # set interest parameter
     i_param = InterestParam()
     i_param.must_be_fresh = True
     i_param.nonce = gen_nonce()
     i_param.lifetime = INT_LT_4
     param = PSKParameters(pubdatainfo=pubdatainfo)
     str_app_param = json.dumps(param, default=serialize)
     return command, i_param, bytes(str_app_param, 'utf-8')
예제 #4
0
 def make_subtopic_cmd(self,
                       prefix,
                       dataname,
                       subinfo: SubInfo = None) -> (str, Any):
     """
     make subtopic command
     :param prefix: network_prefix or topicrn_prefix
     :type prefix: str
     :param dataname: topic name
     :type dataname: str
     :param subinfo: subscription information
     :type subinfo: SubInfo
     :return: command, interest_param, app_param
     """
     # make a subtopic command name with args
     command = prefix + "/" + PSKCmd.commands["CMD_ST"] + dataname
     # set interest parameter
     i_param = InterestParam()
     i_param.must_be_fresh = True
     i_param.nonce = gen_nonce()
     i_param.lifetime = INT_LT_10
     # make a app_params for subscription
     param = PSKParameters(subinfo=subinfo)
     str_app_param = json.dumps(param, default=serialize)
     return command, i_param, bytes(str_app_param, 'utf-8')
예제 #5
0
 def make_pubadv_cmd(self,
                     prefix: str,
                     dataname: str,
                     pubadvinfo: PubAdvInfo = None,
                     irinfo: IRInfo = None,
                     rninfo: RNInfo = None) -> (str, Any):
     """
     make pubadv command
     :param prefix: network_prefix or broker_prefix
     :type prefix: str
     :param dataname: dataname for publishing data
     :type dataname: str
     :param pubinfo: pubadvinfo
     :type pubinfo: PubAdvInfo
     :param irinfo: irinfo
     :type irinfo: IRInfo
     :param rninfo: rninfo
     :type rninfo: RNInfo
     :return: command, interest_param, app_param
     """
     # make a pubadv command name with args
     #command = Name.to_str(prefix + "/" + CMD_PUBADV + dataname)
     command = prefix + "/" + PSKCmd.commands["CMD_PA"] + dataname
     # set interest parameter
     i_param = InterestParam()
     i_param.must_be_fresh = True
     i_param.nonce = gen_nonce()
     i_param.lifetime = INT_LT_10
     param = PSKParameters(pubadvinfo=pubadvinfo,
                           irinfo=irinfo,
                           rninfo=rninfo)
     str_app_param = json.dumps(param, default=serialize)
     return command, i_param, bytes(str_app_param, 'utf-8')
예제 #6
0
    async def add(self, data_name: str, hash: str, desired_copies: int = 3):

        try:
            sql_command = "INSERT INTO data (data_name, hash, desired_copies) VALUES ({0}, {1}, {2});".format(
                data_name, hash, desired_copies)
            name = self.catalog_prefix + "/" + sql_command + "/" + str(
                gen_nonce())
            data_name, meta_info, content = await self.app.express_interest(
                name, must_be_fresh=True, can_be_prefix=False, lifetime=1000)
            print(f'Received Data Name: {Name.to_str(data_name)}')
            print(meta_info)
            print(bytes(content) if content else None)
        except InterestNack as e:
            # A NACK is received
            print(f'Nacked with reason={e.reason}')
        except InterestTimeout:
            # Interest times out
            print(f'Timeout')
        except InterestCanceled:
            # Connection to NFD is broken
            print(f'Canceled')
        except ValidationFailure:
            # Validation failure
            print(f'Data failed to validate')
        finally:
            self.app.shutdown()
예제 #7
0
    async def _check(self, repo_name: str, catalog_name: str, method: str):

        cmd_param = CatalogRequestParameter()
        cmd_param.data_name = 'data1'
        cmd_param_bytes = cmd_param.encode()

        name = Name.from_str(catalog_name)
        name += [method]
        name += [str(gen_nonce())]
        try:
            _, _, data_bytes = await self.app.express_interest(
                name,
                app_param=cmd_param_bytes,
                must_be_fresh=True,
                can_be_prefix=False,
                lifetime=10000)
            data_recvd = bytes(data_bytes)
            assert bytes(repo_name) == data_recvd
        except InterestNack:
            print(">>>NACK")
            return None
        except InterestTimeout:
            print(">>>TIMEOUT")
            return None
        finally:
            app.shutdown()
예제 #8
0
 def make_generic_cmd(self,
                      command: str,
                      prefix: str,
                      dataname: str = "/_",
                      pubadvinfo: PubAdvInfo = None,
                      irinfo: IRInfo = None,
                      rninfo: RNInfo = None,
                      **kwargs) -> (str, Any):
     """
     make generic command
     :param prefix: network_prefix or broker_prefix
     :type prefix: str
     :param dataname: dataname for publishing data
     :type dataname: str
     :param pubinfo: pubadvinfo
     :type pubinfo: PubAdvInfo
     :param irinfo: irinfo
     :type irinfo: IRInfo
     :param rninfo: rninfo
     :type rninfo: RNInfo
     :return: command, interest_param, app_param
     """
     command = prefix + "/" + command + dataname
     # set interest parameter
     i_param = InterestParam()
     i_param.must_be_fresh = True
     i_param.nonce = gen_nonce()
     i_param.lifetime = INT_LT_10
     param = PSKParameters(pubadvinfo=pubadvinfo,
                           irinfo=irinfo,
                           rninfo=rninfo,
                           **kwargs)
     str_app_param = json.dumps(param, default=serialize)
     return command, i_param, bytes(str_app_param, 'utf-8')
    async def delete_file(self,
                          prefix: NonStrictName,
                          start_block_id: int = None,
                          end_block_id: int = None) -> int:
        """
        Delete from repo packets between "<name_at_repo>/<start_block_id>" and\
            "<name_at_repo>/<end_block_id>" inclusively.

        :param prefix: NonStrictName. The name of the file stored in the remote repo.
        :param start_block_id: int. Default value is 0.
        :param end_block_id: int. If not specified, repo will attempt to delete all data packets\
            with segment number starting from `start_block_id` continously.
        :return: Number of deleted packets.
        """
        # send command interest
        cmd_param = RepoCommandParameter()
        cmd_param.name = prefix
        cmd_param.start_block_id = start_block_id
        cmd_param.end_block_id = end_block_id
        cmd_param.register_prefix = prefix
        process_id = gen_nonce()
        cmd_param.process_id = process_id
        cmd_param_bytes = cmd_param.encode()

        # publish msg to repo's delete topic
        await self.pb.wait_for_ready()
        self.pb.publish(self.repo_name + ['delete'], cmd_param_bytes)

        # wait until repo delete all data
        return await self._wait_for_finish(process_id)
예제 #10
0
async def send(app: NDNApp, name: FormalName):
    logging.info('Interest Sent: {}'.format(Name.to_str(name)))
    try:
        data_name, meta_info, content = await app.express_interest(
            name,
            must_be_fresh=True,
            can_be_prefix=False,
            nonce=gen_nonce(),
            lifetime=1000)
        # Print out Data Name, MetaInfo and its conetnt.
        logging.info('Data Received: {}'.format(Name.to_str(data_name)))
    except InterestNack as e:
        # A NACK is received
        logging.warning(f'Interest Nacked with reason={e.reason}\n')
    except InterestTimeout:
        # Interest times out
        logging.warning(f'Interest Timeout\n')
    finally:
        app.shutdown()
    async def insert_file(self, file_path: str, name_at_repo: NonStrictName,
                          segment_size: int, freshness_period: int,
                          cpu_count: int) -> int:
        """
        Insert a file to remote repo.

        :param file_path: Local FS path to file to insert.
        :param name_at_repo: NonStrictName. Name used to store file at repo.
        :param segment_size: Max size of data packets.
        :param freshness_period: Freshness of data packets.
        :param cpu_count: Cores used for converting file to TLV format.
        :return: Number of packets inserted.
        """
        self._prepare_data(file_path, name_at_repo, segment_size,
                           freshness_period, cpu_count)
        num_packets = len(self.encoded_packets)
        if num_packets == 0:
            return

        # Register prefix for responding interests from repo
        await self.app.register(name_at_repo, self._on_interest)

        # construct insert cmd msg
        cmd_param = RepoCommandParameter()
        cmd_param.name = name_at_repo
        cmd_param.start_block_id = 0
        cmd_param.end_block_id = num_packets - 1
        cmd_param.register_prefix = name_at_repo
        process_id = gen_nonce()
        cmd_param.process_id = process_id
        cmd_param_bytes = cmd_param.encode()

        # publish msg to repo's insert topic
        await self.pb.wait_for_ready()
        self.pb.publish(self.repo_name + ['insert'], cmd_param_bytes)
        logging.info('published an insert msg')

        # wait until finish so that repo can finish fetching the data
        return await self._wait_for_finish(process_id)
예제 #12
0
    async def _check(self, method: str, catalog_name: str):
        cmd_param = CatalogCommandParameter()
        cmd_param.repo_name = self.prefix
        cmd_param_bytes = cmd_param.encode()

        name = Name.from_str(catalog_name)
        name += [method]
        name += [str(gen_nonce())]
        print(">>>>>>>>>", Name.to_str(name))
        try:
            _, _, data_bytes = await self.app.express_interest(
                name,
                app_param=cmd_param_bytes,
                must_be_fresh=True,
                can_be_prefix=True)
            print(">>> ACK RECVD: ", bytes(data_bytes))

        except InterestNack:
            print(">>>NACK")
            return None
        except InterestTimeout:
            print(">>>TIMEOUT")
            return None
    async def _publish_helper(self, topic: NonStrictName, msg: bytes):
        """
        Async helper for `subscribe()``.
        """
        logging.info(f'publishing a message to topic: {Name.to_str(topic)}')
        # generate a nonce for each message
        nonce = gen_nonce()
        self.nonce_to_msg[nonce] = msg

        # prepare notify interest
        int_name = topic + ['notify']
        app_param = PubSub.NotifyAppParam()
        app_param.publisher_prefix = self.prefix
        app_param.nonce = nonce
        if self.forwarding_hint:
            app_param.forwarding_hint = self.forwarding_hint

        aio.ensure_future(self._erase_state_after(nonce, 5))

        # express notify interest
        try:
            logging.debug(f'sending notify interest: {Name.to_str(int_name)}')
            data_name, meta_info, content = await self.app.express_interest(
                int_name,
                app_param.encode(),
                must_be_fresh=False,
                can_be_prefix=False)
        except InterestNack as e:
            logging.debug(f'Nacked with reason: {e.reason}')
            return
        except InterestTimeout:
            logging.debug(f'Timeout')
            return

        # if receiving notify response, the subscriber has finished fetching msg
        logging.debug(f'received notify response: {data_name}')
        await self._erase_state_after(nonce, 0)
예제 #14
0
    async def run(self):
        await aio.sleep(1)  # wait for repo to startup

        # respond to interest from repo
        def on_int(int_name, _int_param, _app_param):
            self.app.put_data(int_name, b'foobar', freshness_period=1000)

        await self.app.register('test_name', on_int)

        # construct insert parameter
        cmd_param = RepoCommandParameter()
        cmd_param.name = 'test_name'
        cmd_param.start_block_id = None
        cmd_param.end_block_id = None
        process_id = gen_nonce()
        cmd_param.process_id = process_id
        cmd_param_bytes = cmd_param.encode()

        pb = PubSub(self.app, Name.from_str('/putfile_client'))
        await pb.wait_for_ready()
        pb.publish(Name.from_str(repo_name) + ['insert'], cmd_param_bytes)

        # insert_num should be 1
        checker = CommandChecker(self.app)
        n_retries = 3
        while n_retries > 0:
            response = await checker.check_insert(Name.from_str(repo_name),
                                                  process_id)
            if response.status_code == 404:
                n_retries -= 1
            elif response.status_code != 300:
                assert response.status_code == 200
                assert response.insert_num == 1
                break
            await aio.sleep(1)
        self.app.shutdown()
예제 #15
0
 def make_pubunadv_cmd(self,
                       prefix,
                       dataname,
                       pubadvinfo: PubAdvInfo = None) -> (str, Any):
     """
     make pubunadv command
     :param prefix: network_prefix or broker_prefix
     :type prefix: str
     :param dataname: dataname for unpublishing data
     :type dataname: str
     :param pubadvinfo: pub information
     :type pubadvinfo: 
     :return: command, interest_param, app_param
     """
     # make a pubunadv command name with args
     command = prefix + "/" + PSKCmd.commands["CMD_PU"] + dataname
     # set interest parameter
     i_param = InterestParam()
     i_param.must_be_fresh = True
     i_param.nonce = gen_nonce()
     i_param.lifetime = INT_LT_10
     param = PSKParameters(pubadvinfo=pubadvinfo)
     str_app_param = json.dumps(param, default=serialize)
     return command, i_param, bytes(str_app_param, 'utf-8')
 async def send_repo_command(self, node_prefix : NonStrictName, verb : str , datainfo : DatainfoTlvModel):
     # "/a/b" -> list of bytearrays
     name = Name.normalize(node_prefix)
     # "/a/b" -> "/a/b/insert"
     name.append(Component.from_str(verb))
     datainfo_name_component = Component.from_bytes(datainfo.encode())
     name.append(datainfo_name_component)
     logging.info('Interest Sent: {}'.format(Name.to_str(name)))
     try:
         data_name, meta_info, content = await self.app.express_interest(name, must_be_fresh=True, can_be_prefix=False, nonce=gen_nonce(), lifetime=1000)
         logging.info('Data Received: {}\n'.format(Name.to_str(data_name)))
         # print(meta_info)
         # print(bytes(content) if content else None)
     except InterestNack as e:
         # A NACK is received
         logging.warning(f'Interest Nacked with reason={e.reason}\n')
         return 0
     except InterestTimeout:
         # Interest times out
         logging.warning(f'Interest Timeout\n')
         return 0
     # results = self.parse_results(content)
     # logging.info(results)
     return 1
예제 #17
0
    def express_interest(
        self,
        name: NonStrictName,
        app_param: Optional[BinaryStr] = None,
        validator: Optional[Validator] = None,
        need_raw_packet: bool = False,
        **kwargs
    ) -> Coroutine[Any, None, Tuple[FormalName, MetaInfo,
                                    Optional[BinaryStr]]]:
        r"""
        Express an Interest packet.

        The Interest packet is sent immediately and a coroutine used to get the result is returned.
        Awaiting on what is returned will block until the Data is received and return that Data.
        An exception is raised if unable to receive the Data.

        :param name: the Name.
        :type name: :any:`NonStrictName`
        :param app_param: the ApplicationParameters.
        :type app_param: Optional[:any:`BinaryStr`]
        :param validator: the Validator used to verify the Data received.
        :type validator: Optional[:any:`Validator`]
        :param need_raw_packet: if True, return the raw Data packet with TL.
        :type need_raw_packet: bool
        :param kwargs: :ref:`label-keyword-arguments`.
        :return: A tuple of (Name, MetaInfo, Content) after ``await``.
            If need_raw_packet is True, return a tuple (Name, MetaInfo, Content, RawPacket).
        :rtype: Coroutine[Any, None, Tuple[:any:`FormalName`, :any:`MetaInfo`, Optional[:any:`BinaryStr`]]]

        The following exception is raised by ``express_interest``:

        :raises NetworkError: the face to NFD is down before sending this Interest.

        The following exceptions are raised by the coroutine returned:

        :raises InterestNack: an NetworkNack is received.
        :raises InterestTimeout: time out.
        :raises ValidationFailure: unable to validate the Data packet.
        :raises InterestCanceled: the face to NFD is shut down after sending this Interest.
        """
        if not self.face.running:
            raise NetworkError('cannot send packet before connected')
        if 'signer' in kwargs:
            signer = kwargs['signer']
        elif app_param is not None:
            signer = self.keychain.get_signer(kwargs)
        else:
            signer = None
        if 'interest_param' in kwargs:
            interest_param = kwargs['interest_param']
        else:
            if 'nonce' not in kwargs:
                kwargs['nonce'] = gen_nonce()
            interest_param = InterestParam.from_dict(kwargs)
        interest, final_name = make_interest(name,
                                             interest_param,
                                             app_param,
                                             signer=signer,
                                             need_final_name=True)
        future = aio.get_event_loop().create_future()
        node = self._int_tree.setdefault(final_name, InterestTreeNode())
        node.append_interest(future, interest_param)
        self.face.send(interest)
        return self._wait_for_data(future, interest_param.lifetime, final_name,
                                   node, validator, need_raw_packet)