rflow-components-file 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
 - data/Gemfile +4 -0
 - data/Rakefile +16 -0
 - data/lib/rflow/components/file/directory_watcher.rb +95 -0
 - data/lib/rflow/components/file/extensions.rb +58 -0
 - data/lib/rflow/components/file/output_raw_to_files.rb +90 -0
 - data/lib/rflow/components/file/version.rb +7 -0
 - data/lib/rflow/components/file.rb +26 -0
 - data/lib/rflow-components-file.rb +2 -0
 - data/rflow-components-file.gemspec +28 -0
 - data/schema/file.avsc +14 -0
 - data/spec/directory_watcher_spec.rb +4 -0
 - data/spec/extensions_spec.rb +49 -0
 - data/spec/output_raw_to_files_spec.rb +23 -0
 - data/spec/schema_spec.rb +28 -0
 - data/spec/spec_helper.rb +18 -0
 - metadata +131 -0
 
    
        data/.gitignore
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'bundler'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rspec/core/rake_task'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'rake/rdoctask'
         
     | 
| 
      
 4 
     | 
    
         
            +
            Bundler::GemHelper.install_tasks
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            RSpec::Core::RakeTask.new(:spec) do |t|
         
     | 
| 
      
 7 
     | 
    
         
            +
              t.verbose = true
         
     | 
| 
      
 8 
     | 
    
         
            +
              t.rspec_opts = '--tty --color'
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            Rake::RDocTask.new do |rd|
         
     | 
| 
      
 12 
     | 
    
         
            +
              rd.main = "README"
         
     | 
| 
      
 13 
     | 
    
         
            +
              rd.rdoc_files.include("README", "lib/**/*.rb")
         
     | 
| 
      
 14 
     | 
    
         
            +
              rd.rdoc_dir = File.join('doc', 'html')
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,95 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rflow/component'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'digest/md5'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            class RFlow
         
     | 
| 
      
 6 
     | 
    
         
            +
              module Components
         
     | 
| 
      
 7 
     | 
    
         
            +
                module File
         
     | 
| 
      
 8 
     | 
    
         
            +
                  class DirectoryWatcher < RFlow::Component
         
     | 
| 
      
 9 
     | 
    
         
            +
                    output_port :file_port
         
     | 
| 
      
 10 
     | 
    
         
            +
                    output_port :raw_port
         
     | 
| 
      
 11 
     | 
    
         
            +
                    
         
     | 
| 
      
 12 
     | 
    
         
            +
                    DEFAULT_CONFIG = {
         
     | 
| 
      
 13 
     | 
    
         
            +
                      'directory_path'  => '/tmp/import',
         
     | 
| 
      
 14 
     | 
    
         
            +
                      'file_name_glob'  => '*',
         
     | 
| 
      
 15 
     | 
    
         
            +
                      'poll_interval'   => 1,
         
     | 
| 
      
 16 
     | 
    
         
            +
                      'files_per_poll'  => 1,
         
     | 
| 
      
 17 
     | 
    
         
            +
                      'remove_files'    => true,
         
     | 
| 
      
 18 
     | 
    
         
            +
                    }
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    attr_accessor :config, :poll_interval, :directory_path, :file_name_glob, :remove_files
         
     | 
| 
      
 21 
     | 
    
         
            +
                    
         
     | 
| 
      
 22 
     | 
    
         
            +
                    def configure!(config)
         
     | 
| 
      
 23 
     | 
    
         
            +
                      @config = DEFAULT_CONFIG.merge config
         
     | 
| 
      
 24 
     | 
    
         
            +
                      @directory_path  = ::File.expand_path(@config['directory_path'])
         
     | 
| 
      
 25 
     | 
    
         
            +
                      @file_name_glob  = @config['file_name_glob']
         
     | 
| 
      
 26 
     | 
    
         
            +
                      @poll_interval   = @config['poll_interval'].to_i
         
     | 
| 
      
 27 
     | 
    
         
            +
                      @files_per_poll  = @config['files_per_poll'].to_i
         
     | 
| 
      
 28 
     | 
    
         
            +
                      @remove_files    = to_boolean(@config['remove_files'])
         
     | 
| 
      
 29 
     | 
    
         
            +
                      
         
     | 
| 
      
 30 
     | 
    
         
            +
                      unless ::File.directory?(@directory_path)
         
     | 
| 
      
 31 
     | 
    
         
            +
                        raise ArgumentError, "Invalid directory '#{@directory_path}'"
         
     | 
| 
      
 32 
     | 
    
         
            +
                      end
         
     | 
| 
      
 33 
     | 
    
         
            +
                      
         
     | 
| 
      
 34 
     | 
    
         
            +
                      unless ::File.readable?(@directory_path)
         
     | 
| 
      
 35 
     | 
    
         
            +
                        raise ArgumentError, "Unable to read from directory '#{@directory_path}'"
         
     | 
