From e187972377c19bdd85093677c4c54034e4f9196e Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Tue, 25 Nov 2008 15:19:00 +0000 Subject: * Apply http://opensimulator.org/mantis/view.php?id=2640 * This is Diva's hypergrid patch, as perviously discussed on the opensim-dev mailing list * Applied some minor prebuild.xml jiggling to resolve a dependency issue * Thanks Diva! --- .../Communications/Hypergrid/HGInventoryService.cs | 451 +++++++++++++++++++++ 1 file changed, 451 insertions(+) create mode 100644 OpenSim/Region/Communications/Hypergrid/HGInventoryService.cs (limited to 'OpenSim/Region/Communications/Hypergrid/HGInventoryService.cs') diff --git a/OpenSim/Region/Communications/Hypergrid/HGInventoryService.cs b/OpenSim/Region/Communications/Hypergrid/HGInventoryService.cs new file mode 100644 index 0000000..9ef040b --- /dev/null +++ b/OpenSim/Region/Communications/Hypergrid/HGInventoryService.cs @@ -0,0 +1,451 @@ +/* + * 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 OpenSim 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.Net; +using System.Reflection; +using OpenMetaverse; +using log4net; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Communications.Cache; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Statistics; +using OpenSim.Region.Communications.Local; + +namespace OpenSim.Region.Communications.Hypergrid +{ + public class HGInventoryService : LocalInventoryService, ISecureInventoryService + { + private static readonly ILog m_log + = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private string _inventoryServerUrl; + private Uri m_Uri; + private UserProfileCacheService m_userProfileCache; + private bool m_gridmode = false; + + private Dictionary m_RequestingInventory + = new Dictionary(); + + public UserProfileCacheService UserProfileCache + { + set { m_userProfileCache = value; } + } + + public HGInventoryService(string inventoryServerUrl, UserProfileCacheService userProfileCacheService, bool gridmode) + { + _inventoryServerUrl = HGNetworkServersInfo.ServerURI(inventoryServerUrl); + m_Uri = new Uri(_inventoryServerUrl); + m_userProfileCache = userProfileCacheService; + m_gridmode = gridmode; + } + + #region ISecureInventoryService Members + + public void RequestInventoryForUser(UUID userID, UUID session_id, InventoryReceiptCallback callback) + { + if (IsLocalStandaloneUser(userID)) + { + base.RequestInventoryForUser(userID, callback); + return; + } + + // grid/hypergrid mode + if (!m_RequestingInventory.ContainsKey(userID)) + { + m_RequestingInventory.Add(userID, callback); + + try + { + string invServer = GetUserInventoryURI(userID); + m_log.InfoFormat( + "[HGrid INVENTORY SERVICE]: Requesting inventory from {0}/GetInventory/ for user {1} ({2})", + /*_inventoryServerUrl*/ invServer, userID, userID.Guid); + + + RestSessionObjectPosterResponse requester + = new RestSessionObjectPosterResponse(); + requester.ResponseCallback = InventoryResponse; + + requester.BeginPostObject(invServer + "/GetInventory/", userID.Guid, session_id.ToString(), userID.ToString()); + + //Test(userID.Guid); + + //RestObjectPosterResponse requester + // = new RestObjectPosterResponse(); + //requester.ResponseCallback = InventoryResponse; + + //requester.BeginPostObject(/*_inventoryServerUrl*/ invServer + "/GetInventory/", userID.Guid); + + //RestClient cli = new RestClient(invServer + "/GetInventory/" + userID.Guid); + //Stream reply = cli.Request(); + } + catch (WebException e) + { + if (StatsManager.SimExtraStats != null) + StatsManager.SimExtraStats.AddInventoryServiceRetrievalFailure(); + + m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Request inventory operation failed, {0} {1}", + e.Source, e.Message); + } + } + else + { + m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: RequestInventoryForUser() - could not find user profile for {0}", userID); + } + + } + + /// + /// Add a new folder to the user's inventory + /// + /// + /// true if the folder was successfully added + public bool AddFolder(InventoryFolderBase folder, UUID session_id) + { + if (IsLocalStandaloneUser(folder.Owner)) + { + return base.AddFolder(folder); + } + + try + { + string invServ = GetUserInventoryURI(folder.Owner); + + return SynchronousRestSessionObjectPoster.BeginPostObject( + "POST", invServ + "/NewFolder/", folder, session_id.ToString(), folder.Owner.ToString()); + } + catch (WebException e) + { + m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Add new inventory folder operation failed, {0} {1}", + e.Source, e.Message); + } + + return false; + + } + + /// + /// Update a folder in the user's inventory + /// + /// + /// true if the folder was successfully updated + public bool UpdateFolder(InventoryFolderBase folder, UUID session_id) + { + if (IsLocalStandaloneUser(folder.Owner)) + { + return base.UpdateFolder(folder); + } + try + { + string invServ = GetUserInventoryURI(folder.Owner); + + return SynchronousRestSessionObjectPoster.BeginPostObject( + "POST", invServ + "/UpdateFolder/", folder, session_id.ToString(), folder.Owner.ToString()); + } + catch (WebException e) + { + m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Update inventory folder operation failed, {0} {1}", + e.Source, e.Message); + } + + return false; + + } + + /// + /// 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, UUID session_id) + { + if (IsLocalStandaloneUser(folder.Owner)) + { + return base.MoveFolder(folder); + } + + try + { + string invServ = GetUserInventoryURI(folder.Owner); + + return SynchronousRestSessionObjectPoster.BeginPostObject( + "POST", invServ + "/MoveFolder/", folder, session_id.ToString(), folder.Owner.ToString()); + } + catch (WebException e) + { + m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Move inventory folder operation failed, {0} {1}", + e.Source, e.Message); + } + + return false; + } + + /// + /// Purge an inventory folder of all its items and subfolders. + /// + /// + /// true if the folder was successfully purged + public bool PurgeFolder(InventoryFolderBase folder, UUID session_id) + { + if (IsLocalStandaloneUser(folder.Owner)) + { + return base.PurgeFolder(folder); + } + + try + { + string invServ = GetUserInventoryURI(folder.Owner); + + return SynchronousRestSessionObjectPoster.BeginPostObject( + "POST", invServ + "/PurgeFolder/", folder, session_id.ToString(), folder.Owner.ToString()); + } + catch (WebException e) + { + m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Move inventory folder operation failed, {0} {1}", + e.Source, e.Message); + } + + return false; + } + + /// + /// Add a new item to the user's inventory + /// + /// + /// true if the item was successfully added + public bool AddItem(InventoryItemBase item, UUID session_id) + { + if (IsLocalStandaloneUser(item.Owner)) + { + return base.AddItem(item); + } + + try + { + string invServ = GetUserInventoryURI(item.Owner); + + return SynchronousRestSessionObjectPoster.BeginPostObject( + "POST", invServ + "/NewItem/", item, session_id.ToString(), item.Owner.ToString()); + } + catch (WebException e) + { + m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Add new inventory item operation failed, {0} {1}", + e.Source, e.Message); + } + + return false; + } + + /// + /// Update an item in the user's inventory + /// + /// + /// true if the item was successfully updated + public bool UpdateItem(InventoryItemBase item, UUID session_id) + { + if (IsLocalStandaloneUser(item.Owner)) + { + return base.UpdateItem(item); + } + + try + { + string invServ = GetUserInventoryURI(item.Owner); + return SynchronousRestSessionObjectPoster.BeginPostObject( + "POST", invServ + "/NewItem/", item, session_id.ToString(), item.Owner.ToString()); + } + catch (WebException e) + { + m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Update new inventory item operation failed, {0} {1}", + e.Source, e.Message); + } + + return false; + } + + /// + /// Delete an item from the user's inventory + /// + /// + /// true if the item was successfully deleted + public bool DeleteItem(InventoryItemBase item, UUID session_id) + { + if (IsLocalStandaloneUser(item.Owner)) + { + return base.DeleteItem(item); + } + + try + { + string invServ = GetUserInventoryURI(item.Owner); + + return SynchronousRestSessionObjectPoster.BeginPostObject( + "POST", invServ + "/DeleteItem/", item, session_id.ToString(), item.Owner.ToString()); + } + catch (WebException e) + { + m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Delete inventory item operation failed, {0} {1}", + e.Source, e.Message); + } + + return false; + } + #endregion + + #region Methods common to ISecureInventoryService and IInventoryService + + /// + /// Does the given user have an inventory structure? + /// + /// + /// + public override bool HasInventoryForUser(UUID userID) + { + if (IsLocalStandaloneUser(userID)) + { + return base.HasInventoryForUser(userID); + } + return false; + } + + /// + /// Retrieve the root inventory folder for the given user. + /// + /// + /// null if no root folder was found + public override InventoryFolderBase RequestRootFolder(UUID userID) + { + if (IsLocalStandaloneUser(userID)) + { + return base.RequestRootFolder(userID); + } + + return null; + } + + #endregion + + + /// + /// Callback used by the inventory server GetInventory request + /// + /// + private void InventoryResponse(InventoryCollection response) + { + UUID userID = response.UserID; + if (m_RequestingInventory.ContainsKey(userID)) + { + m_log.InfoFormat("[HGrid INVENTORY SERVICE]: " + + "Received inventory response for user {0} containing {1} folders and {2} items", + userID, response.Folders.Count, response.Items.Count); + + InventoryFolderImpl rootFolder = null; + InventoryReceiptCallback callback = m_RequestingInventory[userID]; + + 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("[HGrid INVENTORY SERVICE]: Did not get back an inventory containing a root folder for user {0}", userID); + } + + callback(folders, items); + + m_RequestingInventory.Remove(userID); + } + else + { + m_log.WarnFormat( + "[HGrid INVENTORY SERVICE]: " + + "Received inventory response for {0} for which we do not have a record of requesting!", + userID); + } + } + + + private bool IsLocalStandaloneUser(UUID userID) + { + CachedUserInfo uinfo = m_userProfileCache.GetUserDetails(userID); + if (uinfo == null) + return true; + + string userInventoryServerURI = HGNetworkServersInfo.ServerURI(uinfo.UserProfile.UserInventoryURI); + + if ((!m_gridmode) && ((userInventoryServerURI == _inventoryServerUrl)) || (userInventoryServerURI == "")) + { + return true; + } + return false; + } + + private string GetUserInventoryURI(UUID userID) + { + string invURI = _inventoryServerUrl; + CachedUserInfo uinfo = m_userProfileCache.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; + } + + } +} -- cgit v1.1