diff --git a/OpenSim/Framework/Communications/Cache/InventoryFolderImpl.cs b/OpenSim/Framework/InventoryFolderImpl.cs similarity index 96% rename from OpenSim/Framework/Communications/Cache/InventoryFolderImpl.cs rename to OpenSim/Framework/InventoryFolderImpl.cs index 71f6f1b9b4..248783fa4f 100644 --- a/OpenSim/Framework/Communications/Cache/InventoryFolderImpl.cs +++ b/OpenSim/Framework/InventoryFolderImpl.cs @@ -1,470 +1,466 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using OpenMetaverse; - -//using System.Reflection; - -//using log4net; - -namespace OpenSim.Framework.Communications.Cache -{ - public class InventoryFolderImpl : InventoryFolderBase - { - //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - public static readonly string PATH_DELIMITER = "/"; - - /// - /// Items that are contained in this folder - /// - public Dictionary Items = new Dictionary(); - - /// - /// Child folders that are contained in this folder - /// - protected Dictionary m_childFolders = new Dictionary(); - - // Constructors - public InventoryFolderImpl(InventoryFolderBase folderbase) - { - Owner = folderbase.Owner; - ID = folderbase.ID; - Name = folderbase.Name; - ParentID = folderbase.ParentID; - Type = folderbase.Type; - Version = folderbase.Version; - } - - public InventoryFolderImpl() - { - } - - /// - /// Create a new subfolder. - /// - /// - /// - /// - /// The newly created subfolder. Returns null if the folder already exists - public InventoryFolderImpl CreateChildFolder(UUID folderID, string folderName, ushort type) - { - lock (m_childFolders) - { - if (!m_childFolders.ContainsKey(folderID)) - { - InventoryFolderImpl subFold = new InventoryFolderImpl(); - subFold.Name = folderName; - subFold.ID = folderID; - subFold.Type = (short) type; - subFold.ParentID = this.ID; - subFold.Owner = Owner; - m_childFolders.Add(subFold.ID, subFold); - - return subFold; - } - } - - return null; - } - - /// - /// Add a folder that already exists. - /// - /// - public void AddChildFolder(InventoryFolderImpl folder) - { - lock (m_childFolders) - { - folder.ParentID = ID; - m_childFolders[folder.ID] = folder; - } - } - - /// - /// Does this folder contain the given child folder? - /// - /// - /// - public bool ContainsChildFolder(UUID folderID) - { - return m_childFolders.ContainsKey(folderID); - } - - /// - /// Get a child folder - /// - /// - /// The folder if it exists, null if it doesn't - public InventoryFolderImpl GetChildFolder(UUID folderID) - { - InventoryFolderImpl folder = null; - - lock (m_childFolders) - { - m_childFolders.TryGetValue(folderID, out folder); - } - - return folder; - } - - /// - /// Removes the given child subfolder. - /// - /// - /// - /// The folder removed, or null if the folder was not present. - /// - public InventoryFolderImpl RemoveChildFolder(UUID folderID) - { - InventoryFolderImpl removedFolder = null; - - lock (m_childFolders) - { - if (m_childFolders.ContainsKey(folderID)) - { - removedFolder = m_childFolders[folderID]; - m_childFolders.Remove(folderID); - } - } - - return removedFolder; - } - - /// - /// Delete all the folders and items in this folder. - /// - public void Purge() - { - foreach (InventoryFolderImpl folder in m_childFolders.Values) - { - folder.Purge(); - } - - m_childFolders.Clear(); - Items.Clear(); - } - - /// - /// Returns the item if it exists in this folder or in any of this folder's descendant folders - /// - /// - /// null if the item is not found - public InventoryItemBase FindItem(UUID itemID) - { - lock (Items) - { - if (Items.ContainsKey(itemID)) - { - return Items[itemID]; - } - } - - lock (m_childFolders) - { - foreach (InventoryFolderImpl folder in m_childFolders.Values) - { - InventoryItemBase item = folder.FindItem(itemID); - - if (item != null) - { - return item; - } - } - } - - return null; - } - - public InventoryItemBase FindAsset(UUID assetID) - { - lock (Items) - { - foreach (InventoryItemBase item in Items.Values) - { - if (item.AssetID == assetID) - return item; - } - } - - lock (m_childFolders) - { - foreach (InventoryFolderImpl folder in m_childFolders.Values) - { - InventoryItemBase item = folder.FindAsset(assetID); - - if (item != null) - { - return item; - } - } - } - - return null; - } - - /// - /// Deletes an item if it exists in this folder or any children - /// - /// - /// - public bool DeleteItem(UUID itemID) - { - bool found = false; - - lock (Items) - { - if (Items.ContainsKey(itemID)) - { - Items.Remove(itemID); - return true; - } - } - - lock (m_childFolders) - { - foreach (InventoryFolderImpl folder in m_childFolders.Values) - { - found = folder.DeleteItem(itemID); - - if (found == true) - { - break; - } - } - } - - return found; - } - - /// - /// Returns the folder requested if it is this folder or is a descendent of this folder. The search is depth - /// first. - /// - /// The requested folder if it exists, null if it does not. - public InventoryFolderImpl FindFolder(UUID folderID) - { - if (folderID == ID) - return this; - - lock (m_childFolders) - { - foreach (InventoryFolderImpl folder in m_childFolders.Values) - { - InventoryFolderImpl returnFolder = folder.FindFolder(folderID); - - if (returnFolder != null) - return returnFolder; - } - } - - return null; - } - - /// - /// Look through all child subfolders for a folder marked as one for a particular asset type, and return it. - /// - /// - /// Returns null if no such folder is found - public InventoryFolderImpl FindFolderForType(int type) - { - lock (m_childFolders) - { - foreach (InventoryFolderImpl f in m_childFolders.Values) - { - if (f.Type == type) - return f; - } - } - - return null; - } - - /// - /// Find a folder given a PATH_DELIMITER delimited path starting from this folder - /// - /// - /// This method does not handle paths that contain multiple delimitors - /// - /// FIXME: We do not yet handle situations where folders have the same name. We could handle this by some - /// XPath like expression - /// - /// FIXME: Delimitors which occur in names themselves are not currently escapable. - /// - /// - /// The path to the required folder. - /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. - /// - /// null if the folder is not found - public InventoryFolderImpl FindFolderByPath(string path) - { - if (path == string.Empty) - return this; - - path = path.Trim(); - - if (path == PATH_DELIMITER) - return this; - - string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); - - lock (m_childFolders) - { - foreach (InventoryFolderImpl folder in m_childFolders.Values) - { - if (folder.Name == components[0]) - if (components.Length > 1) - return folder.FindFolderByPath(components[1]); - else - return folder; - } - } - - // We didn't find a folder with the given name - return null; - } - - /// - /// Find an item given a PATH_DELIMITOR delimited path starting from this folder. - /// - /// This method does not handle paths that contain multiple delimitors - /// - /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some - /// XPath like expression - /// - /// FIXME: Delimitors which occur in names themselves are not currently escapable. - /// - /// - /// The path to the required item. - /// - /// null if the item is not found - public InventoryItemBase FindItemByPath(string path) - { - string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); - - if (components.Length == 1) - { - lock (Items) - { - foreach (InventoryItemBase item in Items.Values) - { - if (item.Name == components[0]) - return item; - } - } - } - else - { - lock (m_childFolders) - { - foreach (InventoryFolderImpl folder in m_childFolders.Values) - { - if (folder.Name == components[0]) - return folder.FindItemByPath(components[1]); - } - } - } - - // We didn't find an item or intermediate folder with the given name - return null; - } - - /// - /// Return a copy of the list of child items in this folder. The items themselves are the originals. - /// - public List RequestListOfItems() - { - List itemList = new List(); - - lock (Items) - { - foreach (InventoryItemBase item in Items.Values) - { - itemList.Add(item); - } - } - - //m_log.DebugFormat("[INVENTORY FOLDER IMPL]: Found {0} items", itemList.Count); - - return itemList; - } - - /// - /// Return a copy of the list of child folders in this folder. The folders themselves are the originals. - /// - public List RequestListOfFolders() - { - List folderList = new List(); - - lock (m_childFolders) - { - foreach (InventoryFolderBase folder in m_childFolders.Values) - { - folderList.Add(folder); - } - } - - return folderList; - } - - public List RequestListOfFolderImpls() - { - List folderList = new List(); - - lock (m_childFolders) - { - foreach (InventoryFolderImpl folder in m_childFolders.Values) - { - folderList.Add(folder); - } - } - - return folderList; - } - - /// - /// The total number of items in this folder and in the immediate child folders (though not from other - /// descendants). - /// - public int TotalCount - { - get - { - int total = Items.Count; - - foreach (InventoryFolderImpl folder in m_childFolders.Values) - { - total = total + folder.TotalCount; - } - - return total; - } - } - } -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenMetaverse; + +namespace OpenSim.Framework +{ + public class InventoryFolderImpl : InventoryFolderBase + { + //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public static readonly string PATH_DELIMITER = "/"; + + /// + /// Items that are contained in this folder + /// + public Dictionary Items = new Dictionary(); + + /// + /// Child folders that are contained in this folder + /// + protected Dictionary m_childFolders = new Dictionary(); + + // Constructors + public InventoryFolderImpl(InventoryFolderBase folderbase) + { + Owner = folderbase.Owner; + ID = folderbase.ID; + Name = folderbase.Name; + ParentID = folderbase.ParentID; + Type = folderbase.Type; + Version = folderbase.Version; + } + + public InventoryFolderImpl() + { + } + + /// + /// Create a new subfolder. + /// + /// + /// + /// + /// The newly created subfolder. Returns null if the folder already exists + public InventoryFolderImpl CreateChildFolder(UUID folderID, string folderName, ushort type) + { + lock (m_childFolders) + { + if (!m_childFolders.ContainsKey(folderID)) + { + InventoryFolderImpl subFold = new InventoryFolderImpl(); + subFold.Name = folderName; + subFold.ID = folderID; + subFold.Type = (short)type; + subFold.ParentID = this.ID; + subFold.Owner = Owner; + m_childFolders.Add(subFold.ID, subFold); + + return subFold; + } + } + + return null; + } + + /// + /// Add a folder that already exists. + /// + /// + public void AddChildFolder(InventoryFolderImpl folder) + { + lock (m_childFolders) + { + folder.ParentID = ID; + m_childFolders[folder.ID] = folder; + } + } + + /// + /// Does this folder contain the given child folder? + /// + /// + /// + public bool ContainsChildFolder(UUID folderID) + { + return m_childFolders.ContainsKey(folderID); + } + + /// + /// Get a child folder + /// + /// + /// The folder if it exists, null if it doesn't + public InventoryFolderImpl GetChildFolder(UUID folderID) + { + InventoryFolderImpl folder = null; + + lock (m_childFolders) + { + m_childFolders.TryGetValue(folderID, out folder); + } + + return folder; + } + + /// + /// Removes the given child subfolder. + /// + /// + /// + /// The folder removed, or null if the folder was not present. + /// + public InventoryFolderImpl RemoveChildFolder(UUID folderID) + { + InventoryFolderImpl removedFolder = null; + + lock (m_childFolders) + { + if (m_childFolders.ContainsKey(folderID)) + { + removedFolder = m_childFolders[folderID]; + m_childFolders.Remove(folderID); + } + } + + return removedFolder; + } + + /// + /// Delete all the folders and items in this folder. + /// + public void Purge() + { + foreach (InventoryFolderImpl folder in m_childFolders.Values) + { + folder.Purge(); + } + + m_childFolders.Clear(); + Items.Clear(); + } + + /// + /// Returns the item if it exists in this folder or in any of this folder's descendant folders + /// + /// + /// null if the item is not found + public InventoryItemBase FindItem(UUID itemID) + { + lock (Items) + { + if (Items.ContainsKey(itemID)) + { + return Items[itemID]; + } + } + + lock (m_childFolders) + { + foreach (InventoryFolderImpl folder in m_childFolders.Values) + { + InventoryItemBase item = folder.FindItem(itemID); + + if (item != null) + { + return item; + } + } + } + + return null; + } + + public InventoryItemBase FindAsset(UUID assetID) + { + lock (Items) + { + foreach (InventoryItemBase item in Items.Values) + { + if (item.AssetID == assetID) + return item; + } + } + + lock (m_childFolders) + { + foreach (InventoryFolderImpl folder in m_childFolders.Values) + { + InventoryItemBase item = folder.FindAsset(assetID); + + if (item != null) + { + return item; + } + } + } + + return null; + } + + /// + /// Deletes an item if it exists in this folder or any children + /// + /// + /// + public bool DeleteItem(UUID itemID) + { + bool found = false; + + lock (Items) + { + if (Items.ContainsKey(itemID)) + { + Items.Remove(itemID); + return true; + } + } + + lock (m_childFolders) + { + foreach (InventoryFolderImpl folder in m_childFolders.Values) + { + found = folder.DeleteItem(itemID); + + if (found == true) + { + break; + } + } + } + + return found; + } + + /// + /// Returns the folder requested if it is this folder or is a descendent of this folder. The search is depth + /// first. + /// + /// The requested folder if it exists, null if it does not. + public InventoryFolderImpl FindFolder(UUID folderID) + { + if (folderID == ID) + return this; + + lock (m_childFolders) + { + foreach (InventoryFolderImpl folder in m_childFolders.Values) + { + InventoryFolderImpl returnFolder = folder.FindFolder(folderID); + + if (returnFolder != null) + return returnFolder; + } + } + + return null; + } + + /// + /// Look through all child subfolders for a folder marked as one for a particular asset type, and return it. + /// + /// + /// Returns null if no such folder is found + public InventoryFolderImpl FindFolderForType(int type) + { + lock (m_childFolders) + { + foreach (InventoryFolderImpl f in m_childFolders.Values) + { + if (f.Type == type) + return f; + } + } + + return null; + } + + /// + /// Find a folder given a PATH_DELIMITER delimited path starting from this folder + /// + /// + /// This method does not handle paths that contain multiple delimitors + /// + /// FIXME: We do not yet handle situations where folders have the same name. We could handle this by some + /// XPath like expression + /// + /// FIXME: Delimitors which occur in names themselves are not currently escapable. + /// + /// + /// The path to the required folder. + /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. + /// + /// null if the folder is not found + public InventoryFolderImpl FindFolderByPath(string path) + { + if (path == string.Empty) + return this; + + path = path.Trim(); + + if (path == PATH_DELIMITER) + return this; + + string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); + + lock (m_childFolders) + { + foreach (InventoryFolderImpl folder in m_childFolders.Values) + { + if (folder.Name == components[0]) + if (components.Length > 1) + return folder.FindFolderByPath(components[1]); + else + return folder; + } + } + + // We didn't find a folder with the given name + return null; + } + + /// + /// Find an item given a PATH_DELIMITOR delimited path starting from this folder. + /// + /// This method does not handle paths that contain multiple delimitors + /// + /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some + /// XPath like expression + /// + /// FIXME: Delimitors which occur in names themselves are not currently escapable. + /// + /// + /// The path to the required item. + /// + /// null if the item is not found + public InventoryItemBase FindItemByPath(string path) + { + string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); + + if (components.Length == 1) + { + lock (Items) + { + foreach (InventoryItemBase item in Items.Values) + { + if (item.Name == components[0]) + return item; + } + } + } + else + { + lock (m_childFolders) + { + foreach (InventoryFolderImpl folder in m_childFolders.Values) + { + if (folder.Name == components[0]) + return folder.FindItemByPath(components[1]); + } + } + } + + // We didn't find an item or intermediate folder with the given name + return null; + } + + /// + /// Return a copy of the list of child items in this folder. The items themselves are the originals. + /// + public List RequestListOfItems() + { + List itemList = new List(); + + lock (Items) + { + foreach (InventoryItemBase item in Items.Values) + { + itemList.Add(item); + } + } + + //m_log.DebugFormat("[INVENTORY FOLDER IMPL]: Found {0} items", itemList.Count); + + return itemList; + } + + /// + /// Return a copy of the list of child folders in this folder. The folders themselves are the originals. + /// + public List RequestListOfFolders() + { + List folderList = new List(); + + lock (m_childFolders) + { + foreach (InventoryFolderBase folder in m_childFolders.Values) + { + folderList.Add(folder); + } + } + + return folderList; + } + + public List RequestListOfFolderImpls() + { + List folderList = new List(); + + lock (m_childFolders) + { + foreach (InventoryFolderImpl folder in m_childFolders.Values) + { + folderList.Add(folder); + } + } + + return folderList; + } + + /// + /// The total number of items in this folder and in the immediate child folders (though not from other + /// descendants). + /// + public int TotalCount + { + get + { + int total = Items.Count; + + foreach (InventoryFolderImpl folder in m_childFolders.Values) + { + total = total + folder.TotalCount; + } + + return total; + } + } + } +} diff --git a/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/HGInventoryBroker.cs new file mode 100644 index 0000000000..f4cd269f59 --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/HGInventoryBroker.cs @@ -0,0 +1,366 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using log4net; +using Nini.Config; +using System; +using System.Collections.Generic; +using System.Reflection; +using OpenSim.Framework; +using OpenSim.Framework.Communications.Cache; +using OpenSim.Server.Base; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Connectors; +using OpenMetaverse; + +namespace OpenSim.Region.CoreModules.ServiceConnectors.Inventory +{ + public class HGInventoryBroker : ISharedRegionModule, IInventoryService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private bool m_Enabled = false; + private bool m_Initialized = false; + private Scene m_Scene; + private UserProfileCacheService m_UserProfileService; // This should change to IUserProfileService + + private IInventoryService m_GridService; + private ISessionAuthInventoryService m_HGService; + + private string m_LocalGridInventoryURI = string.Empty; + public string Name + { + get { return "HGInventoryBroker"; } + } + + public void Initialise(IConfigSource source) + { + IConfig moduleConfig = source.Configs["Modules"]; + if (moduleConfig != null) + { + string name = moduleConfig.GetString("InventoryServices", ""); + if (name == Name) + { + IConfig inventoryConfig = source.Configs["InventoryService"]; + if (inventoryConfig == null) + { + m_log.Error("[HG INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini"); + return; + } + + string localDll = inventoryConfig.GetString("LocalGridInventoryService", + String.Empty); + string HGDll = inventoryConfig.GetString("HypergridInventoryService", + String.Empty); + + if (localDll == String.Empty) + { + m_log.Error("[HG INVENTORY CONNECTOR]: No LocalGridInventoryService named in section InventoryService"); + return; + } + + if (HGDll == String.Empty) + { + m_log.Error("[HG INVENTORY CONNECTOR]: No HypergridInventoryService named in section InventoryService"); + return; + } + + Object[] args = new Object[] { source }; + m_GridService = + ServerUtils.LoadPlugin(localDll, + args); + + m_HGService = + ServerUtils.LoadPlugin(HGDll, + args); + + if (m_GridService == null) + { + m_log.Error("[HG INVENTORY CONNECTOR]: Can't load local inventory service"); + return; + } + if (m_HGService == null) + { + m_log.Error("[HG INVENTORY CONNECTOR]: Can't load hypergrid inventory service"); + return; + } + + m_LocalGridInventoryURI = inventoryConfig.GetString("InventoryServerURI", string.Empty); + + m_Enabled = true; + m_log.Info("[HG INVENTORY CONNECTOR]: HG asset broker enabled"); + } + } + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + public void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + + if (!m_Initialized) + { + m_Scene = scene; + // HACK for now. Ugh! + m_UserProfileService = m_Scene.CommsManager.UserProfileCacheService; + } + + scene.RegisterModuleInterface(this); + } + + public void RemoveRegion(Scene scene) + { + } + + public void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + + m_log.InfoFormat("[INVENTORY CONNECTOR]: Enabled remote inventory for region {0}", scene.RegionInfo.RegionName); + + } + + #region IInventoryService + + public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) + { + if (IsLocalGridUser(userID)) + m_GridService.GetUserInventory(userID, callback); + else + { + UUID sessionID = GetSessionID(userID); + string uri = "http://" + GetUserInventoryURI(userID) + "/" + userID.ToString(); + m_HGService.GetUserInventory(uri, sessionID, callback); + } + } + + public bool AddFolder(InventoryFolderBase folder) + { + if (folder == null) + return false; + + if (IsLocalGridUser(folder.Owner)) + return m_GridService.AddFolder(folder); + else + { + UUID sessionID = GetSessionID(folder.Owner); + string uri = "http://" + GetUserInventoryURI(folder.Owner) + "/" + folder.Owner.ToString(); + return m_HGService.AddFolder(uri, folder, sessionID); + } + } + + public bool UpdateFolder(InventoryFolderBase folder) + { + if (folder == null) + return false; + + if (IsLocalGridUser(folder.Owner)) + return m_GridService.UpdateFolder(folder); + else + { + UUID sessionID = GetSessionID(folder.Owner); + string uri = "http://" + GetUserInventoryURI(folder.Owner) + "/" + folder.Owner.ToString(); + return m_HGService.UpdateFolder(uri, folder, sessionID); + } + } + + public bool MoveFolder(InventoryFolderBase folder) + { + if (folder == null) + return false; + + if (IsLocalGridUser(folder.Owner)) + return m_GridService.MoveFolder(folder); + else + { + UUID sessionID = GetSessionID(folder.Owner); + string uri = "http://" + GetUserInventoryURI(folder.Owner) + "/" + folder.Owner.ToString(); + return m_HGService.MoveFolder(uri, folder, sessionID); + } + } + + public bool PurgeFolder(InventoryFolderBase folder) + { + if (folder == null) + return false; + + if (IsLocalGridUser(folder.Owner)) + return m_GridService.PurgeFolder(folder); + else + { + UUID sessionID = GetSessionID(folder.Owner); + string uri = "http://" + GetUserInventoryURI(folder.Owner) + "/" + folder.Owner.ToString(); + return m_HGService.PurgeFolder(uri, folder, sessionID); + } + } + + public bool AddItem(InventoryItemBase item) + { + if (item == null) + return false; + + if (IsLocalGridUser(item.Owner)) + return m_GridService.AddItem(item); + else + { + UUID sessionID = GetSessionID(item.Owner); + string uri = "http://" + GetUserInventoryURI(item.Owner) + "/" + item.Owner.ToString(); + return m_HGService.AddItem(uri, item, sessionID); + } + } + + public bool UpdateItem(InventoryItemBase item) + { + if (item == null) + return false; + + if (IsLocalGridUser(item.Owner)) + return m_GridService.UpdateItem(item); + else + { + UUID sessionID = GetSessionID(item.Owner); + string uri = "http://" + GetUserInventoryURI(item.Owner) + "/" + item.Owner.ToString(); + return m_HGService.UpdateItem(uri, item, sessionID); + } + } + + public bool DeleteItem(InventoryItemBase item) + { + if (item == null) + return false; + + if (IsLocalGridUser(item.Owner)) + return m_GridService.DeleteItem(item); + else + { + UUID sessionID = GetSessionID(item.Owner); + string uri = "http://" + GetUserInventoryURI(item.Owner) + "/" + item.Owner.ToString(); + return m_HGService.DeleteItem(uri, item, sessionID); + } + } + + public InventoryItemBase QueryItem(InventoryItemBase item) + { + if (item == null) + return null; + + if (IsLocalGridUser(item.Owner)) + return m_GridService.QueryItem(item); + else + { + UUID sessionID = GetSessionID(item.Owner); + string uri = "http://" + GetUserInventoryURI(item.Owner) + "/" + item.Owner.ToString(); + return m_HGService.QueryItem(uri, item, sessionID); + } + } + + public InventoryFolderBase QueryFolder(InventoryFolderBase folder) + { + if (folder == null) + return null; + + if (IsLocalGridUser(folder.Owner)) + return m_GridService.QueryFolder(folder); + else + { + UUID sessionID = GetSessionID(folder.Owner); + string uri = "http://" + GetUserInventoryURI(folder.Owner) + "/" + folder.Owner.ToString(); + return m_HGService.QueryFolder(uri, folder, sessionID); + } + } + + public bool HasInventoryForUser(UUID userID) + { + return false; + } + + public InventoryFolderBase RequestRootFolder(UUID userID) + { + return null; + } + + #endregion + + private UUID GetSessionID(UUID userID) + { + ScenePresence sp = m_Scene.GetScenePresence(userID); + if (sp != null) + return sp.ControllingClient.SessionId; + + return UUID.Zero; + } + + private bool IsLocalGridUser(UUID userID) + { + if (m_UserProfileService == null) + return false; + + CachedUserInfo uinfo = m_UserProfileService.GetUserDetails(userID); + if (uinfo == null) + return true; + + string userInventoryServerURI = HGNetworkServersInfo.ServerURI(uinfo.UserProfile.UserInventoryURI); + + if ((userInventoryServerURI == m_LocalGridInventoryURI) || (userInventoryServerURI == "")) + { + return true; + } + return false; + } + + private string GetUserInventoryURI(UUID userID) + { + string invURI = m_LocalGridInventoryURI; + + CachedUserInfo uinfo = m_UserProfileService.GetUserDetails(userID); + if ((uinfo == null) || (uinfo.UserProfile == null)) + return invURI; + + string userInventoryServerURI = HGNetworkServersInfo.ServerURI(uinfo.UserProfile.UserInventoryURI); + + if ((userInventoryServerURI != null) && + (userInventoryServerURI != "")) + invURI = userInventoryServerURI; + return invURI; + } + + + } +} diff --git a/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/LocalInventoryServiceConnector.cs new file mode 100644 index 0000000000..3db08ebd51 --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/LocalInventoryServiceConnector.cs @@ -0,0 +1,246 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using log4net; +using Nini.Config; +using System; +using System.Collections.Generic; +using System.Reflection; +using OpenSim.Framework; +using OpenSim.Data; +using OpenSim.Server.Base; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenMetaverse; + +namespace OpenSim.Region.CoreModules.ServiceConnectors.Inventory +{ + public class LocalInventoryServicesConnector : + ISharedRegionModule, IInventoryService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private IInventoryService m_InventoryService; + + private bool m_Enabled = false; + + public string Name + { + get { return "LocalInventoryServicesConnector"; } + } + + public void Initialise(IConfigSource source) + { + IConfig moduleConfig = source.Configs["Modules"]; + if (moduleConfig != null) + { + string name = moduleConfig.GetString("InventoryServices", ""); + if (name == Name) + { + IConfig assetConfig = source.Configs["InventoryService"]; + if (assetConfig == null) + { + m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini"); + return; + } + + string serviceDll = assetConfig.GetString("LocalServiceModule", + String.Empty); + + if (serviceDll == String.Empty) + { + m_log.Error("[INVENTORY CONNECTOR]: No LocalServiceModule named in section InventoryService"); + return; + } + + Object[] args = new Object[] { source }; + m_InventoryService = + ServerUtils.LoadPlugin(serviceDll, + args); + + if (m_InventoryService == null) + { + m_log.Error("[INVENTORY CONNECTOR]: Can't load asset service"); + return; + } + + //List plugins + // = DataPluginFactory.LoadDataPlugins( + // configSettings.StandaloneInventoryPlugin, + // configSettings.StandaloneInventorySource); + + //foreach (IInventoryDataPlugin plugin in plugins) + //{ + // // Using the OSP wrapper plugin for database plugins should be made configurable at some point + // m_InventoryService.AddPlugin(new OspInventoryWrapperPlugin(plugin, this)); + //} + + m_Enabled = true; + m_log.Info("[INVENTORY CONNECTOR]: Local asset connector enabled"); + } + } + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + public void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + + scene.RegisterModuleInterface(this); + } + + public void RemoveRegion(Scene scene) + { + } + + public void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + + m_log.InfoFormat("[INVENTORY CONNECTOR]: Enabled local assets for region {0}", scene.RegionInfo.RegionName); + + } + + public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) + { + m_InventoryService.GetUserInventory(userID, callback); + } + + /// + /// Add a new folder to the user's inventory + /// + /// + /// true if the folder was successfully added + public bool AddFolder(InventoryFolderBase folder) + { + return m_InventoryService.AddFolder(folder); + } + + /// + /// Update a folder in the user's inventory + /// + /// + /// true if the folder was successfully updated + public bool UpdateFolder(InventoryFolderBase folder) + { + return m_InventoryService.UpdateFolder(folder); + } + + /// + /// Move an inventory folder to a new location + /// + /// A folder containing the details of the new location + /// true if the folder was successfully moved + public bool MoveFolder(InventoryFolderBase folder) + { + return m_InventoryService.MoveFolder(folder); + } + + /// + /// Purge an inventory folder of all its items and subfolders. + /// + /// + /// true if the folder was successfully purged + public bool PurgeFolder(InventoryFolderBase folder) + { + return m_InventoryService.PurgeFolder(folder); + } + + /// + /// Add a new item to the user's inventory + /// + /// + /// true if the item was successfully added + public bool AddItem(InventoryItemBase item) + { + return m_InventoryService.AddItem(item); + } + + /// + /// Update an item in the user's inventory + /// + /// + /// true if the item was successfully updated + public bool UpdateItem(InventoryItemBase item) + { + return m_InventoryService.UpdateItem(item); + } + + /// + /// Delete an item from the user's inventory + /// + /// + /// true if the item was successfully deleted + public bool DeleteItem(InventoryItemBase item) + { + return m_InventoryService.DeleteItem(item); + } + + public InventoryItemBase QueryItem(InventoryItemBase item) + { + return m_InventoryService.QueryItem(item); + } + + public InventoryFolderBase QueryFolder(InventoryFolderBase folder) + { + return m_InventoryService.QueryFolder(folder); + } + + /// + /// Does the given user have an inventory structure? + /// + /// + /// + public bool HasInventoryForUser(UUID userID) + { + return m_InventoryService.HasInventoryForUser(userID); + } + + /// + /// Retrieve the root inventory folder for the given user. + /// + /// + /// null if no root folder was found + public InventoryFolderBase RequestRootFolder(UUID userID) + { + return m_InventoryService.RequestRootFolder(userID); + } + + } +} diff --git a/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/RemoteInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/RemoteInventoryServiceConnector.cs new file mode 100644 index 0000000000..ddb6cffe30 --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/RemoteInventoryServiceConnector.cs @@ -0,0 +1,246 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using log4net; +using System; +using System.Collections.Generic; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Statistics; +using OpenSim.Services.Connectors; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenMetaverse; + +namespace OpenSim.Region.CoreModules.ServiceConnectors.Inventory +{ + public class RemoteInventoryServicesConnector : + ISharedRegionModule, IInventoryService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private bool m_Enabled = false; + private bool m_Initialized = false; + private Scene m_Scene; + private InventoryServicesConnector m_RemoteConnector; + + public string Name + { + get { return "RemoteInventoryServicesConnector"; } + } + + public RemoteInventoryServicesConnector(IConfigSource source) + { + Init(source); + } + + private void Init(IConfigSource source) + { + m_RemoteConnector = new InventoryServicesConnector(source); + } + + + #region ISharedRegionModule + + public void Initialise(IConfigSource source) + { + IConfig moduleConfig = source.Configs["Modules"]; + if (moduleConfig != null) + { + string name = moduleConfig.GetString("InventoryServices", ""); + if (name == Name) + { + Init(source); + m_Enabled = true; + + m_log.Info("[INVENTORY CONNECTOR]: Remote inventory enabled"); + } + } + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + public void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + + if (!m_Initialized) + m_Scene = scene; + + scene.RegisterModuleInterface(this); + } + + public void RemoveRegion(Scene scene) + { + } + + public void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + + m_log.InfoFormat("[INVENTORY CONNECTOR]: Enabled remote inventory for region {0}", scene.RegionInfo.RegionName); + + } + + #endregion ISharedRegionModule + + #region IInventoryService + + public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) + { + UUID sessionID = GetSessionID(userID); + try + { + m_RemoteConnector.GetUserInventory(userID.ToString(), sessionID, callback); + } + catch (Exception e) + { + if (StatsManager.SimExtraStats != null) + StatsManager.SimExtraStats.AddInventoryServiceRetrievalFailure(); + + m_log.ErrorFormat("[INVENTORY CONNECTOR]: Request inventory operation failed, {0} {1}", + e.Source, e.Message); + } + + } + + public bool AddFolder(InventoryFolderBase folder) + { + if (folder == null) + return false; + + UUID sessionID = GetSessionID(folder.Owner); + return m_RemoteConnector.AddFolder(folder.Owner.ToString(), folder, sessionID); + } + + public bool UpdateFolder(InventoryFolderBase folder) + { + if (folder == null) + return false; + + UUID sessionID = GetSessionID(folder.Owner); + return m_RemoteConnector.UpdateFolder(folder.Owner.ToString(), folder, sessionID); + } + + public bool MoveFolder(InventoryFolderBase folder) + { + if (folder == null) + return false; + + UUID sessionID = GetSessionID(folder.Owner); + return m_RemoteConnector.MoveFolder(folder.Owner.ToString(), folder, sessionID); + } + + public bool PurgeFolder(InventoryFolderBase folder) + { + if (folder == null) + return false; + + UUID sessionID = GetSessionID(folder.Owner); + return m_RemoteConnector.PurgeFolder(folder.Owner.ToString(), folder, sessionID); + } + + public bool AddItem(InventoryItemBase item) + { + if (item == null) + return false; + + UUID sessionID = GetSessionID(item.Owner); + return m_RemoteConnector.AddItem(item.Owner.ToString(), item, sessionID); + } + + public bool UpdateItem(InventoryItemBase item) + { + if (item == null) + return false; + + UUID sessionID = GetSessionID(item.Owner); + return m_RemoteConnector.UpdateItem(item.Owner.ToString(), item, sessionID); + } + + public bool DeleteItem(InventoryItemBase item) + { + if (item == null) + return false; + + UUID sessionID = GetSessionID(item.Owner); + return m_RemoteConnector.DeleteItem(item.Owner.ToString(), item, sessionID); + } + + public InventoryItemBase QueryItem(InventoryItemBase item) + { + if (item == null) + return null; + + UUID sessionID = GetSessionID(item.Owner); + return m_RemoteConnector.QueryItem(item.Owner.ToString(), item, sessionID); + } + + public InventoryFolderBase QueryFolder(InventoryFolderBase folder) + { + if (folder == null) + return null; + + UUID sessionID = GetSessionID(folder.Owner); + return m_RemoteConnector.QueryFolder(folder.Owner.ToString(), folder, sessionID); + } + + public bool HasInventoryForUser(UUID userID) + { + return false; + } + + public InventoryFolderBase RequestRootFolder(UUID userID) + { + return null; + } + + #endregion + + private UUID GetSessionID(UUID userID) + { + ScenePresence sp = m_Scene.GetScenePresence(userID); + if (sp != null) + return sp.ControllingClient.SessionId; + + return UUID.Zero; + } + + } +} diff --git a/OpenSim/Services/Connectors/Inventory/ISessionAuthInventoryService.cs b/OpenSim/Services/Connectors/Inventory/ISessionAuthInventoryService.cs new file mode 100644 index 0000000000..4fc436327c --- /dev/null +++ b/OpenSim/Services/Connectors/Inventory/ISessionAuthInventoryService.cs @@ -0,0 +1,107 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenSim.Framework; +using OpenSim.Services.Interfaces; +using OpenMetaverse; + +namespace OpenSim.Services.Connectors +{ + /// + /// Defines all operations to access a remote inventory service + /// using session authentication as a form of security. + /// + public interface ISessionAuthInventoryService + { + string Host + { + get; + } + + /// + /// Request the inventory for a user. This is an asynchronous operation that will call the callback when the + /// inventory has been received + /// + /// + /// + void GetUserInventory(string userID, UUID session_id, InventoryReceiptCallback callback); + + /// + /// Add a new folder to the user's inventory + /// + /// + /// true if the folder was successfully added + bool AddFolder(string userID, InventoryFolderBase folder, UUID session_id); + + /// + /// Update a folder in the user's inventory + /// + /// + /// true if the folder was successfully updated + bool UpdateFolder(string userID, InventoryFolderBase folder, UUID session_id); + + /// + /// Move an inventory folder to a new location + /// + /// A folder containing the details of the new location + /// true if the folder was successfully moved + bool MoveFolder(string userID, InventoryFolderBase folder, UUID session_id); + + /// + /// Purge an inventory folder of all its items and subfolders. + /// + /// + /// true if the folder was successfully purged + bool PurgeFolder(string userID, InventoryFolderBase folder, UUID session_id); + + /// + /// Add a new item to the user's inventory + /// + /// + /// true if the item was successfully added + bool AddItem(string userID, InventoryItemBase item, UUID session_id); + + /// + /// Update an item in the user's inventory + /// + /// + /// true if the item was successfully updated + bool UpdateItem(string userID, InventoryItemBase item, UUID session_id); + + /// + /// Delete an item from the user's inventory + /// + /// + /// true if the item was successfully deleted + bool DeleteItem(string userID, InventoryItemBase item, UUID session_id); + + InventoryItemBase QueryItem(string userID, InventoryItemBase item, UUID session_id); + + InventoryFolderBase QueryFolder(string userID, InventoryFolderBase item, UUID session_id); + + } +} diff --git a/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs b/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs new file mode 100644 index 0000000000..34478aeb17 --- /dev/null +++ b/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs @@ -0,0 +1,343 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Services.Interfaces; +using OpenMetaverse; + +namespace OpenSim.Services.Connectors +{ + public class InventoryServicesConnector : ISessionAuthInventoryService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + + private Dictionary m_RequestingInventory = new Dictionary(); + + public InventoryServicesConnector() + { + } + + public InventoryServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/'); + } + + public InventoryServicesConnector(IConfigSource source) + { + Initialise(source); + } + + public virtual void Initialise(IConfigSource source) + { + IConfig inventoryConfig = source.Configs["InventoryService"]; + if (inventoryConfig == null) + { + m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpanSim.ini"); + throw new Exception("Inventory connector init error"); + } + + string serviceURI = inventoryConfig.GetString("InventoryServerURI", + String.Empty); + + if (serviceURI == String.Empty) + { + m_log.Error("[INVENTORY CONNECTOR]: No Server URI named in section InventoryService"); + throw new Exception("Inventory connector init error"); + } + m_ServerURI = serviceURI.TrimEnd('/'); + } + + #region ISessionAuthInventoryService + + public string Host + { + get { return m_ServerURI; } + } + + /// + /// Caller must catch eventual Exceptions. + /// + /// + /// + /// + public void GetUserInventory(string userIDStr, UUID sessionID, InventoryReceiptCallback callback) + { + UUID userID = UUID.Zero; + if (UUID.TryParse(userIDStr, out userID)) + { + lock (m_RequestingInventory) + { + if (!m_RequestingInventory.ContainsKey(userID)) + m_RequestingInventory.Add(userID, callback); + else + { + m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetUserInventory - ignoring repeated request for user {0}", userID); + return; + } + } + + m_log.InfoFormat( + "[INVENTORY CONNECTOR]: Requesting inventory from {0}/GetInventory/ for user {1}", + m_ServerURI, userID); + + RestSessionObjectPosterResponse requester + = new RestSessionObjectPosterResponse(); + requester.ResponseCallback = InventoryResponse; + + requester.BeginPostObject(m_ServerURI + "/GetInventory/", userID.Guid, sessionID.ToString(), userID.ToString()); + } + } + + public bool AddFolder(string userID, InventoryFolderBase folder, UUID sessionID) + { + try + { + return SynchronousRestSessionObjectPoster.BeginPostObject( + "POST", m_ServerURI + "/NewFolder/", folder, sessionID.ToString(), folder.Owner.ToString()); + } + catch (Exception e) + { + m_log.ErrorFormat("[INVENTORY CONNECTOR]: Add new inventory folder operation failed, {0} {1}", + e.Source, e.Message); + } + + return false; + } + + public bool UpdateFolder(string userID, InventoryFolderBase folder, UUID sessionID) + { + try + { + return SynchronousRestSessionObjectPoster.BeginPostObject( + "POST", m_ServerURI + "/UpdateFolder/", folder, sessionID.ToString(), folder.Owner.ToString()); + } + catch (Exception e) + { + m_log.ErrorFormat("[INVENTORY CONNECTOR]: Update inventory folder operation failed, {0} {1}", + e.Source, e.Message); + } + + return false; + } + + public bool MoveFolder(string userID, InventoryFolderBase folder, UUID sessionID) + { + try + { + return SynchronousRestSessionObjectPoster.BeginPostObject( + "POST", m_ServerURI + "/MoveFolder/", folder, sessionID.ToString(), folder.Owner.ToString()); + } + catch (Exception e) + { + m_log.ErrorFormat("[INVENTORY CONNECTOR]: Move inventory folder operation failed, {0} {1}", + e.Source, e.Message); + } + + return false; + } + + public bool PurgeFolder(string userID, InventoryFolderBase folder, UUID sessionID) + { + try + { + return SynchronousRestSessionObjectPoster.BeginPostObject( + "POST", m_ServerURI + "/PurgeFolder/", folder, sessionID.ToString(), folder.Owner.ToString()); + } + catch (Exception e) + { + m_log.ErrorFormat("[INVENTORY CONNECTOR]: Move inventory folder operation failed, {0} {1}", + e.Source, e.Message); + } + + return false; + } + + public bool AddItem(string userID, InventoryItemBase item, UUID sessionID) + { + try + { + return SynchronousRestSessionObjectPoster.BeginPostObject( + "POST", m_ServerURI + "/NewItem/", item, sessionID.ToString(), item.Owner.ToString()); + } + catch (Exception e) + { + m_log.ErrorFormat("[INVENTORY CONNECTOR]: Add new inventory item operation failed, {0} {1}", + e.Source, e.Message); + } + + return false; + } + + public bool UpdateItem(string userID, InventoryItemBase item, UUID sessionID) + { + try + { + return SynchronousRestSessionObjectPoster.BeginPostObject( + "POST", m_ServerURI + "/NewItem/", item, sessionID.ToString(), item.Owner.ToString()); + } + catch (Exception e) + { + m_log.ErrorFormat("[INVENTORY CONNECTOR]: Update new inventory item operation failed, {0} {1}", + e.Source, e.Message); + } + + return false; + } + + public bool DeleteItem(string userID, InventoryItemBase item, UUID sessionID) + { + try + { + return SynchronousRestSessionObjectPoster.BeginPostObject( + "POST", m_ServerURI + "/DeleteItem/", item, sessionID.ToString(), item.Owner.ToString()); + } + catch (Exception e) + { + m_log.ErrorFormat("[INVENTORY CONNECTOR]: Delete inventory item operation failed, {0} {1}", + e.Source, e.Message); + } + + return false; + } + + public InventoryItemBase QueryItem(string userID, InventoryItemBase item, UUID sessionID) + { + try + { + return SynchronousRestSessionObjectPoster.BeginPostObject( + "POST", m_ServerURI + "/QueryItem/", item, sessionID.ToString(), item.Owner.ToString()); + } + catch (Exception e) + { + m_log.ErrorFormat("[INVENTORY CONNECTOR]: Query inventory item operation failed, {0} {1}", + e.Source, e.Message); + } + + return null; + } + + public InventoryFolderBase QueryFolder(string userID, InventoryFolderBase item, UUID sessionID) + { + try + { + return SynchronousRestSessionObjectPoster.BeginPostObject( + "POST", m_ServerURI + "/QueryFolder/", item, sessionID.ToString(), item.Owner.ToString()); + } + catch (Exception e) + { + m_log.ErrorFormat("[INVENTORY CONNECTOR]: Query inventory item operation failed, {0} {1}", + e.Source, e.Message); + } + + return null; + } + + #endregion + + /// + /// Callback used by the inventory server GetInventory request + /// + /// + private void InventoryResponse(InventoryCollection response) + { + UUID userID = response.UserID; + InventoryReceiptCallback callback = null; + lock (m_RequestingInventory) + { + if (m_RequestingInventory.ContainsKey(userID)) + { + callback = m_RequestingInventory[userID]; + m_RequestingInventory.Remove(userID); + } + else + { + m_log.WarnFormat( + "[INVENTORY CONNECTOR]: " + + "Received inventory response for {0} for which we do not have a record of requesting!", + userID); + return; + } + } + + m_log.InfoFormat("[INVENTORY CONNECTOR]: " + + "Received inventory response for user {0} containing {1} folders and {2} items", + userID, response.Folders.Count, response.Items.Count); + + InventoryFolderImpl rootFolder = null; + + ICollection folders = new List(); + ICollection items = new List(); + + foreach (InventoryFolderBase folder in response.Folders) + { + if (folder.ParentID == UUID.Zero) + { + rootFolder = new InventoryFolderImpl(folder); + folders.Add(rootFolder); + + break; + } + } + + if (rootFolder != null) + { + foreach (InventoryFolderBase folder in response.Folders) + { + if (folder.ID != rootFolder.ID) + { + folders.Add(new InventoryFolderImpl(folder)); + } + } + + foreach (InventoryItemBase item in response.Items) + { + items.Add(item); + } + } + else + { + m_log.ErrorFormat("[INVENTORY CONNECTOR]: Did not get back an inventory containing a root folder for user {0}", userID); + } + + callback(folders, items); + + } + + + } +} diff --git a/OpenSim/Services/Interfaces/IInventoryService.cs b/OpenSim/Services/Interfaces/IInventoryService.cs new file mode 100644 index 0000000000..9fe419fce4 --- /dev/null +++ b/OpenSim/Services/Interfaces/IInventoryService.cs @@ -0,0 +1,118 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenSim.Framework; +using OpenMetaverse; + +namespace OpenSim.Services.Interfaces +{ + /// + /// Callback used when a user's inventory is received from the inventory service + /// + public delegate void InventoryReceiptCallback( + ICollection folders, ICollection items); + + public interface IInventoryService + { + /// + /// Request the inventory for a user. This is an asynchronous operation that will call the callback when the + /// inventory has been received + /// + /// + /// + void GetUserInventory(UUID userID, InventoryReceiptCallback callback); + + /// + /// Add a new folder to the user's inventory + /// + /// + /// true if the folder was successfully added + bool AddFolder(InventoryFolderBase folder); + + /// + /// Update a folder in the user's inventory + /// + /// + /// true if the folder was successfully updated + bool UpdateFolder(InventoryFolderBase folder); + + /// + /// Move an inventory folder to a new location + /// + /// A folder containing the details of the new location + /// true if the folder was successfully moved + bool MoveFolder(InventoryFolderBase folder); + + /// + /// Purge an inventory folder of all its items and subfolders. + /// + /// + /// true if the folder was successfully purged + bool PurgeFolder(InventoryFolderBase folder); + + /// + /// Add a new item to the user's inventory + /// + /// + /// true if the item was successfully added + bool AddItem(InventoryItemBase item); + + /// + /// Update an item in the user's inventory + /// + /// + /// true if the item was successfully updated + bool UpdateItem(InventoryItemBase item); + + /// + /// Delete an item from the user's inventory + /// + /// + /// true if the item was successfully deleted + bool DeleteItem(InventoryItemBase item); + + InventoryItemBase QueryItem(InventoryItemBase item); + + InventoryFolderBase QueryFolder(InventoryFolderBase folder); + + /// + /// Does the given user have an inventory structure? + /// + /// + /// + bool HasInventoryForUser(UUID userID); + + /// + /// Retrieve the root inventory folder for the given user. + /// + /// + /// null if no root folder was found + InventoryFolderBase RequestRootFolder(UUID userID); + } +} diff --git a/OpenSim/Services/InventoryService/HGInventoryService.cs b/OpenSim/Services/InventoryService/HGInventoryService.cs new file mode 100644 index 0000000000..e5e40c63ef --- /dev/null +++ b/OpenSim/Services/InventoryService/HGInventoryService.cs @@ -0,0 +1,178 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using log4net; +using Nini.Config; +using System; +using System.Collections.Generic; +using System.Reflection; +using OpenSim.Framework; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Connectors; +using OpenMetaverse; + +namespace OpenSim.Services.InventoryService +{ + public class HGInventoryService : ISessionAuthInventoryService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private Dictionary m_connectors = new Dictionary(); + + public HGInventoryService(IConfigSource source) + { + IConfig moduleConfig = source.Configs["Modules"]; + if (moduleConfig != null) + { + + IConfig assetConfig = source.Configs["InventoryService"]; + if (assetConfig == null) + { + m_log.Error("[HG INVENTORY SERVICE]: InventoryService missing from OpenSim.ini"); + return; + } + + m_log.Info("[HG INVENTORY SERVICE]: HG inventory service enabled"); + } + } + + private bool StringToUrlAndUserID(string id, out string url, out string userID) + { + url = String.Empty; + userID = String.Empty; + + Uri assetUri; + + if (Uri.TryCreate(id, UriKind.Absolute, out assetUri) && + assetUri.Scheme == Uri.UriSchemeHttp) + { + url = "http://" + assetUri.Authority; + userID = assetUri.LocalPath.Trim(new char[] { '/' }); + return true; + } + + return false; + } + private ISessionAuthInventoryService GetConnector(string url) + { + InventoryServicesConnector connector = null; + lock (m_connectors) + { + if (m_connectors.ContainsKey(url)) + { + connector = m_connectors[url]; + } + else + { + // We're instantiating this class explicitly, but this won't + // work in general, because the remote grid may be running + // an inventory server that has a different protocol. + // Eventually we will want a piece of protocol asking + // the remote server about its kind. Definitely cool thing to do! + connector = new InventoryServicesConnector(url); + m_connectors.Add(url, connector); + } + } + return connector; + } + + public string Host + { + get { return string.Empty; } + } + + public void GetUserInventory(string id, UUID sessionID, InventoryReceiptCallback callback) + { + string url = string.Empty; + string userID = string.Empty; + + if (StringToUrlAndUserID(id, out url, out userID)) + { + ISessionAuthInventoryService connector = GetConnector(url); + connector.GetUserInventory(userID, sessionID, callback); + } + + } + + public bool AddFolder(string userID, InventoryFolderBase folder, UUID sessionID) + { + // TODO + return false; + } + + public bool UpdateFolder(string userID, InventoryFolderBase folder, UUID sessionID) + { + // TODO + return false; + } + + public bool MoveFolder(string userID, InventoryFolderBase folder, UUID sessionID) + { + // TODO + return false; + } + + public bool PurgeFolder(string userID, InventoryFolderBase folder, UUID sessionID) + { + // TODO + return false; + } + + public bool AddItem(string userID, InventoryItemBase item, UUID sessionID) + { + // TODO + return false; + } + + public bool UpdateItem(string userID, InventoryItemBase item, UUID sessionID) + { + // TODO + return false; + } + + public bool DeleteItem(string userID, InventoryItemBase item, UUID sessionID) + { + // TODO + return false; + } + + public InventoryItemBase QueryItem(string userID, InventoryItemBase item, UUID sessionID) + { + // TODO + return null; + } + + public InventoryFolderBase QueryFolder(string userID, InventoryFolderBase folder, UUID sessionID) + { + // TODO + return null; + } + + } +} diff --git a/OpenSim/Services/InventoryService/InventoryService.cs b/OpenSim/Services/InventoryService/InventoryService.cs new file mode 100644 index 0000000000..b4e2549153 --- /dev/null +++ b/OpenSim/Services/InventoryService/InventoryService.cs @@ -0,0 +1,544 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System.Collections.Generic; +using System.Reflection; +using log4net; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Data; +using OpenSim.Framework; +using OpenSim.Services.Interfaces; + +namespace OpenSim.Services.InventoryService +{ + /// + /// The Inventory service reference implementation + /// + public class InventoryService : InventoryServiceBase, IInventoryService + { + private static readonly ILog m_log + = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public InventoryService(IConfigSource config) : base(config) + { + } + + #region IInventoryServices methods + + public string Host + { + get { return "default"; } + } + + public List GetInventorySkeleton(UUID userId) + { +// m_log.DebugFormat("[AGENT INVENTORY]: Getting inventory skeleton for {0}", userId); + + InventoryFolderBase rootFolder = RequestRootFolder(userId); + + // Agent has no inventory structure yet. + if (null == rootFolder) + { + return null; + } + + List userFolders = new List(); + + userFolders.Add(rootFolder); + + foreach (IInventoryDataPlugin plugin in m_plugins) + { + IList folders = plugin.getFolderHierarchy(rootFolder.ID); + userFolders.AddRange(folders); + } + +// foreach (InventoryFolderBase folder in userFolders) +// { +// m_log.DebugFormat("[AGENT INVENTORY]: Got folder {0} {1}", folder.name, folder.folderID); +// } + + return userFolders; + } + + // See IInventoryServices + public virtual bool HasInventoryForUser(UUID userID) + { + return false; + } + + // See IInventoryServices + public virtual InventoryFolderBase RequestRootFolder(UUID userID) + { + // Retrieve the first root folder we get from the list of plugins. + foreach (IInventoryDataPlugin plugin in m_plugins) + { + InventoryFolderBase rootFolder = plugin.getUserRootFolder(userID); + if (rootFolder != null) + return rootFolder; + } + + // Return nothing if no plugin was able to supply a root folder + return null; + } + + // See IInventoryServices + public bool CreateNewUserInventory(UUID user) + { + InventoryFolderBase existingRootFolder = RequestRootFolder(user); + + if (null != existingRootFolder) + { + m_log.WarnFormat( + "[AGENT INVENTORY]: Did not create a new inventory for user {0} since they already have " + + "a root inventory folder with id {1}", + user, existingRootFolder.ID); + } + else + { + UsersInventory inven = new UsersInventory(); + inven.CreateNewInventorySet(user); + AddNewInventorySet(inven); + + return true; + } + + return false; + } + + // See IInventoryServices + public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) + { + m_log.InfoFormat("[LOCAL INVENTORY SERVICE]: Requesting inventory for user {0}", userID); + + List folders = new List(); + List items = new List(); + + List skeletonFolders = GetInventorySkeleton(userID); + + if (skeletonFolders != null) + { + + InventoryFolderImpl rootFolder = null; + + // Need to retrieve the root folder on the first pass + foreach (InventoryFolderBase folder in skeletonFolders) + { + if (folder.ParentID == UUID.Zero) + { + rootFolder = new InventoryFolderImpl(folder); + folders.Add(rootFolder); + items.AddRange(RequestFolderItems(rootFolder.ID)); + break; // Only 1 root folder per user + } + } + + if (rootFolder != null) + { + foreach (InventoryFolderBase folder in skeletonFolders) + { + if (folder.ID != rootFolder.ID) + { + folders.Add(new InventoryFolderImpl(folder)); + items.AddRange(RequestFolderItems(folder.ID)); + } + } + } + + m_log.InfoFormat( + "[LOCAL INVENTORY SERVICE]: Received inventory response for user {0} containing {1} folders and {2} items", + userID, folders.Count, items.Count); + } + else + { + m_log.WarnFormat("[LOCAL INVENTORY SERVICE]: User {0} inventory not available", userID); + } + + callback(folders, items); + } + + public List GetActiveGestures(UUID userId) + { + List activeGestures = new List(); + foreach (IInventoryDataPlugin plugin in m_plugins) + { + activeGestures.AddRange(plugin.fetchActiveGestures(userId)); + } + + return activeGestures; + } + + #endregion + + #region Methods used by GridInventoryService + + public List RequestSubFolders(UUID parentFolderID) + { + List inventoryList = new List(); + + foreach (IInventoryDataPlugin plugin in m_plugins) + { + inventoryList.AddRange(plugin.getInventoryFolders(parentFolderID)); + } + + return inventoryList; + } + + public List RequestFolderItems(UUID folderID) + { + List itemsList = new List(); + + foreach (IInventoryDataPlugin plugin in m_plugins) + { + itemsList.AddRange(plugin.getInventoryInFolder(folderID)); + } + + return itemsList; + } + + #endregion + + // See IInventoryServices + public virtual bool AddFolder(InventoryFolderBase folder) + { + m_log.DebugFormat( + "[AGENT INVENTORY]: Adding folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID); + + foreach (IInventoryDataPlugin plugin in m_plugins) + { + plugin.addInventoryFolder(folder); + } + + // FIXME: Should return false on failure + return true; + } + + // See IInventoryServices + public virtual bool UpdateFolder(InventoryFolderBase folder) + { + m_log.DebugFormat( + "[AGENT INVENTORY]: Updating folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID); + + foreach (IInventoryDataPlugin plugin in m_plugins) + { + plugin.updateInventoryFolder(folder); + } + + // FIXME: Should return false on failure + return true; + } + + // See IInventoryServices + public virtual bool MoveFolder(InventoryFolderBase folder) + { + m_log.DebugFormat( + "[AGENT INVENTORY]: Moving folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID); + + foreach (IInventoryDataPlugin plugin in m_plugins) + { + plugin.moveInventoryFolder(folder); + } + + // FIXME: Should return false on failure + return true; + } + + // See IInventoryServices + public virtual bool AddItem(InventoryItemBase item) + { + m_log.DebugFormat( + "[AGENT INVENTORY]: Adding item {0} {1} to folder {2}", item.Name, item.ID, item.Folder); + + foreach (IInventoryDataPlugin plugin in m_plugins) + { + plugin.addInventoryItem(item); + } + + // FIXME: Should return false on failure + return true; + } + + // See IInventoryServices + public virtual bool UpdateItem(InventoryItemBase item) + { + m_log.InfoFormat( + "[AGENT INVENTORY]: Updating item {0} {1} in folder {2}", item.Name, item.ID, item.Folder); + + foreach (IInventoryDataPlugin plugin in m_plugins) + { + plugin.updateInventoryItem(item); + } + + // FIXME: Should return false on failure + return true; + } + + // See IInventoryServices + public virtual bool DeleteItem(InventoryItemBase item) + { + m_log.InfoFormat( + "[AGENT INVENTORY]: Deleting item {0} {1} from folder {2}", item.Name, item.ID, item.Folder); + + foreach (IInventoryDataPlugin plugin in m_plugins) + { + plugin.deleteInventoryItem(item.ID); + } + + // FIXME: Should return false on failure + return true; + } + + public virtual InventoryItemBase QueryItem(InventoryItemBase item) + { + foreach (IInventoryDataPlugin plugin in m_plugins) + { + InventoryItemBase result = plugin.queryInventoryItem(item.ID); + if (result != null) + return result; + } + + return null; + } + + public virtual InventoryFolderBase QueryFolder(InventoryFolderBase item) + { + foreach (IInventoryDataPlugin plugin in m_plugins) + { + InventoryFolderBase result = plugin.queryInventoryFolder(item.ID); + if (result != null) + return result; + } + + return null; + } + + /// + /// Purge a folder of all items items and subfolders. + /// + /// FIXME: Really nasty in a sense, because we have to query the database to get information we may + /// already know... Needs heavy refactoring. + /// + /// + public virtual bool PurgeFolder(InventoryFolderBase folder) + { + m_log.DebugFormat( + "[AGENT INVENTORY]: Purging folder {0} {1} of its contents", folder.Name, folder.ID); + + List subFolders = RequestSubFolders(folder.ID); + + foreach (InventoryFolderBase subFolder in subFolders) + { +// m_log.DebugFormat("[AGENT INVENTORY]: Deleting folder {0} {1}", subFolder.Name, subFolder.ID); + + foreach (IInventoryDataPlugin plugin in m_plugins) + { + plugin.deleteInventoryFolder(subFolder.ID); + } + } + + List items = RequestFolderItems(folder.ID); + + foreach (InventoryItemBase item in items) + { + DeleteItem(item); + } + + // FIXME: Should return false on failure + return true; + } + + private void AddNewInventorySet(UsersInventory inventory) + { + foreach (InventoryFolderBase folder in inventory.Folders.Values) + { + AddFolder(folder); + } + } + + public InventoryItemBase GetInventoryItem(UUID itemID) + { + foreach (IInventoryDataPlugin plugin in m_plugins) + { + InventoryItemBase item = plugin.getInventoryItem(itemID); + if (item != null) + return item; + } + + return null; + } + + /// + /// Used to create a new user inventory. + /// + private class UsersInventory + { + public Dictionary Folders = new Dictionary(); + public Dictionary Items = new Dictionary(); + + public virtual void CreateNewInventorySet(UUID user) + { + InventoryFolderBase folder = new InventoryFolderBase(); + + folder.ParentID = UUID.Zero; + folder.Owner = user; + folder.ID = UUID.Random(); + folder.Name = "My Inventory"; + folder.Type = (short)AssetType.Folder; + folder.Version = 1; + Folders.Add(folder.ID, folder); + + UUID rootFolder = folder.ID; + + folder = new InventoryFolderBase(); + folder.ParentID = rootFolder; + folder.Owner = user; + folder.ID = UUID.Random(); + folder.Name = "Animations"; + folder.Type = (short)AssetType.Animation; + folder.Version = 1; + Folders.Add(folder.ID, folder); + + folder = new InventoryFolderBase(); + folder.ParentID = rootFolder; + folder.Owner = user; + folder.ID = UUID.Random(); + folder.Name = "Body Parts"; + folder.Type = (short)AssetType.Bodypart; + folder.Version = 1; + Folders.Add(folder.ID, folder); + + folder = new InventoryFolderBase(); + folder.ParentID = rootFolder; + folder.Owner = user; + folder.ID = UUID.Random(); + folder.Name = "Calling Cards"; + folder.Type = (short)AssetType.CallingCard; + folder.Version = 1; + Folders.Add(folder.ID, folder); + + folder = new InventoryFolderBase(); + folder.ParentID = rootFolder; + folder.Owner = user; + folder.ID = UUID.Random(); + folder.Name = "Clothing"; + folder.Type = (short)AssetType.Clothing; + folder.Version = 1; + Folders.Add(folder.ID, folder); + + folder = new InventoryFolderBase(); + folder.ParentID = rootFolder; + folder.Owner = user; + folder.ID = UUID.Random(); + folder.Name = "Gestures"; + folder.Type = (short)AssetType.Gesture; + folder.Version = 1; + Folders.Add(folder.ID, folder); + + folder = new InventoryFolderBase(); + folder.ParentID = rootFolder; + folder.Owner = user; + folder.ID = UUID.Random(); + folder.Name = "Landmarks"; + folder.Type = (short)AssetType.Landmark; + folder.Version = 1; + Folders.Add(folder.ID, folder); + + folder = new InventoryFolderBase(); + folder.ParentID = rootFolder; + folder.Owner = user; + folder.ID = UUID.Random(); + folder.Name = "Lost And Found"; + folder.Type = (short)AssetType.LostAndFoundFolder; + folder.Version = 1; + Folders.Add(folder.ID, folder); + + folder = new InventoryFolderBase(); + folder.ParentID = rootFolder; + folder.Owner = user; + folder.ID = UUID.Random(); + folder.Name = "Notecards"; + folder.Type = (short)AssetType.Notecard; + folder.Version = 1; + Folders.Add(folder.ID, folder); + + folder = new InventoryFolderBase(); + folder.ParentID = rootFolder; + folder.Owner = user; + folder.ID = UUID.Random(); + folder.Name = "Objects"; + folder.Type = (short)AssetType.Object; + folder.Version = 1; + Folders.Add(folder.ID, folder); + + folder = new InventoryFolderBase(); + folder.ParentID = rootFolder; + folder.Owner = user; + folder.ID = UUID.Random(); + folder.Name = "Photo Album"; + folder.Type = (short)AssetType.SnapshotFolder; + folder.Version = 1; + Folders.Add(folder.ID, folder); + + folder = new InventoryFolderBase(); + folder.ParentID = rootFolder; + folder.Owner = user; + folder.ID = UUID.Random(); + folder.Name = "Scripts"; + folder.Type = (short)AssetType.LSLText; + folder.Version = 1; + Folders.Add(folder.ID, folder); + + folder = new InventoryFolderBase(); + folder.ParentID = rootFolder; + folder.Owner = user; + folder.ID = UUID.Random(); + folder.Name = "Sounds"; + folder.Type = (short)AssetType.Sound; + folder.Version = 1; + Folders.Add(folder.ID, folder); + + folder = new InventoryFolderBase(); + folder.ParentID = rootFolder; + folder.Owner = user; + folder.ID = UUID.Random(); + folder.Name = "Textures"; + folder.Type = (short)AssetType.Texture; + folder.Version = 1; + Folders.Add(folder.ID, folder); + + folder = new InventoryFolderBase(); + folder.ParentID = rootFolder; + folder.Owner = user; + folder.ID = UUID.Random(); + folder.Name = "Trash"; + folder.Type = (short)AssetType.TrashFolder; + folder.Version = 1; + Folders.Add(folder.ID, folder); + } + } + } +} diff --git a/OpenSim/Services/InventoryService/InventoryServiceBase.cs b/OpenSim/Services/InventoryService/InventoryServiceBase.cs new file mode 100644 index 0000000000..a10e94f45f --- /dev/null +++ b/OpenSim/Services/InventoryService/InventoryServiceBase.cs @@ -0,0 +1,98 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Data; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Base; + +namespace OpenSim.Services.InventoryService +{ + public class InventoryServiceBase : ServiceBase + { + protected IInventoryDataPlugin m_Database = null; + + protected List m_plugins = new List(); + + public InventoryServiceBase(IConfigSource config) : base(config) + { + IConfig assetConfig = config.Configs["InventoryService"]; + if (assetConfig == null) + throw new Exception("No InventoryService configuration"); + + string dllName = assetConfig.GetString("StorageProvider", + String.Empty); + + if (dllName == String.Empty) + throw new Exception("No StorageProvider configured"); + + string connString = assetConfig.GetString("ConnectionString", + String.Empty); + + m_Database = LoadPlugin(dllName); + if (m_Database == null) + throw new Exception("Could not find a storage interface in the given module"); + + m_Database.Initialise(connString); + + } + + #region Plugin methods + + /// + /// Add a new inventory data plugin - plugins will be requested in the order they were added. + /// + /// The plugin that will provide data + public void AddPlugin(IInventoryDataPlugin plugin) + { + m_plugins.Add(plugin); + } + + /// + /// Adds a list of inventory data plugins, as described by `provider' + /// and `connect', to `m_plugins'. + /// + /// + /// The filename of the inventory server plugin DLL. + /// + /// + /// The connection string for the storage backend. + /// + public void AddPlugin(string provider, string connect) + { + m_plugins.AddRange(DataPluginFactory.LoadDataPlugins(provider, connect)); + } + + #endregion + + + } +} diff --git a/prebuild.xml b/prebuild.xml index 94d5cdcb13..9e6b68667b 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1392,6 +1392,37 @@ + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + + + +