예제 #1
0
class Worker(multiprocessing.Process):
    def __init__(self, worker_id, transfer_type, signal_host, target_host,
                 port, number_of_files):
        super().__init__()

        self.id = worker_id
        self.basepath = os.path.join(BASE_DIR, "data", "target")
        self.number_of_files = number_of_files

        self.port = port

        print("start Transfer on port", port)
        self.query = Transfer(transfer_type, signal_host, use_log=None)
        self.query.start([target_host, port])

        self.run()

    def run(self):
        try:
            while True:
                # print("Worker-{0}: waiting".format(self.id))
                [metadata, data] = self.query.get()
                if metadata and data:
                    self.number_of_files.value += 1
        finally:
            self.stop()

    def stop(self):
        self.query.stop()

    def __exit__(self):
        self.stop()

    def __del__(self):
        self.stop()
예제 #2
0
def main():
    """Requests data from hidra on a query basis.
    """

    parser = argparse.ArgumentParser()

    parser.add_argument("--signal_host",
                        type=str,
                        help="Host where HiDRA is running",
                        default=socket.getfqdn())
    parser.add_argument("--target_host",
                        type=str,
                        help="Host where the data should be send to",
                        default=socket.getfqdn())

    arguments = parser.parse_args()

    targets = [[arguments.target_host, "50101", 1]]

    print("\n==== TEST: Query for the newest filename ====\n")

    query = Transfer("QUERY_NEXT", arguments.signal_host, use_log="debug")

    query.initiate(targets)

    try:
        query.start()
    except Exception:
        query.stop()
        return

    timeout = None
#    timeout = 2000  # in ms

    try:
        while True:
            [metadata, data] = query.get(timeout)

            print()
            if metadata and data:
                print("metadata", metadata["filename"])
                print("data", data)

            else:
                print("metadata", metadata)
                print("data", data)
            print()
    finally:
        query.stop()

        print("\n==== TEST END: Query for the newest filename ====\n")
예제 #3
0
def main():
    """Requests data from hidra on a query basis.
    """
    arguments = get_arguments()

    if arguments.debug:
        use_log = "debug"
        print("Using debug mode")
    else:
        use_log = False  # pylint: disable=redefined-variable-type

    targets = [[arguments.target_host, "50101", 1, ".*(tif|cbf)$"]]
    detector_id = socket.getfqdn()  # the hidra instance to connect to

    print("\n==== TEST: Query for the newest filename ====\n")

    query = Transfer("QUERY_NEXT",
                     arguments.signal_host,
                     use_log=use_log,
                     detector_id=detector_id)

    query.initiate(targets)

    try:
        query.start()
    except Exception:
        query.stop()
        return

    timeout = None
    #    timeout = 2000  # in ms

    while True:
        try:
            [metadata, data] = query.get(timeout)
        except Exception:
            print(sys.exc_info())
            break

        print()
        if metadata and data:
            print("metadata", metadata["filename"])
            print("data", str(data)[:10])
        else:
            print("metadata", metadata)
            print("data", data)
        print()

    query.stop()

    print("\n==== TEST END: Query for the newest filename ====\n")
예제 #4
0
def main():
    """Connect to hidra and get the streamed metadata.
    """

    parser = argparse.ArgumentParser()

    parser.add_argument("--signal_host",
                        type=str,
                        help="Host where HiDRA is running",
                        default=socket.getfqdn())
    parser.add_argument("--target_host",
                        type=str,
                        help="Host where the data should be send to",
                        default=socket.getfqdn())
    parser.add_argument("--detector_id",
                        type=str,
                        help="Which detector to get data from",
                        default=socket.getfqdn())

    arguments = parser.parse_args()

    #    targets = [arguments.target_host, "50101", 0]
    targets = [[arguments.target_host, "50101", 0, ".*(tif|cbf)$"]]
    #    targets = [[arguments.target_host, "50101", 0, [".tif", ".cbf"]]]

    print("\n==== TEST: Stream all files ====\n")

    query = Transfer("STREAM_METADATA",
                     signal_host=arguments.signal_host,
                     detector_id=arguments.detector_id)

    query.initiate(targets)

    query.start()

    while True:
        try:
            print("waiting to get metadata")
            [metadata, _] = query.get()
        except Exception:
            break

        print()
        print("metadata", metadata["filename"])
        #    print ("data", str(data)[:10])
        print()

    query.stop()

    print("\n==== TEST END: Stream all files ====\n")
예제 #5
0
def main():
    """Connect to hidra and get streamed data.
    """

    parser = argparse.ArgumentParser()

    parser.add_argument("--signal_host",
                        type=str,
                        help="Host where HiDRA is running",
                        default=socket.getfqdn())
    parser.add_argument("--target_host",
                        type=str,
                        help="Host where the data should be send to",
                        default=socket.getfqdn())

    arguments = parser.parse_args()

    #    targets = [arguments.target_host, "50101", 0]
    targets = [[arguments.target_host, "50101", 0, ".*(tif|cbf)$"]]
    #    targets = [[arguments.target_host, "50101", 0, [".tif", ".cbf"]]]

    print("\n==== TEST: Stream all files ====\n")

    query = Transfer("STREAM", arguments.signal_host)

    query.initiate(targets)

    query.start()

    while True:
        try:
            [metadata, data] = query.get()
        except Exception:
            break

        print()
        print("metadata", metadata["filename"])
        print("data", len(data))
        print()

    query.stop()

    print("\n==== TEST END: Stream all files ====\n")