| 
      
 36 
     | 
    
         
            +
                      end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                      # TODO: more error checking of input config
         
     | 
| 
      
 39 
     | 
    
         
            +
                    end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                    # TODO: optimize sending of messages based on what is connected
         
     | 
| 
      
 43 
     | 
    
         
            +
                    def run!
         
     | 
| 
      
 44 
     | 
    
         
            +
                      timer = EventMachine::PeriodicTimer.new(poll_interval) do
         
     | 
| 
      
 45 
     | 
    
         
            +
                        RFlow.logger.debug "Polling for files in #{::File.join(@directory_path, @file_name_glob)}"
         
     | 
| 
      
 46 
     | 
    
         
            +
                        # Sort by last modified, which will process the earliest
         
     | 
| 
      
 47 
     | 
    
         
            +
                        # modified file first
         
     | 
| 
      
 48 
     | 
    
         
            +
                        file_paths = Dir.glob(::File.join(@directory_path, @file_name_glob)).sort_by {|f| test(?M, f)}
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                        file_paths.first(@files_per_poll).each do |file_path|
         
     | 
| 
      
 51 
     | 
    
         
            +
                          RFlow.logger.debug "Importing #{file_path}"
         
     | 
| 
      
 52 
     | 
    
         
            +
                          ::File.open(file_path, 'r:BINARY') do |file|
         
     | 
| 
      
 53 
     | 
    
         
            +
                            file_content = file.read
         
     | 
| 
      
 54 
     | 
    
         
            +
                            
         
     | 
| 
      
 55 
     | 
    
         
            +
                            RFlow.logger.debug "read #{file_content.bytesize} bytes of #{file.size} in #{file.path}, md5 #{Digest::MD5.hexdigest(file_content)}"
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                            file_message = RFlow::Message.new('RFlow::Message::Data::File')
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                            file_message.data.path = ::File.expand_path(file.path)
         
     | 
| 
      
 60 
     | 
    
         
            +
                            file_message.data.size = file.size
         
     | 
| 
      
 61 
     | 
    
         
            +
                            file_message.data.content = file_content
         
     | 
| 
      
 62 
     | 
    
         
            +
                            file_message.data.creation_timestamp = file.ctime
         
     | 
| 
      
 63 
     | 
    
         
            +
                            file_message.data.modification_timestamp = file.mtime
         
     | 
| 
      
 64 
     | 
    
         
            +
                            file_message.data.access_timestamp = file.atime
         
     | 
| 
      
 65 
     | 
    
         
            +
                            
         
     | 
| 
      
 66 
     | 
    
         
            +
                            file_port.send_message file_message
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                            raw_message = RFlow::Message.new('RFlow::Message::Data::Raw')
         
     | 
| 
      
 69 
     | 
    
         
            +
                            raw_message.data.raw = file_content
         
     | 
| 
      
 70 
     | 
    
         
            +
                            raw_port.send_message raw_message
         
     | 
| 
      
 71 
     | 
    
         
            +
                          end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                          if @remove_files
         
     | 
| 
      
 74 
     | 
    
         
            +
                            RFlow.logger.debug "Removing #{::File.join(@directory_path, file_path)}"
         
     | 
| 
      
 75 
     | 
    
         
            +
                            ::File.delete file_path
         
     | 
| 
      
 76 
     | 
    
         
            +
                          end
         
     | 
| 
      
 77 
     | 
    
         
            +
                        end
         
     | 
| 
      
 78 
     | 
    
         
            +
                      end
         
     | 
| 
      
 79 
     | 
    
         
            +
                    end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                    def to_boolean(string)
         
     | 
| 
      
 82 
     | 
    
         
            +
                      case string
         
     | 
| 
      
 83 
     | 
    
         
            +
                      when /^true$/i, '1', true
         
     | 
| 
      
 84 
     | 
    
         
            +
                        true
         
     | 
| 
      
 85 
     | 
    
         
            +
                      when /^false/i, '0', false
         
     | 
| 
      
 86 
     | 
    
         
            +
                        false
         
     | 
| 
      
 87 
     | 
    
         
            +
                      else
         
     | 
| 
      
 88 
     | 
    
         
            +
                        raise ArgumentError, "'#{string}' cannot be coerced to a boolean value"
         
     | 
| 
      
 89 
     | 
    
         
            +
                      end
         
     | 
| 
      
 90 
     | 
    
         
            +
                    end
         
     | 
| 
      
 91 
     | 
    
         
            +
                    
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
                end
         
     | 
| 
      
 94 
     | 
    
         
            +
              end
         
     | 
| 
      
 95 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,58 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class RFlow
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Components
         
     | 
| 
      
 3 
     | 
    
         
            +
                module File
         
     | 
| 
      
 4 
     | 
    
         
            +
                  
         
     | 
| 
      
 5 
     | 
    
         
            +
                  # The set of extensions to add capability to File data types
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module Extensions
         
     | 
