content_server 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|