content_server 1.1.0 → 1.2.0
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/bin/backup_server +8 -20
- data/bin/content_server +8 -20
- data/bin/testing_memory +60 -0
- data/bin/testing_server +57 -0
- data/ext/run_in_background/mkrf_conf.rb +34 -0
- data/lib/content_data/content_data.rb +613 -0
- data/lib/content_data/version.rb +3 -0
- data/lib/content_data.rb +6 -0
- data/lib/content_server/backup_server.rb +65 -86
- data/lib/content_server/content_server.rb +47 -77
- data/lib/content_server/file_streamer.rb +27 -33
- data/lib/content_server/queue_copy.rb +154 -49
- data/lib/content_server/queue_indexer.rb +19 -11
- data/lib/content_server/remote_content.rb +41 -23
- data/lib/content_server/server.rb +91 -0
- data/lib/content_server/version.rb +1 -1
- data/lib/content_server.rb +0 -15
- data/lib/email/email.rb +87 -0
- data/lib/email/version.rb +3 -0
- data/lib/email.rb +4 -0
- data/lib/file_copy/copy.rb +68 -0
- data/lib/file_copy/version.rb +4 -0
- data/lib/file_copy.rb +4 -0
- data/lib/file_indexing/index_agent.rb +170 -0
- data/lib/file_indexing/indexer_patterns.rb +72 -0
- data/lib/file_indexing/version.rb +3 -0
- data/lib/file_indexing.rb +9 -0
- data/lib/file_monitoring/file_monitoring.rb +105 -0
- data/lib/file_monitoring/monitor_path.rb +304 -0
- data/lib/file_monitoring/version.rb +3 -0
- data/lib/file_monitoring.rb +29 -0
- data/lib/file_utils/file_generator/README +97 -0
- data/lib/file_utils/file_generator/file_generator.rb +156 -0
- data/lib/file_utils/file_utils.rb +260 -0
- data/lib/file_utils/version.rb +3 -0
- data/lib/file_utils.rb +4 -0
- data/lib/log/version.rb +3 -0
- data/lib/log.rb +188 -0
- data/lib/networking/tcp.rb +213 -0
- data/lib/networking/version.rb +3 -0
- data/lib/networking.rb +4 -0
- data/lib/params/version.rb +3 -0
- data/lib/params.rb +419 -0
- data/lib/process_monitoring/monitoring.rb +85 -0
- data/lib/process_monitoring/monitoring_info.rb +79 -0
- data/lib/process_monitoring/send_email.rb +40 -0
- data/lib/process_monitoring/thread_safe_hash.rb +77 -0
- data/lib/process_monitoring/version.rb +3 -0
- data/lib/process_monitoring.rb +6 -0
- data/lib/run_in_background/version.rb +3 -0
- data/lib/run_in_background.rb +432 -0
- data/lib/testing_memory/testing_memory.rb +187 -0
- data/lib/testing_server/testing_server.rb +236 -0
- data/lib/testing_server/version.rb +3 -0
- data/lib/testing_server.rb +12 -0
- data/lib/validations/index_validations.rb +106 -0
- data/lib/validations/version.rb +3 -0
- data/lib/validations.rb +4 -0
- data/spec/content_data/validations_spec.rb +113 -0
- data/spec/file_copy/copy_spec.rb +54 -0
- data/spec/file_indexing/index_agent_spec.rb +53 -0
- data/spec/networking/tcp_spec.rb +95 -0
- data/spec/validations/index_validations_spec.rb +77 -0
- data/test/content_data/content_data_test.rb +290 -0
- data/test/file_generator/file_generator_spec.rb +84 -0
- data/test/file_indexing/index_agent_test/New.txt +0 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/bin/libexslt.dll +0 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/bin/libxslt.dll +0 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/bin/xsltproc.exe +0 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libexslt/exslt.h +102 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libexslt/exsltconfig.h +73 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libexslt/exsltexports.h +140 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libexslt/libexslt.h +29 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/attributes.h +38 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/documents.h +93 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/extensions.h +262 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/extra.h +80 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/functions.h +78 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/imports.h +75 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/keys.h +53 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/libxslt.h +30 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/namespaces.h +68 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/numbersInternals.h +69 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/pattern.h +81 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/preproc.h +43 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/security.h +104 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/templates.h +77 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/transform.h +207 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/trio.h +216 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/triodef.h +220 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/variables.h +91 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/win32config.h +101 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xslt.h +103 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltInternals.h +1967 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltconfig.h +172 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltexports.h +142 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltlocale.h +57 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltutils.h +309 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltwin32config.h +105 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/lib/libexslt.lib +0 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/lib/libexslt_a.lib +0 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/lib/libxslt.lib +0 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/lib/libxslt_a.lib +0 -0
- data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/readme.txt +22 -0
- data/test/file_indexing/index_agent_test/patterns.input +3 -0
- data/test/file_indexing/index_agent_test.rb +51 -0
- data/test/file_monitoring/file_monitoring_test/conf.yml +4 -0
- data/test/file_monitoring/file_monitoring_test/conf_win32.yml +5 -0
- data/test/file_monitoring/file_monitoring_test/log +56 -0
- data/test/file_monitoring/file_monitoring_test.rb +0 -0
- data/test/file_monitoring/monitor_path_test/dir1000/test_file.1000 +1000 -0
- data/test/file_monitoring/monitor_path_test/dir1000/test_file.1000.0 +1000 -0
- data/test/file_monitoring/monitor_path_test/dir1000/test_file.1000.1 +1000 -0
- data/test/file_monitoring/monitor_path_test/dir1500/test_file.1500 +1500 -0
- data/test/file_monitoring/monitor_path_test/dir1500/test_file.1500.0 +1500 -0
- data/test/file_monitoring/monitor_path_test/dir1500/test_file.1500.1 +1500 -0
- data/test/file_monitoring/monitor_path_test/test_file.500 +500 -0
- data/test/file_monitoring/monitor_path_test/test_file.500.0 +500 -0
- data/test/file_monitoring/monitor_path_test/test_file.500.1 +500 -0
- data/test/file_monitoring/monitor_path_test.rb +153 -0
- data/test/file_utils/fileutil_mksymlink_test/dir1000/dir1500/test_file.1500 +1500 -0
- data/test/file_utils/fileutil_mksymlink_test/dir1000/dir1500/test_file.1500.0 +1500 -0
- data/test/file_utils/fileutil_mksymlink_test/dir1000/dir1500/test_file.1500.1 +1500 -0
- data/test/file_utils/fileutil_mksymlink_test/dir1000/test_file.1000 +1000 -0
- data/test/file_utils/fileutil_mksymlink_test/dir1000/test_file.1000.0 +1000 -0
- data/test/file_utils/fileutil_mksymlink_test/dir1000/test_file.1000.1 +1000 -0
- data/test/file_utils/fileutil_mksymlink_test/test_file.500 +500 -0
- data/test/file_utils/fileutil_mksymlink_test/test_file.500.0 +500 -0
- data/test/file_utils/fileutil_mksymlink_test/test_file.500.1 +500 -0
- data/test/file_utils/fileutil_mksymlink_test.rb +125 -0
- data/test/file_utils/time_modification_test.rb +132 -0
- data/test/params/params_spec.rb +280 -0
- data/test/params/params_test.rb +43 -0
- data/test/run_in_background/run_in_background_test.rb +122 -0
- data/test/run_in_background/test_app +57 -0
- metadata +272 -132
- data/lib/content_server/globals.rb +0 -10
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
require 'content_server/server'
|
|
2
|
+
require 'log'
|
|
3
|
+
require 'params'
|
|
4
|
+
|
|
5
|
+
module FileMonitoring
|
|
6
|
+
# Path monitoring.
|
|
7
|
+
|
|
8
|
+
# Enum-like structure that includes possible filesystem entities (files/directories) states:
|
|
9
|
+
# * <tt>NON_EXISTING</tt> - Entity that was treated during previous run, but absent currently
|
|
10
|
+
# * <tt>NEW</tt> - Entity that was found and added to control during this run
|
|
11
|
+
# * <tt>CHANGED</tt> - State was changed between two checks
|
|
12
|
+
# * <tt>UNCHANGED</tt> - Opposite to CHANGED
|
|
13
|
+
# * <tt>STABLE</tt> - Entity is in the UNCHANGED state for a defined (by user) number of iterations
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class FileStatEnum
|
|
17
|
+
NON_EXISTING = "NON_EXISTING"
|
|
18
|
+
NEW = "NEW"
|
|
19
|
+
CHANGED = "CHANGED"
|
|
20
|
+
UNCHANGED = "UNCHANGED"
|
|
21
|
+
STABLE = "STABLE"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# This class holds current state of file and methods to control and report changes
|
|
25
|
+
class FileStat
|
|
26
|
+
attr_reader :cycles, :path, :stable_state, :state, :size, :modification_time
|
|
27
|
+
|
|
28
|
+
DEFAULT_STABLE_STATE = 10
|
|
29
|
+
|
|
30
|
+
@@log = nil
|
|
31
|
+
|
|
32
|
+
# Initializes new file monitoring object
|
|
33
|
+
# ==== Arguments:
|
|
34
|
+
#
|
|
35
|
+
# * <tt>path</tt> - File location
|
|
36
|
+
# * <tt>stable_state</tt> - Number of iterations to move unchanged file to stable state
|
|
37
|
+
def initialize(path, stable_state = DEFAULT_STABLE_STATE, content_data_cache, state)
|
|
38
|
+
@path ||= path
|
|
39
|
+
@size = nil
|
|
40
|
+
@creation_time = nil
|
|
41
|
+
@modification_time = nil
|
|
42
|
+
@cycles = 0 # number of iterations from the last file modification
|
|
43
|
+
@state = state
|
|
44
|
+
@stable_state = stable_state # number of iteration to move unchanged file to stable state
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def set_output_queue(event_queue)
|
|
48
|
+
@event_queue = event_queue
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Sets a log file to report changes
|
|
52
|
+
# ==== Arguments:
|
|
53
|
+
#
|
|
54
|
+
# * <tt>log</tt> - already opened ruby File object
|
|
55
|
+
def self.set_log (log)
|
|
56
|
+
@@log = log
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Checks whether file was changed from the last iteration.
|
|
60
|
+
# For files, size and modification time are checked.
|
|
61
|
+
def monitor
|
|
62
|
+
file_stats = File.lstat(@path) rescue nil
|
|
63
|
+
new_state = nil
|
|
64
|
+
if file_stats == nil
|
|
65
|
+
new_state = FileStatEnum::NON_EXISTING
|
|
66
|
+
@size = nil
|
|
67
|
+
@creation_time = nil
|
|
68
|
+
@modification_time = nil
|
|
69
|
+
@cycles = 0
|
|
70
|
+
elsif @size == nil
|
|
71
|
+
new_state = FileStatEnum::NEW
|
|
72
|
+
@size = file_stats.size
|
|
73
|
+
@creation_time = file_stats.ctime.utc
|
|
74
|
+
@modification_time = file_stats.mtime.utc
|
|
75
|
+
@cycles = 0
|
|
76
|
+
elsif changed?(file_stats)
|
|
77
|
+
new_state = FileStatEnum::CHANGED
|
|
78
|
+
@size = file_stats.size
|
|
79
|
+
@creation_time = file_stats.ctime.utc
|
|
80
|
+
@modification_time = file_stats.mtime.utc
|
|
81
|
+
@cycles = 0
|
|
82
|
+
else
|
|
83
|
+
new_state = FileStatEnum::UNCHANGED
|
|
84
|
+
@cycles += 1
|
|
85
|
+
if @cycles >= @stable_state
|
|
86
|
+
new_state = FileStatEnum::STABLE
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# The assignment
|
|
91
|
+
self.state= new_state
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Checks that stored file attributes are the same as file attributes taken from file system.
|
|
95
|
+
def changed?(file_stats)
|
|
96
|
+
not (file_stats.size == @size &&
|
|
97
|
+
file_stats.ctime.utc == @creation_time.utc &&
|
|
98
|
+
file_stats.mtime.utc == @modification_time.utc)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def set_event_queue(queue)
|
|
102
|
+
@event_queue = queue
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Sets and writes to the log a new state.
|
|
106
|
+
def state= (new_state)
|
|
107
|
+
if (@state != new_state or @state == FileStatEnum::CHANGED)
|
|
108
|
+
@state = new_state
|
|
109
|
+
if (@@log)
|
|
110
|
+
@@log.info(state + ": " + path)
|
|
111
|
+
@@log.outputters[0].flush if Params['log_flush_each_message']
|
|
112
|
+
end
|
|
113
|
+
if @event_queue and FileStatEnum::NEW != @state # NEW state is ignored in indexer
|
|
114
|
+
Log.debug1 "Writing to event queue [#{self.state}, #{self.path}]"
|
|
115
|
+
@event_queue.push([self.state, self.instance_of?(DirStat), self.path,
|
|
116
|
+
self.modification_time, self.size])
|
|
117
|
+
$process_vars.set('monitor to index queue size', @event_queue.size)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Checks whether path and state are the same as of the argument
|
|
123
|
+
def == (other)
|
|
124
|
+
@path == other.path and @stable_state == other.stable_state
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Returns path and state of the file with indentation
|
|
128
|
+
def to_s (indent = 0)
|
|
129
|
+
(" " * indent) + path.to_s + " : " + state.to_s
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# This class holds current state of directory and methods to control changes
|
|
134
|
+
class DirStat < FileStat
|
|
135
|
+
# Initializes new directory monitoring object
|
|
136
|
+
# ==== Arguments:
|
|
137
|
+
#
|
|
138
|
+
# * <tt>path</tt> - File location
|
|
139
|
+
# * <tt>stable_state</tt> - Number of iterations to move unchanged directory to stable state
|
|
140
|
+
def initialize(path, stable_state = DEFAULT_STABLE_STATE, content_data_cache, state)
|
|
141
|
+
super
|
|
142
|
+
@dirs = nil
|
|
143
|
+
@files = nil
|
|
144
|
+
@non_utf8_paths = {}
|
|
145
|
+
@content_data_cache = content_data_cache
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Adds directory for monitoring.
|
|
149
|
+
def add_dir (dir)
|
|
150
|
+
@dirs[dir.path] = dir
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Adds file for monitoring.
|
|
154
|
+
def add_file (file)
|
|
155
|
+
@files[file.path] = file
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Removes directory from monitoring.
|
|
159
|
+
def rm_dir(dir)
|
|
160
|
+
@dirs.delete(dir.path)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Removes file from monitoring.
|
|
164
|
+
def rm_file(file)
|
|
165
|
+
@files.delete(file.path)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Checks that there is a sub-folder with a given path.
|
|
169
|
+
def has_dir?(path)
|
|
170
|
+
@dirs.has_key?(path)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Checks that there is a file with a given path.
|
|
174
|
+
def has_file?(path)
|
|
175
|
+
@files.has_key?(path)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Returns string which contains path and state of this directory as well as it's structure.
|
|
179
|
+
def to_s(indent = 0)
|
|
180
|
+
indent_increment = 2
|
|
181
|
+
child_indent = indent + indent_increment
|
|
182
|
+
res = super
|
|
183
|
+
@files.each_value do |file|
|
|
184
|
+
res += "\n" + file.to_s(child_indent)
|
|
185
|
+
end if @files
|
|
186
|
+
@dirs.each_value do |dir|
|
|
187
|
+
res += "\n" + dir.to_s(child_indent)
|
|
188
|
+
end if @dirs
|
|
189
|
+
res
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
# Checks that directory structure (i.e. files and directories located directly under this directory)
|
|
193
|
+
# wasn't changed since the last iteration.
|
|
194
|
+
def monitor
|
|
195
|
+
was_changed = false
|
|
196
|
+
new_state = nil
|
|
197
|
+
self_stat = File.lstat(@path) rescue nil
|
|
198
|
+
if self_stat == nil
|
|
199
|
+
new_state = FileStatEnum::NON_EXISTING
|
|
200
|
+
@files = nil
|
|
201
|
+
@dirs = nil
|
|
202
|
+
@cycles = 0
|
|
203
|
+
elsif @files == nil
|
|
204
|
+
new_state = FileStatEnum::NEW
|
|
205
|
+
@files = Hash.new
|
|
206
|
+
@dirs = Hash.new
|
|
207
|
+
@cycles = 0
|
|
208
|
+
update_dir
|
|
209
|
+
elsif update_dir
|
|
210
|
+
new_state = FileStatEnum::CHANGED
|
|
211
|
+
@cycles = 0
|
|
212
|
+
else
|
|
213
|
+
new_state = FileStatEnum::UNCHANGED
|
|
214
|
+
@cycles += 1
|
|
215
|
+
if @cycles >= @stable_state
|
|
216
|
+
new_state = FileStatEnum::STABLE
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# The assignment
|
|
221
|
+
self.state= new_state
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# Updates the files and directories hashes and globs the directory for changes.
|
|
225
|
+
def update_dir
|
|
226
|
+
was_changed = false
|
|
227
|
+
|
|
228
|
+
# monitor existing and absent files
|
|
229
|
+
@files.each_value do |file|
|
|
230
|
+
file.monitor
|
|
231
|
+
|
|
232
|
+
if file.state == FileStatEnum::NON_EXISTING
|
|
233
|
+
was_changed = true
|
|
234
|
+
rm_file(file)
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
@dirs.each_value do |dir|
|
|
239
|
+
dir.monitor
|
|
240
|
+
|
|
241
|
+
if dir.state == FileStatEnum::NON_EXISTING
|
|
242
|
+
was_changed = true
|
|
243
|
+
rm_dir(dir)
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
was_changed = was_changed || glob_me
|
|
248
|
+
|
|
249
|
+
return was_changed
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# Globs the directory for new files and directories
|
|
253
|
+
def glob_me
|
|
254
|
+
was_changed = false
|
|
255
|
+
files = Dir.glob(path + "/*")
|
|
256
|
+
|
|
257
|
+
# add and monitor new files and directories
|
|
258
|
+
files.each do |file|
|
|
259
|
+
# keep only files with names in UTF-8
|
|
260
|
+
next if @non_utf8_paths[file]
|
|
261
|
+
check_utf_8_encoding_file = file.clone
|
|
262
|
+
unless check_utf_8_encoding_file.force_encoding("UTF-8").valid_encoding?
|
|
263
|
+
Log.warning("Non UTF-8 file name '#{check_utf_8_encoding_file}', skipping.")
|
|
264
|
+
@non_utf8_paths[file]=true
|
|
265
|
+
next
|
|
266
|
+
end
|
|
267
|
+
file_stat = File.lstat(file) rescue nil
|
|
268
|
+
if (file_stat.directory?)
|
|
269
|
+
unless (has_dir?(file)) # new directory
|
|
270
|
+
# change state only for existing directories
|
|
271
|
+
# newly added directories have to remain with NEW state
|
|
272
|
+
was_changed = true
|
|
273
|
+
ds = DirStat.new(file, self.stable_state, @content_data_cache, FileStatEnum::NON_EXISTING)
|
|
274
|
+
ds.set_event_queue(@event_queue) unless @event_queue.nil?
|
|
275
|
+
ds.monitor
|
|
276
|
+
add_dir(ds)
|
|
277
|
+
end
|
|
278
|
+
else # it is a file
|
|
279
|
+
unless(has_file?(file)) # new file
|
|
280
|
+
# change state only for existing directories
|
|
281
|
+
# newly added directories have to remain with NEW state
|
|
282
|
+
was_changed = true
|
|
283
|
+
# check if file exist in content data cache - set state to STABLE
|
|
284
|
+
file_state = FileStatEnum::NON_EXISTING
|
|
285
|
+
if !@content_data_cache.nil? && @content_data_cache.include?(file)
|
|
286
|
+
file_state = FileStatEnum::STABLE
|
|
287
|
+
end
|
|
288
|
+
fs = FileStat.new(file, self.stable_state, @content_data_cache, file_state)
|
|
289
|
+
|
|
290
|
+
fs.set_event_queue(@event_queue) unless @event_queue.nil?
|
|
291
|
+
fs.monitor
|
|
292
|
+
add_file(fs)
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
return was_changed
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
protected :add_dir, :add_file, :rm_dir, :rm_file, :update_dir, :glob_me
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
end
|
|
304
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'file_monitoring/file_monitoring'
|
|
2
|
+
|
|
3
|
+
# Daemon for monitoring directories for changes.
|
|
4
|
+
# Paths are checked for changes per user-defined period of time.
|
|
5
|
+
#
|
|
6
|
+
# Directory defined changed when:
|
|
7
|
+
# 1. Directory structure changed, i.e. sub-directories or files were added/removed
|
|
8
|
+
# 2. One of the files located in the directory or one of its sub-directories was changed
|
|
9
|
+
# 3. One of sub-directories changed (see 1. and 2. above)
|
|
10
|
+
#
|
|
11
|
+
# File monitoring controled by following configuration parameters:
|
|
12
|
+
# * <tt>default_monitoring_log_path</tt> - holds path of file monitoring log.
|
|
13
|
+
# This log containd track of changes found during monitoring
|
|
14
|
+
# * <tt>monitoring_paths</tt> - path and file monitoring configuration data
|
|
15
|
+
# regarding these paths.
|
|
16
|
+
|
|
17
|
+
module FileMonitoring
|
|
18
|
+
Params.path('default_monitoring_log_path', '~/.bbfs/log/file_monitoring.log',
|
|
19
|
+
'Default path for file monitoring log file. ' \
|
|
20
|
+
'This log containd track of changes found during monitoring')
|
|
21
|
+
Params.complex('monitoring_paths', [], 'Array of Hashes with 3 fields: ' \
|
|
22
|
+
'path, scan_period and stable_state.')
|
|
23
|
+
|
|
24
|
+
# @see FileMonitoring#monitor_files
|
|
25
|
+
def monitor_files
|
|
26
|
+
fm = FileMonitoring.new
|
|
27
|
+
fm.monitor_files
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
File Generator utility
|
|
2
|
+
------------------------------------------------------------------
|
|
3
|
+
A. Short program description:
|
|
4
|
+
Generates files and folders with random content with random file size according to
|
|
5
|
+
the given FileGenerator Parameters.
|
|
6
|
+
The parameters can be provided by two ways. One way is by YML file. Second way is
|
|
7
|
+
by passing parameters to application trought command line.
|
|
8
|
+
The two ways and meaning of parameters described in next sections.
|
|
9
|
+
|
|
10
|
+
B. Instalation of application and it dependencies:
|
|
11
|
+
1. The File Generator utility is integrated to general file utility.
|
|
12
|
+
You have to install file_utils and log
|
|
13
|
+
Install file_utils as follow:
|
|
14
|
+
bbfs> gem build file_utils.gemspec
|
|
15
|
+
after run this you will get next message: "Successfully built RubyGem..."
|
|
16
|
+
and run:
|
|
17
|
+
bbfs> gem install file_utils-0.0.1.gem
|
|
18
|
+
after run this you will get next message:
|
|
19
|
+
"Successfully installed file_utils-0.0.1..."
|
|
20
|
+
|
|
21
|
+
2. The File Generation Util is depend on log gem. Install log gem as follow:
|
|
22
|
+
bbfs> gem build log.gemspec
|
|
23
|
+
after run this you will get next message: "Successfully built RubyGem..."
|
|
24
|
+
run:
|
|
25
|
+
bbfs> gem install log-0.0.1.gem
|
|
26
|
+
and get "Successfully installed log-0.0.1..."
|
|
27
|
+
|
|
28
|
+
C. How to run.
|
|
29
|
+
1. Create YML configuration file and locate it in file system. The path where the
|
|
30
|
+
YML file is located must be provided by --conf_file parameter that passed to
|
|
31
|
+
program in command line.
|
|
32
|
+
2. Run the program by
|
|
33
|
+
bbfs> ruby -Ilib bin/file_utils --command=generate_files --conf_file=~/.bbfs/conf/file_generator.yml
|
|
34
|
+
3. In order to see all parameters that can be provided to application run next:
|
|
35
|
+
bbfs> ruby -Ilib bin/file_utils --print_params_to_stdout=true
|
|
36
|
+
4. In order to get help run: bbfs> ruby -Ilib bin/file_utils --help
|
|
37
|
+
|
|
38
|
+
D. Desription of YML file
|
|
39
|
+
The parameters of YML file is divided to two relevant group:
|
|
40
|
+
"Location and naming", "Processing"
|
|
41
|
+
|
|
42
|
+
********************************Location and naming*******************************
|
|
43
|
+
target_path - Represents the root path where directories and files will be
|
|
44
|
+
generated.
|
|
45
|
+
dir_name_prefix - Represents the directory name template. Name of created
|
|
46
|
+
directories will be dir_name_prefix_xxx. where xxx is random
|
|
47
|
+
characters
|
|
48
|
+
file_name_prefix - Represents the file name template for generated file. Name of
|
|
49
|
+
created files will be dir_name_prefix_xxx. where xxx is random
|
|
50
|
+
characters
|
|
51
|
+
|
|
52
|
+
*******************************************Processing**********************************************
|
|
53
|
+
total_created_directories - Represents the total created directories. Use any
|
|
54
|
+
negative value or zero for Infinity. Not relevant if
|
|
55
|
+
random calculation is triggered.
|
|
56
|
+
is_tot_files_in_dir_random - Indicates that total files in a directory will be
|
|
57
|
+
calculated randomly. If false then value will be
|
|
58
|
+
taken from parameter:'total_files_in_dir'.
|
|
59
|
+
Also lower\upper_limit_4_files_in_dir parameters will
|
|
60
|
+
not be used.
|
|
61
|
+
lower_limit_4_files_in_dir - Represents the Lower limit for total files in
|
|
62
|
+
directory for random calculation. Active only if
|
|
63
|
+
parameter:'is_tot_files_in_dir_random' is true.
|
|
64
|
+
upper_limit_4_files_in_dir - Represents the Upper limit for total files in
|
|
65
|
+
directory for random calculation. Active only if
|
|
66
|
+
parameter:'is_tot_files_in_dir_random' is true.
|
|
67
|
+
total_files_in_dir - Represents the total files in directory. Use any
|
|
68
|
+
negative value or zero for Infinity. Active only if
|
|
69
|
+
parameter:'is_tot_files_in_dir_random' is false.
|
|
70
|
+
is_use_random_size - Indicates that file size will be calculated randomly.
|
|
71
|
+
If false then value will be taken from
|
|
72
|
+
parameter:'file_size_in_mb'. Also next 2 parameters
|
|
73
|
+
will not be used.
|
|
74
|
+
upper_size_in_mb - Represents the upper limit file size in MB for random
|
|
75
|
+
size calculation.
|
|
76
|
+
Active only if parameter:'is_use_random_size' is
|
|
77
|
+
true.
|
|
78
|
+
down_size_in_mb - Represents the Lower limit file size in MB for random
|
|
79
|
+
size calculation. Active only if
|
|
80
|
+
parameter:'is_use_random_size' is true.
|
|
81
|
+
file_size_in_mb - Represents the file size in MB. Not relevant if
|
|
82
|
+
random calculation is triggered. Active only if
|
|
83
|
+
parameter:'is_use_random_size' is false.
|
|
84
|
+
sleep_time_in_seconds - Represent delay between two close cycles of
|
|
85
|
+
processing. In each cycle of processing
|
|
86
|
+
file\s and\or folder\s created.
|
|
87
|
+
|
|
88
|
+
Example of using parameter in yml document is in line below:
|
|
89
|
+
target_path: home/user_name/.bbfs/test_files
|
|
90
|
+
|
|
91
|
+
Note: you can override parameters given in YML file by providing the parameter
|
|
92
|
+
trough command line.
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# Author: Slava Pasechnik (slavapas13@gmail.com)
|
|
2
|
+
# Run from bbfs> file_utils generate_files
|
|
3
|
+
|
|
4
|
+
require 'digest'
|
|
5
|
+
require 'fileutils'
|
|
6
|
+
require 'params'
|
|
7
|
+
require 'yaml'
|
|
8
|
+
|
|
9
|
+
require 'log'
|
|
10
|
+
|
|
11
|
+
module FileGenerator
|
|
12
|
+
Params.path('target_path', '~/.bbfs/test_files', 'Represents the target path for files generation')
|
|
13
|
+
Params.boolean('is_clear_target_path', false, 'Should files and directories already presented in target path be removed')
|
|
14
|
+
Params.string('file_name_prefix', 'auto_generated_file_4_backup_server',
|
|
15
|
+
'Represents the file name template for generated file')
|
|
16
|
+
Params.string('dir_name_prefix', 'test_dir_4_backup_server',
|
|
17
|
+
'Represents the directory name template for generated file')
|
|
18
|
+
Params.integer('file_size_in_bytes', 500,
|
|
19
|
+
'Represents the required file size in MB. Not relevant if random calculation is triggered')
|
|
20
|
+
Params.integer('total_created_directories', -1,
|
|
21
|
+
'Represents the total created directories. Use any negative value or zero for Infinity.
|
|
22
|
+
Not relevant if random calculation is triggered')
|
|
23
|
+
Params.integer('max_total_files', 0, 'Maximum number of files to generate, 0 for no limit.')
|
|
24
|
+
Params.integer('total_files_in_dir', 10,
|
|
25
|
+
'Represents the total files in directory. Use any negative value or zero for Infinity')
|
|
26
|
+
Params.float('sleep_time_in_seconds', 10, 'Represents the sleeping time for generation files')
|
|
27
|
+
Params.float('upper_size_in_bytes', 500, 'Represents the upper limit file size in MB for random size calculation')
|
|
28
|
+
Params.float('down_size_in_bytes', 50, 'Represents the Lower limit file size in MB for random size calculation')
|
|
29
|
+
Params.integer('lower_limit_4_files_in_dir', 10,
|
|
30
|
+
'Represents the Lower limit for total files in directory for random calculation')
|
|
31
|
+
Params.integer('upper_limit_4_files_in_dir', 20,
|
|
32
|
+
'Represents the Upper limit for total files in directory for random calculation')
|
|
33
|
+
Params.boolean('is_tot_files_in_dir_random', true,
|
|
34
|
+
'Indicates that total files in a directory will be calculated randomly.')
|
|
35
|
+
Params.boolean('is_use_random_size', true, 'Indicates that file size will be calculated randomly.')
|
|
36
|
+
|
|
37
|
+
#Generates files with random content with random file size according to the given Params
|
|
38
|
+
class FileGenerator
|
|
39
|
+
attr_reader :one_bytes_string
|
|
40
|
+
FILE_EXT = 'txt'
|
|
41
|
+
|
|
42
|
+
#Gets one MB string
|
|
43
|
+
def one_bytes_string
|
|
44
|
+
@one_bytes_string ||= prepare_one_bytes_string
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
#Gets the some random string
|
|
48
|
+
def get_small_rand_unique_str
|
|
49
|
+
rand(36**8).to_s(36)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
#Gets the unique name according to current time and random string
|
|
53
|
+
def get_unique_name
|
|
54
|
+
"#{Time.new.to_i}_#{get_small_rand_unique_str}"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
#Gets the random letter
|
|
58
|
+
def get_random_letter
|
|
59
|
+
(rand(122-97) + 97).chr
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
#Gets the new directory name
|
|
63
|
+
def get_new_directory_name
|
|
64
|
+
"#{Params['dir_name_prefix']}_#{get_unique_name}"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
#Gets the new file name
|
|
68
|
+
def get_new_file_name
|
|
69
|
+
"#{Params['file_name_prefix']}_#{get_unique_name}.#{FILE_EXT}"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
#Gets the required file size im MB
|
|
73
|
+
def get_file_bytes_size
|
|
74
|
+
if Params['is_use_random_size']
|
|
75
|
+
rand(Params['upper_size_in_bytes'] - Params['down_size_in_bytes']) +
|
|
76
|
+
Params['down_size_in_bytes']
|
|
77
|
+
else
|
|
78
|
+
Params['file_size_in_bytes']
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
#Generates one MB string with random content
|
|
83
|
+
def prepare_one_bytes_string
|
|
84
|
+
get_random_letter
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
#Determines whether to generate new directory or not
|
|
88
|
+
def is_generate_dir(dir_counter, total_file_counter)
|
|
89
|
+
if Params['max_total_files'] > 0 && total_file_counter > Params['max_total_files']
|
|
90
|
+
return false
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
if Params['total_created_directories'] < 1 || #Any negative value or zero will be indication for Infinity
|
|
94
|
+
dir_counter < Params['total_created_directories'] then
|
|
95
|
+
return true
|
|
96
|
+
else
|
|
97
|
+
return false
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
#Determines whether to generate new file or not
|
|
102
|
+
def is_generate_file(file_counter, total_file_counter)
|
|
103
|
+
if Params['max_total_files'] > 0 && total_file_counter > Params['max_total_files']
|
|
104
|
+
return false
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
total_files_in_dir = Params['total_files_in_dir']
|
|
108
|
+
if file_counter == 0 && Params['is_tot_files_in_dir_random'] then
|
|
109
|
+
total_files_in_dir =
|
|
110
|
+
rand(Params['upper_limit_4_files_in_dir'] -
|
|
111
|
+
Params['lower_limit_4_files_in_dir']) +
|
|
112
|
+
Params['lower_limit_4_files_in_dir']
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
#When total_files_in_dir < 1 it will be treated as unlimited files creation in directory
|
|
116
|
+
if total_files_in_dir < 1 ||
|
|
117
|
+
file_counter < total_files_in_dir then
|
|
118
|
+
return true
|
|
119
|
+
else
|
|
120
|
+
return false
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
#Generates files with random content with random file size according to the given Params
|
|
125
|
+
def run
|
|
126
|
+
dir_counter = 0
|
|
127
|
+
total_file_count = 0
|
|
128
|
+
if Params['is_clear_target_path']
|
|
129
|
+
target_path_all_regexp = File.expand_path(File.join(Params['target_path'], '*'))
|
|
130
|
+
Dir[target_path_all_regexp].each {|file| FileUtils.rm_rf file}
|
|
131
|
+
end
|
|
132
|
+
while is_generate_dir dir_counter, total_file_count
|
|
133
|
+
new_dir_name = File.expand_path(File.join Params['target_path'], get_new_directory_name)
|
|
134
|
+
::FileUtils.mkdir_p new_dir_name unless File.directory?(new_dir_name)
|
|
135
|
+
dir_counter += 1
|
|
136
|
+
file_counter = 0
|
|
137
|
+
|
|
138
|
+
while is_generate_file file_counter, total_file_count
|
|
139
|
+
new_file_name = get_new_file_name
|
|
140
|
+
File.open(File.join(new_dir_name, new_file_name), "w") do |f|
|
|
141
|
+
get_file_bytes_size.to_i.times { f.write(get_random_letter) }
|
|
142
|
+
end
|
|
143
|
+
file_counter += 1
|
|
144
|
+
total_file_count += 1
|
|
145
|
+
|
|
146
|
+
sleep Params['sleep_time_in_seconds'] if Params['sleep_time_in_seconds'] > 0
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end # module FileGenerator
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|