| 
      
 7 
     | 
    
         
            +
                    
         
     | 
| 
      
 8 
     | 
    
         
            +
                    # Need to be careful when extending to not clobber data already in data_object
         
     | 
| 
      
 9 
     | 
    
         
            +
                    module FileExtension
         
     | 
| 
      
 10 
     | 
    
         
            +
                      def self.extended(base_data)
         
     | 
| 
      
 11 
     | 
    
         
            +
                        base_data.data_object ||= {
         
     | 
| 
      
 12 
     | 
    
         
            +
                          'path' => '/', 'size' => 0, 'content' => '',
         
     | 
| 
      
 13 
     | 
    
         
            +
                          'creation_timestamp' => nil, 'modification_timestamp' => nil, 'access_timestamp' => nil
         
     | 
| 
      
 14 
     | 
    
         
            +
                        }
         
     | 
| 
      
 15 
     | 
    
         
            +
                      end
         
     | 
| 
      
 16 
     | 
    
         
            +
                      
         
     | 
| 
      
 17 
     | 
    
         
            +
                      # Default/string accessors
         
     | 
| 
      
 18 
     | 
    
         
            +
                      ['path', 'content'].each do |name|
         
     | 
| 
      
 19 
     | 
    
         
            +
                        define_method name do |*args|
         
     | 
| 
      
 20 
     | 
    
         
            +
                          data_object[name]
         
     | 
| 
      
 21 
     | 
    
         
            +
                        end
         
     | 
| 
      
 22 
     | 
    
         
            +
                        define_method :"#{name}=" do |*args|
         
     | 
| 
      
 23 
     | 
    
         
            +
                          data_object[name] = args.first
         
     | 
| 
      
 24 
     | 
    
         
            +
                        end
         
     | 
| 
      
 25 
     | 
    
         
            +
                      end
         
     | 
| 
      
 26 
     | 
    
         
            +
                      
         
     | 
| 
      
 27 
     | 
    
         
            +
                      # Integer Accessors
         
     | 
| 
      
 28 
     | 
    
         
            +
                      ['size'].each do |name|
         
     | 
| 
      
 29 
     | 
    
         
            +
                        define_method name do |*args|
         
     | 
| 
      
 30 
     | 
    
         
            +
                          data_object[name]
         
     | 
| 
      
 31 
     | 
    
         
            +
                        end
         
     | 
| 
      
 32 
     | 
    
         
            +
                        define_method :"#{name}=" do |*args|
         
     | 
| 
      
 33 
     | 
    
         
            +
                          data_object[name] = args.first.to_i
         
     | 
| 
      
 34 
     | 
    
         
            +
                        end
         
     | 
| 
      
 35 
     | 
    
         
            +
                      end
         
     | 
| 
      
 36 
     | 
    
         
            +
                      
         
     | 
| 
      
 37 
     | 
    
         
            +
                      # Timestamp Accessors.  Note, the precision of the
         
     | 
| 
      
 38 
     | 
    
         
            +
                      # XMLTimestamp is set to 9 digits, meaning that the time you
         
     | 
| 
      
 39 
     | 
    
         
            +
                      # put in might be slightly different from the time you read
         
     | 
| 
      
 40 
     | 
    
         
            +
                      # out.
         
     | 
| 
      
 41 
     | 
    
         
            +
                      ['creation_timestamp', 'modification_timestamp', 'access_timestamp'].each do |name|
         
     | 
| 
      
 42 
     | 
    
         
            +
                        define_method name do |*args|
         
     | 
| 
      
 43 
     | 
    
         
            +
                          data_object[name] ? Time.xmlschema(data_object[name]) : nil
         
     | 
| 
      
 44 
     | 
    
         
            +
                        end
         
     | 
| 
      
 45 
     | 
    
         
            +
                        define_method :"#{name}=" do |*args|
         
     | 
| 
      
 46 
     | 
    
         
            +
                          if args.first.is_a? Time
         
     | 
| 
      
 47 
     | 
    
         
            +
                            data_object[name] = args.first.xmlschema(9)
         
     | 
| 
      
 48 
     | 
    
         
            +
                          else
         
     | 
| 
      
 49 
     | 
    
         
            +
                            data_object[name] = args.first
         
     | 
| 
      
 50 
     | 
    
         
            +
                          end
         
     | 
| 
      
 51 
     | 
    
         
            +
                        end
         
     | 
| 
      
 52 
     | 
    
         
            +
                      end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                    end
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,90 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'eventmachine'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rflow/component'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require 'digest/md5'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            class RFlow
         
     | 
| 
      
 7 
     | 
    
         
            +
              module Components
         
     | 
| 
      
 8 
     | 
    
         
            +
                module File
         
     | 
| 
      
 9 
     | 
    
         
            +
                  class OutputRawToFiles < RFlow::Component
         
     | 
