diff options
Merge branch 'master' into careminster-presence-refactor
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar')
3 files changed, 145 insertions, 18 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index dd16bfe..e043caa 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs | |||
@@ -46,6 +46,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
46 | { | 46 | { |
47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | 48 | ||
49 | /// <summary> | ||
50 | /// Determine whether this archive will save assets. Default is true. | ||
51 | /// </summary> | ||
52 | public bool SaveAssets { get; set; } | ||
53 | |||
49 | /// <value> | 54 | /// <value> |
50 | /// Used to select all inventory nodes in a folder but not the folder itself | 55 | /// Used to select all inventory nodes in a folder but not the folder itself |
51 | /// </value> | 56 | /// </value> |
@@ -112,6 +117,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
112 | m_invPath = invPath; | 117 | m_invPath = invPath; |
113 | m_saveStream = saveStream; | 118 | m_saveStream = saveStream; |
114 | m_assetGatherer = new UuidGatherer(m_scene.AssetService); | 119 | m_assetGatherer = new UuidGatherer(m_scene.AssetService); |
120 | |||
121 | SaveAssets = true; | ||
115 | } | 122 | } |
116 | 123 | ||
117 | protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids) | 124 | protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids) |
@@ -147,7 +154,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
147 | string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService); | 154 | string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService); |
148 | m_archiveWriter.WriteFile(filename, serialization); | 155 | m_archiveWriter.WriteFile(filename, serialization); |
149 | 156 | ||
150 | m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids); | 157 | if (SaveAssets) |
158 | m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids); | ||
151 | } | 159 | } |
152 | 160 | ||
153 | /// <summary> | 161 | /// <summary> |
@@ -189,6 +197,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
189 | /// </summary> | 197 | /// </summary> |
190 | public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService) | 198 | public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService) |
191 | { | 199 | { |
200 | if (options.ContainsKey("noassets") && (bool)options["noassets"]) | ||
201 | SaveAssets = false; | ||
202 | |||
192 | try | 203 | try |
193 | { | 204 | { |
194 | InventoryFolderBase inventoryFolder = null; | 205 | InventoryFolderBase inventoryFolder = null; |
@@ -279,12 +290,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
279 | 290 | ||
280 | // Don't put all this profile information into the archive right now. | 291 | // Don't put all this profile information into the archive right now. |
281 | //SaveUsers(); | 292 | //SaveUsers(); |
282 | 293 | ||
283 | new AssetsRequest( | 294 | if (SaveAssets) |
284 | new AssetsArchiver(m_archiveWriter), | 295 | { |
285 | m_assetUuids, m_scene.AssetService, | 296 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetUuids.Count); |
286 | m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, | 297 | |
287 | options, ReceivedAllAssets).Execute(); | 298 | new AssetsRequest( |
299 | new AssetsArchiver(m_archiveWriter), | ||
300 | m_assetUuids, m_scene.AssetService, | ||
301 | m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, | ||
302 | options, ReceivedAllAssets).Execute(); | ||
303 | } | ||
304 | else | ||
305 | { | ||
306 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Not saving assets since --noassets was specified"); | ||
307 | |||
308 | ReceivedAllAssets(new List<UUID>(), new List<UUID>()); | ||
309 | } | ||
288 | } | 310 | } |
289 | catch (Exception) | 311 | catch (Exception) |
290 | { | 312 | { |
@@ -381,19 +403,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
381 | /// </summary> | 403 | /// </summary> |
382 | /// <param name="options"></param> | 404 | /// <param name="options"></param> |
383 | /// <returns></returns> | 405 | /// <returns></returns> |
384 | public static string CreateControlFile(Dictionary<string, object> options) | 406 | public string CreateControlFile(Dictionary<string, object> options) |
385 | { | 407 | { |
386 | int majorVersion, minorVersion; | 408 | int majorVersion, minorVersion; |
387 | 409 | ||
388 | if (options.ContainsKey("profile")) | 410 | if (options.ContainsKey("profile")) |
389 | { | 411 | { |
390 | majorVersion = 1; | 412 | majorVersion = 1; |
391 | minorVersion = 1; | 413 | minorVersion = 2; |
392 | } | 414 | } |
393 | else | 415 | else |
394 | { | 416 | { |
395 | majorVersion = 0; | 417 | majorVersion = 0; |
396 | minorVersion = 2; | 418 | minorVersion = 3; |
397 | } | 419 | } |
398 | 420 | ||
399 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion); | 421 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion); |
@@ -405,6 +427,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
405 | xtw.WriteStartElement("archive"); | 427 | xtw.WriteStartElement("archive"); |
406 | xtw.WriteAttributeString("major_version", majorVersion.ToString()); | 428 | xtw.WriteAttributeString("major_version", majorVersion.ToString()); |
407 | xtw.WriteAttributeString("minor_version", minorVersion.ToString()); | 429 | xtw.WriteAttributeString("minor_version", minorVersion.ToString()); |
430 | |||
431 | xtw.WriteElementString("assets_included", SaveAssets.ToString()); | ||
432 | |||
408 | xtw.WriteEndElement(); | 433 | xtw.WriteEndElement(); |
409 | 434 | ||
410 | xtw.Flush(); | 435 | xtw.Flush(); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index 613f0ed..e0b02aa 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs | |||
@@ -122,7 +122,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
122 | 122 | ||
123 | scene.AddCommand( | 123 | scene.AddCommand( |
124 | this, "save iar", | 124 | this, "save iar", |
125 | "save iar [--p|-profile=<url>] <first> <last> <inventory path> <password> [<IAR path>]", | 125 | "save iar [--p|-profile=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [--v|-verbose]", |
126 | "Save user inventory archive (IAR).", | 126 | "Save user inventory archive (IAR).", |
127 | "<first> is the user's first name." + Environment.NewLine | 127 | "<first> is the user's first name." + Environment.NewLine |
128 | + "<last> is the user's last name." + Environment.NewLine | 128 | + "<last> is the user's last name." + Environment.NewLine |
@@ -130,6 +130,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
130 | + "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine | 130 | + "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine |
131 | + "-c|--creators preserves information about foreign creators." + Environment.NewLine | 131 | + "-c|--creators preserves information about foreign creators." + Environment.NewLine |
132 | + "-v|--verbose extra debug messages." + Environment.NewLine | 132 | + "-v|--verbose extra debug messages." + Environment.NewLine |
133 | + "--noassets stops assets being saved to the IAR." | ||
133 | + "<IAR path> is the filesystem path at which to save the IAR." | 134 | + "<IAR path> is the filesystem path at which to save the IAR." |
134 | + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), | 135 | + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), |
135 | HandleSaveInvConsoleCommand); | 136 | HandleSaveInvConsoleCommand); |
@@ -398,6 +399,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
398 | ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); | 399 | ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); |
399 | ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; }); | 400 | ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; }); |
400 | ops.Add("c|creators", delegate(string v) { options["creators"] = v; }); | 401 | ops.Add("c|creators", delegate(string v) { options["creators"] = v; }); |
402 | ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); | ||
401 | 403 | ||
402 | List<string> mainParams = ops.Parse(cmdparams); | 404 | List<string> mainParams = ops.Parse(cmdparams); |
403 | 405 | ||
@@ -406,7 +408,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
406 | if (mainParams.Count < 6) | 408 | if (mainParams.Count < 6) |
407 | { | 409 | { |
408 | m_log.Error( | 410 | m_log.Error( |
409 | "[INVENTORY ARCHIVER]: usage is save iar [--p|-profile=<url>] <first name> <last name> <inventory path> <user password> [<save file path>]"); | 411 | "[INVENTORY ARCHIVER]: usage is save iar [--p|-profile=<url>] [--noassets] <first name> <last name> <inventory path> <user password> [<save file path>]"); |
410 | return; | 412 | return; |
411 | } | 413 | } |
412 | 414 | ||
@@ -423,16 +425,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
423 | m_log.InfoFormat( | 425 | m_log.InfoFormat( |
424 | "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", | 426 | "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", |
425 | savePath, invPath, firstName, lastName); | 427 | savePath, invPath, firstName, lastName); |
426 | 428 | ||
429 | lock (m_pendingConsoleSaves) | ||
430 | m_pendingConsoleSaves.Add(id); | ||
431 | |||
427 | ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options); | 432 | ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options); |
428 | } | 433 | } |
429 | catch (InventoryArchiverException e) | 434 | catch (InventoryArchiverException e) |
430 | { | 435 | { |
431 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); | 436 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); |
432 | } | 437 | } |
433 | |||
434 | lock (m_pendingConsoleSaves) | ||
435 | m_pendingConsoleSaves.Add(id); | ||
436 | } | 438 | } |
437 | 439 | ||
438 | private void SaveInvConsoleCommandCompleted( | 440 | 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 d97311a..ae3ab21 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs | |||
@@ -123,11 +123,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
123 | } | 123 | } |
124 | 124 | ||
125 | /// <summary> | 125 | /// <summary> |
126 | /// Test saving a single inventory item to a V0.1 OpenSim Inventory Archive | 126 | /// Test saving a single inventory item to an IAR |
127 | /// (subject to change since there is no fixed format yet). | 127 | /// (subject to change since there is no fixed format yet). |
128 | /// </summary> | 128 | /// </summary> |
129 | [Test] | 129 | [Test] |
130 | public void TestSaveItemToIarV0_1() | 130 | public void TestSaveItemToIar() |
131 | { | 131 | { |
132 | TestHelper.InMethod(); | 132 | TestHelper.InMethod(); |
133 | // log4net.Config.XmlConfigurator.Configure(); | 133 | // log4net.Config.XmlConfigurator.Configure(); |
@@ -217,6 +217,106 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
217 | 217 | ||
218 | // TODO: Test presence of more files and contents of files. | 218 | // TODO: Test presence of more files and contents of files. |
219 | } | 219 | } |
220 | |||
221 | /// <summary> | ||
222 | /// Test saving a single inventory item to an IAR without its asset | ||
223 | /// </summary> | ||
224 | [Test] | ||
225 | public void TestSaveItemToIarNoAssets() | ||
226 | { | ||
227 | TestHelper.InMethod(); | ||
228 | // log4net.Config.XmlConfigurator.Configure(); | ||
229 | |||
230 | // Create user | ||
231 | string userFirstName = "Jock"; | ||
232 | string userLastName = "Stirrup"; | ||
233 | string userPassword = "troll"; | ||
234 | UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); | ||
235 | UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); | ||
236 | |||
237 | // Create asset | ||
238 | UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); | ||
239 | SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50); | ||
240 | |||
241 | UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); | ||
242 | AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); | ||
243 | m_scene.AssetService.Store(asset1); | ||
244 | |||
245 | // Create item | ||
246 | UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080"); | ||
247 | string item1Name = "My Little Dog"; | ||
248 | InventoryItemBase item1 = new InventoryItemBase(); | ||
249 | item1.Name = item1Name; | ||
250 | item1.AssetID = asset1.FullID; | ||
251 | item1.ID = item1Id; | ||
252 | InventoryFolderBase objsFolder | ||
253 | = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0]; | ||
254 | item1.Folder = objsFolder.ID; | ||
255 | m_scene.AddInventoryItem(item1); | ||
256 | |||
257 | MemoryStream archiveWriteStream = new MemoryStream(); | ||
258 | |||
259 | Dictionary<string, Object> options = new Dictionary<string, Object>(); | ||
260 | options.Add("noassets", true); | ||
261 | |||
262 | // When we're not saving assets, archiving is being done synchronously. | ||
263 | m_archiverModule.ArchiveInventory( | ||
264 | Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream, options); | ||
265 | |||
266 | byte[] archive = archiveWriteStream.ToArray(); | ||
267 | MemoryStream archiveReadStream = new MemoryStream(archive); | ||
268 | TarArchiveReader tar = new TarArchiveReader(archiveReadStream); | ||
269 | |||
270 | //bool gotControlFile = false; | ||
271 | bool gotObject1File = false; | ||
272 | //bool gotObject2File = false; | ||
273 | string expectedObject1FileName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1); | ||
274 | string expectedObject1FilePath = string.Format( | ||
275 | "{0}{1}", | ||
276 | ArchiveConstants.INVENTORY_PATH, | ||
277 | expectedObject1FileName); | ||
278 | |||
279 | string filePath; | ||
280 | TarArchiveReader.TarEntryType tarEntryType; | ||
281 | |||
282 | // Console.WriteLine("Reading archive"); | ||
283 | |||
284 | while (tar.ReadEntry(out filePath, out tarEntryType) != null) | ||
285 | { | ||
286 | Console.WriteLine("Got {0}", filePath); | ||
287 | |||
288 | // if (ArchiveConstants.CONTROL_FILE_PATH == filePath) | ||
289 | // { | ||
290 | // gotControlFile = true; | ||
291 | // } | ||
292 | |||
293 | if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH) && filePath.EndsWith(".xml")) | ||
294 | { | ||
295 | // string fileName = filePath.Remove(0, "Objects/".Length); | ||
296 | // | ||
297 | // if (fileName.StartsWith(part1.Name)) | ||
298 | // { | ||
299 | Assert.That(expectedObject1FilePath, Is.EqualTo(filePath)); | ||
300 | gotObject1File = true; | ||
301 | // } | ||
302 | // else if (fileName.StartsWith(part2.Name)) | ||
303 | // { | ||
304 | // Assert.That(fileName, Is.EqualTo(expectedObject2FileName)); | ||
305 | // gotObject2File = true; | ||
306 | // } | ||
307 | } | ||
308 | else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) | ||
309 | { | ||
310 | Assert.Fail("Found asset path in TestSaveItemToIarNoAssets()"); | ||
311 | } | ||
312 | } | ||
313 | |||
314 | // Assert.That(gotControlFile, Is.True, "No control file in archive"); | ||
315 | Assert.That(gotObject1File, Is.True, "No item1 file in archive"); | ||
316 | // Assert.That(gotObject2File, Is.True, "No object2 file in archive"); | ||
317 | |||
318 | // TODO: Test presence of more files and contents of files. | ||
319 | } | ||
220 | 320 | ||
221 | /// <summary> | 321 | /// <summary> |
222 | /// Test case where a creator account exists for the creator UUID embedded in item metadata and serialized | 322 | /// Test case where a creator account exists for the creator UUID embedded in item metadata and serialized |