예제 #6
0
def main():
    """Connects to hidra and stores the streamed data to disk.
    """

    parser = argparse.ArgumentParser()

    parser.add_argument("--signal_host",
                        type=str,
                        help="Host where HiDRA is running",
                        default=socket.getfqdn())
    parser.add_argument("--target_host",
                        type=str,
                        help="Host where the data should be send to",
                        default=socket.getfqdn())

    arguments = parser.parse_args()

    # enable logging
    logfile_path = os.path.join(BASE_DIR, "logs")
    logfile = os.path.join(logfile_path, "testAPI.log")
    utils.init_logging(logfile, True, "DEBUG")

    targets = [arguments.target_host, "50100", 0]

    print("\n==== TEST: Stream all files and store them ====\n")

    query = Transfer("STREAM", arguments.signal_host, use_log=True)

    query.initiate(targets)

    query.start()

    target_dir = os.path.join(BASE_DIR, "data", "zmq_target")
    target_file = os.path.join(target_dir, "test_store")
    try:
        query.store(target_file)
    except Exception as excp:
        print("Storing data failed.")
        print("Error was:", excp)

    query.stop()

    print("\n==== TEST END: Stream all files and store them ====\n")
예제 #7
0
def nexus_transfer():
    obj = Transfer("NEXUS", use_log=True)
    obj.start([socket_m.getfqdn(), "50100"])

    callback_params = {"run_loop": True}

    # number to receive + open signal + close signal
    try:
        while callback_params["run_loop"]:
            try:
                obj.read(callback_params, open_callback, read_callback,
                         close_callback)
            except KeyboardInterrupt:
                break
            except Exception:
                logging.error("nexus_transfer break", exc_info=True)
                break
    finally:
        obj.stop()
예제 #8
0
def main():
    """Connects to hidra and request metadata.
    """

    parser = argparse.ArgumentParser()

    parser.add_argument("--signal_host",
                        type=str,
                        help="Host where HiDRA is running",
                        default=socket.getfqdn())
    parser.add_argument("--target_host",
                        type=str,
                        help="Host where the data should be send to",
                        default=socket.getfqdn())

    arguments = parser.parse_args()

    targets = [[arguments.target_host, "50101", 0]]
    base_target_path = os.path.join(BASE_DIR, "data", "target")

    print("\n==== TEST: Query for the newest filename ====\n")

    query = Transfer("QUERY_NEXT_METADATA", arguments.signal_host)

    query.initiate(targets)

    query.start()

    try:
        while True:
            try:
                [metadata, _] = query.get()
            except Exception:
                query.stop()
                raise

            print()
            print(generate_filepath(base_target_path, metadata))
            print()
    finally:
        query.stop()
        print("\n==== TEST END: Query for the newest filename ====\n")
예제 #9
0
class Worker(multiprocessing.Process):
    """Start a connection to hidra an get a data block.
    """
    def __init__(self, identifier, transfer_type, signal_host, target_host,
                 port):  # noqa F811

        super().__init__()

        self.identifier = identifier
        self.port = port

        self.query = Transfer(transfer_type, signal_host, use_log=False)

        # Set up ZeroMQ for this worker
        print("start Transfer on port {0}".format(port))
        self.query.start([target_host, port])

        self.run()

    def run(self):
        while True:
            try:
                # Get new data
                print("Worker-{0}: waiting".format(self.identifier))
                [metadata, data] = self.query.get()
            except Exception:
                break

            print("metadata", metadata)
            print("data", str(data)[:100])

    def stop(self):
        """Clean up:
        """
        self.query.stop()

    def __exit__(self, exception_type, exception_value, traceback):
        self.stop()

    def __del__(self):
        self.stop()
예제 #10
0
def main():
    """
    The fixes target is configured on the sender side. Start up receiving side.
    """

    # enable logging
    logfile_path = os.path.join(BASE_DIR, "logs")
    logfile = os.path.join(logfile_path, "test_fixedStream.log")
    utils.init_logging(logfile, True, "DEBUG")

    data_port = "50100"

    print("\n==== TEST: Fixed stream ====\n")

    query = Transfer("STREAM", use_log=True)

    query.start(data_port)

    while True:
        try:
            [metadata, data] = query.get()
        except KeyboardInterrupt:
            break
        except Exception as excp:
            print("Getting data failed.")
            print("Error was: {0}".format(excp))
            break

        print()
        try:
            print("metadata of file", metadata["filename"])
            print("data", str(data)[:10])
        except TypeError:
            print("metadata", metadata)
        print()

    query.stop()

    print("\n==== TEST END: Fixed Stream ====\n")
예제 #11
0
def main():
    sender_thread = SenderAsThread()
    sender_thread.start()

    obj = Transfer("NEXUS", use_log=True)
    obj.start([socket_m.get_fqdn(), "50100"])

    callback_params = {"run_loop": True}

    try:
        while callback_params["run_loop"]:
            try:
                obj.read(callback_params, open_callback, read_callback,
                         close_callback)
            except KeyboardInterrupt:
                break
            except Exception:
                logging.error("break", exc_info=True)
                break
    finally:
        sender_thread.stop()
        obj.stop()

    print("\n==== TEST END: nexus transfer ====\n")
예제 #12
0
def main():
    """Requests data from hidra on a query basis.
    """

    parser = argparse.ArgumentParser()

    parser.add_argument("--signal_host",
                        type=str,
                        help="Host where HiDRA is running",
                        default=socket.getfqdn())
    parser.add_argument("--target_host",
                        type=str,
                        help="Host where the data should be send to",
                        default=socket.getfqdn())
    parser.add_argument("--detector_id",
                        type=str,
                        help="Used for connection with control server",
                        default=None)
    parser.add_argument("--query_type",
                        type=str,
                        help="Query type like QUERY_NEXT",
                        default=True)
    parser.add_argument("--max_queries",
                        type=int,
                        help="Maximum number of queries",
                        default=None)
    parser.add_argument("--timeout",
                        type=int,
                        help="Timeout for get call",
                        default=2000)

    args = parser.parse_args()

    targets = [[args.target_host, "50101", 1, ".*(tif|cbf)$"]]

    timeout = args.timeout

    query = Transfer(args.query_type,
                     signal_host=args.signal_host,
                     detector_id=args.detector_id,
                     use_log="DEBUG")  # should use the logging module

    query.initiate(targets)

    try:
        query.start()
    except Exception:
        query.stop()
        return

    print("Begin query...", file=sys.stderr)
    count = 0
    while args.max_queries is None or count < args.max_queries:
        count += 1
        try:
            [metadata, data] = query.get(timeout)
        except Exception:
            print(sys.exc_info(), file=sys.stderr)
            break

        if metadata and data != "null":
            md5sum = hashlib.md5()
            md5sum.update(data)
            print("{}: {}".format(get_filename(metadata), md5sum.hexdigest()))
        elif metadata:
            print("{}: null".format(get_filename(metadata)))
            break
        else:
            break

    query.stop()
예제 #13
0
class DataFetcher(DataFetcherBase):
    """
    Implementation of the data fetcher reacting on data sent by another
    hidra instance.
    """
    def __init__(self, datafetcher_base_config):
        """Initial setup

        Checks if all required parameters are set in the configuration
        """

        self.f_descriptors = dict()
        self.transfer = None

        DataFetcherBase.__init__(self, datafetcher_base_config, name=__name__)

        # base class sets
        #   self.config_all - all configurations
        #   self.config_df - the config of the datafetcher
        #   self.config - the module specific config
        #   self.df_type -  the name of the datafetcher module
        #   self.log_queue
        #   self.log

        self.metadata_r = None
        self.data_r = None

        self.set_required_params()

        # check that the required_params are set inside of module specific
        # config
        self.check_config()

        self._setup()

    def set_required_params(self):
        """
        Defines the parameters to be in configuration to run this data fetcher.
        Depending if on Linux or Windows other parameters are required.
        """

        self.required_params = {
            "network": ["ext_ip"],
        }

        df_params = [
            "status_check_resp_port", "confirmation_resp_port", "context"
        ]

        if utils.is_windows():
            df_params += ["datafetcher_port"]
        else:
            self.required_params["network"] += ["ipc_dir", "main_pid"]

        self.required_params["datafetcher"] = [
            "store_data", {
                self.df_type: df_params
            }
        ]

    def _setup(self):
        """Sets up and configures the transfer.
        """
        self.transfer = Transfer("STREAM", use_log=self.log_queue)

        config_net = self.config_all["network"]

        endpoint = "{}_{}".format(config_net["main_pid"], "out")
        self.transfer.start([config_net["ipc_dir"], endpoint],
                            protocol="ipc",
                            data_con_style="connect")

        # enable status check requests from any sender
        self.transfer.setopt(option="status_check",
                             value=[
                                 config_net["ext_ip"],
                                 self.config["status_check_resp_port"]
                             ])

        # enable confirmation reply if this is requested in a received data
        # packet
        self.transfer.setopt(option="confirmation",
                             value=[
                                 config_net["ext_ip"],
                                 self.config["confirmation_resp_port"]
                             ])

    def get_metadata(self, targets, metadata):
        """Implementation of the abstract method get_metadata.

        Args:
            targets (list): The target list this file is supposed to go.
            metadata (dict): The dictionary with the metadata to extend.
        """

        timeout = 10000

        # Get new data
        self.metadata_r, self.data_r = self.transfer.get(timeout)

        if (metadata["relative_path"] != self.metadata_r["relative_path"]
                or metadata["source_path"] != self.metadata_r["source_path"]
                or metadata["filename"] != self.metadata_r["filename"]):
            self.log.error("Received metadata do not match data")

        # Use received data to prevent mismatch of metadata and data
        # TODO handle case if file type requested by target does not match

        # pylint: disable=attribute-defined-outside-init

        # Build source file
        self.source_file = generate_filepath(self.metadata_r["source_path"],
                                             self.metadata_r)

        # Build target file
        # if local_target is not set (== None) generate_filepath returns None
        self.target_file = generate_filepath(self.config_df["local_target"],
                                             self.metadata_r)

        # Extends metadata
        if targets:
            if "filesize" not in self.metadata_r:
                self.log.error("Received metadata do not contain 'filesize'")

            if "file_mod_time" not in self.metadata_r:
                self.log.error("Received metadata do not contain "
                               "'file_mod_time'. Setting it to current time")
                self.metadata_r["file_mod_time"] = time.time()

            if "file_create_time" not in self.metadata_r:
                self.log.error("Received metadata do not contain "
                               "'file_create_time'. Setting it to current "
                               "time")
                self.metadata_r["file_create_time"] = time.time()

            if "chunksize" not in self.metadata_r:
                self.log.error("Received metadata do not contain 'chunksize'. "
                               "Setting it to locally configured one")
                self.metadata_r["chunksize"] = self.config_df["chunksize"]

    def send_data(self, targets, metadata, open_connections):
        """Implementation of the abstract method send_data.

        Args:
            targets (list): The target list this file is supposed to go.
            metadata (dict): The dictionary with the metadata of the file
            open_connections (dict): The dictionary containing all open zmq
                                     connections.
        """
        # pylint: disable=unused-argument

        if not targets:
            return

        # targets are of the form [[<host:port>, <prio>, <metadata|data>], ...]
        targets_data = [i for i in targets if i[2] == "data"]

        if not targets_data:
            return

        self.log.debug("Received data for file %s (chunknumber %s)",
                       self.source_file, self.metadata_r["chunk_number"])

        self.log.debug("Passing multipart-message for file '%s'...",
                       self.source_file)

        try:
            chunk_payload = [
                json.dumps(self.metadata_r).encode("utf-8"), self.data_r
            ]
        except Exception:
            self.log.error("Unable to pack multipart-message for file "
                           "'%s'",
                           self.source_file,
                           exc_info=True)
            return

        # send message to data targets
        try:
            self.send_to_targets(targets=targets_data,
                                 open_connections=open_connections,
                                 metadata=None,
                                 payload=chunk_payload,
                                 chunk_number=self.metadata_r["chunk_number"])
        except DataError:
            self.log.error(
                "Unable to send multipart-message for file '%s' (chunk %s)",
                self.source_file,
                self.metadata_r["chunk_number"],
                exc_info=True)
        except Exception:
            self.log.error(
                "Unable to send multipart-message for file '%s' (chunk %s)",
                self.source_file,
                self.metadata_r["chunk_number"],
                exc_info=True)

    def finish(self, targets, metadata, open_connections):
        """Implementation of the abstract method finish.

        Args:
            targets (list): The target list this file is supposed to go.
            metadata (dict): The dictionary with the metadata of the file
            open_connections (dict): The dictionary containing all open zmq
                                     connections.
        """

        # targets are of the form [[<host:port>, <prio>, <metadata|data>], ...]
        targets_metadata = [i for i in targets if i[2] == "metadata"]

        # send message to metadata targets
        if targets_metadata:
            try:
                self.send_to_targets(targets=targets_metadata,
                                     open_connections=open_connections,
                                     metadata=metadata,
                                     payload=None,
                                     chunk_number=None,
                                     timeout=self.config["send_timeout"])
                self.log.debug(
                    "Passing metadata multipart-message for file "
                    "%s...done.", self.source_file)

            except Exception:
                self.log.error(
                    "Unable to send metadata multipart-message for file"
                    "'%s' to '%s'",
                    self.source_file,
                    targets_metadata,
                    exc_info=True)

        # store data
        if self.config_df["store_data"]:
            try:
                # TODO: save message to file using a thread (avoids blocking)
                self.transfer.store_chunk(
                    descriptors=self.f_descriptors,
                    filepath=self.target_file,
                    payload=self.data_r,
                    base_path=self.config_df["local_target"],
                    metadata=self.metadata_r)
            except Exception:
                self.log.error(
                    "Storing multipart message for file '%s' failed",
                    self.source_file,
                    exc_info=True)

    def stop(self):
        """Implementation of the abstract method stop.
        """

        # Close base class zmq sockets
        self.close_socket()

        # Close open file handler to prevent file corruption
        for target_file in list(self.f_descriptors):
            self.f_descriptors[target_file].close()
            del self.f_descriptors[target_file]

        # Close zmq sockets
        if self.transfer is not None:
            self.transfer.stop()