| 
      
 10 
     | 
    
         
            +
                    input_port :raw_port
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                    DEFAULT_CONFIG = {
         
     | 
| 
      
 13 
     | 
    
         
            +
                      'directory_path'  => '/tmp',
         
     | 
| 
      
 14 
     | 
    
         
            +
                      'file_name_prefix' => 'output.', 
         
     | 
| 
      
 15 
     | 
    
         
            +
                      'file_name_suffix' => '.out', 
         
     | 
| 
      
 16 
     | 
    
         
            +
                    }
         
     | 
| 
      
 17 
     | 
    
         
            +
                    
         
     | 
| 
      
 18 
     | 
    
         
            +
                    attr_accessor :config, :directory_path, :file_name_prefix, :file_name_suffix
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    
         
     | 
| 
      
 21 
     | 
    
         
            +
                    def configure!(config)
         
     | 
| 
      
 22 
     | 
    
         
            +
                      @config = DEFAULT_CONFIG.merge config
         
     | 
| 
      
 23 
     | 
    
         
            +
                      @directory_path  = ::File.expand_path(@config['directory_path'])
         
     | 
| 
      
 24 
     | 
    
         
            +
                      @file_name_prefix = @config['file_name_prefix']
         
     | 
| 
      
 25 
     | 
    
         
            +
                      @file_name_suffix = @config['file_name_suffix']
         
     | 
| 
      
 26 
     | 
    
         
            +
                      
         
     | 
| 
      
 27 
     | 
    
         
            +
                      unless ::File.directory?(@directory_path)
         
     | 
| 
      
 28 
     | 
    
         
            +
                        raise ArgumentError, "Invalid directory '#{@directory_path}'"
         
     | 
| 
      
 29 
     | 
    
         
            +
                      end
         
     | 
| 
      
 30 
     | 
    
         
            +
                      
         
     | 
| 
      
 31 
     | 
    
         
            +
                      unless ::File.writable?(@directory_path)
         
     | 
| 
      
 32 
     | 
    
         
            +
                        raise ArgumentError, "Unable to read from directory '#{@directory_path}'"
         
     | 
| 
      
 33 
     | 
    
         
            +
                      end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                      @output_file_entropy = 0
         
     | 
| 
      
 36 
     | 
    
         
            +
                      
         
     | 
| 
      
 37 
     | 
    
         
            +
                      # TODO: more error checking of input config
         
     | 
| 
      
 38 
     | 
    
         
            +
                    end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                    
         
     | 
| 
      
 41 
     | 
    
         
            +
                    def process_message(input_port, input_port_key, connection, message)
         
     | 
| 
      
 42 
     | 
    
         
            +
                      return unless message.data_type_name == 'RFlow::Message::Data::Raw'
         
     | 
| 
      
 43 
     | 
    
         
            +
                      
         
     | 
| 
      
 44 
     | 
    
         
            +
                      @output_file_entropy = 0
         
     | 
| 
      
 45 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 46 
     | 
    
         
            +
                        final_output_file_name = output_file_name
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                        temp_output_file_path = ::File.join(directory_path, ".#{final_output_file_name}")
         
     | 
| 
      
 49 
     | 
    
         
            +
                        final_output_file_path = ::File.join(directory_path, "#{final_output_file_name}")
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                        RFlow.logger.debug "#{self.class.name}##{__method__}: Outputting raw message to #{final_output_file_path} (via #{temp_output_file_path}) with #{message.data.raw.bytesize} bytes and md5 #{Digest::MD5.hexdigest message.data.raw}"
         
     | 
| 
      
 52 
     | 
    
         
            +
                        
         
     | 
| 
      
 53 
     | 
    
         
            +
                        ::File.open(temp_output_file_path, ::File::CREAT|::File::EXCL|::File::RDWR, 0644) do |file|
         
     | 
| 
      
 54 
     | 
    
         
            +
                          file.flock(::File::LOCK_EX)
         
     | 
| 
      
 55 
     | 
    
         
            +
                          file.write(message.data.raw)
         
     | 
| 
      
 56 
     | 
    
         
            +
                        end
         
     | 
| 
      
 57 
     | 
    
         
            +
                        ::File.rename(temp_output_file_path, final_output_file_path)
         
     | 
| 
      
 58 
     | 
    
         
            +
                        RFlow.logger.debug "#{self.class.name}##{__method__}: Succesfully output raw message to #{final_output_file_path}"
         
     | 
| 
      
 59 
     | 
    
         
            +
                      rescue Errno::EEXIST => e
         
     | 
| 
      
 60 
     | 
    
         
            +
                        RFlow.logger.debug("#{self.class.name}##{__method__}: File #{temp_output_file_path} exists, increasing entropy")
         
     | 
| 
      
 61 
     | 
    
         
            +
                        retry
         
     | 
| 
      
 62 
     | 
    
         
            +
                      end
         
     | 
| 
      
 63 
     | 
    
         
            +
                      
         
     | 
| 
      
 64 
     | 
    
         
            +
                      final_output_file_path
         
     | 
