aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Inventory
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs96
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs9
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs139
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverException.cs (renamed from OpenSim/Framework/ConfigBase.cs)16
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs111
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs125
6 files changed, 318 insertions, 178 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index f130b3e..7683288 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -100,37 +100,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
100 /// </returns> 100 /// </returns>
101 public HashSet<InventoryNodeBase> Execute() 101 public HashSet<InventoryNodeBase> Execute()
102 { 102 {
103 string filePath = "ERROR";
104 int successfulAssetRestores = 0;
105 int failedAssetRestores = 0;
106 int successfulItemRestores = 0;
107
108 HashSet<InventoryNodeBase> loadedNodes = new HashSet<InventoryNodeBase>();
109
110 List<InventoryFolderBase> folderCandidates
111 = InventoryArchiveUtils.FindFolderByPath(
112 m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath);
113
114 if (folderCandidates.Count == 0)
115 {
116 // Possibly provide an option later on to automatically create this folder if it does not exist
117 m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath);
118
119 return loadedNodes;
120 }
121
122 InventoryFolderBase rootDestinationFolder = folderCandidates[0];
123 archive = new TarArchiveReader(m_loadStream);
124
125 // In order to load identically named folders, we need to keep track of the folders that we have already
126 // resolved
127 Dictionary <string, InventoryFolderBase> resolvedFolders = new Dictionary<string, InventoryFolderBase>();
128
129 byte[] data;
130 TarArchiveReader.TarEntryType entryType;
131
132 try 103 try
133 { 104 {
105 string filePath = "ERROR";
106 int successfulAssetRestores = 0;
107 int failedAssetRestores = 0;
108 int successfulItemRestores = 0;
109
110 HashSet<InventoryNodeBase> loadedNodes = new HashSet<InventoryNodeBase>();
111
112 List<InventoryFolderBase> folderCandidates
113 = InventoryArchiveUtils.FindFolderByPath(
114 m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath);
115
116 if (folderCandidates.Count == 0)
117 {
118 // Possibly provide an option later on to automatically create this folder if it does not exist
119 m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath);
120
121 return loadedNodes;
122 }
123
124 InventoryFolderBase rootDestinationFolder = folderCandidates[0];
125 archive = new TarArchiveReader(m_loadStream);
126
127 // In order to load identically named folders, we need to keep track of the folders that we have already
128 // resolved
129 Dictionary <string, InventoryFolderBase> resolvedFolders = new Dictionary<string, InventoryFolderBase>();
130
131 byte[] data;
132 TarArchiveReader.TarEntryType entryType;
133
134 while ((data = archive.ReadEntry(out filePath, out entryType)) != null) 134 while ((data = archive.ReadEntry(out filePath, out entryType)) != null)
135 { 135 {
136 if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) 136 if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
@@ -173,18 +173,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
173 } 173 }
174 } 174 }
175 } 175 }
176
177 archive.Close();
178
179 m_log.DebugFormat(
180 "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures",
181 successfulAssetRestores, failedAssetRestores);
182 m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", successfulItemRestores);
183
184 return loadedNodes;
176 } 185 }
177 finally 186 finally
178 { 187 {
179 archive.Close(); 188 m_loadStream.Close();
180 } 189 }
181
182 m_log.DebugFormat(
183 "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures",
184 successfulAssetRestores, failedAssetRestores);
185 m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", successfulItemRestores);
186
187 return loadedNodes;
188 } 190 }
189 191
190 public void Close() 192 public void Close()
@@ -220,9 +222,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
220 InventoryFolderBase destFolder 222 InventoryFolderBase destFolder
221 = ResolveDestinationFolder(rootDestFolder, ref iarPathExisting, resolvedFolders); 223 = ResolveDestinationFolder(rootDestFolder, ref iarPathExisting, resolvedFolders);
222 224
223 m_log.DebugFormat( 225// m_log.DebugFormat(
224 "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]", 226// "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]",
225 iarPath, iarPathExisting); 227// iarPath, iarPathExisting);
226 228
227 string iarPathToCreate = iarPath.Substring(iarPathExisting.Length); 229 string iarPathToCreate = iarPath.Substring(iarPathExisting.Length);
228 CreateFoldersForPath(destFolder, iarPathExisting, iarPathToCreate, resolvedFolders, loadedNodes); 230 CreateFoldersForPath(destFolder, iarPathExisting, iarPathToCreate, resolvedFolders, loadedNodes);
@@ -255,7 +257,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
255 ref string archivePath, 257 ref string archivePath,
256 Dictionary <string, InventoryFolderBase> resolvedFolders) 258 Dictionary <string, InventoryFolderBase> resolvedFolders)
257 { 259 {
258 string originalArchivePath = archivePath; 260// string originalArchivePath = archivePath;
259 261
260 while (archivePath.Length > 0) 262 while (archivePath.Length > 0)
261 { 263 {
@@ -263,8 +265,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
263 265
264 if (resolvedFolders.ContainsKey(archivePath)) 266 if (resolvedFolders.ContainsKey(archivePath))
265 { 267 {
266 m_log.DebugFormat( 268// m_log.DebugFormat(
267 "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath); 269// "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath);
268 return resolvedFolders[archivePath]; 270 return resolvedFolders[archivePath];
269 } 271 }
270 else 272 else
@@ -296,9 +298,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
296 } 298 }
297 else 299 else
298 { 300 {
299 m_log.DebugFormat( 301// m_log.DebugFormat(
300 "[INVENTORY ARCHIVER]: Found no previously created folder for archive path {0}", 302// "[INVENTORY ARCHIVER]: Found no previously created folder for archive path {0}",
301 originalArchivePath); 303// originalArchivePath);
302 archivePath = string.Empty; 304 archivePath = string.Empty;
303 return rootDestFolder; 305 return rootDestFolder;
304 } 306 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
index ca33968..84afb40 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
@@ -206,11 +206,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
206 206
207 if (components.Length == 1) 207 if (components.Length == 1)
208 { 208 {
209// m_log.DebugFormat("FOUND SINGLE COMPONENT [{0}]", components[0]); 209// m_log.DebugFormat(
210// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}",
211// components[0], startFolder.Name, startFolder.ID);
210 212
211 List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID); 213 List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID);
214
215// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count);
216
212 foreach (InventoryItemBase item in items) 217 foreach (InventoryItemBase item in items)
213 { 218 {
219// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Inspecting item {0} {1}", item.Name, item.ID);
220
214 if (item.Name == components[0]) 221 if (item.Name == components[0])
215 return item; 222 return item;
216 } 223 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index 2c2724e..25a78ff 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -119,22 +119,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
119 protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids) 119 protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids)
120 { 120 {
121 Exception reportedException = null; 121 Exception reportedException = null;
122 bool succeeded = true; 122 bool succeeded = true;
123 123
124 try 124 try
125 { 125 {
126 // We're almost done. Just need to write out the control file now 126 // We're almost done. Just need to write out the control file now
127 m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, Create0p1ControlFile()); 127 m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, Create0p1ControlFile());
128 m_log.InfoFormat("[ARCHIVER]: Added control file to archive."); 128 m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
129
130 m_archiveWriter.Close(); 129 m_archiveWriter.Close();
131 } 130 }
132 catch (Exception e) 131 catch (Exception e)
133 { 132 {
134 m_saveStream.Close();
135 reportedException = e; 133 reportedException = e;
136 succeeded = false; 134 succeeded = false;
137 } 135 }
136 finally
137 {
138 m_saveStream.Close();
139 }
138 140
139 m_module.TriggerInventoryArchiveSaved( 141 m_module.TriggerInventoryArchiveSaved(
140 m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException); 142 m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException);
@@ -213,70 +215,68 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
213 /// </summary> 215 /// </summary>
214 public void Execute() 216 public void Execute()
215 { 217 {
216 InventoryFolderBase inventoryFolder = null; 218 try
217 InventoryItemBase inventoryItem = null;
218 InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID);
219
220 bool foundStar = false;
221
222 // Eliminate double slashes and any leading / on the path.
223 string[] components
224 = m_invPath.Split(
225 new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries);
226
227 int maxComponentIndex = components.Length - 1;
228
229 // If the path terminates with a STAR then later on we want to archive all nodes in the folder but not the
230 // folder itself. This may get more sophisicated later on
231 if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD)
232 {
233 foundStar = true;
234 maxComponentIndex--;
235 }
236
237 m_invPath = String.Empty;
238 for (int i = 0; i <= maxComponentIndex; i++)
239 {
240 m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER;
241 }
242
243 // Annoyingly Split actually returns the original string if the input string consists only of delimiters
244 // Therefore if we still start with a / after the split, then we need the root folder
245 if (m_invPath.Length == 0)
246 {
247 inventoryFolder = rootFolder;
248 }
249 else
250 {
251 m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER));
252 List<InventoryFolderBase> candidateFolders
253 = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath);
254 if (candidateFolders.Count > 0)
255 inventoryFolder = candidateFolders[0];
256 }
257
258 // The path may point to an item instead
259 if (inventoryFolder == null)
260 {
261 inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath);
262 //inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath);
263 }
264
265 if (null == inventoryFolder && null == inventoryItem)
266 { 219 {
267 // We couldn't find the path indicated 220 InventoryFolderBase inventoryFolder = null;
268 string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath); 221 InventoryItemBase inventoryItem = null;
269 m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", errorMessage); 222 InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID);
270 m_module.TriggerInventoryArchiveSaved( 223
271 m_id, false, m_userInfo, m_invPath, m_saveStream, 224 bool foundStar = false;
272 new Exception(errorMessage)); 225
273 return; 226 // Eliminate double slashes and any leading / on the path.
274 } 227 string[] components
228 = m_invPath.Split(
229 new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries);
230
231 int maxComponentIndex = components.Length - 1;
232
233 // If the path terminates with a STAR then later on we want to archive all nodes in the folder but not the
234 // folder itself. This may get more sophisicated later on
235 if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD)
236 {
237 foundStar = true;
238 maxComponentIndex--;
239 }
240
241 m_invPath = String.Empty;
242 for (int i = 0; i <= maxComponentIndex; i++)
243 {
244 m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER;
245 }
246
247 // Annoyingly Split actually returns the original string if the input string consists only of delimiters
248 // Therefore if we still start with a / after the split, then we need the root folder
249 if (m_invPath.Length == 0)
250 {
251 inventoryFolder = rootFolder;
252 }
253 else
254 {
255 m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER));
256 List<InventoryFolderBase> candidateFolders
257 = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath);
258 if (candidateFolders.Count > 0)
259 inventoryFolder = candidateFolders[0];
260 }
261
262 // The path may point to an item instead
263 if (inventoryFolder == null)
264 {
265 inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath);
266 //inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath);
267 }
268
269 if (null == inventoryFolder && null == inventoryItem)
270 {
271 // We couldn't find the path indicated
272 string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath);
273 Exception e = new InventoryArchiverException(errorMessage);
274 m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e);
275 throw e;
276 }
275 277
276 m_archiveWriter = new TarArchiveWriter(m_saveStream); 278 m_archiveWriter = new TarArchiveWriter(m_saveStream);
277 279
278 try
279 {
280 if (inventoryFolder != null) 280 if (inventoryFolder != null)
281 { 281 {
282 m_log.DebugFormat( 282 m_log.DebugFormat(
@@ -297,16 +297,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
297 297
298 // Don't put all this profile information into the archive right now. 298 // Don't put all this profile information into the archive right now.
299 //SaveUsers(); 299 //SaveUsers();
300
301 new AssetsRequest(
302 new AssetsArchiver(m_archiveWriter), m_assetUuids, m_scene.AssetService, ReceivedAllAssets).Execute();
300 } 303 }
301 catch (Exception) 304 catch (Exception)
302 { 305 {
303 m_archiveWriter.Close(); 306 m_saveStream.Close();
304 throw; 307 throw;
305 } 308 }
306
307 new AssetsRequest(
308 new AssetsArchiver(m_archiveWriter), m_assetUuids,
309 m_scene.AssetService, ReceivedAllAssets).Execute();
310 } 309 }
311 310
312 /// <summary> 311 /// <summary>
diff --git a/OpenSim/Framework/ConfigBase.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverException.cs
index 40ec32f..e07e2ca 100644
--- a/OpenSim/Framework/ConfigBase.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverException.cs
@@ -26,13 +26,15 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
30using System.Text;
31 29
32namespace OpenSim.Framework 30namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
33{ 31{
34 public abstract class ConfigBase 32 /// <summary>
35 { 33 /// Signals an inventory archiving problem
36 protected ConfigurationMember m_configMember; 34 /// </summary>
35 public class InventoryArchiverException : Exception
36 {
37 public InventoryArchiverException(string message) : base(message) {}
38 public InventoryArchiverException(string message, Exception e) : base(message, e) {}
37 } 39 }
38} 40} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
index 668c344..f03f2a1 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
@@ -324,34 +324,41 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
324 /// <param name="cmdparams"></param> 324 /// <param name="cmdparams"></param>
325 protected void HandleLoadInvConsoleCommand(string module, string[] cmdparams) 325 protected void HandleLoadInvConsoleCommand(string module, string[] cmdparams)
326 { 326 {
327 m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME."); 327 try
328 328 {
329 Dictionary<string, object> options = new Dictionary<string, object>(); 329 m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME.");
330 OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; }); 330
331 331 Dictionary<string, object> options = new Dictionary<string, object>();
332 List<string> mainParams = optionSet.Parse(cmdparams); 332 OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; });
333 333
334 if (mainParams.Count < 6) 334 List<string> mainParams = optionSet.Parse(cmdparams);
335 { 335
336 m_log.Error( 336 if (mainParams.Count < 6)
337 "[INVENTORY ARCHIVER]: usage is load iar <first name> <last name> <inventory path> <user password> [<load file path>]"); 337 {
338 return; 338 m_log.Error(
339 } 339 "[INVENTORY ARCHIVER]: usage is load iar [--merge] <first name> <last name> <inventory path> <user password> [<load file path>]");
340 340 return;
341 string firstName = mainParams[2]; 341 }
342 string lastName = mainParams[3]; 342
343 string invPath = mainParams[4]; 343 string firstName = mainParams[2];
344 string pass = mainParams[5]; 344 string lastName = mainParams[3];
345 string loadPath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); 345 string invPath = mainParams[4];
346 346 string pass = mainParams[5];
347 m_log.InfoFormat( 347 string loadPath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME);
348 "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}", 348
349 loadPath, invPath, firstName, lastName);
350
351 if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options))
352 m_log.InfoFormat( 349 m_log.InfoFormat(
353 "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}", 350 "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}",
354 loadPath, firstName, lastName); 351 loadPath, invPath, firstName, lastName);
352
353 if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options))
354 m_log.InfoFormat(
355 "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}",
356 loadPath, firstName, lastName);
357 }
358 catch (InventoryArchiverException e)
359 {
360 m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message);
361 }
355 } 362 }
356 363
357 /// <summary> 364 /// <summary>
@@ -360,30 +367,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
360 /// <param name="cmdparams"></param> 367 /// <param name="cmdparams"></param>
361 protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams) 368 protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams)
362 { 369 {
363 if (cmdparams.Length < 6) 370 Guid id = Guid.NewGuid();
371
372 try
364 { 373 {
365 m_log.Error( 374 if (cmdparams.Length < 6)
366 "[INVENTORY ARCHIVER]: usage is save iar <first name> <last name> <inventory path> <user password> [<save file path>]"); 375 {
367 return; 376 m_log.Error(
377 "[INVENTORY ARCHIVER]: usage is save iar <first name> <last name> <inventory path> <user password> [<save file path>]");
378 return;
379 }
380
381 m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME.");
382
383 string firstName = cmdparams[2];
384 string lastName = cmdparams[3];
385 string invPath = cmdparams[4];
386 string pass = cmdparams[5];
387 string savePath = (cmdparams.Length > 6 ? cmdparams[6] : DEFAULT_INV_BACKUP_FILENAME);
388
389 m_log.InfoFormat(
390 "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
391 savePath, invPath, firstName, lastName);
392
393 ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, new Dictionary<string, object>());
368 } 394 }
369 395 catch (InventoryArchiverException e)
370 m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME."); 396 {
371 397 m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message);
372 string firstName = cmdparams[2]; 398 }
373 string lastName = cmdparams[3]; 399
374 string invPath = cmdparams[4];
375 string pass = cmdparams[5];
376 string savePath = (cmdparams.Length > 6 ? cmdparams[6] : DEFAULT_INV_BACKUP_FILENAME);
377
378 m_log.InfoFormat(
379 "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
380 savePath, invPath, firstName, lastName);
381
382 Guid id = Guid.NewGuid();
383 ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, new Dictionary<string, object>());
384
385 lock (m_pendingConsoleSaves) 400 lock (m_pendingConsoleSaves)
386 m_pendingConsoleSaves.Add(id); 401 m_pendingConsoleSaves.Add(id);
387 } 402 }
388 403
389 private void SaveInvConsoleCommandCompleted( 404 private void SaveInvConsoleCommandCompleted(
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index 5fad0a9..2d80382 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -63,13 +63,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
63 } 63 }
64 64
65 /// <summary> 65 /// <summary>
66 /// Test saving a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet). 66 /// Test saving an inventory path to a V0.1 OpenSim Inventory Archive
67 /// (subject to change since there is no fixed format yet).
67 /// </summary> 68 /// </summary>
68 // Commenting for now! The mock inventory service needs more beef, at least for
69 // GetFolderForType
70 // REFACTORING PROBLEM. This needs to be rewritten.
71 [Test] 69 [Test]
72 public void TestSaveIarV0_1() 70 public void TestSavePathToIarV0_1()
73 { 71 {
74 TestHelper.InMethod(); 72 TestHelper.InMethod();
75// log4net.Config.XmlConfigurator.Configure(); 73// log4net.Config.XmlConfigurator.Configure();
@@ -182,6 +180,123 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
182 } 180 }
183 181
184 /// <summary> 182 /// <summary>
183 /// Test saving a single inventory item to a V0.1 OpenSim Inventory Archive
184 /// (subject to change since there is no fixed format yet).
185 /// </summary>
186 [Test]
187 public void TestSaveItemToIarV0_1()
188 {
189 TestHelper.InMethod();
190// log4net.Config.XmlConfigurator.Configure();
191
192 InventoryArchiverModule archiverModule = new InventoryArchiverModule(true);
193
194 Scene scene = SceneSetupHelpers.SetupScene("Inventory");
195 SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
196
197 // Create user
198 string userFirstName = "Jock";
199 string userLastName = "Stirrup";
200 string userPassword = "troll";
201 UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
202 UserProfileTestUtils.CreateUserWithInventory(scene, userFirstName, userLastName, userId, userPassword);
203
204 // Create asset
205 SceneObjectGroup object1;
206 SceneObjectPart part1;
207 {
208 string partName = "My Little Dog Object";
209 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
210 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
211 Vector3 groupPosition = new Vector3(10, 20, 30);
212 Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
213 Vector3 offsetPosition = new Vector3(5, 10, 15);
214
215 part1
216 = new SceneObjectPart(
217 ownerId, shape, groupPosition, rotationOffset, offsetPosition);
218 part1.Name = partName;
219
220 object1 = new SceneObjectGroup(part1);
221 scene.AddNewSceneObject(object1, false);
222 }
223
224 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
225 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
226 scene.AssetService.Store(asset1);
227
228 // Create item
229 UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080");
230 string item1Name = "My Little Dog";
231 InventoryItemBase item1 = new InventoryItemBase();
232 item1.Name = item1Name;
233 item1.AssetID = asset1.FullID;
234 item1.ID = item1Id;
235 InventoryFolderBase objsFolder
236 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects")[0];
237 item1.Folder = objsFolder.ID;
238 scene.AddInventoryItem(userId, item1);
239
240 MemoryStream archiveWriteStream = new MemoryStream();
241 archiverModule.OnInventoryArchiveSaved += SaveCompleted;
242
243 mre.Reset();
244 archiverModule.ArchiveInventory(
245 Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream);
246 mre.WaitOne(60000, false);
247
248 byte[] archive = archiveWriteStream.ToArray();
249 MemoryStream archiveReadStream = new MemoryStream(archive);
250 TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
251
252 //bool gotControlFile = false;
253 bool gotObject1File = false;
254 //bool gotObject2File = false;
255 string expectedObject1FileName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1);
256 string expectedObject1FilePath = string.Format(
257 "{0}{1}",
258 ArchiveConstants.INVENTORY_PATH,
259 expectedObject1FileName);
260
261 string filePath;
262 TarArchiveReader.TarEntryType tarEntryType;
263
264// Console.WriteLine("Reading archive");
265
266 while (tar.ReadEntry(out filePath, out tarEntryType) != null)
267 {
268 Console.WriteLine("Got {0}", filePath);
269
270// if (ArchiveConstants.CONTROL_FILE_PATH == filePath)
271// {
272// gotControlFile = true;
273// }
274
275 if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH) && filePath.EndsWith(".xml"))
276 {
277// string fileName = filePath.Remove(0, "Objects/".Length);
278//
279// if (fileName.StartsWith(part1.Name))
280// {
281 Assert.That(expectedObject1FilePath, Is.EqualTo(filePath));
282 gotObject1File = true;
283// }
284// else if (fileName.StartsWith(part2.Name))
285// {
286// Assert.That(fileName, Is.EqualTo(expectedObject2FileName));
287// gotObject2File = true;
288// }
289 }
290 }
291
292// Assert.That(gotControlFile, Is.True, "No control file in archive");
293 Assert.That(gotObject1File, Is.True, "No item1 file in archive");
294// Assert.That(gotObject2File, Is.True, "No object2 file in archive");
295
296 // TODO: Test presence of more files and contents of files.
297 }
298
299 /// <summary>
185 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where 300 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
186 /// an account exists with the creator name. 301 /// an account exists with the creator name.
187 /// </summary> 302 /// </summary>