filestore 0.0.14 → 0.0.19

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,211 @@
1
+ #
2
+ # store_factory.rb
3
+ #
4
+ # author: Thomas Stätter
5
+ # date: 2014/01/06
6
+ #
7
+ module FileStore
8
+ #
9
+ # Base factory class
10
+ #
11
+ class BaseFactory
12
+ #
13
+ # Creates a new instance of the given class
14
+ #
15
+ # Arguments:
16
+ # klass: The class to be instantiated
17
+ # path: The path to be used wether for stores or managers
18
+ # observable (optional): Determines wether this instance should support observation
19
+ # logger (optional): The logging facility
20
+ #
21
+ # Returns:
22
+ # A new instance of 'klass'
23
+ #
24
+ def self.create(klass, path, observable = false, logger = StdoutLogger)
25
+ logger.debug "Creating new instance of class #{klass} with path '#{path}'"
26
+ obj = klass.new path
27
+
28
+ obj.logger = logger if not logger.nil?
29
+
30
+ if observable then
31
+ logger.debug "Extending instance with module 'ObservedSubject'"
32
+
33
+ obj.extend ObservedSubject
34
+ obj.initialize_obs
35
+ end
36
+
37
+ return obj
38
+ end
39
+
40
+ end
41
+ #
42
+ # MetaManager factory class
43
+ #
44
+ class MemoryMetaFactory < BaseFactory
45
+ #
46
+ # Creates a memory meta-manager instance
47
+ #
48
+ # Arguments:
49
+ # persist_file: The file where the manager will be persistet
50
+ # observable (optional): Determines wether this instance should support observation
51
+ # logger (optional): The logging facility
52
+ #
53
+ # Returns:
54
+ # A new instance of MemoryMetaManager
55
+ #
56
+ def self.create(persist_file = MemoryMetaManager::FILE, observable = false, logger = StdoutLogger)
57
+ return super(MemoryMetaManager, persist_file, observable, logger)
58
+ end
59
+ end
60
+ #
61
+ # MultiTenantFileStore factory class
62
+ #
63
+ class MultiTenantStoreFactory < BaseFactory
64
+ #
65
+ # Creates a multi tenant store instance
66
+ #
67
+ # Arguments:
68
+ # base_path: The directory of the multitenant store
69
+ # observable (optional): Determines wether this instance should support observation
70
+ # logger (optional): The logging facility
71
+ #
72
+ # Returns:
73
+ # A new instance of MultiTenantStore
74
+ #
75
+ def self.create(base_path, observable = false, logger = StdoutLogger)
76
+ logger.debug "Creating new MultiTenantFileStore"
77
+ multi_store = super MultiTenantFileStore, base_path, observable, logger
78
+
79
+ multi_store.stores = MultiTenantStoreFactory::recover_tenant_stores(base_path, observable, logger) if File.exists?(base_path)
80
+
81
+ return multi_store
82
+ end
83
+
84
+ #
85
+ # Recovers a multitenant store
86
+ #
87
+ # Arguments:
88
+ # rootPath: The base path of the multitenant store
89
+ # logger (optional): The logging facility
90
+ #
91
+ # Returns:
92
+ # A hashset of file stores (with the user ID as key) recovered
93
+ # from the given directory
94
+ #
95
+ def self.recover_tenant_stores(root_path, observable, logger)
96
+ raise FileStoreException, "Root path #{rootPath} isn't a valid multitenant store" if not File.directory?(root_path)
97
+
98
+ stores = {}
99
+
100
+ logger.debug "Trying to recover tenant stores"
101
+
102
+ Dir.glob(File.join(root_path, "*")).each do |e|
103
+ begin
104
+ if File.directory?(e) then
105
+ tenant = File.basename(e)
106
+ tenant_path = File.absolute_path e
107
+
108
+ logger.debug "Restoring tenant store in directory #{tenant_path}"
109
+
110
+ sfs = SimpleStoreFactory::create tenant_path, observable, logger
111
+
112
+ stores[tenant] = sfs
113
+ end
114
+ rescue Exception => e
115
+ logger.error "Couldn't create store for tenant #{tenant}.\n#{e}"
116
+ end
117
+ end
118
+
119
+ return stores
120
+ end
121
+
122
+ end
123
+ #
124
+ # SimpleFileStore factory class
125
+ #
126
+ class SimpleStoreFactory < BaseFactory
127
+ #
128
+ # Creates a simple file-store instance
129
+ #
130
+ # Arguments:
131
+ # base_path: The base path directory
132
+ # observable (optional): Determines wether this instance should support observation
133
+ # logger (optional): The logging facility
134
+ #
135
+ # Returns:
136
+ # A new instance of SimpleFileStore
137
+ #
138
+ def self.create(base_path, observable = false, logger = StdoutLogger)
139
+ store = super(SimpleFileStore, base_path, observable, logger)
140
+ mm = MemoryMetaFactory.create File.join(base_path, MemoryMetaManager::FILE), observable, logger
141
+
142
+ store.meta_manager = mm
143
+
144
+ begin
145
+ SimpleStoreFactory.recover_store(store)
146
+ rescue FileStoreException => e
147
+ logger.debug "Couldn't recover store.\nReason: #{e.message}\nTrying to create the store"
148
+ SimpleStoreFactory.create_store(store)
149
+ end
150
+
151
+ return store
152
+ end
153
+
154
+ #
155
+ # Setup for a new file store directory
156
+ #
157
+ # Arguments:
158
+ # store: The file store instance to set up
159
+ #
160
+ def self.create_store(store)
161
+ # Try to create needed directories
162
+ begin
163
+ FileUtils.mkdir [store.store_path, store.deleted_path, store.rollback_path]
164
+ rescue Errno::ENOENT => e
165
+ raise FileStoreException, "One ore more system directories couldn't be created.\n#{e.message}"
166
+ end
167
+ #
168
+ # Try to create hidden meta file
169
+ #
170
+ begin
171
+ meta = {
172
+ :created_at => Date.today.strftime('%d.%m.%Y %H:%M:%S:%L'),
173
+ :store_path => store.store_path,
174
+ :deleted_path => store.deleted_path,
175
+ :rollback_path => store.rollback_path,
176
+ :created_by => Etc.getlogin
177
+ }
178
+
179
+ File.open(store.meta_file, "wb+") do |fh|
180
+ YAML.dump(meta, fh)
181
+ end
182
+ #
183
+ # Creation was successful
184
+ #
185
+ rescue Exception => e
186
+ raise FileStoreException, "Store meta file #{store.meta_file} couldn't be created.\n#{e.message}"
187
+ end
188
+ end
189
+ #
190
+ # Recover an existing file store
191
+ #
192
+ # Arguments:
193
+ # store: The file store instance to recover
194
+ #
195
+ def self.recover_store(store)
196
+ # trying to recover existing file store
197
+ begin
198
+ meta = YAML.load_file(store.meta_file)
199
+
200
+ raise FileStoreException, "Store directory not found" if not File.directory?(meta[:store_path])
201
+ raise FileStoreException, "Deleted directory not found" if not File.directory?(meta[:deleted_path])
202
+ raise FileStoreException, "Rollback directory not found" if not File.directory?(meta[:rollback_path])
203
+ #
204
+ # Recovery was successful
205
+ #
206
+ rescue Exception => e
207
+ raise FileStoreException, "Unable to recover file store from path #{store.root_path}.\n#{e.message}"
208
+ end
209
+ end
210
+ end
211
+ end
@@ -8,10 +8,9 @@ module FileStore
8
8
  #