| 
      
 65 
     | 
    
         
            +
                    end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                    
         
     | 
| 
      
 68 
     | 
    
         
            +
                    private
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                    
         
     | 
| 
      
 71 
     | 
    
         
            +
                    def output_file_name 
         
     | 
| 
      
 72 
     | 
    
         
            +
                      "#{file_name_prefix}#{current_timestamp}-#{output_file_entropy}#{file_name_suffix}"
         
     | 
| 
      
 73 
     | 
    
         
            +
                    end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                    
         
     | 
| 
      
 76 
     | 
    
         
            +
                    def output_file_entropy
         
     | 
| 
      
 77 
     | 
    
         
            +
                      @output_file_entropy += 1
         
     | 
| 
      
 78 
     | 
    
         
            +
                      sprintf("%04d", @output_file_entropy)
         
     | 
| 
      
 79 
     | 
    
         
            +
                    end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                    
         
     | 
| 
      
 82 
     | 
    
         
            +
                    def current_timestamp
         
     | 
| 
      
 83 
     | 
    
         
            +
                      time = Time.now
         
     | 
| 
      
 84 
     | 
    
         
            +
                      time.utc.strftime("%Y%m%d_%H%M%S.") + "%06d" % time.utc.usec
         
     | 
| 
      
 85 
     | 
    
         
            +
                    end
         
     | 
| 
      
 86 
     | 
    
         
            +
                    
         
     | 
| 
      
 87 
     | 
    
         
            +
                  end
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
              end
         
     | 
| 
      
 90 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,26 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rflow/components/file/extensions'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rflow/components/file/directory_watcher'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'rflow/components/file/output_raw_to_files'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            class RFlow
         
     | 
| 
      
 6 
     | 
    
         
            +
              module Components
         
     | 
| 
      
 7 
     | 
    
         
            +
                module File
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # Load the schemas
         
     | 
| 
      
 9 
     | 
    
         
            +
                  SCHEMA_DIRECTORY = ::File.expand_path(::File.join(::File.dirname(__FILE__), '..', '..', '..', 'schema'))
         
     | 
| 
      
 10 
     | 
    
         
            +
                  
         
     | 
| 
      
 11 
     | 
    
         
            +
                  SCHEMA_FILES = {
         
     | 
| 
      
 12 
     | 
    
         
            +
                    'file.avsc' => 'RFlow::Message::Data::File',
         
     | 
| 
      
 13 
     | 
    
         
            +
                  }
         
     | 
| 
      
 14 
     | 
    
         
            +
                  
         
     | 
| 
      
 15 
     | 
    
         
            +
                  SCHEMA_FILES.each do |file_name, data_type_name|
         
     | 
| 
      
 16 
     | 
    
         
            +
                    schema_string = ::File.read(::File.join(SCHEMA_DIRECTORY, file_name))
         
     | 
| 
      
 17 
     | 
    
         
            +
                    RFlow::Configuration.add_available_data_type data_type_name, 'avro', schema_string
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  # Load the data extensions
         
     | 
| 
      
 21 
     | 
    
         
            +
                  RFlow::Configuration.add_available_data_extension('RFlow::Message::Data::File',
         
     | 
| 
      
 22 
     | 
    
         
            +
                                                                    RFlow::Components::File::Extensions::FileExtension)
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- encoding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            $:.push File.expand_path("../lib", __FILE__)
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "rflow/components/file/version"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            Gem::Specification.new do |s|
         
     | 
| 
      
 6 
     | 
    
         
            +
              s.name        = "rflow-components-file"
         
     | 
| 
      
 7 
     | 
    
         
            +
              s.version     = RFlow::Components::File::VERSION
         
     | 
| 
      
 8 
     | 
    
         
            +
              s.platform    = Gem::Platform::RUBY
         
     | 
| 
      
 9 
     | 
    
         
            +
              s.required_ruby_version = '~> 1.9'
         
     | 
| 
      
 10 
     | 
    
         
            +
              s.authors     = ["Michael L. Artz"]
         
     | 
| 
      
 11 
     | 
    
         
            +
              s.email       = ["michael.artz@redjack.com"]
         
     | 
| 
      
 12 
     | 
    
         
            +
              s.homepage    = ""
         
     | 
| 
      
 13 
     | 
    
         
            +
              s.summary     = %q{Components that operate on files for the RFlow FBP framework}
         
     | 
| 
      
 14 
     | 
    
         
            +
              s.description = %q{Components that operate on files for the RFlow FBP framework.  Also includes the File schema}
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              s.rubyforge_project = "rflow-components-file"
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              s.files         = `git ls-files`.split("\n")
         
     | 
| 
      
 19 
     | 
    
         
            +
              s.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
         
     | 
| 
      
 20 
     | 
    
         
            +
              s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
         
     | 
| 
      
 21 
     | 
    
         
            +
              s.require_paths = ["lib"]
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              s.add_dependency 'rflow', '~> 0.0'
         
     | 
| 
      
 24 
     | 
    
         
            +
              s.add_dependency 'eventmachine_httpserver', '~> 0.2'
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              s.add_development_dependency 'rspec', '~> 2.6'
         
     | 
| 
      
 27 
     | 
    
         
            +
              s.add_development_dependency 'rake', '~> 0.8'
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
    
        data/schema/file.avsc
    ADDED
    
    | 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            {
         
     | 
| 
      
 2 
     | 
    
         
            +
                "type": "record",
         
     | 
| 
      
 3 
     | 
    
         
            +
                "name": "File",
         
     | 
| 
      
 4 
     | 
    
         
            +
                "namespace": "org.rflow.message.data",
         
     | 
| 
      
 5 
     | 
    
         
            +
                "aliases": [],
         
     | 
| 
      
 6 
     | 
    
         
            +
                "fields": [
         
     | 
| 
      
 7 
     | 
    
         
            +
                    {"name": "path",    "type": ["string", "null"]},
         
     | 
| 
      
 8 
     | 
    
         
            +
                    {"name": "size",    "type": "long"},
         
     | 
| 
      
 9 
     | 
    
         
            +
                    {"name": "content", "type": "bytes"},
         
     | 
| 
      
 10 
     | 
    
         
            +
                    {"name": "creation_timestamp",     "type": ["string", "null"]},
         
     | 
| 
      
 11 
     | 
    
         
            +
                    {"name": "modification_timestamp", "type": ["string", "null"]},
         
     | 
| 
      
 12 
     | 
    
         
            +
                    {"name": "access_timestamp",       "type": ["string", "null"]}
         
     | 
| 
      
 13 
     | 
    
         
            +
                ]
         
     | 
| 
      
 14 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,49 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper.rb'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'time'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            describe RFlow::Components::File::Extensions::FileExtension do
         
     | 
| 
      
 6 
     | 
    
         
            +
              before(:each) do
         
     | 
| 
      
 7 
     | 
    
         
            +
                @schema_string = RFlow::Configuration.available_data_types['RFlow::Message::Data::File']['avro']
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              it "should add the extension to RFlow::Configuration" do
         
     | 
| 
      
 11 
     | 
    
         
            +
                RFlow::Configuration.available_data_extensions['RFlow::Message::Data::File'].should include(described_class)
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
              
         
     | 
| 
      
 14 
     | 
    
         
            +
              it "should set the defaults" do
         
     | 
| 
      
 15 
     | 
    
         
            +
                file = RFlow::Message.new('RFlow::Message::Data::File')
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                file.data.path.should == '/'
         
     | 
| 
      
 18 
     | 
    
         
            +
                file.data.size.should == 0
         
     | 
| 
      
 19 
     | 
    
         
            +
                file.data.content.should == ''
         
     | 
| 
      
 20 
     | 
    
         
            +
                file.data.creation_timestamp.should == nil
         
     | 
| 
      
 21 
     | 
    
         
            +
                file.data.modification_timestamp.should == nil
         
     | 
| 
      
 22 
     | 
    
         
            +
                file.data.access_timestamp.should == nil
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              it "should correctly use integers or strings for size field" do
         
     | 
| 
      
 26 
     | 
    
         
            +
                file = RFlow::Message.new('RFlow::Message::Data::File')
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                file.data.size.should == 0
         
     | 
| 
      
 29 
     | 
    
         
            +
                file.data.size = 10
         
     | 
| 
      
 30 
     | 
    
         
            +
                file.data.size.should == 10
         
     | 
| 
      
 31 
     | 
    
         
            +
                file.data.size = '20'
         
     | 
| 
      
 32 
     | 
    
         
            +
                file.data.size == 20
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              it "should correctly use Time or xmlschema strings for timestamp fields" do
         
     | 
| 
      
 36 
     | 
    
         
            +
                file = RFlow::Message.new('RFlow::Message::Data::File')
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                file.data.creation_timestamp.should == nil
         
     | 
| 
      
 39 
     | 
    
         
            +
                now = Time.now
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                file.data.creation_timestamp = now
         
     | 
| 
      
 42 
     | 
    
         
            +
                file.data.creation_timestamp.should == Time.xmlschema(now.xmlschema(9))
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                file.data.creation_timestamp = now.xmlschema
         
     | 
| 
      
 45 
     | 
    
         
            +
                file.data.creation_timestamp.should == Time.xmlschema(now.xmlschema)
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              
         
     | 
| 
      
 49 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper.rb'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe RFlow::Components::File::OutputRawToFiles do
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              it "should correctly process file name prefix/suffix" do
         
     | 
| 
      
 6 
     | 
    
         
            +
                component = described_class.new(1)
         
     | 
| 
      
 7 
     | 
    
         
            +
                component.configure!('file_name_prefix' => 'boom', 'file_name_suffix' => 'town', 'directory_path' => '/tmp')
         
     | 
| 
      
 8 
     | 
    
         
            +
                component.send(:output_file_name).should match(/boom.*0001town/)
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              it "should do stuff" do
         
     | 
| 
      
 12 
     | 
    
         
            +
                component = described_class.new(1)
         
     | 
| 
      
 13 
     | 
    
         
            +
                component.configure!('file_name_prefix' => 'boom.', 'file_name_suffix' => '.town', 'directory_path' => '/tmp')
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                message = RFlow::Message.new('RFlow::Message::Data::Raw')
         
     | 
| 
      
 16 
     | 
    
         
            +
                message.data.raw = 'boomertown'
         
     | 
| 
      
 17 
     | 
    
         
            +
                
         
     | 
| 
      
 18 
     | 
    
         
            +
                output_file_path = component.process_message nil, nil, nil, message
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                File.exist?(output_file_path).should be_true
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
              
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
    
        data/spec/schema_spec.rb
    ADDED
    
    | 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper.rb'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe 'RFlow::Message::Data::File Avro Schema' do
         
     | 
| 
      
 4 
     | 
    
         
            +
              before(:each) do
         
     | 
| 
      
 5 
     | 
    
         
            +
                @schema_string = RFlow::Configuration.available_data_types['RFlow::Message::Data::File']['avro']
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
              
         
     | 
| 
      
 8 
     | 
    
         
            +
              it "should encode and decode an object" do
         
     | 
| 
      
 9 
     | 
    
         
            +
                file = {
         
     | 
| 
      
 10 
     | 
    
         
            +
                  'path' => '/full/file/path/filename',
         
     | 
| 
      
 11 
     | 
    
         
            +
                  'size' => 1,
         
     | 
| 
      
 12 
     | 
    
         
            +
                  'content' => 'CONTENT',
         
     | 
| 
      
 13 
     | 
    
         
            +
                  'creation_timestamp' => 'CREATEDTIMESTRING',
         
     | 
| 
      
 14 
     | 
    
         
            +
                  'modification_timestamp' => 'MODIFIEDTIMESTRING',
         
     | 
| 
      
 15 
     | 
    
         
            +
                  'access_timestamp' => 'ACCESSEDTIMESTRING'
         
     | 
| 
      
 16 
     | 
    
         
            +
                }
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                expect {encode_avro(@schema_string, file)}.to_not raise_error
         
     | 
| 
      
 19 
     | 
    
         
            +
                avro_encoded_file = encode_avro(@schema_string, file)
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                expect {decode_avro(@schema_string, avro_encoded_file)}.to_not raise_error
         
     | 
| 
      
 22 
     | 
    
         
            +
                decoded_file = decode_avro(@schema_string, avro_encoded_file)
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                decoded_file.should == file
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
    
        data/spec/spec_helper.rb
    ADDED
    
    | 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'rflow-components-file'))
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'logger'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            RFlow.logger = Logger.new STDOUT
         
     | 
