30 using System.Collections.Generic;
32 using System.Reflection;
34 using OpenSim.Framework;
35 using OpenSim.Framework.Console;
37 using OpenSim.Framework.Monitoring;
38 using OpenSim.Services.Interfaces;
39 using OpenSim.Server.Base;
42 namespace OpenSim.Services.Connectors
46 private static readonly ILog m_log =
48 MethodBase.GetCurrentMethod().DeclaringType);
53 public int RequestsMade {
get;
private set; }
55 private string m_ServerURI = String.Empty;
63 private int m_requestTimeoutSecs = -1;
65 private const double CACHE_EXPIRATION_SECONDS = 20.0;
66 private static ExpiringCache<UUID, InventoryItemBase> m_ItemCache =
new ExpiringCache<UUID,InventoryItemBase>();
74 m_ServerURI = serverURI.TrimEnd(
'/');
78 : base(source,
"InventoryService")
85 IConfig config = source.Configs[
"InventoryService"];
88 m_log.Error(
"[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini");
89 throw new Exception(
"Inventory connector init error");
92 string serviceURI = config.GetString(
"InventoryServerURI",
95 if (serviceURI == String.Empty)
97 m_log.Error(
"[INVENTORY CONNECTOR]: No Server URI named in section InventoryService");
98 throw new Exception(
"Inventory connector init error");
100 m_ServerURI = serviceURI;
102 m_requestTimeoutSecs = config.GetInt(
"RemoteRequestTimeout", m_requestTimeoutSecs);
104 StatsManager.RegisterStat(
108 "Number of requests made to the remove inventory service",
114 s => s.Value = RequestsMade,
118 private bool CheckReturn(Dictionary<string, object> ret)
126 if (ret.ContainsKey(
"RESULT"))
128 if (ret[
"RESULT"] is
string)
132 if (
bool.TryParse((
string)ret[
"RESULT"], out result))
144 Dictionary<string,object> ret = MakeRequest(
"CREATEUSERINVENTORY",
145 new Dictionary<string,object> {
146 {
"PRINCIPAL", principalID.ToString() }
149 return CheckReturn(ret);
154 Dictionary<string,object> ret = MakeRequest(
"GETINVENTORYSKELETON",
155 new Dictionary<string,object> {
156 {
"PRINCIPAL", principalID.ToString() }
159 if (!CheckReturn(ret))
162 Dictionary<string, object> folders = (Dictionary<string, object>)ret[
"FOLDERS"];
164 List<InventoryFolderBase> fldrs =
new List<InventoryFolderBase>();
168 foreach (Object o
in folders.Values)
169 fldrs.Add(BuildFolder((Dictionary<string, object>)o));
173 m_log.Error(
"[XINVENTORY SERVICES CONNECTOR]: Exception unwrapping folder list: ", e);
181 Dictionary<string,object> ret = MakeRequest(
"GETROOTFOLDER",
182 new Dictionary<string,object> {
183 {
"PRINCIPAL", principalID.ToString() }
186 if (!CheckReturn(ret))
189 return BuildFolder((Dictionary<string, object>)ret[
"folder"]);
194 Dictionary<string,object> ret = MakeRequest(
"GETFOLDERFORTYPE",
195 new Dictionary<string,object> {
196 {
"PRINCIPAL", principalID.ToString() },
197 {
"TYPE", ((int)type).ToString() }
200 if (!CheckReturn(ret))
203 return BuildFolder((Dictionary<string, object>)ret[
"folder"]);
209 inventory.Folders =
new List<InventoryFolderBase>();
210 inventory.Items =
new List<InventoryItemBase>();
211 inventory.OwnerID = principalID;
215 Dictionary<string,object> ret = MakeRequest(
"GETFOLDERCONTENT",
216 new Dictionary<string,object> {
217 {
"PRINCIPAL", principalID.ToString() },
218 {
"FOLDER", folderID.ToString() }
221 if (!CheckReturn(ret))
224 Dictionary<string,object> folders = ret.ContainsKey(
"FOLDERS") ?
225 (Dictionary<string,object>)ret[
"FOLDERS"] : null;
226 Dictionary<string,object> items = ret.ContainsKey(
"ITEMS") ?
227 (Dictionary<string, object>)ret[
"ITEMS"] : null;
230 foreach (Object o
in folders.Values)
231 inventory.Folders.Add(BuildFolder((Dictionary<string, object>)o));
233 foreach (Object o
in items.Values)
234 inventory.Items.Add(BuildItem((Dictionary<string, object>)o));
238 m_log.WarnFormat(
"[XINVENTORY SERVICES CONNECTOR]: Exception in GetFolderContent: {0}", e.Message);
250 Dictionary<string, object> resultSet = MakeRequest(
"GETMULTIPLEFOLDERSCONTENT",
251 new Dictionary<string, object> {
252 {
"PRINCIPAL", principalID.ToString() },
253 {
"FOLDERS", String.Join(
",", folderIDs) },
254 {
"COUNT", folderIDs.Length.ToString() }
257 if (!CheckReturn(resultSet))
261 foreach (KeyValuePair<string, object> kvp
in resultSet)
264 if (kvp.Key.StartsWith(
"F_"))
266 UUID fid = UUID.Zero;
267 if (UUID.TryParse(kvp.Key.Substring(2), out fid) && fid == folderIDs[i])
269 inventory.Folders =
new List<InventoryFolderBase>();
270 inventory.Items =
new List<InventoryItemBase>();
272 Dictionary<string, object> ret = (Dictionary<string, object>)kvp.Value;
274 if (ret.ContainsKey(
"FID"))
276 if (!UUID.TryParse(ret[
"FID"].ToString(), out inventory.FolderID))
277 m_log.WarnFormat(
"[XINVENTORY SERVICES CONNECTOR]: Could not parse folder id {0}", ret[
"FID"].ToString());
280 m_log.WarnFormat(
"[XINVENTORY SERVICES CONNECTOR]: FID key not present in response");
282 inventory.Version = -1;
283 if (ret.ContainsKey(
"VERSION"))
284 Int32.TryParse(ret[
"VERSION"].ToString(), out inventory.Version);
285 if (ret.ContainsKey(
"OWNER"))
286 UUID.TryParse(ret[
"OWNER"].ToString(), out inventory.OwnerID);
290 Dictionary<string, object> folders =
291 (Dictionary<string, object>)ret[
"FOLDERS"];
292 Dictionary<string, object> items =
293 (Dictionary<string, object>)ret[
"ITEMS"];
295 foreach (Object o
in folders.Values)
297 inventory.Folders.Add(BuildFolder((Dictionary<string, object>)o));
299 foreach (Object o
in items.Values)
301 inventory.Items.Add(BuildItem((Dictionary<string, object>)o));
304 inventoryArr[i] = inventory;
308 m_log.WarnFormat(
"[XINVENTORY SERVICES CONNECTOR]: Folder id does not match. Expected {0} got {1}",
310 m_log.WarnFormat(
"[XINVENTORY SERVICES CONNECTOR]: {0} {1}", String.Join(
",", folderIDs), String.Join(
",", resultSet.Keys));
319 m_log.WarnFormat(
"[XINVENTORY SERVICES CONNECTOR]: Exception in GetMultipleFoldersContent: {0}", e.Message);
327 Dictionary<string,object> ret = MakeRequest(
"GETFOLDERITEMS",
328 new Dictionary<string,object> {
329 {
"PRINCIPAL", principalID.ToString() },
330 {
"FOLDER", folderID.ToString() }
333 if (!CheckReturn(ret))
336 Dictionary<string, object> items = (Dictionary<string, object>)ret[
"ITEMS"];
337 List<InventoryItemBase> fitems =
new List<InventoryItemBase>();
338 foreach (Object o
in items.Values)
339 fitems.Add(BuildItem((Dictionary<string, object>)o));
346 Dictionary<string,object> ret = MakeRequest(
"ADDFOLDER",
347 new Dictionary<string,object> {
348 {
"ParentID", folder.ParentID.ToString() },
349 {
"Type", folder.Type.ToString() },
350 {
"Version", folder.Version.ToString() },
351 {
"Name", folder.Name.ToString() },
352 {
"Owner", folder.Owner.ToString() },
353 {
"ID", folder.ID.ToString() }
356 return CheckReturn(ret);
361 Dictionary<string,object> ret = MakeRequest(
"UPDATEFOLDER",
362 new Dictionary<string,object> {
363 {
"ParentID", folder.ParentID.ToString() },
364 {
"Type", folder.Type.ToString() },
365 {
"Version", folder.Version.ToString() },
366 {
"Name", folder.Name.ToString() },
367 {
"Owner", folder.Owner.ToString() },
368 {
"ID", folder.ID.ToString() }
371 return CheckReturn(ret);
376 Dictionary<string,object> ret = MakeRequest(
"MOVEFOLDER",
377 new Dictionary<string,object> {
378 {
"ParentID", folder.ParentID.ToString() },
379 {
"ID", folder.ID.ToString() },
380 {
"PRINCIPAL", folder.Owner.ToString() }
383 return CheckReturn(ret);
388 List<string> slist =
new List<string>();
390 foreach (UUID f
in folderIDs)
391 slist.Add(f.ToString());
393 Dictionary<string,object> ret = MakeRequest(
"DELETEFOLDERS",
394 new Dictionary<string,object> {
395 {
"PRINCIPAL", principalID.ToString() },
399 return CheckReturn(ret);
404 Dictionary<string,object> ret = MakeRequest(
"PURGEFOLDER",
405 new Dictionary<string,object> {
406 {
"ID", folder.ID.ToString() }
409 return CheckReturn(ret);
415 item.Description = String.Empty;
417 item.CreatorData = String.Empty;
419 item.CreatorId = String.Empty;
420 Dictionary<string, object> ret = MakeRequest(
"ADDITEM",
421 new Dictionary<string,object> {
422 {
"AssetID", item.AssetID.ToString() },
423 {
"AssetType", item.AssetType.ToString() },
424 {
"Name", item.Name.ToString() },
425 {
"Owner", item.Owner.ToString() },
426 {
"ID", item.ID.ToString() },
427 {
"InvType", item.InvType.ToString() },
428 {
"Folder", item.Folder.ToString() },
429 {
"CreatorId", item.CreatorId.ToString() },
430 {
"CreatorData", item.CreatorData.ToString() },
431 {
"Description", item.Description.ToString() },
432 {
"NextPermissions", item.NextPermissions.ToString() },
433 {
"CurrentPermissions", item.CurrentPermissions.ToString() },
434 {
"BasePermissions", item.BasePermissions.ToString() },
435 {
"EveryOnePermissions", item.EveryOnePermissions.ToString() },
436 {
"GroupPermissions", item.GroupPermissions.ToString() },
437 {
"GroupID", item.GroupID.ToString() },
438 {
"GroupOwned", item.GroupOwned.ToString() },
439 {
"SalePrice", item.SalePrice.ToString() },
440 {
"SaleType", item.SaleType.ToString() },
441 {
"Flags", item.Flags.ToString() },
442 {
"CreationDate", item.CreationDate.ToString() }
445 return CheckReturn(ret);
451 item.CreatorData = String.Empty;
452 Dictionary<string,object> ret = MakeRequest(
"UPDATEITEM",
453 new Dictionary<string,object> {
454 {
"AssetID", item.AssetID.ToString() },
455 {
"AssetType", item.AssetType.ToString() },
456 {
"Name", item.Name.ToString() },
457 {
"Owner", item.Owner.ToString() },
458 {
"ID", item.ID.ToString() },
459 {
"InvType", item.InvType.ToString() },
460 {
"Folder", item.Folder.ToString() },
461 {
"CreatorId", item.CreatorId.ToString() },
462 {
"CreatorData", item.CreatorData.ToString() },
463 {
"Description", item.Description.ToString() },
464 {
"NextPermissions", item.NextPermissions.ToString() },
465 {
"CurrentPermissions", item.CurrentPermissions.ToString() },
466 {
"BasePermissions", item.BasePermissions.ToString() },
467 {
"EveryOnePermissions", item.EveryOnePermissions.ToString() },
468 {
"GroupPermissions", item.GroupPermissions.ToString() },
469 {
"GroupID", item.GroupID.ToString() },
470 {
"GroupOwned", item.GroupOwned.ToString() },
471 {
"SalePrice", item.SalePrice.ToString() },
472 {
"SaleType", item.SaleType.ToString() },
473 {
"Flags", item.Flags.ToString() },
474 {
"CreationDate", item.CreationDate.ToString() }
477 bool result = CheckReturn(ret);
480 m_ItemCache.AddOrUpdate(item.ID, item, CACHE_EXPIRATION_SECONDS);
486 public bool MoveItems(UUID principalID, List<InventoryItemBase> items)
488 List<string> idlist =
new List<string>();
489 List<string> destlist =
new List<string>();
493 idlist.Add(item.ID.ToString());
494 destlist.Add(item.Folder.ToString());
497 Dictionary<string,object> ret = MakeRequest(
"MOVEITEMS",
498 new Dictionary<string,object> {
499 {
"PRINCIPAL", principalID.ToString() },
500 {
"IDLIST", idlist },
501 {
"DESTLIST", destlist }
504 return CheckReturn(ret);
509 List<string> slist =
new List<string>();
511 foreach (UUID f
in itemIDs)
512 slist.Add(f.ToString());
514 Dictionary<string,object> ret = MakeRequest(
"DELETEITEMS",
515 new Dictionary<string,object> {
516 {
"PRINCIPAL", principalID.ToString() },
520 return CheckReturn(ret);
526 if (m_ItemCache.TryGetValue(item.
ID, out retrieved))
533 Dictionary<string, object> ret = MakeRequest(
"GETITEM",
534 new Dictionary<string, object> {
535 {
"ID", item.ID.ToString() }
538 if (!CheckReturn(ret))
541 retrieved = BuildItem((Dictionary<string, object>)ret[
"item"]);
545 m_log.Error(
"[XINVENTORY SERVICES CONNECTOR]: Exception in GetItem: ", e);
548 m_ItemCache.AddOrUpdate(item.ID, retrieved, CACHE_EXPIRATION_SECONDS);
559 List<UUID> pending =
new List<UUID>();
563 foreach (UUID
id in itemIDs)
565 if (m_ItemCache.TryGetValue(
id, out item))
571 if (pending.Count == 0)
576 Dictionary<string, object> resultSet = MakeRequest(
"GETMULTIPLEITEMS",
577 new Dictionary<string, object> {
578 {
"PRINCIPAL", principalID.ToString() },
579 {
"ITEMS", String.Join(
",", pending.ToArray()) },
580 {
"COUNT", pending.Count.ToString() }
583 if (!CheckReturn(resultSet))
592 foreach (KeyValuePair<string, object> kvp
in resultSet)
595 if (kvp.Key.StartsWith(
"item_"))
597 if (kvp.Value is Dictionary<string, object>)
599 item = BuildItem((Dictionary<string, object>)kvp.Value);
600 m_ItemCache.AddOrUpdate(item.ID, item, CACHE_EXPIRATION_SECONDS);
610 m_log.WarnFormat(
"[XINVENTORY SERVICES CONNECTOR]: Exception in GetMultipleItems: {0}", e.Message);
620 Dictionary<string, object> ret = MakeRequest(
"GETFOLDER",
621 new Dictionary<string, object> {
622 {
"ID", folder.ID.ToString() }
625 if (!CheckReturn(ret))
628 return BuildFolder((Dictionary<string, object>)ret[
"folder"]);
632 m_log.Error(
"[XINVENTORY SERVICES CONNECTOR]: Exception in GetFolder: ", e);
640 Dictionary<string,object> ret = MakeRequest(
"GETACTIVEGESTURES",
641 new Dictionary<string,object> {
642 {
"PRINCIPAL", principalID.ToString() }
645 if (!CheckReturn(ret))
648 List<InventoryItemBase> items =
new List<InventoryItemBase>();
650 foreach (Object o
in ((Dictionary<string,object>)ret[
"ITEMS"]).Values)
651 items.Add(BuildItem((Dictionary<string, object>)o));
658 Dictionary<string,object> ret = MakeRequest(
"GETASSETPERMISSIONS",
659 new Dictionary<string,object> {
660 {
"PRINCIPAL", principalID.ToString() },
661 {
"ASSET", assetID.ToString() }
668 if (ret.ContainsKey(
"RESULT"))
670 if (ret[
"RESULT"] is
string)
674 if (
int.TryParse ((
string)ret[
"RESULT"], out intResult))
689 private Dictionary<string,object> MakeRequest(
string method,
690 Dictionary<string,object> sendData)
694 Dictionary<string, object> temp = sendData;
695 sendData =
new Dictionary<string,object>{ {
"METHOD", method } };
696 foreach (KeyValuePair<string, object> kvp
in temp)
697 sendData.Add(kvp.Key, kvp.Value);
702 = SynchronousRestFormsRequester.MakeRequest(
703 "POST", m_ServerURI +
"/xinventory",
704 ServerUtils.BuildQueryString(sendData), m_requestTimeoutSecs, m_Auth);
706 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
718 folder.ParentID =
new UUID(data[
"ParentID"].ToString());
719 folder.Type = short.Parse(data[
"Type"].ToString());
720 folder.Version = ushort.Parse(data[
"Version"].ToString());
721 folder.Name = data[
"Name"].ToString();
722 folder.Owner =
new UUID(data[
"Owner"].ToString());
723 folder.ID =
new UUID(data[
"ID"].ToString());
727 m_log.Error(
"[XINVENTORY SERVICES CONNECTOR]: Exception building folder: ", e);
739 item.AssetID =
new UUID(data[
"AssetID"].ToString());
740 item.AssetType = int.Parse(data[
"AssetType"].ToString());
741 item.Name = data[
"Name"].ToString();
742 item.Owner =
new UUID(data[
"Owner"].ToString());
743 item.ID =
new UUID(data[
"ID"].ToString());
744 item.InvType = int.Parse(data[
"InvType"].ToString());
745 item.Folder =
new UUID(data[
"Folder"].ToString());
746 item.CreatorId = data[
"CreatorId"].ToString();
747 if (data.ContainsKey(
"CreatorData"))
750 item.CreatorData = String.Empty;
751 item.Description = data[
"Description"].ToString();
752 item.NextPermissions = uint.Parse(data[
"NextPermissions"].ToString());
753 item.CurrentPermissions = uint.Parse(data[
"CurrentPermissions"].ToString());
754 item.BasePermissions = uint.Parse(data[
"BasePermissions"].ToString());
755 item.EveryOnePermissions = uint.Parse(data[
"EveryOnePermissions"].ToString());
756 item.GroupPermissions = uint.Parse(data[
"GroupPermissions"].ToString());
757 item.GroupID =
new UUID(data[
"GroupID"].ToString());
758 item.GroupOwned = bool.Parse(data[
"GroupOwned"].ToString());
759 item.SalePrice = int.Parse(data[
"SalePrice"].ToString());
760 item.SaleType = byte.Parse(data[
"SaleType"].ToString());
761 item.Flags = uint.Parse(data[
"Flags"].ToString());
762 item.CreationDate = int.Parse(data[
"CreationDate"].ToString());
766 m_log.Error(
"[XINVENTORY CONNECTOR]: Exception building item: ", e);
InventoryItemBase GetItem(InventoryItemBase item)
Get an item, given by its UUID
InventoryFolderBase GetRootFolder(UUID principalID)
Retrieve the root inventory folder for the given user.
bool DeleteItems(UUID principalID, List< UUID > itemIDs)
Delete an item from the user's inventory
XInventoryServicesConnector(IConfigSource source)
virtual InventoryItemBase[] GetMultipleItems(UUID principalID, UUID[] itemIDs)
Get multiple items, given by their UUIDs
Holds individual statistic details
bool UpdateFolder(InventoryFolderBase folder)
Update a folder in the user's inventory
bool AddFolder(InventoryFolderBase folder)
Add a new folder to the user's inventory
List< InventoryItemBase > GetFolderItems(UUID principalID, UUID folderID)
Gets the items inside a folder
bool MoveFolder(InventoryFolderBase folder)
Move an inventory folder to a new location
bool AddItem(InventoryItemBase item)
Add a new item to the user's inventory
virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs)
Gets everything (folders and items) inside a folder
bool CreateUserInventory(UUID principalID)
Create the entire inventory for a given user
bool PurgeFolder(InventoryFolderBase folder)
Purge an inventory folder of all its items and subfolders.
XInventoryServicesConnector(string serverURI)
bool UpdateItem(InventoryItemBase item)
Update an item in the user's inventory
Inventory Item - contains all the properties associated with an individual inventory piece...
bool DeleteFolders(UUID principalID, List< UUID > folderIDs)
Delete an item from the user's inventory
InventoryFolderBase GetFolder(InventoryFolderBase folder)
Get a folder, given by its UUID
StatVerbosity
Verbosity of stat.
bool HasInventoryForUser(UUID principalID)
Does the given user have an inventory structure?
List< InventoryItemBase > GetActiveGestures(UUID principalID)
Get the active gestures of the agent.
string CreatorData
Extended creator information of the form <profile url>="">;<name>
InventoryFolderBase GetFolderForType(UUID principalID, FolderType type)
Gets the user folder for the given folder-type
UUID ID
A UUID containing the ID for the inventory node itself
bool MoveItems(UUID principalID, List< InventoryItemBase > items)
virtual void Initialise(IConfigSource source)
MeasuresOfInterest
Measures of interest for this stat.
List< InventoryFolderBase > GetInventorySkeleton(UUID principalID)
Gets the skeleton of the inventory – folders only
int GetAssetPermissions(UUID principalID, UUID assetID)
Get the union of permissions of all inventory items that hold the given assetID.
InventoryCollection GetFolderContent(UUID principalID, UUID folderID)
Gets everything (folders and items) inside a folder
Used to serialize a whole inventory for transfer over the network.
XInventoryServicesConnector()