filestore 0.0.14 → 0.0.19

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.
@@ -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