| 
      
 6 
     | 
    
         
            +
              
         
     | 
| 
      
 7 
     | 
    
         
            +
            def decode_avro(schema_string, serialized_object)
         
     | 
| 
      
 8 
     | 
    
         
            +
              schema = Avro::Schema.parse(schema_string)
         
     | 
| 
      
 9 
     | 
    
         
            +
              sio = StringIO.new(serialized_object)
         
     | 
| 
      
 10 
     | 
    
         
            +
              Avro::IO::DatumReader.new(schema, schema).read Avro::IO::BinaryDecoder.new(sio)
         
     | 
| 
      
 11 
     | 
    
         
            +
            end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            def encode_avro(schema_string, object)
         
     | 
| 
      
 14 
     | 
    
         
            +
              schema = Avro::Schema.parse(schema_string)
         
     | 
| 
      
 15 
     | 
    
         
            +
              sio = StringIO.new
         
     | 
| 
      
 16 
     | 
    
         
            +
              Avro::IO::DatumWriter.new(schema).write object, Avro::IO::BinaryEncoder.new(sio)
         
     | 
| 
      
 17 
     | 
    
         
            +
              sio.string
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,131 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: rflow-components-file
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.0.5
         
     | 
| 
      
 5 
     | 
    
         
            +
              prerelease: 
         
     | 
| 
      
 6 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 7 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 8 
     | 
    
         
            +
            - Michael L. Artz
         
     | 
| 
      
 9 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 10 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 11 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2014-03-16 00:00:00.000000000 Z
         
     | 
| 
      
 13 
     | 
    
         
            +
            dependencies:
         
     | 
| 
      
 14 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 15 
     | 
    
         
            +
              name: rflow
         
     | 
| 
      
 16 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 17 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 18 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 19 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 20 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 21 
     | 
    
         
            +
                    version: '0.0'
         
     | 
| 
      
 22 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 23 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 24 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 25 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 26 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 27 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 28 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 29 
     | 
    
         
            +
                    version: '0.0'
         
     | 