9
9
  # Class implementing a memory based MetaManager
10
10
  #
11
- class MemoryMetaManager < MetaManager
11
+ class MemoryMetaManager
12
12
  include Logger
13
- include OberservedSubject
14
-
13
+
15
14
  # Constant defining the default file path
16
15
  FILE = 'meta.yaml'
17
16
  # Accessor for the file to store data to
@@ -21,14 +20,13 @@ module FileStore
21
20
  #
22
21
  # Arguments:
23
22
  # persistentFile: The file where the manager class is persisted to
23
+ # logger: The logging facility
24
24
  #
25
- def initialize(persistentFile = '', logger)
25
+ def initialize(persistent_file = MemoryMetaManager::FILE, logger = StdoutLogger)
26
26
  @logger = logger
27
27
  @data = Hash.new
28
28
  @removed = Hash.new
29
- @file = (persistentFile.nil? or persistentFile == '')? MemoryMetaManager::FILE : persistentFile
30
-
31
- self.initialize_obs
29
+ @file = (persistent_file.nil? or persistent_file == '') ? MemoryMetaManager::FILE : persistent_file
32
30
 
33
31
  begin
34
32
  if File.exists?(@file)
@@ -62,8 +60,8 @@ module FileStore
62
60
 
63
61
  @data[id] = (@data.key?(id) ? @data[id].merge!(metaData) : @data[id] = metaData)
64
62
 
65
- self.inform ObserverAction.new(:type => ObserverAction::TYPE_META_ADD,
66
- :objects => [id, metaData], :msg => "Added/Updated file to meta store")
63
+ inform ObserverAction.new(:type => ObserverAction::TYPE_META_ADD,
64
+ :objects => [id, metaData], :msg => "Added/Updated file to meta store") if self.is_a?(ObservedSubject)
67
65
  end
68
66
  #
69
67
  # see: MetaManager::remove
@@ -75,8 +73,8 @@ module FileStore
75
73
  @removed[id] = @data[id]
76
74
  @data.delete(id)
77
75
 
78
- self.inform ObserverAction.new(:type => ObserverAction::TYPE_META_REMOVE,
79
- :objects => [id], :msg => "Removed file to meta store")
76
+ inform ObserverAction.new(:type => ObserverAction::TYPE_META_REMOVE,
77
+ :objects => [id], :msg => "Removed file to meta store") if self.is_a?(ObservedSubject)
80
78
  end
81
79
  #
82
80
  # see: MetaManager::restore
@@ -88,26 +86,34 @@ module FileStore
88
86
  @data[id] = @removed[id]
89
87
  @removed.delete(id)
90
88
 
91
- self.inform ObserverAction.new(:type => ObserverAction::TYPE_META_RESTORE,
92
- :objects => [id], :msg => "Restored file in meta store")
89
+ inform ObserverAction.new(:type => ObserverAction::TYPE_META_RESTORE,
90
+ :objects => [id], :msg => "Restored file in meta store") if self.is_a?(ObservedSubject)
93
91
  end
94
92
  #
95
- # see: MetaManager::shutdown
93
+ # see: MetaManager::save
96
94
  #
97
- def shutdown
98
- begin
99
- File.open(@file, "wb+") do |fh|
100
- YAML.dump({:current => @data, :removed => @removed}, fh)
101
- end
102
-
103
- @data = nil
104
-
105
- self.inform ObserverAction.new(:type => ObserverAction::TYPE_META_SHUTDOWN,
106
- :msg => "Restored file in meta store")
107
- rescue Exception => e
108
- raise FileStoreException, "Couldn't serialize meta manager to file #{@file}.\n#{e.message}"
109
- end
110
- end
95
+ def save
96
+ begin
97
+ @logger.info "Persisting meta store to #{@file}"
98
+
99
+ File.open(@file, "wb+") do |fh|
100
+ YAML.dump({:current => @data, :removed => @removed}, fh)
101
+ end
102
+
103
+ inform ObserverAction.new(:type => ObserverAction::TYPE_META_SHUTDOWN,
104
+ :msg => "Shut down meta manager") if self.is_a?(ObservedSubject)
105
+ rescue Exception => e
106
+ raise FileStoreException, "Couldn't persist meta manager to file #{@file}.\n#{e.message}"
107
+ end
108
+ end
109
+ #
110
+ # see: MetaManager::shutdown
111
+ #
112
+ def shutdown
113
+ save
114
+
115
+ @data = @removed = nil
116
+ end
111
117
  #