예제 #14
0
class Worker(multiprocessing.Process):
    """Start a connection to hidra an get a data block.
    """
    def __init__(self, identifier, transfer_type, basepath, signal_host,
                 target_host, port):

        super().__init__()

        self.identifier = identifier
        self.port = port

        self.transfer_type = transfer_type

        self.log = logging.getLogger("Worker-{}".format(self.identifier))

        self.query = Transfer(self.transfer_type, signal_host, use_log=True)

        self.basepath = basepath

        self.log.debug("start Transfer on port %s", port)
        # targets are locally
        self.query.start([target_host, port])
        #        self.query.start(port)

        self.run()

    def run(self):
        while True:
            try:
                self.log.debug("Worker-%s: waiting", self.identifier)
                [metadata, data] = self.query.get()
                time.sleep(0.1)
            except Exception:
                break

            if self.transfer_type in [
                    "QUERY_NEXT_METADATA", "STREAM_METADATA"
            ]:
                self.log.debug("Worker-%s: metadata %s", self.identifier,
                               metadata["filename"])

                filepath = generate_filepath(self.basepath, metadata)

                self.log.debug("Worker-%s: filepath %s", self.identifier,
                               filepath)

                with open(filepath, "r") as file_descriptor:
                    file_descriptor.read()
                    self.log.debug("Worker-%s: file %s read", self.identifier,
                                   filepath)
            else:
                print("filepath", generate_filepath(self.basepath, metadata))
                print("metadata", metadata)

            print("data", str(data)[:100])

    def stop(self):
        """Clean up.
        """
        self.query.stop()

    def __exit__(self, exception_type, exception_value, traceback):
        self.stop()

    def __del__(self):
        self.stop()
예제 #15
0
class Passthrough(Operations):

    def __init__(self, signal_host):

        self.log = self.__get_logger()

        self.timeout = 2000
        self.read_pointer = 0

        targets = [socket.getfqdn(), "50101", 1]

        # create HiDRA Transfer instance which wants data by request only
        self.query = Transfer("QUERY_NEXT", signal_host)
        self.query.initiate(targets)
        self.query.start()

        self.metadata = None
        self.data = None

    # utils
    # ==================

    def __get_logger(self):
        # create the default logger used by the logging mixin
        log = logging.getLogger("fuse.log-mixin")
        log.setLevel(logging.DEBUG)
        # create console handler with a higher log level
        handler = logging.StreamHandler()
        handler.setLevel(logging.DEBUG)
        # add the handlers to the logger
        log.addHandler(handler)

        return log

    # Filesystem methods
    # ==================

#    def access(self, path, mode):
#        pass

#    def chmod(self, path, mode):
#        pass

#    def chown(self, path, uid, gid):
#        pass

    def getattr(self, path, fh=None):
        self.log.debug("path=%s", path)

        if path == "/" or path.startswith("/.Trash"):
            st = os.lstat(path)  # pylint: disable=invalid-name
            return {
                "st_mode": getattr(st, "st_mode"),
                "st_nlink": getattr(st, "st_nlink"),
                "st_uid": getattr(st, "st_uid"),
                "st_gid": getattr(st, "st_gid"),
                "st_ctime": getattr(st, "st_ctime"),
                "st_mtime": getattr(st, "st_mtime"),
                "st_size": getattr(st, "st_size")
            }
        else:
            if self.metadata is None and self.data is None:
                self.log.debug("get")
                [self.metadata, self.data] = self.query.get(self.timeout)

            return {
                "st_mode": (stat.S_IFREG | 0644),
                "st_nlink": 1,
                "st_uid": 1000,
                "st_gid": 1000,
                "st_ctime": self.metadata["file_create_time"],
                "st_mtime": self.metadata["file_mod_time"],
                "st_size": self.metadata["filesize"]
            }

    def readdir(self, path, fh):
        # if self.metadata is None and self.data is None:
        [self.metadata, self.data] = self.query.get(self.timeout)

        if self.metadata is None:
            return [".", ".."]
        else:
            return [".", "..", self.metadata["filename"]]

    # The method readlink() returns a string representing the path to which the
    # symbolic link points. It may return an absolute or relative pathname.
#    def readlink(self, path):
#        pass

    # The method mknod() creates a filesystem node (file, device special file
    # or named pipe) named filename.
#    def mknod(self, path, mode, dev):
#        pass

#    def rmdir(self, path):
#        pass

#    def mkdir(self, path, mode):
#        pass

    # The method statvfs() perform a statvfs system call on the given path.
#    def statfs(self, path):
#        pass

    # The method unlink() removes (deletes) the file path. If the path is a
    # directory, OSError is raised.
#    def unlink(self, path):
#        pass

    # The method symlink() creates a symbolic link dst pointing to src.
#    def symlink(self, name, target):
#        pass

#    def rename(self, old, new):
#        pass

#    def link(self, target, name):
#        signal_host = "zitpcx19282.desy.de"
#        targets = ["zitpcx19282.desy.de", "50101", 1]
#        pass

    # The method utime() sets the access and modified times of the file
    # specified by path.
#    def utimens(self, path, times=None):
#        pass

    # File methods
    # ============

    # The method open() opens the file file and set various flags according to
    # flags and possibly its mode according to mode.The default mode is 0777
    # (octal), and the current umask value is first masked out.
    def open(self, path, flags):
        # self.log.debug("open")
        if self.metadata is None and self.data is None:
            self.log.debug("get")
            [self.metadata, self.data] = self.query.get(self.timeout)
        # for reading
        self.read_pointer = 0
        return 0

#    def create(self, path, mode, fi=None):
#        pass

    def read(self, path, length, offset, fh):
        # self.log.debug("read")

        self.read_pointer += length
        return self.data[self.read_pointer - length:self.read_pointer]

#    def write(self, path, buf, offset, fh):
#        pass

    # The method truncate() truncates the file's size. The file is truncated to
    # (at most) that size of the argument length
    def truncate(self, path, length, fh=None):
        self.log.debug("truncate")

    # The method fsync() forces write of file with file descriptor fd to disk.
#    def flush(self, path, fh):
#        self.release(path, fh)

    def release(self, path, fh):
        # self.log.debug("release")
        self.metadata = None
        self.data = None
예제 #16
0
def main():
    """Requests data from hidra on a query basis.
    """

    parser = argparse.ArgumentParser()

    parser.add_argument("--signal_host",
                        type=str,
                        help="Host where HiDRA is running",
                        default=socket.getfqdn())
    parser.add_argument("--target_host",
                        type=str,
                        help="Host where the data should be send to",
                        default=socket.getfqdn())

    arguments = parser.parse_args()

    #    targets = [[arguments.target_host, "50101", 1]]
    targets = [[arguments.target_host, "50101", 1, ".*(tif|cbf)$"]]
    #    targets = [[arguments.target_host, "50101", 1, [".tif", ".cbf"]]]

    print("\n==== TEST: Query for the newest filename ====\n")

    query = Transfer("QUERY_NEXT", arguments.signal_host)

    query.initiate(targets)

    try:
        query.start()
    except Exception:
        query.stop()
        return

    use_md5sum = False
    timeout = None
    #    timeout = 2000  # in ms

    while True:
        try:
            [metadata, data] = query.get(timeout)
        except Exception:
            print(sys.exc_info())
            break

        print()
        if metadata and data:
            print("metadata", metadata["filename"])
            print("data", str(data)[:10])

            # generate md5sum
            if use_md5sum:
                md5sum = hashlib.md5()
                md5sum.update(data)
                print("md5sum", md5sum.hexdigest())

        else:
            print("metadata", metadata)
            print("data", data)
        print()

    query.stop()

    print("\n==== TEST END: Query for the newest filename ====\n")
예제 #17
0
class LiveView(QThread):
    FILETYPE_CBF = 0
    FILETYPE_TIF = 1
    FILETYPE_HDF5 = 2

    alive = False
    path = ""
    filetype = 0
    interval = 0.5  # s
    stoptimer = -1.0

    viewer = None
    subframe = None
    mutex = None

    query = None
    transfer_type = socket.getfqdn()
    data_port = "50122"
    basepath = os.path.join(BASE_DIR, "data", "target")

    #    basepath = "/gpfs"

    def __init__(self, path=None, filetype=None, interval=None, parent=None):
        QThread.__init__(self, parent)
        if path is not None:
            self.path = path
        if filetype is not None:
            self.filetype = filetype
        if interval is not None:
            self.interval = interval

#        suffix = [".cbf", ".tif", ".hdf5"]

        self.query = Transfer("QUERY_NEXT_METADATA", self.transfer_type)
        self.query.initiate([socket.getfqdn(), self.data_port, "1"])
        self.query.start(self.data_port)
        #        self.query.initiate(["zitpcx22614w", self.data_port, "1"])
        #        self.query.start(["zitpcx22614w", self.data_port])

        self.mutex = QMutex()

    def start(self, path=None, filetype=None, interval=None):
        if path is not None:
            self.path = path
        if filetype is not None:
            self.filetype = filetype
        if interval is not None:
            self.interval = interval
        QThread.start(self)

    def stop(self, interval=0.0):
        if self.stoptimer < 0.0 and interval > 0.0:
            print("Live view thread: Stopping in %d seconds" % interval)
            self.stoptimer = interval
            return
        print("Live view thread: Stopping thread")
        self.alive = False

        self.wait()  # waits until run stops on his own

    def run(self):
        self.alive = True
        print("Live view thread: started")

        if self.filetype in [LiveView.FILETYPE_CBF,
                             LiveView.FILETYPE_TIF]:  # noqa F821
            # open viewer
            while self.alive:
                # find latest image
                self.mutex.lock()

                # get latest file from reveiver
                [metadata, _] = self.query.get(2000)

                receivedfile = (self.query.generate_target_filepath(
                    self.basepath, metadata))
                print("Next file: ", receivedfile)

                if receivedfile is None:
                    self.mutex.unlock()
                    continue


#                time.sleep(0.2)
# display image
#                try:
#                    self.subframe.loadFile(receivedfile)
#                # viewer or subframe has been closed by the user
#                except:
#                    self.mutex.unlock()
#                    time.sleep(0.1)
#                    try:
#                        self.subframe = self.viewer.openSubFrame()
#                    except:
#                        self.viewer = albula.openMainFrame()
#                        self.subframe = self.viewer.openSubFrame()
#                    continue
                self.mutex.unlock()
                # wait interval
                interval = 0.0
                while interval < self.interval and self.alive:
                    if self.stoptimer > 0.0:
                        self.stoptimer -= 0.05
                        if self.stoptimer < 0.0:
                            self.stoptimer = -1.0
                            self.alive = False
                    time.sleep(0.05)
                    interval += 0.05
        elif self.filetype == LiveView.FILETYPE_HDF5:  # noqa F821
            print("Live view thread: HDF5 not supported yet")

        print("Live view thread: Thread for Live view died")
        self.alive = False

    def setPath(self, path=None):  # noqa N802
        self.mutex.lock()
        if path is not None:
            self.path = path
        self.mutex.unlock()

    def setFiletype(self, filetype=None):  # noqa N802
        restart = False
        if self.alive:
            restart = True
            self.stop()
        if filetype is not None:
            self.filetype = filetype
        if restart:
            self.start()

    def setInterval(self, interval=None):  # noqa N802
        if interval is not None:
            self.interval = interval

    def __exit__(self):
        self.query.stop()

    def __del__(self):
        self.query.stop()