| 
      
 30 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 31 
     | 
    
         
            +
              name: eventmachine_httpserver
         
     | 
| 
      
 32 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 33 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 34 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 35 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 36 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 37 
     | 
    
         
            +
                    version: '0.2'
         
     | 
| 
      
 38 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 39 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 40 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 41 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 42 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 43 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 44 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 45 
     | 
    
         
            +
                    version: '0.2'
         
     | 
| 
      
 46 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 47 
     | 
    
         
            +
              name: rspec
         
     | 
| 
      
 48 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 49 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 50 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 51 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 52 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 53 
     | 
    
         
            +
                    version: '2.6'
         
     | 
| 
      
 54 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 55 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 56 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 57 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 58 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 59 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 60 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 61 
     | 
    
         
            +
                    version: '2.6'
         
     | 
| 
      
 62 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 63 
     | 
    
         
            +
              name: rake
         
     | 
| 
      
 64 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 65 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 66 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 67 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 68 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 69 
     | 
    
         
            +
                    version: '0.8'
         
     | 
| 
      
 70 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 71 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 72 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 73 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 74 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 75 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 76 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 77 
     | 
    
         
            +
                    version: '0.8'
         
     | 
| 
      
 78 
     | 
    
         
            +
            description: Components that operate on files for the RFlow FBP framework.  Also includes
         
     | 
| 
      
 79 
     | 
    
         
            +
              the File schema
         
     | 
| 
      
 80 
     | 
    
         
            +
            email:
         
     | 
| 
      
 81 
     | 
    
         
            +
            - michael.artz@redjack.com
         
     | 
| 
      
 82 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 83 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 84 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 85 
     | 
    
         
            +
            files:
         
     | 
| 
      
 86 
     | 
    
         
            +
            - .gitignore
         
     | 
| 
      
 87 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
      
 88 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 89 
     | 
    
         
            +
            - lib/rflow-components-file.rb
         
     | 
| 
      
 90 
     | 
    
         
            +
            - lib/rflow/components/file.rb
         
     | 
| 
      
 91 
     | 
    
         
            +
            - lib/rflow/components/file/directory_watcher.rb
         
     | 
| 
      
 92 
     | 
    
         
            +
            - lib/rflow/components/file/extensions.rb
         
     | 
| 
      
 93 
     | 
    
         
            +
            - lib/rflow/components/file/output_raw_to_files.rb
         
     | 
| 
      
 94 
     | 
    
         
            +
            - lib/rflow/components/file/version.rb
         
     | 
| 
      
 95 
     | 
    
         
            +
            - rflow-components-file.gemspec
         
     | 
| 
      
 96 
     | 
    
         
            +
            - schema/file.avsc
         
     | 
| 
      
 97 
     | 
    
         
            +
            - spec/directory_watcher_spec.rb
         
     | 
| 
      
 98 
     | 
    
         
            +
            - spec/extensions_spec.rb
         
     | 
| 
      
 99 
     | 
    
         
            +
            - spec/output_raw_to_files_spec.rb
         
     | 
| 
      
 100 
     | 
    
         
            +
            - spec/schema_spec.rb
         
     | 
| 
      
 101 
     | 
    
         
            +
            - spec/spec_helper.rb
         
     | 
| 
      
 102 
     | 
    
         
            +
            homepage: ''
         
     | 
| 
      
 103 
     | 
    
         
            +
            licenses: []
         
     | 
| 
      
 104 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 105 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 106 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 107 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 108 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 109 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 110 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 111 
     | 
    
         
            +
              - - ~>
         
     | 
| 
      
 112 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 113 
     | 
    
         
            +
                  version: '1.9'
         
     | 
| 
      
 114 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 115 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 116 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 117 
     | 
    
         
            +
              - - ! '>='
         
     | 
| 
      
 118 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 119 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 120 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 121 
     | 
    
         
            +
            rubyforge_project: rflow-components-file
         
     | 
| 
      
 122 
     | 
    
         
            +
            rubygems_version: 1.8.24
         
     | 
| 
      
 123 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 124 
     | 
    
         
            +
            specification_version: 3
         
     | 
| 
      
 125 
     | 
    
         
            +
            summary: Components that operate on files for the RFlow FBP framework
         
     | 
| 
      
 126 
     | 
    
         
            +
            test_files:
         
     | 
| 
      
 127 
     | 
    
         
            +
            - spec/directory_watcher_spec.rb
         
     | 
| 
      
 128 
     | 
    
         
            +
            - spec/extensions_spec.rb
         
     | 
| 
      
 129 
     | 
    
         
            +
            - spec/output_raw_to_files_spec.rb
         
     | 
| 
      
 130 
     | 
    
         
            +
            - spec/schema_spec.rb
         
     | 
| 
      
 131 
     | 
    
         
            +
            - spec/spec_helper.rb
         
     |