112
118
  # see: MetaManager::has_id?
113
119
  #
@@ -47,6 +47,11 @@ module FileStore
47
47
  def add_or_update(id, metaData)
48
48
  end
49
49
  #
50
+ # Saves the meta data in the current state
51
+ #
52
+ def save
53
+ end
54
+ #
50
55
  # Shuts down the manager class and clears all used resources
51
56
  #
52
57
  def shutdown
@@ -4,40 +4,22 @@
4
4
  # author: Thomas Stätter
5
5
  # date: 2012/11/21
6
6
  #
7
- require 'filestore'
8
-
9
7
  module FileStore
10
8
  #
11
- # Singleton class implementing a multitenant file store
9
+ # Class implementing a multitenant file store
12
10
  #
13
11
  class MultiTenantFileStore
14
12
  include Logger
15
- include OberservedSubject
16
- # Make this class a singleton class
17
- include Singleton
18
13
  # Accessors
19
- attr_reader :stores, :rootPath
14
+ attr_reader :rootPath
15
+ attr_accessor :stores
20
16
  #
21
17
  # Initializes a new instance of MultiTenantFileStore
22
18
  #
23
- def initialize()
24
- @rootPath = Dir.getwd
19
+ def initialize(root_path = ".", logger = StdoutLogger)
20
+ @rootPath = root_path
25
21
  @stores = {}
26
-
27
- self.initialize_obs
28
- end
29
- #
30
- # Sets the root path of the multitenant store. As FileStore::MultiTenantFileStore
31
- # is a singleton class, this method must be used before any other
32
- #
33
- # Arguments:
34
- # rootPath: The path to be used
35
- #
36
- def set_root_path(rootPath)
37
- raise FileStoreException, "Root path #{rootPath} doesn't exist" if not File.exists?(rootPath)
38
-
39
- @rootPath = rootPath
40
- @stores = MultiTenantFileStore.recover(rootPath, @logger)
22
+ @logger = logger
41
23
  end
42
24
  #
43
25
  # Creates a new file store for a tenant
@@ -55,13 +37,12 @@ module FileStore
55
37
  begin
56
38
  path = File.join(@rootPath, id)
57
39
  FileUtils.mkdir path if not File.directory?(path)
58
- mm = MemoryMetaManager.new File.join(path, "meta.yaml"), @logger
59
- sfs = SimpleFileStore.new mm, path, @logger
40
+ sfs = SimpleStoreFactory::create path, self.is_a?(ObservedSubject), @logger
60
41
 
61
42
  @stores[id] = sfs
62
43
 
63
- self.inform ObserverAction.new(:type => ObserverAction::TYPE_MSTORE_CREATE,
64
- :msg => "Created new tenant store")
44
+ inform ObserverAction.new(:type => ObserverAction::TYPE_MSTORE_CREATE,
45
+ :msg => "Created new tenant store") if self.is_a?(ObservedSubject)
65
46
  rescue Exception => e
66
47
  raise FileStoreException, "Couldn't create multitenant store.\n#{e.message}"
67
48
  end
@@ -106,13 +87,18 @@ module FileStore
106
87
  # file: The file to be added
107
88
  # md: Optional meta data
108
89
  #
90
+ # Returns:
91
+ # The file ID
92
+ #
109
93
  def add_to_tenant(tenant, file, md = {})
110
94
  raise FileStoreException, "Tenant #{tenant} not registered. File #{file} can't be added." if not @stores.key?(tenant)
111
95
 
112
- @stores[tenant].add(file, md)
96
+ f_id = @stores[tenant].add(file, md)
113
97
 
114
- self.inform ObserverAction.new(:type => ObserverAction::TYPE_MSTORE_ADD,
115
- :objects => [tenant, file], :msg => "Added file to tenant")
98
+ inform ObserverAction.new(:type => ObserverAction::TYPE_MSTORE_ADD,
99
+ :objects => [tenant, file, f_id], :msg => "Added file to tenant #{tenant} with ID #{f_id}") if self.is_a?(ObservedSubject)
100
+
101
+ return f_id
116
102
  end
117
103
  #
118
104
  # Removes a file from the tenant's store
@@ -156,39 +142,14 @@ module FileStore
156
142
  #
157
143
  def shutdown
158
144
  # Shut down any tenant store
159
- @stores.values.each do |s|
160
- s.shutdown
145
+ @stores.each do |id, store|
146
+ @logger.info "Shutting down file store for tenant #{id}"
147
+ store.shutdown
161
148
  end
162
149
  end
163
150
 
164
151
  private
165
- #
166
- # Recovers a multitenant store
167
- #
168
- # Arguments:
169
- # rootPath: The base path of the multitenant store
170
- #
171
- def self.recover(rootPath, logger)
172
- raise FileStoreException, "Root path #{rootPath} isn't a valid multitenant store" if not File.directory?(rootPath)
173
-
174
- stores = {}
175
-
176
- Dir.glob(File.join(rootPath, "*")).each { |e|
177
- begin
178
- if File.directory?(e)
179
- tenant = File.basename(e)
180
- mm = MemoryMetaManager.new File.join(e, MemoryMetaManager::FILE), logger
181
- sfs = SimpleFileStore.new mm, e, @logger
182
-
183
- stores[tenant] = sfs
184
- end
185
- rescue Exception => e
186
- logger.error "Couldn't create store for tenant #{tenant}.\n#{e.message}"
187
- end
188
- }
189
-
190
- return stores
191
- end
152
+
192
153
  end
