Ejemplo n.º 1
0
def dispatch(source, destinations):
    """Dispatch source file to destinations."""
    any_error = False
    # check that file actually exists
    if not os.path.exists(source):
        message = "Source file for dispatching does not exist:{}".format(
            str(source))
        logger.error(message)
        any_error = True
    success = {}
    # rename and send file with right protocol
    for url, params, client in destinations:
        # Multiple destinations for one client isn't implemented
        if client in success:
            raise NotImplementedError(
                "Only one destination allowed per client")
        try:
            logger.debug("Dispatching %s to %s", source, str(clean_url(url)))
            move_it(source, url, params)
            success[client] = True
        except Exception as err:
            message = "Could not dispatch to {}: {}".format(
                str(clean_url(url)), str(err))
            logger.error(message)
            any_error = True
            success[client] = False
    if not any_error:
        logger.info("Dispatched all files.")

    return success
Ejemplo n.º 2
0
    def ack(self, message):
        """Reply with ack to a publication
        """
        for url in gen_dict_extract(message.data, 'uri'):
            uri = urlparse(url)
            pathname = uri.path

            if 'origin' in self._attrs and not fnmatch.fnmatch(
                    os.path.basename(pathname),
                    os.path.basename(globify(self._attrs["origin"]))):
                LOGGER.warning('Client trying to get invalid file: %s', pathname)
                return Message(message.subject,
                               "err",
                               data="{0:s} not reacheable".format(pathname))

            if (self._attrs.get('compression') or self._attrs.get(
                    'delete', 'False').lower() in ["1", "yes", "true", "on"]):
                self._deleter.add(pathname)
        new_msg = Message(message.subject, "ack", data=message.data.copy())
        try:
            new_msg.data['destination'] = clean_url(new_msg.data[
                'destination'])
        except KeyError:
            pass
        return new_msg
Ejemplo n.º 3
0
def _get_cleaned_ack_message(message):
    new_msg = Message(message.subject, "ack", data=message.data.copy())
    try:
        new_msg.data['destination'] = clean_url(new_msg.data['destination'])
    except KeyError:
        pass

    return new_msg
Ejemplo n.º 4
0
def _sanitize_message_destination(message):
    sanitized_message = Message(rawstr=str(message))
    try:
        _ = urlparse(message.data['destination'])
    except (KeyError, TypeError):
        pass
    else:
        sanitized_message.data['destination'] = clean_url(
            message.data['destination'])
    return sanitized_message
Ejemplo n.º 5
0
    def push(self, message):
        """Reply to push request."""
        new_msg = self._move_files(message)
        if new_msg is None:
            new_msg = Message(message.subject,
                              _get_push_message_type(message),
                              data=message.data.copy())
            new_msg.data['destination'] = clean_url(
                new_msg.data['destination'])

        return new_msg
Ejemplo n.º 6
0
def dispatch(source, destinations):
    """Dispatch source file to destinations."""
    any_error = False
    # check that file actually exists
    if not os.path.exists(source):
        message = "Source file for dispatching does not exist:{}".format(
            str(source))
        logger.error(message)
        any_error = True
    # rename and send file with right protocol
    for url, params in destinations:
        try:
            logger.debug("Dispatching %s to %s", source, str(clean_url(url)))
            move_it(source, url, params)
        except Exception as err:
            message = "Could not dispatch to {}: {}".format(
                str(clean_url(url)), str(err))
            logger.error(message)
            any_error = True
    if not any_error:
        logger.info("Dispatched all files.")
