diff --git a/OpenSim/Framework/Communications/InventoryServiceBase.cs b/OpenSim/Framework/Communications/InventoryServiceBase.cs index 091d829862..e86eaac5e5 100644 --- a/OpenSim/Framework/Communications/InventoryServiceBase.cs +++ b/OpenSim/Framework/Communications/InventoryServiceBase.cs @@ -82,10 +82,12 @@ namespace OpenSim.Framework.Communications /// public List RequestFirstLevelFolders(LLUUID userID) { - List inventoryList = new List(); + List inventoryList = new List(); + InventoryFolderBase rootFolder = null; + foreach (KeyValuePair plugin in m_plugins) { - InventoryFolderBase rootFolder = plugin.Value.getUserRootFolder(userID); + rootFolder = plugin.Value.getUserRootFolder(userID); if (rootFolder != null) { inventoryList = plugin.Value.getInventoryFolders(rootFolder.folderID); @@ -93,6 +95,13 @@ namespace OpenSim.Framework.Communications return inventoryList; } } + + if (null == rootFolder) + { + MainLog.Instance.Warn( + "INVENTORY", "Could not find a root folder belonging to user with ID " + userID); + } + return inventoryList; } @@ -235,4 +244,4 @@ namespace OpenSim.Framework.Communications public abstract void AddNewInventoryItem(LLUUID userID, InventoryItemBase item); public abstract void DeleteInventoryItem(LLUUID userID, InventoryItemBase item); } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/Data.MSSQL/MSSQLInventoryData.cs b/OpenSim/Framework/Data.MSSQL/MSSQLInventoryData.cs index 364e0f2500..cd0470c5da 100644 --- a/OpenSim/Framework/Data.MSSQL/MSSQLInventoryData.cs +++ b/OpenSim/Framework/Data.MSSQL/MSSQLInventoryData.cs @@ -201,11 +201,7 @@ namespace OpenSim.Framework.Data.MSSQL } } - /// - /// Returns the users inventory root folder. - /// - /// - /// + // see InventoryItemBase.getUserRootFolder public InventoryFolderBase getUserRootFolder(LLUUID user) { try @@ -224,8 +220,14 @@ namespace OpenSim.Framework.Data.MSSQL items.Add(readInventoryFolder(reader)); InventoryFolderBase rootFolder = null; + + // There should only ever be one root folder for a user. However, if there's more + // than one we'll simply use the first one rather than failing. It would be even + // nicer to print some message to this effect, but this feels like it's too low a + // to put such a message out, and it's too minor right now to spare the time to + // suitably refactor. if (items.Count > 0) { - rootFolder = items[0]; //should only be one folder with parent set to zero (the root one). + rootFolder = items[0]; } reader.Close(); @@ -694,4 +696,4 @@ namespace OpenSim.Framework.Data.MSSQL } } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/Data.MySQL/MySQLInventoryData.cs b/OpenSim/Framework/Data.MySQL/MySQLInventoryData.cs index 7c86e2c3e5..4020cc13ea 100644 --- a/OpenSim/Framework/Data.MySQL/MySQLInventoryData.cs +++ b/OpenSim/Framework/Data.MySQL/MySQLInventoryData.cs @@ -211,11 +211,7 @@ namespace OpenSim.Framework.Data.MySQL } } - /// - /// Returns the users inventory root folder. - /// - /// - /// + // see InventoryItemBase.getUserRootFolder public InventoryFolderBase getUserRootFolder(LLUUID user) { try @@ -234,9 +230,19 @@ namespace OpenSim.Framework.Data.MySQL List items = new List(); while (reader.Read()) items.Add(readInventoryFolder(reader)); + + InventoryFolderBase rootFolder = null; + + // There should only ever be one root folder for a user. However, if there's more + // than one we'll simply use the first one rather than failing. It would be even + // nicer to print some message to this effect, but this feels like it's too low a + // to put such a message out, and it's too minor right now to spare the time to + // suitably refactor. + if (items.Count > 0) + { + rootFolder = items[0]; + } - InventoryFolderBase rootFolder = items[0]; - //should only be one folder with parent set to zero (the root one). reader.Close(); result.Dispose(); @@ -252,7 +258,9 @@ namespace OpenSim.Framework.Data.MySQL } /// - /// Returns a list of folders in a users inventory contained within the specified folder + /// Return a list of folders in a users inventory contained within the specified folder. + /// This method is only used in tests - in normal operation the user always have one, + /// and only one, root folder. /// /// The folder to search /// A list of inventory folders @@ -605,4 +613,4 @@ namespace OpenSim.Framework.Data.MySQL } } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/Data.SQLite/SQLiteInventoryStore.cs b/OpenSim/Framework/Data.SQLite/SQLiteInventoryStore.cs index 5e95878666..94084a6a91 100644 --- a/OpenSim/Framework/Data.SQLite/SQLiteInventoryStore.cs +++ b/OpenSim/Framework/Data.SQLite/SQLiteInventoryStore.cs @@ -226,11 +226,7 @@ namespace OpenSim.Framework.Data.SQLite return new List(); } - /// - /// Returns the users inventory root folder. - /// - /// The UUID of the user who is having inventory being returned - /// Root inventory folder + // see InventoryItemBase.getUserRootFolder public InventoryFolderBase getUserRootFolder(LLUUID user) { List folders = new List(); @@ -242,22 +238,15 @@ namespace OpenSim.Framework.Data.SQLite folders.Add(buildFolder(row)); } - if (folders.Count == 1) + // There should only ever be one root folder for a user. However, if there's more + // than one we'll simply use the first one rather than failing. It would be even + // nicer to print some message to this effect, but this feels like it's too low a + // to put such a message out, and it's too minor right now to spare the time to + // suitably refactor. + if (folders.Count > 1) { - //we found the root - //System.Console.WriteLine("found root inventory folder"); return folders[0]; } - else if (folders.Count > 1) - { - //err shouldn't be more than one root - //System.Console.WriteLine("found more than one root inventory folder"); - } - else if (folders.Count == 0) - { - // no root? - //System.Console.WriteLine("couldn't find root inventory folder"); - } return null; } @@ -608,4 +597,4 @@ namespace OpenSim.Framework.Data.SQLite return true; } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/InventoryItemBase.cs b/OpenSim/Framework/InventoryItemBase.cs index 0ee30bb53a..b9a11c9955 100644 --- a/OpenSim/Framework/InventoryItemBase.cs +++ b/OpenSim/Framework/InventoryItemBase.cs @@ -184,7 +184,7 @@ namespace OpenSim.Framework /// Returns the users inventory root folder. /// /// The UUID of the user who is having inventory being returned - /// Root inventory folder + /// Root inventory folder, null if no root inventory folder was found InventoryFolderBase getUserRootFolder(LLUUID user); /// @@ -285,4 +285,4 @@ namespace OpenSim.Framework [XmlElement(ElementName = "folder", IsNullable = true)] public SerializableFolder root; } -} \ No newline at end of file +} diff --git a/OpenSim/Grid/UserServer/UserLoginService.cs b/OpenSim/Grid/UserServer/UserLoginService.cs index f404cce7fb..fa5eac5ed7 100644 --- a/OpenSim/Grid/UserServer/UserLoginService.cs +++ b/OpenSim/Grid/UserServer/UserLoginService.cs @@ -197,15 +197,32 @@ namespace OpenSim.Grid.UserServer protected override InventoryData CreateInventoryData(LLUUID userID) { - List folders = SynchronousRestObjectPoster.BeginPostObject>("POST", m_config.InventoryUrl + "RootFolders/", userID); - if (folders ==null | folders.Count == 0) + List folders + = SynchronousRestObjectPoster.BeginPostObject>( + "POST", m_config.InventoryUrl + "RootFolders/", userID); + + // In theory, the user will only ever be missing a root folder in situations where a grid + // which didn't previously run a grid wide inventory server is being transitioned to one + // which does. + if (null == folders | folders.Count == 0) { - RestObjectPoster.BeginPostObject(m_config.InventoryUrl + "CreateInventory/", userID); - Thread.Sleep(1000); - folders = SynchronousRestObjectPoster.BeginPostObject>("POST", m_config.InventoryUrl + "RootFolders/", userID); + MainLog.Instance.Warn( + "LOGIN", + "A root inventory folder for user ID " + userID + " was not found. A new set" + + " of empty inventory folders is being created."); + + RestObjectPoster.BeginPostObject( + m_config.InventoryUrl + "CreateInventory/", userID); + + // A big delay should be okay here since the recreation of the user's root folders should + // only ever happen once. We need to sleep to let the inventory server do its work - + // previously 1000ms has been found to be too short. + Thread.Sleep(10000); + folders = SynchronousRestObjectPoster.BeginPostObject>( + "POST", m_config.InventoryUrl + "RootFolders/", userID); } - if(folders.Count >0) + if (folders.Count > 0) { LLUUID rootID = LLUUID.Zero; ArrayList AgentInventoryArray = new ArrayList(); @@ -228,6 +245,9 @@ namespace OpenSim.Grid.UserServer } else { + MainLog.Instance.Warn("LOGIN", "The root inventory folder could still not be retrieved" + + " for user ID " + userID); + AgentInventory userInventory = new AgentInventory(); userInventory.CreateRootFolder(userID, false); @@ -248,4 +268,4 @@ namespace OpenSim.Grid.UserServer } } } -} \ No newline at end of file +}