193
154
 
194
155
  end
@@ -50,10 +50,10 @@ module FileStore
50
50
  end
51
51
  end
52
52
  #
53
- # Module FileStore::OberservedSubject can be mixed in to implement an
53
+ # Module FileStore::ObservedSubject can be mixed in to implement an
54
54
  # observed object.
55
55
  #
56
- module OberservedSubject
56
+ module ObservedSubject
57
57
  #
58
58
  # Reader for collection of observers
59
59
  #
@@ -82,7 +82,7 @@ module FileStore
82
82
  def register(obj)
83
83
  if obj.is_a?(Observer) and not obj.nil? and not @observers.include?(obj) then
84
84
  @observers << obj
85
- self.logger.debug "Added #{obj} to observers" if not self.logger.nil?
85
+ @logger.debug "Added #{obj} to observers" if not self.logger.nil?
86
86
  else
87
87
  raise FileStoreException, "Only instances of FileStore::Observer can be registered"
88
88
  end
@@ -97,7 +97,7 @@ module FileStore
97
97
  def unregister(obj)
98
98
  if @observers.include?(obj) then
99
99
  @observers.delete_at(@observers.index(obj))
100
- self.logger.debug "Removed observing object #{obj} from the list" if not self.logger.nil?
100
+ @logger.debug "Removed observing object #{obj} from the list" if not self.logger.nil?
101
101
  else
102
102
  raise FileStoreException, "Object #{obj} isn't a registered observer"
103
103
  end
@@ -5,21 +5,13 @@
5
5
  # date: 2012/11/07
6
6
  #
7
7
  module FileStore
8
- #
9
- # Base exception class used for errors occurring in this module
10
- #
11
- class FileStoreException < Exception
12
- end
13
8
  #
14
9
  # Main library class implementing a simple file store used for storing and managing
15
10
  # arbitrary files
16
11
  #
17
12
  class SimpleFileStore
18
13
  include Logger
19
- include OberservedSubject
20
14
 
21
- # Name of the lock file
22
- STORE_LOCK_FILE = ".locked"
23
15
  # Name of the meta file describing the current file store
24
16
  META_FILE = "filestore.yaml"
25
17
  # The base name of the file store directory
@@ -32,41 +24,28 @@ module FileStore
32
24
  #
33
25
  # Accessors for important properties
34
26
  #
35
- attr_reader :metaManager, :rootPath, :storePath, :deletedPath, :rollbackPath, :metaFile
27
+ attr_accessor :meta_manager
28
+ attr_reader :root_path, :store_path, :deleted_path, :meta_file
29
+ #
30
+ # Rollback path will be used in future versions
31
+ #
32
+ attr_reader :rollback_path
36
33
  #
37
34
  # Initializes a new instance of SimpleFileStore
38
35
  #
39
36
  # Arguments:
40
- # metaManager: The meta data manager instance to be used by this store
41
- # rootPath: The path where the file store resides
42
- #
43
- def initialize(metaManager, rootPath = '.', logger)
44
- raise FileStoreException, "Root path already locked" if SimpleFileStore.is_directory_locked?(rootPath)
45
- raise FileStoreException, "FileStore root path #{rootPath} doesn't exist" if not File.directory?(rootPath)
46
- raise FileStoreException, "FileStore root path #{rootPath} isn't writable" if not File.writable?(rootPath)
47
- raise FileStoreException, "No meta data manager given" if metaManager.nil?
48
- raise FileStoreException, "Meta data manager must be of type FileStore::MetaManager" if not metaManager.is_a?(MetaManager)
49
-
50
- @metaManager = metaManager
51
- @rootPath = rootPath
52
- @storePath = File.join(@rootPath, STORE_ROOT)
53
- @deletedPath = File.join(@rootPath, DELETED_ROOT)
54
- @rollbackPath = File.join(@rootPath, ROLLBACK_ROOT)
55
- @metaFile = File.join(@rootPath, META_FILE)
56
- @locked = false
57
- @logger = logger
58
-
59
- self.initialize_obs
60
-
61
- begin
62
- # Try to recover existing store
63
- SimpleFileStore.recover_store(self)
64
- rescue FileStoreException => e
65
- # Recovery failed, trying to create the store
66
- SimpleFileStore.create_store(self)
67
- end
68
-
69
- lock
37
+ # root_path: The path where the file store resides
38
+ # logger: The logging facility
39
+ #
40
+ def initialize(root_path, logger = StdoutLogger)
41
+ raise FileStoreException, "FileStore root path #{root_path} doesn't exist" if not File.directory?(root_path)
42
+ raise FileStoreException, "FileStore root path #{root_path} isn't writable" if not File.writable?(root_path)
43
+
44
+ @root_path = root_path
45
+ @store_path = File.join(@root_path, STORE_ROOT)
46
+ @deleted_path = File.join(@root_path, DELETED_ROOT)
47
+ @rollback_path = File.join(@root_path, ROLLBACK_ROOT)
48
+ @meta_file = File.join(@root_path, SimpleFileStore::META_FILE)
70
49
  end
71
50
  #
72
51
  # Adds a file to the store
@@ -88,7 +67,7 @@ module FileStore
88
67
  id = ""
89
68
 
90
69
  begin
91
- dir = SimpleFileStore.get_daily_directory(@storePath)
70
+ dir = SimpleFileStore.get_daily_directory(@store_path)
92
71
  @logger.info "Adding file #{file} to directory #{dir}"
93
72
  id = SimpleFileStore.get_id(self)
94
73
  @logger.info "Using file id #{id}"