예제 #18
0
class DataReceiver(object):
    """Receives data and stores it to disc usign the hidra API.
    """
    def __init__(self):

        self.transfer = None
        self.checking_thread = None
        self.timeout = None

        self.config = None

        self.log = None
        self.dirs_not_to_create = None
        self.lock = None
        self.target_dir = None
        self.data_ip = None
        self.data_port = None
        self.transfer = None
        self.checking_thread = None

        self.plugin_handler = None

        self.run_loop = True

        self.setup()

        self.exec_run()

    def setup(self):
        """Initializes parameters, logging and transfer object.
        """

        global _whitelist

        try:
            self.config = argument_parsing()
        except Exception:
            self.log = logging.getLogger("DataReceiver")
            raise

        config_gen = self.config["general"]
        config_recv = self.config["datareceiver"]

        # change user
        user_info, user_was_changed = utils.change_user(config_gen)

        # set up logging
        utils.check_writable(config_gen["log_file"])
        self._setup_logging()

        utils.log_user_change(self.log, user_was_changed, user_info)

        # set process name
        # pylint: disable=no-member
        setproctitle.setproctitle(config_gen["procname"])

        self.log.info("Version: %s", __version__)

        self.dirs_not_to_create = config_gen["dirs_not_to_create"]

        # for proper clean up if kill is called
        signal.signal(signal.SIGTERM, self.signal_term_handler)

        self.timeout = 2000
        self.lock = threading.Lock()

        try:
            ldap_retry_time = config_gen["ldap_retry_time"]
        except KeyError:
            ldap_retry_time = 10

        try:
            check_time = config_gen["netgroup_check_time"]
        except KeyError:
            check_time = 2

        if config_gen["whitelist"] is not None:
            self.log.debug("config_gen['whitelist']=%s",
                           config_gen["whitelist"])

            with self.lock:
                _whitelist = utils.extend_whitelist(config_gen["whitelist"],
                                                    config_gen["ldapuri"],
                                                    self.log)
            self.log.info("Configured whitelist: %s", _whitelist)
        else:
            _whitelist = None

        # only start the thread if a netgroup was configured
        if (config_gen["whitelist"] is not None
                and isinstance(config_gen["whitelist"], str)):
            self.log.debug("Starting checking thread")
            try:
                self.checking_thread = CheckNetgroup(config_gen["whitelist"],
                                                     self.lock,
                                                     config_gen["ldapuri"],
                                                     ldap_retry_time,
                                                     check_time)
                self.checking_thread.start()
            except Exception:
                self.log.error("Could not start checking thread",
                               exc_info=True)
        else:
            self.log.debug("Checking thread not started: %s",
                           config_gen["whitelist"])

        self.target_dir = os.path.normpath(config_recv["target_dir"])
        self.data_ip = config_recv["data_stream_ip"]
        self.data_port = config_recv["data_stream_port"]

        self.log.info("Writing to directory '%s'", self.target_dir)

        self.transfer = Transfer(connection_type="STREAM",
                                 use_log=True,
                                 dirs_not_to_create=self.dirs_not_to_create)

        self._load_plugin()

    def _setup_logging(self):
        config_gen = self.config["general"]

        # enable logging
        root = logging.getLogger()
        root.setLevel(logging.DEBUG)

        handlers = utils.get_log_handlers(config_gen["log_file"],
                                          config_gen["log_size"],
                                          config_gen["verbose"],
                                          config_gen["onscreen"])

        if isinstance(handlers, tuple):
            for hdl in handlers:
                root.addHandler(hdl)
        else:
            root.addHandler(handlers)

        self.log = logging.getLogger("DataReceiver")

    def _load_plugin(self):
        try:
            plugin_name = self.config["datareceiver"]["plugin"]
            plugin_config = self.config[plugin_name]
        except KeyError:
            self.log.debug("No plugin specified")
            return

        self.plugin_handler = PluginHandler(plugin_name, plugin_config,
                                            self.target_dir, self.log)

    def exec_run(self):
        """Wrapper around run to react to exceptions.
        """

        try:
            self.run()
        except KeyboardInterrupt:
            pass
        except Exception:
            self.log.error("Stopping due to unknown error condition",
                           exc_info=True)
            raise
        finally:
            self.stop()

    def run(self):
        """Start the transfer and store the data.
        """

        global _whitelist  # pylint: disable=global-variable-not-assigned
        global _changed_netgroup

        if self.plugin_handler is not None:
            plugin_type = self.plugin_handler.get_data_type()
            self.plugin_handler.start()
        else:
            plugin_type = None

        try:
            self.transfer.start([self.data_ip, self.data_port], _whitelist)
        except Exception:
            self.log.error("Could not initiate stream", exc_info=True)
            self.stop(store=False)
            raise

        # enable status check requests from any sender
        self.transfer.setopt("status_check")
        # enable confirmation reply if this is requested in a received data
        # packet
        self.transfer.setopt("confirmation")

        self.log.debug("Waiting for new messages...")
        self.run_loop = True
        # run loop, and wait for incoming messages
        while self.run_loop:
            if _changed_netgroup:
                self.log.debug("Re-registering whitelist")
                self.transfer.register(_whitelist)

                # reset flag
                with self.lock:
                    _changed_netgroup = False

            try:
                ret_val = self.transfer.store(target_base_path=self.target_dir,
                                              timeout=self.timeout,
                                              return_type=plugin_type)

            except KeyboardInterrupt:
                break
            except Exception:
                self.log.error("Storing data...failed.", exc_info=True)
                raise

            if self.plugin_handler is None or ret_val is None:
                continue

            try:
                self.plugin_handler.put(ret_val)
                # ret_val might have been mutated by the plugin and therefore
                # should only be reused if this is acceptable
            except Exception:
                self.log.error("Cannot submit message to plugin")

    def stop(self, store=True):
        """Stop threads, close sockets and cleans up.

        Args:
            store (optional, bool): Run a little longer to store remaining
                                    data.
        """

        self.run_loop = False

        if self.transfer is not None:
            self.transfer.status = [b"ERROR", "receiver is shutting down"]

            if store:
                stop_timeout = 0.5
                start_time = time.time()
                diff_time = (time.time() - start_time) * 1000
                self.log.debug("Storing remaining data.")
                while diff_time < stop_timeout:
                    try:
                        self.log.debug("Storing remaining data...")
                        self.transfer.store(self.target_dir, self.timeout)
                    except Exception:
                        self.log.error("Storing data...failed.", exc_info=True)
                    diff_time = (time.time() - start_time) * 1000

            self.log.info("Shutting down receiver...")
            self.transfer.stop()
            self.transfer = None

        if self.plugin_handler is not None:
            self.plugin_handler.stop()

        if self.checking_thread is not None:
            self.checking_thread.stop()
            self.checking_thread.join()
            self.log.debug("checking_thread stopped")
            self.checking_thread = None

    # pylint: disable=unused-argument
    def signal_term_handler(self, signal_to_react, frame):
        """React on external SIGTERM signal.
        """

        self.log.debug('got SIGTERM')
        self.stop()

    def __exit__(self, exception_type, exception_value, traceback):
        self.stop()

    def __del__(self):
        self.stop()
