From af0febf6a72434d5fd68b7acc6ed6ff01544a012 Mon Sep 17 00:00:00 2001
From: UbitUmarov
Date: Fri, 11 Sep 2015 19:55:38 +0100
Subject: inventory mess
---
OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 44 ++--
.../Inventory/XInventoryServicesConnector.cs | 285 ++++++++++++++++-----
2 files changed, 241 insertions(+), 88 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 2f37483..edb881f 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -898,33 +898,33 @@ namespace OpenSim.Region.Framework.Scenes
}
- if (remoteClient.AgentId == oldAgentID
- || (LibraryService != null
- && LibraryService.LibraryRootFolder != null
- && oldAgentID == LibraryService.LibraryRootFolder.Owner))
+ if (remoteClient.AgentId == oldAgentID
+ || (LibraryService != null
+ && LibraryService.LibraryRootFolder != null
+ && oldAgentID == LibraryService.LibraryRootFolder.Owner))
+ {
+ CreateNewInventoryItem(
+ remoteClient, item.CreatorId, item.CreatorData, newFolderID,
+ newName, item.Description, item.Flags, callbackID, item.AssetID, (sbyte)item.AssetType, (sbyte)item.InvType,
+ item.BasePermissions, item.CurrentPermissions, item.EveryOnePermissions,
+ item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch(), false);
+ }
+ else
+ {
+ // If item is transfer or permissions are off or calling agent is allowed to copy item owner's inventory item.
+ if (((item.CurrentPermissions & (uint)PermissionMask.Transfer) != 0)
+ && (m_permissions.BypassPermissions()
+ || m_permissions.CanCopyUserInventory(remoteClient.AgentId, oldItemID)))
{
CreateNewInventoryItem(
- remoteClient, item.CreatorId, item.CreatorData, newFolderID,
- newName, item.Description, item.Flags, callbackID, item.AssetID, (sbyte)item.AssetType, (sbyte)item.InvType,
- item.BasePermissions, item.CurrentPermissions, item.EveryOnePermissions,
+ remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Description, item.Flags, callbackID,
+ item.AssetID, (sbyte)item.AssetType, (sbyte) item.InvType,
+ item.NextPermissions, item.NextPermissions, item.EveryOnePermissions & item.NextPermissions,
item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch(), false);
}
- else
- {
- // If item is transfer or permissions are off or calling agent is allowed to copy item owner's inventory item.
- if (((item.CurrentPermissions & (uint)PermissionMask.Transfer) != 0)
- && (m_permissions.BypassPermissions()
- || m_permissions.CanCopyUserInventory(remoteClient.AgentId, oldItemID)))
- {
- CreateNewInventoryItem(
- remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Description, item.Flags, callbackID,
- item.AssetID, (sbyte)item.AssetType, (sbyte)item.InvType,
- item.NextPermissions, item.NextPermissions, item.EveryOnePermissions & item.NextPermissions,
- item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch(), false);
- }
- }
}
- else
+ }
+ else
{
m_log.ErrorFormat(
"[AGENT INVENTORY]: Could not copy item {0} since asset {1} could not be found",
diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs
index 36d4ae2..f235446 100644
--- a/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs
@@ -33,22 +33,37 @@ using System.Reflection;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.Console;
-using OpenSim.Framework.Communications;
+
+using OpenSim.Framework.Monitoring;
using OpenSim.Services.Interfaces;
using OpenSim.Server.Base;
using OpenMetaverse;
namespace OpenSim.Services.Connectors
{
- public class XInventoryServicesConnector : IInventoryService
+ public class XInventoryServicesConnector : BaseServiceConnector, IInventoryService
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
+ ///
+ /// Number of requests made to the remote inventory service.
+ ///
+ public int RequestsMade { get; private set; }
+
private string m_ServerURI = String.Empty;
- private object m_Lock = new object();
+ ///
+ /// Timeout for remote requests.
+ ///
+ ///
+ /// In this case, -1 is default timeout (100 seconds), not infinite.
+ ///
+ private int m_requestTimeoutSecs = -1;
+
+ private const double CACHE_EXPIRATION_SECONDS = 20.0;
+ private static ExpiringCache m_ItemCache = new ExpiringCache();
public XInventoryServicesConnector()
{
@@ -60,20 +75,21 @@ namespace OpenSim.Services.Connectors
}
public XInventoryServicesConnector(IConfigSource source)
+ : base(source, "InventoryService")
{
Initialise(source);
}
public virtual void Initialise(IConfigSource source)
{
- IConfig assetConfig = source.Configs["InventoryService"];
- if (assetConfig == null)
+ IConfig config = source.Configs["InventoryService"];
+ if (config == null)
{
m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini");
throw new Exception("Inventory connector init error");
}
- string serviceURI = assetConfig.GetString("InventoryServerURI",
+ string serviceURI = config.GetString("InventoryServerURI",
String.Empty);
if (serviceURI == String.Empty)
@@ -82,6 +98,21 @@ namespace OpenSim.Services.Connectors
throw new Exception("Inventory connector init error");
}
m_ServerURI = serviceURI;
+
+ m_requestTimeoutSecs = config.GetInt("RemoteRequestTimeout", m_requestTimeoutSecs);
+
+ StatsManager.RegisterStat(
+ new Stat(
+ "RequestsMade",
+ "Requests made",
+ "Number of requests made to the remove inventory service",
+ "requests",
+ "inventory",
+ serviceURI,
+ StatType.Pull,
+ MeasuresOfInterest.AverageChangeOverTime,
+ s => s.Value = RequestsMade,
+ StatVerbosity.Debug));
}
private bool CheckReturn(Dictionary ret)
@@ -158,7 +189,7 @@ namespace OpenSim.Services.Connectors
return BuildFolder((Dictionary)ret["folder"]);
}
- public InventoryFolderBase GetFolderForType(UUID principalID, AssetType type)
+ public InventoryFolderBase GetFolderForType(UUID principalID, FolderType type)
{
Dictionary ret = MakeRequest("GETFOLDERFORTYPE",
new Dictionary {
@@ -177,7 +208,7 @@ namespace OpenSim.Services.Connectors
InventoryCollection inventory = new InventoryCollection();
inventory.Folders = new List();
inventory.Items = new List();
- inventory.UserID = principalID;
+ inventory.OwnerID = principalID;
try
{
@@ -190,15 +221,17 @@ namespace OpenSim.Services.Connectors
if (!CheckReturn(ret))
return null;
- Dictionary folders =
- (Dictionary)ret["FOLDERS"];
- Dictionary items =
- (Dictionary)ret["ITEMS"];
-
- foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i
- inventory.Folders.Add(BuildFolder((Dictionary)o));
- foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i
- inventory.Items.Add(BuildItem((Dictionary)o));
+ Dictionary folders = ret.ContainsKey("FOLDERS") ?
+ (Dictionary)ret["FOLDERS"] : null;
+ Dictionary items = ret.ContainsKey("ITEMS") ?
+ (Dictionary)ret["ITEMS"] : null;
+
+ if (folders != null)
+ foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i
+ inventory.Folders.Add(BuildFolder((Dictionary)o));
+ if (items != null)
+ foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i
+ inventory.Items.Add(BuildItem((Dictionary)o));
}
catch (Exception e)
{
@@ -207,6 +240,87 @@ namespace OpenSim.Services.Connectors
return inventory;
}
+
+ public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs)
+ {
+ InventoryCollection[] inventoryArr = new InventoryCollection[folderIDs.Length];
+ // m_log.DebugFormat("[XXX]: In GetMultipleFoldersContent {0}", String.Join(",", folderIDs));
+ try
+ {
+ Dictionary resultSet = MakeRequest("GETMULTIPLEFOLDERSCONTENT",
+ new Dictionary {
+ { "PRINCIPAL", principalID.ToString() },
+ { "FOLDERS", String.Join(",", folderIDs) },
+ { "COUNT", folderIDs.Length.ToString() }
+ });
+
+ if (!CheckReturn(resultSet))
+ return null;
+
+ int i = 0;
+ foreach (KeyValuePair kvp in resultSet)
+ {
+ InventoryCollection inventory = new InventoryCollection();
+ if (kvp.Key.StartsWith("F_"))
+ {
+ UUID fid = UUID.Zero;
+ if (UUID.TryParse(kvp.Key.Substring(2), out fid) && fid == folderIDs[i])
+ {
+ inventory.Folders = new List();
+ inventory.Items = new List();
+
+ Dictionary ret = (Dictionary)kvp.Value;
+
+ if (ret.ContainsKey("FID"))
+ {
+ if (!UUID.TryParse(ret["FID"].ToString(), out inventory.FolderID))
+ m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: Could not parse folder id {0}", ret["FID"].ToString());
+ }
+ else
+ m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: FID key not present in response");
+
+ inventory.Version = -1;
+ if (ret.ContainsKey("VERSION"))
+ Int32.TryParse(ret["VERSION"].ToString(), out inventory.Version);
+ if (ret.ContainsKey("OWNER"))
+ UUID.TryParse(ret["OWNER"].ToString(), out inventory.OwnerID);
+
+ //m_log.DebugFormat("[XXX]: Received {0} ({1}) {2} {3}", inventory.FolderID, fid, inventory.Version, inventory.OwnerID);
+
+ Dictionary folders =
+ (Dictionary)ret["FOLDERS"];
+ Dictionary items =
+ (Dictionary)ret["ITEMS"];
+
+ foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i
+ {
+ inventory.Folders.Add(BuildFolder((Dictionary)o));
+ }
+ foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i
+ {
+ inventory.Items.Add(BuildItem((Dictionary)o));
+ }
+
+ inventoryArr[i] = inventory;
+ }
+ else
+ {
+ m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: Folder id does not match. Expected {0} got {1}",
+ folderIDs[i], fid);
+ m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: {0} {1}", String.Join(",", folderIDs), String.Join(",", resultSet.Keys));
+ }
+
+ i += 1;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: Exception in GetMultipleFoldersContent: {0}", e.Message);
+ }
+
+ return inventoryArr;
+ }
public List GetFolderItems(UUID principalID, UUID folderID)
{
@@ -297,9 +411,13 @@ namespace OpenSim.Services.Connectors
public bool AddItem(InventoryItemBase item)
{
+ if (item.Description == null)
+ item.Description = String.Empty;
if (item.CreatorData == null)
item.CreatorData = String.Empty;
- Dictionary ret = MakeRequest("ADDITEM",
+ if (item.CreatorId == null)
+ item.CreatorId = String.Empty;
+ Dictionary ret = MakeRequest("ADDITEM",
new Dictionary {
{ "AssetID", item.AssetID.ToString() },
{ "AssetType", item.AssetType.ToString() },
@@ -398,6 +516,10 @@ namespace OpenSim.Services.Connectors
public InventoryItemBase GetItem(InventoryItemBase item)
{
+ InventoryItemBase retrieved = null;
+ if (m_ItemCache.TryGetValue(item.ID, out retrieved))
+ return retrieved;
+
try
{
Dictionary ret = MakeRequest("GETITEM",
@@ -408,14 +530,78 @@ namespace OpenSim.Services.Connectors
if (!CheckReturn(ret))
return null;
- return BuildItem((Dictionary)ret["item"]);
+ retrieved = BuildItem((Dictionary)ret["item"]);
}
catch (Exception e)
{
m_log.Error("[XINVENTORY SERVICES CONNECTOR]: Exception in GetItem: ", e);
}
- return null;
+ m_ItemCache.AddOrUpdate(item.ID, retrieved, CACHE_EXPIRATION_SECONDS);
+
+ return retrieved;
+ }
+
+ public virtual InventoryItemBase[] GetMultipleItems(UUID principalID, UUID[] itemIDs)
+ {
+ //m_log.DebugFormat("[XXX]: In GetMultipleItems {0}", String.Join(",", itemIDs));
+
+ InventoryItemBase[] itemArr = new InventoryItemBase[itemIDs.Length];
+ // Try to get them from the cache
+ List pending = new List();
+ InventoryItemBase item = null;
+ int i = 0;
+ foreach (UUID id in itemIDs)
+ {
+ if (m_ItemCache.TryGetValue(id, out item))
+ itemArr[i++] = item;
+ else
+ pending.Add(id);
+ }
+
+ if (pending.Count == 0) // we're done, everything was in the cache
+ return itemArr;
+
+ try
+ {
+ Dictionary resultSet = MakeRequest("GETMULTIPLEITEMS",
+ new Dictionary {
+ { "PRINCIPAL", principalID.ToString() },
+ { "ITEMS", String.Join(",", pending.ToArray()) },
+ { "COUNT", pending.Count.ToString() }
+ });
+
+ if (!CheckReturn(resultSet))
+ {
+ if (i == 0)
+ return null;
+ else
+ return itemArr;
+ }
+
+ // carry over index i where we left above
+ foreach (KeyValuePair kvp in resultSet)
+ {
+ InventoryCollection inventory = new InventoryCollection();
+ if (kvp.Key.StartsWith("item_"))
+ {
+ if (kvp.Value is Dictionary)
+ {
+ item = BuildItem((Dictionary)kvp.Value);
+ m_ItemCache.AddOrUpdate(item.ID, item, CACHE_EXPIRATION_SECONDS);
+ itemArr[i++] = item;
+ }
+ else
+ itemArr[i++] = null;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: Exception in GetMultipleItems: {0}", e.Message);
+ }
+
+ return itemArr;
}
public InventoryFolderBase GetFolder(InventoryFolderBase folder)
@@ -484,45 +670,6 @@ namespace OpenSim.Services.Connectors
return 0;
}
- public InventoryCollection GetUserInventory(UUID principalID)
- {
- InventoryCollection inventory = new InventoryCollection();
- inventory.Folders = new List();
- inventory.Items = new List();
- inventory.UserID = principalID;
-
- try
- {
- Dictionary ret = MakeRequest("GETUSERINVENTORY",
- new Dictionary {
- { "PRINCIPAL", principalID.ToString() }
- });
-
- if (!CheckReturn(ret))
- return null;
-
- Dictionary folders =
- (Dictionary)ret["FOLDERS"];
- Dictionary items =
- (Dictionary)ret["ITEMS"];
-
- foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i
- inventory.Folders.Add(BuildFolder((Dictionary)o));
- foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i
- inventory.Items.Add(BuildItem((Dictionary)o));
- }
- catch (Exception e)
- {
- m_log.Error("[XINVENTORY SERVICES CONNECTOR]: Exception in GetUserInventory: ", e);
- }
-
- return inventory;
- }
-
- public void GetUserInventory(UUID principalID, InventoryReceiptCallback callback)
- {
- }
-
public bool HasInventoryForUser(UUID principalID)
{
return false;
@@ -533,13 +680,19 @@ namespace OpenSim.Services.Connectors
private Dictionary MakeRequest(string method,
Dictionary sendData)
{
- sendData["METHOD"] = method;
+ // Add "METHOD" as the first key in the dictionary. This ensures that it will be
+ // visible even when using partial logging ("debug http all 5").
+ Dictionary temp = sendData;
+ sendData = new Dictionary{ { "METHOD", method } };
+ foreach (KeyValuePair kvp in temp)
+ sendData.Add(kvp.Key, kvp.Value);
+
+ RequestsMade++;
- string reply = string.Empty;
- lock (m_Lock)
- reply = SynchronousRestFormsRequester.MakeRequest("POST",
- m_ServerURI + "/xinventory",
- ServerUtils.BuildQueryString(sendData));
+ string reply
+ = SynchronousRestFormsRequester.MakeRequest(
+ "POST", m_ServerURI + "/xinventory",
+ ServerUtils.BuildQueryString(sendData), m_requestTimeoutSecs, m_Auth);
Dictionary replyData = ServerUtils.ParseXmlResponse(
reply);
@@ -607,4 +760,4 @@ namespace OpenSim.Services.Connectors
return item;
}
}
-}
\ No newline at end of file
+}
--
cgit v1.1