@@ -98,14 +77,14 @@ module FileStore
98
77
  shouldMove ? (@logger.info("Moving file"); FileUtils.mv(file, dstPath)) :
99
78
  (@logger.info("Copying file"); FileUtils.copy_file(file, dstPath))
100
79
 
101
- self.inform ObserverAction.new(:type => ObserverAction::TYPE_STORE_ADD,
102
- :objects => [file, meta], :msg => "Added file to file store")
80
+ inform ObserverAction.new(:type => ObserverAction::TYPE_STORE_ADD,
81
+ :objects => [file, meta], :msg => "Added file to file store") if self.is_a?(ObservedSubject)
103
82
  rescue Exception => e
104
83
  raise FileStoreException, "Couldn't add file #{file} to store.", e.backtrace
105
84
  end
106
85
 
107
86
  meta[:path] = dstPath
108
- @metaManager.add_or_update(id, meta)
87
+ @meta_manager.add_or_update(id, meta)
109
88
 
110
89
  return id
111
90
  end
@@ -121,15 +100,15 @@ module FileStore
121
100
  #
122
101
  def get(id)
123
102
  raise FileStoreException, "No ID given" if id.nil? or id == ''
124
- raise FileStoreException, "No file for ID #{id} found" if not @metaManager.has_id?(id)
103
+ raise FileStoreException, "No file for ID #{id} found" if not @meta_manager.has_id?(id)
125
104
 
126
- md = @metaManager.get_data(id)
105
+ md = @meta_manager.get_data(id)
127
106
  path = md[:path]
128
107
 
129
108
  raise FileStoreException, "No valid meta data found for ID #{id}" if md.nil? or not File.exists?(path)
130
109
 
131
- self.inform ObserverAction.new :type => ObserverAction::TYPE_STORE_GET,
132
- :objects => [id], :msg => "Returning file from file store"
110
+ inform ObserverAction.new(:type => ObserverAction::TYPE_STORE_GET,
111
+ :objects => [id], :msg => "Returning file from file store") if self.is_a?(ObservedSubject)
133
112
 
134
113
  return { :path => File.new(path), :data => md }
135
114
  end
@@ -141,20 +120,20 @@ module FileStore
141
120
  #
142
121
  def remove(id)
143
122
  raise FileStoreException, "No file ID given for removal" if id == '' or id.nil?
144
- raise FileStoreException, "File ID for removal not found in store" if not @metaManager.has_id?(id)
123
+ raise FileStoreException, "File ID for removal not found in store" if not @meta_manager.has_id?(id)
145
124
 
146
- file = @metaManager.get_data(id)[:path]
125
+ file = @meta_manager.get_data(id)[:path]
147
126
 
148
127
  begin
149
- @metaManager.remove(id)
128
+ @meta_manager.remove(id)
150
129
 
151
- dir = SimpleFileStore.get_daily_directory(@deletedPath)
130
+ dir = SimpleFileStore.get_daily_directory(@deleted_path)
152
131
  dstPath = File.join(dir, id)
153
132
 
154
133
  FileUtils.move(file, dstPath)
155
134
 
156
- self.inform ObserverAction.new :type => ObserverAction::TYPE_STORE_REMOVE,
157
- :objects => [id], :msg => "Deleted file from store"
135
+ inform ObserverAction.new(:type => ObserverAction::TYPE_STORE_REMOVE,
136
+ :objects => [id], :msg => "Deleted file from store") if self.is_a?(ObservedSubject)
158
137
  rescue Exception => e
159
138
  raise FileStoreException, "Couldn't move file #{file} to deleted store.\n#{e.message}"
160
139
  end
@@ -169,74 +148,36 @@ module FileStore
169
148
  raise FileStoreException, "No file ID given for restore" if id == '' or id.nil?
170
149
 
171
150
  begin
172
- md = @metaManager.restore id
151
+ md = @meta_manager.restore id
173
152
  @logger.debug "Restoring meta data #{md}"
174
153
  file = md[:path]
175
154
 
176
- dir = SimpleFileStore.get_daily_directory(@storePath)
155
+ dir = SimpleFileStore.get_daily_directory(@store_path)
177
156
  dstPath = File.join(dir, id)
178
157
 
179
158
  FileUtils.move(file, dstPath)
180
159
 
181
- self.inform ObserverAction.new :type => ObserverAction::TYPE_STORE_RESTORE,
182
- :objects => [id], :msg => "Restored file from store"
160
+ inform ObserverAction.new(:type => ObserverAction::TYPE_STORE_RESTORE,
161
+ :objects => [id], :msg => "Restored file from store") if self.is_a?(ObservedSubject)
183
162
  rescue Exception => e
184
163
  raise FileStoreException, "Couldn't restore file #{file} from deleted store.\n#{e.message}"
185
164
  #
186
165
  # Delete restored entry from metaManager
187
- @metaManager.delete(id)
166
+ #
167
+ @meta_manager.delete(id)
188
168
  end
189
169
  end
190
170
  #
191
171
  # Shuts down the file store
192
172
  #
193
173
  def shutdown
194
- @metaManager.shutdown
195
-
196
- release_lock
174
+ @meta_manager.shutdown
197
175
 
198
- self.inform ObserverAction.new :type => ObserverAction::TYPE_STORE_SHUTDOWN,
199
- :msg => "File store shutdown"
200
- end
201
- #
202
- # Determines wether this store is locked
203
- #
204
- def locked?
205
- return @locked
176
+ inform ObserverAction.new(:type => ObserverAction::TYPE_STORE_SHUTDOWN,
177
+ :msg => "File store shutdown") if self.is_a?(ObservedSubject)
206
178
  end
207
179
 
208
180
  private