Ejemplo n.º 7
0
    def run(self):
        while self._loop:
            try:
                socks = dict(self._poller.poll(timeout=2000))
            except ZMQError:
                LOGGER.info("Poller interrupted.")
                continue
            if socks.get(self.out_socket) == POLLIN:
                LOGGER.debug("Received a request")
                address, _, payload = self.out_socket.recv_multipart(
                    NOBLOCK)
                message = Message(rawstr=payload)
                fake_msg = Message(rawstr=str(message))
                try:
                    urlparse(message.data['destination'])
                except (KeyError, TypeError):
                    pass
                else:
                    fake_msg.data['destination'] = clean_url(message.data[
                        'destination'])

                LOGGER.debug("processing request: %s", str(fake_msg))
                if message.type == "ping":
                    Thread(target=self.reply_and_send,
                           args=(self.pong, address, message)).start()
                elif message.type == "push":
                    Thread(target=self.reply_and_send,
                           args=(self.push, address, message)).start()
                elif message.type == "ack":
                    Thread(target=self.reply_and_send,
                           args=(self.ack, address, message)).start()
                elif message.type == "info":
                    Thread(target=self.reply_and_send,
                           args=(self.info, address, message)).start()
                else:  # unknown request
                    Thread(target=self.reply_and_send,
                           args=(self.unknown, address, message)).start()
            elif socks.get(self.in_socket) == POLLIN:
                self.out_socket.send_multipart(
                    self.in_socket.recv_multipart(NOBLOCK))

            else:  # timeout
                pass
Ejemplo n.º 8
0
    def push(self, message):
        """Reply to push request
        """
        for the_dict in gen_dict_contains(message.data, 'uri'):
            uri = urlparse(the_dict['uri'])
            rel_path = the_dict.get('path', None)
            pathname = uri.path
            # FIXME: check against file_cache
            if 'origin' in self._attrs and not fnmatch.fnmatch(
                    os.path.basename(pathname),
                    os.path.basename(globify(self._attrs["origin"]))):
                LOGGER.warning('Client trying to get invalid file: %s', pathname)
                return Message(message.subject,
                               "err",
                               data="{0:s} not reachable".format(pathname))
            try:
                move_it(pathname, message.data['destination'], self._attrs, rel_path=rel_path)
            except Exception as err:
                return Message(message.subject, "err", data=str(err))
            else:
                if (self._attrs.get('compression') or self._attrs.get(
                        'delete', 'False').lower() in ["1", "yes", "true", "on"]):
                    self._deleter.add(pathname)

            if 'dataset' in message.data:
                mtype = 'dataset'
            elif 'collection' in message.data:
                mtype = 'collection'
            elif 'uid' in message.data:
                mtype = 'file'
            else:
                raise KeyError('No known metadata in message.')

        new_msg = Message(message.subject,
                          mtype,
                          data=message.data.copy())
        new_msg.data['destination'] = clean_url(new_msg.data[
            'destination'])
        return new_msg
Ejemplo n.º 9
0
def move_it(pathname, destination, attrs=None, hook=None, rel_path=None):
    """Check if the file pointed by *pathname* is in the filelist, and move it
    if it is.

    The *destination* provided is used, and if *rel_path* is provided, it will
    be appended to the destination path.

    """
    dest_url = urlparse(destination)
    if rel_path is not None:
        new_path = os.path.join(dest_url.path, rel_path)
    else:
        new_path = dest_url.path
    new_dest = dest_url._replace(path=new_path)
    fake_dest = clean_url(new_dest)

    LOGGER.debug("new_dest = %s", new_dest)
    LOGGER.debug("Copying to: %s", fake_dest)
    try:
        LOGGER.debug("Scheme = %s", str(dest_url.scheme))
        mover = MOVERS[dest_url.scheme]
    except KeyError:
        LOGGER.error("Unsupported protocol '" + str(dest_url.scheme) +
                     "'. Could not copy " + pathname + " to " +
                     str(destination))
        raise

    try:
        mover(pathname, new_dest, attrs=attrs).copy()
        if hook:
            hook(pathname, new_dest)
    except Exception as err:
        exc_type, exc_value, exc_traceback = sys.exc_info()
        LOGGER.error("Something went wrong during copy of %s to %s: %s",
                     pathname, str(fake_dest), str(err))
        LOGGER.debug("".join(traceback.format_tb(exc_traceback)))
        raise err
    else:
        LOGGER.info("Successfully copied %s to %s", pathname, str(fake_dest))