예제 #19
0
class NexusReceiver:
    def __init__(self):
        self.transfer = None

        try:
            params = argument_parsing()
        except Exception:
            self.log = self.get_logger()
            raise

        self.log = self.get_logger()

        self.whitelist = params["whitelist"]

        self.log.info("Configured whitelist: {0}".format(self.whitelist))

        self.target_dir = os.path.normpath(params["target_dir"])
        self.data_ip = params["data_stream_ip"]
        self.data_port = params["data_stream_port"]

        self.log.info("Writing to directory '{0}'".format(self.target_dir))

        self.transfer = Transfer("NEXUS", use_log=True)

        try:
            self.run()
        except KeyboardInterrupt:
            pass
        except Exception:
            self.log.error("Stopping due to unknown error condition",
                           exc_info=True)
        finally:
            self.stop()

    def get_logger(self):
        logger = logging.getLogger("NexusReceiver")
        return logger

    def open_callback(self, params, filename):
        target_file = os.path.join(BASE_DIR, "data", "target", "local",
                                   filename)

        try:
            params["target_fp"] = open(target_file, "wb")
        except IOError as e:
            # errno.ENOENT == "No such file or directory"
            if e.errno == errno.ENOENT:
                try:
                    target_path = os.path.split(target_file)[0]
                    print("target_path", target_path)
                    os.makedirs(target_path)

                    params["target_fp"] = open(target_file, "wb")
                    print("New target directory created:", target_path)
                except Exception:
                    raise
            else:
                raise
        print(params, filename)

    def read_callback(self, params, received_data):
        metadata = received_data[0]
        data = received_data[1]
        print(params, metadata)

        params["target_fp"].write(data)

    def close_callback(self, params, data):
        print(params, data)
        params["target_fp"].close()

    def run(self):
        callback_params = {"target_fp": None}

        try:
            self.transfer.start([self.data_ip, self.data_port], self.whitelist)
#            self.transfer.start(self.data_port)
        except Exception:
            self.log.error("Could not initiate stream", exc_info=True)
            raise

        # run loop, and wait for incoming messages
        while True:
            try:
                data = self.transfer.read(callback_params, self.open_callback,
                                          self.read_callback,
                                          self.close_callback)
                logging.debug("Retrieved: " + str(data)[:100])


#                if data == "CLOSE_FILE":
#                    break
            except KeyboardInterrupt:
                break
            except Exception:
                self.log.error("Could not read")
                raise

    def stop(self):
        if self.transfer:
            self.log.info("Shutting down receiver...")
            self.transfer.stop()
            self.transfer = None

    def __exit__(self):
        self.stop()

    def __del__(self):
        self.stop()