209
-
210
- #
211
- # Release the lock from the store
212
- #
213
- def release_lock
214
- begin
215
- File.delete File.join(@rootPath, STORE_LOCK_FILE)
216
- @locked = false
217
- rescue Exception => e
218
- raise FileStoreException, "Couldn't release lock from #{@storePath}.\n#{e.message}"
219
- end
220
- end
221
- #
222
- # Locks the current instance of file store as well as the corresponding path on
223
- # the file system using a hidden file
224
- #
225
- def lock
226
- begin
227
- FileUtils.touch File.join(@rootPath, STORE_LOCK_FILE)
228
- @locked = true
229
- rescue Exception => e
230
- raise FileStoreException, "Couldn't lock the store in path #{@storePath}.\n#{e.message}"
231
- end
232
- end
233
- #
234
- # Determines wether the store path is already locked by another instance
235
- # of SimpleFileStore
236
- #
237
- def self.is_directory_locked?(rootPath)
238
- return File.exists?(File.join(rootPath, SimpleFileStore::STORE_LOCK_FILE))
239
- end
240
181
  #
241
182
  # Creates a new file ID
242
183
  #
@@ -247,7 +188,7 @@ module FileStore
247
188
  for i in 0..2 do
248
189
  id = UUIDTools::UUID.random_create.to_s
249
190
 
250
- return id if not store.metaManager.has_id?(id)
191
+ return id if not store.meta_manager.has_id?(id)
251
192
  end
252
193
 
253
194
  raise FileStoreException, "Couldn't find unique ID"
@@ -268,61 +209,6 @@ module FileStore
268
209
  raise FileStoreException, "Daily directory #{dir} isn't writable" if not File.writable?(dir)
269
210
  return dir
270
211
  end
271
- #
272
- # Setup for a new file store directory
273
- #
274
- # Arguments:
275
- # store: The file store instance to set up
276
- #
277
- def self.create_store(store)
278
- # Try to create needed directories
279
- begin
280
- FileUtils.mkdir [store.storePath, store.deletedPath, store.rollbackPath]
281
- rescue Errno::ENOENT => e
282
- raise FileStoreException, "One ore more system directories couldn't be created.\n#{e.message}"
283
- end
284
- # Try to create hidden meta file
285
- begin
286
- meta = { :created_at => Date.today.strftime('%d.%m.%Y %H:%M:%S:%L'),
287
- :storePath => store.storePath,
288
- :deletedPath => store.deletedPath,
289
- :rollbackPath => store.rollbackPath,
290
- :created_by => Etc.getlogin
291
- }
292
-
293
- File.open(store.metaFile, "w+") do |fh|
294
- YAML.dump(meta, fh)
295
- end
296
-
297
- #
298
- # Creation was successful
299
- #
300
- rescue Exception => e
301
- raise FileStoreException, "Meta file #{store.metaFile} couldn't be created.\n#{e.message}"
302
- end
303
- end
304
- #
305
- # Recover an existing file store
306
- #
307
- # Arguments:
308
- # store: The file store instance to recover
309
- #
310
- def self.recover_store(store)
311
- # trying to recover existing file store
312
- begin
313
- meta = YAML.load_file(store.metaFile)
314
-
315
- raise FileStoreException, "Store directory not found" if not File.directory?(meta[:storePath])
316
- raise FileStoreException, "Deleted directory not found" if not File.directory?(meta[:deletedPath])
317
- raise FileStoreException, "Rollback directory not found" if not File.directory?(meta[:rollbackPath])
318
-
319
- #
320
- # Recovery was successful
321
- #
322
- rescue Exception => e
323
- raise FileStoreException, "Unable to recover file store from path #{store.rootPath}.\n#{e.message}"
324
- end
325
- end
326
212
 
327
213
  end
328
214
 
data/lib/filestore.rb CHANGED
@@ -4,6 +4,14 @@
4
4
  # @date 2012/11/26
5
5
  # @description
6
6
  #
7
+ module FileStore
8
+ #
9
+ # Base exception class used for errors occurring in this module
10
+ #
11
+ class FileStoreException < Exception
12
+ end
13
+ end
14
+
7
15
  LIBS = [
8
16
  #
9
17
  # Required 3rd party libs
@@ -11,8 +19,7 @@ LIBS = [
11
19
  'uuidtools',
12
20
  'fileutils',
13
21
  'yaml',
14
- 'etc',
15
- 'singleton'
22
+ 'etc'
16
23
  ]
17
24
  FILESTORE_FILES = [
18
25
  #
@@ -23,7 +30,8 @@ FILESTORE_FILES = [
23
30
  'log',
24
31
  'memory_meta',
25
32
  'simple_store',
26
- 'multitenant_store'
33
+ 'multitenant_store',
34
+ 'factory'
27
35
  ]
28
36
  #
29
37
  # Loads required 3rd party libs as defined in FileStore::LIBS
data/test/classes.rb CHANGED
@@ -12,16 +12,22 @@ class FileStoreTest < Test::Unit::TestCase
12
12
 
13
13
  def setup
14
14
  # create test directory and file
15
- @basePath = "#{Dir.getwd}/store_test"
16
- @testFile = File.join(@basePath, "testfile.txt")
15
+ @uid = Etc.getlogin
16
+ @basePathSimple = "#{Dir.getwd}/simple_store_test"
17
+ @basePathMulti = "#{Dir.getwd}/multi_store_test"
18
+ @testFileSimple = File.join(@basePathSimple, "testfile.txt")
19
+ @testFileMulti = File.join(@basePathMulti, "testfile.txt")
17
20
 
18
- FileUtils.mkdir(@basePath) if not File.exists?(@basePath)
19
- FileUtils.touch(@testFile) if not File.exists?(@testFile)
21
+ FileUtils.mkdir(@basePathSimple) if not File.exists?(@basePathSimple)
22
+ FileUtils.mkdir(@basePathMulti) if not File.exists?(@basePathMulti)
23
+ FileUtils.touch(@testFileSimple)
24
+ FileUtils.touch(@testFileMulti)
20
25
  end
21
26
 
22
27
  def teardown
23
- # remove test directory and file
24
- FileUtils.remove_dir(@basePath, true) if File.exists?(@basePath)
28
+ # remove test directories and file
29
+ FileUtils.remove_dir(@basePathSimple, true) if File.exists?(@basePathSimple)
30
+ FileUtils.remove_dir(@basePathMulti, true) if File.exists?(@basePathMulti)
25
31
  end
26
32
 
27
33
  end
data/test/tc_filestore.rb CHANGED
@@ -3,7 +3,6 @@
3
3
  # @author Thomas Stätter
4
4
  # @date 2012/11/14
5
5
  #
6
- # require 'filestore'
7
6
  require './classes.rb'
8
7
  require 'test/unit'
9
8
 
@@ -16,14 +15,12 @@ class TestFileStore < FileStoreTest
16
15
  puts "TestFileStore::test_init_shutdown"
17
16
  puts "=" * 80
18
17
 
19
- mm = MemoryMetaManager.new File.join(@basePath, "meta.yaml"), StdoutLogger
20
- sfs = nil
21
-
22
18
  assert_nothing_raised(FileStoreException) {
23
- sfs = SimpleFileStore.new mm, @basePath, StdoutLogger
19
+ SimpleStoreFactory::create @basePathSimple
24
20
  }
25
- assert_not_nil(sfs)
21
+ assert_not_nil(SimpleStoreFactory::create @basePathSimple)
26
22
  assert_nothing_raised(FileStoreException) {
23
+ sfs = SimpleStoreFactory::create @basePathSimple
27
24
  sfs.shutdown
28
25
  }
29
26
  end
@@ -33,8 +30,7 @@ class TestFileStore < FileStoreTest
33
30
  puts "TestFileStorage::test_registration_observer"
34
31
  puts "=" * 80
35
32
 
36
- mm = MemoryMetaManager.new File.join(@basePath, "meta.yaml"), StdoutLogger
37
- sfs = SimpleFileStore.new mm, @basePath, StdoutLogger
33
+ sfs = SimpleStoreFactory::create @basePathSimple, true
38
34
  o1 = OtherObserverClass.new
39
35
  o2 = ObserverClass.new
40
36
 
@@ -56,14 +52,13 @@ class TestFileStore < FileStoreTest
56
52
 
57
53
  o1 = ObserverClass.new
58
54
  o1.logger = StdoutLogger
59
- mm = MemoryMetaManager.new File.join(@basePath, "meta.yaml"), StdoutLogger
60
- sfs = SimpleFileStore.new mm, @basePath, StdoutLogger
55
+ sfs = SimpleStoreFactory::create @basePathSimple, true
61
56
  id = nil
62
57
 
63
58
  sfs.register o1
64
59
 
65
60
  assert_nothing_raised(FileStoreException) {
66
- id = sfs.add @testFile, { :original_file => @testFile }, false
61
+ id = sfs.add @testFileSimple, { :original_file => @testFileSimple }, false
67
62
  }
68
63
  assert_nothing_raised(FileStoreException) { file = sfs.get id }
69
64
  assert_not_nil(sfs.get(id))
data/test/tc_meta.rb CHANGED
@@ -14,11 +14,13 @@ class TestMetaManager < FileStoreTest
14
14
  puts "=" * 80
15
15
  puts "TestMetaManager::test_init_shutdown"
16
16
  puts "=" * 80
17
+
17
18
  assert_nothing_raised(FileStoreException) {
18
- MemoryMetaManager.new File.join(@basePath, "meta.yaml"), StdoutLogger
19
+ mm = MemoryMetaFactory::create File.join(@basePathSimple, MemoryMetaManager::FILE)
19
20
  }
21
+ assert_not_nil(MemoryMetaFactory::create File.join(@basePathSimple, MemoryMetaManager::FILE))
20
22
  assert_nothing_raised(FileStoreException) {
21
- mm = MemoryMetaManager.new File.join(@basePath, "meta.yaml"), StdoutLogger
23
+ mm = MemoryMetaFactory::create File.join(@basePathSimple, MemoryMetaManager::FILE)
22
24
 
23
25
  mm.shutdown
24
26
  }
@@ -35,19 +37,19 @@ class TestMetaManager < FileStoreTest
35
37
  o1.logger = StdoutLogger
36
38
  o2.logger = StdoutLogger
37
39
 
38
- mm = MemoryMetaManager.new(File.join(@basePath, "meta.yaml"), StdoutLogger)
40
+ mm = MemoryMetaFactory::create File.join(@basePathSimple, MemoryMetaManager::FILE), true
39
41
 
40
42
  assert_nothing_raised(FileStoreException) {
41
43
  mm.register o1
42
44
  mm.register o2
43
45
  }
44
- assert_raise(FileStoreException) { mm.register o1 }
46
+ assert_raise(FileStoreException) { mm.register "" }
45
47
  assert_nothing_raised(FileStoreException) {
46
48
  mm.unregister(o1)
47
49
  mm.unregister(o2)
48
50
  }
49
51
  end
50
-
52
+
51
53
  def test_actions_with_observer
52
54
  puts "=" * 80
53
55
  puts "TestMetaManager::test_actions_with_observer"
@@ -55,14 +57,15 @@ class TestMetaManager < FileStoreTest
55
57
 
56
58
  o1 = ObserverClass.new
57
59
  o1.logger = StdoutLogger
58
- mm = MemoryMetaManager.new(File.join(@basePath, "meta.yaml"), StdoutLogger)
60
+ mm = MemoryMetaFactory::create File.join(@basePathSimple, MemoryMetaManager::FILE), true
59
61
 
60
62
  mm.register o1
61
63
 
62
- assert_nothing_raised(Exception) { mm.add_or_update "1", {} }
63
- assert_nothing_raised(Exception) { mm.add_or_update "1", {} }
64
- assert_nothing_raised(Exception) { mm.remove "1" }
65
- assert_nothing_raised(Exception) { mm.restore "1" }
66
- assert_nothing_raised(Exception) { mm.shutdown }
64
+ assert_nothing_raised(FileStoreException) { mm.add_or_update "1", {} }
65
+ assert_nothing_raised(FileStoreException) { mm.add_or_update "1", {} }
66
+ assert_nothing_raised(FileStoreException) { mm.remove "1" }
67
+ assert_nothing_raised(FileStoreException) { mm.restore "1" }
68
+ assert_nothing_raised(FileStoreException) { mm.shutdown }
67
69
  end
70
+
68
71
  end
data/test/tc_module.rb CHANGED
@@ -12,13 +12,18 @@ class TestModule < Test::Unit::TestCase
12
12
  puts "=" * 80
13
13
  puts "TestModule::test_inclusion"
14
14
  puts "=" * 80
15
+
15
16
  assert_nothing_raised(NameError) { ObserverAction }
16
- assert_nothing_raised(NameError) { OberservedSubject }
17
+ assert_nothing_raised(NameError) { ObservedSubject }
17
18
  assert_nothing_raised(NameError) { Observer }
18
19
  assert_nothing_raised(NameError) { SimpleFileStore }
19
20
  assert_nothing_raised(NameError) { MultiTenantFileStore }
20
21
  assert_nothing_raised(NameError) { MemoryMetaManager }
21
22
  assert_nothing_raised(NameError) { MetaManager }
22
23
  assert_nothing_raised(NameError) { FileStoreException }
24
+ assert_nothing_raised(NameError) { BaseFactory }
25
+ assert_nothing_raised(NameError) { MemoryMetaFactory }
26
+ assert_nothing_raised(NameError) { MultiTenantStoreFactory }
27
+ assert_nothing_raised(NameError) { SimpleStoreFactory }
23
28
  end
24
29
  end
@@ -12,38 +12,56 @@ include FileStore
12
12
 
13
13
  class TestMultiTenantFileStore < FileStoreTest
14
14
 
15
- def test_registration_observer
15
+ def test_init_shutdown
16
16
  puts "=" * 80
17
- puts "TestMultiTenantFileStore::test_registration_observer"
17
+ puts "TestMultiTenantFileStore::test_init"
18
18
  puts "=" * 80
19
19
 
20
- MultiTenantFileStore.instance.set_root_path @basePath
21
- MultiTenantFileStore.instance.logger = StdoutLogger
22
- tenant = MultiTenantFileStore.instance.create_tenant_store
23
- o1 = OtherObserverClass.new
24
- o2 = ObserverClass.new
25
-
26
20
  assert_nothing_raised(FileStoreException) {
27
- MultiTenantFileStore.instance.register o1
28
- MultiTenantFileStore.instance.register o2
21
+ MultiTenantStoreFactory::create @basePathMulti
22
+ }
23
+ assert_not_nil(MultiTenantStoreFactory::create @basePathMulti)
24
+ assert(MultiTenantStoreFactory::create(@basePathMulti).is_a?(MultiTenantFileStore))
25
+ assert_nothing_raised(FileStoreException) {
26
+ m_store = MultiTenantStoreFactory::create @basePathMulti
27
+
28
+ m_store.shutdown
29
29
  }
30
30
  end
31
31
 
32
+ def test_observer_registration
33
+ puts "=" * 80
34
+ puts "TestMultiTenantFileStore::test_observer_registration"
35
+ puts "=" * 80
36
+
37
+ assert_nothing_raised(Exception) {
38
+ o1 = ObserverClass.new
39
+ o1.logger = StdoutLogger
40
+ m_store = MultiTenantStoreFactory::create @basePathMulti, true
41
+
42
+ m_store.register o1
43
+ m_store.inform "Some test message"
44
+ m_store.shutdown
45
+ }
46
+ end
47
+
32
48
  def test_actions_with_observer
33
49
  puts "=" * 80
34
50
  puts "TestMultiTenantFileStore::test_actions_with_observer"
35
51
  puts "=" * 80
36
52
 
37
- MultiTenantFileStore.instance.set_root_path @basePath
38
- MultiTenantFileStore.instance.logger = StdoutLogger
39
53
  o1 = OtherObserverClass.new
40
54
  o1.logger = StdoutLogger
41
- MultiTenantFileStore.instance.register o1
55
+
56
+ m_store = MultiTenantStoreFactory::create @basePathMulti, true
57
+ m_store.register o1
42
58
 
43
59
  assert_nothing_raised(FileStoreException) {
44
- tenant = MultiTenantFileStore.instance.create_tenant_store
45
- MultiTenantFileStore.instance.add_to_tenant tenant,
46
- @testFile, { :original_file => @testFile }
60
+ tenant_id = m_store.create_tenant_store @uid
61
+ f_id = m_store.add_to_tenant tenant_id,
62
+ @testFileMulti, { :original_file => @testFileMulti }
63
+ m_store.remove_from_tenant tenant_id, f_id
64
+ m_store.shutdown
47
65
  }
48
66
  end
49
67
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: filestore
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14
4
+ version: 0.0.19
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -39,6 +39,7 @@ executables: []
39
39
  extensions: []
40
40
  extra_rdoc_files: []
41
41
  files:
42
+ - lib/filestore/factory.rb
42
43
  - lib/filestore/log.rb
43
44
  - lib/filestore/memory_meta.rb
44
45
  - lib/filestore/meta_manager.rb