HGInventoryService.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSim Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using System.Net;
  30. using System.Reflection;
  31. using OpenMetaverse;
  32. using log4net;
  33. using OpenSim.Framework;
  34. using OpenSim.Framework.Communications;
  35. using OpenSim.Framework.Communications.Cache;
  36. using OpenSim.Framework.Servers;
  37. using OpenSim.Framework.Statistics;
  38. using OpenSim.Region.Communications.Local;
  39. namespace OpenSim.Region.Communications.Hypergrid
  40. {
  41. public class HGInventoryService : LocalInventoryService, ISecureInventoryService
  42. {
  43. private static readonly ILog m_log
  44. = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  45. private string _inventoryServerUrl;
  46. //private Uri m_Uri;
  47. private UserProfileCacheService m_userProfileCache;
  48. private bool m_gridmode = false;
  49. private Dictionary<UUID, InventoryReceiptCallback> m_RequestingInventory
  50. = new Dictionary<UUID, InventoryReceiptCallback>();
  51. public UserProfileCacheService UserProfileCache
  52. {
  53. set { m_userProfileCache = value; }
  54. }
  55. public HGInventoryService(string inventoryServerUrl, UserProfileCacheService userProfileCacheService, bool gridmode)
  56. {
  57. _inventoryServerUrl = HGNetworkServersInfo.ServerURI(inventoryServerUrl);
  58. //m_Uri = new Uri(_inventoryServerUrl);
  59. m_userProfileCache = userProfileCacheService;
  60. m_gridmode = gridmode;
  61. }
  62. #region ISecureInventoryService Members
  63. public void RequestInventoryForUser(UUID userID, UUID session_id, InventoryReceiptCallback callback)
  64. {
  65. if (IsLocalStandaloneUser(userID))
  66. {
  67. base.RequestInventoryForUser(userID, callback);
  68. return;
  69. }
  70. // grid/hypergrid mode
  71. if (!m_RequestingInventory.ContainsKey(userID))
  72. {
  73. m_RequestingInventory.Add(userID, callback);
  74. try
  75. {
  76. string invServer = GetUserInventoryURI(userID);
  77. m_log.InfoFormat(
  78. "[HGrid INVENTORY SERVICE]: Requesting inventory from {0}/GetInventory/ for user {1} ({2})",
  79. /*_inventoryServerUrl*/ invServer, userID, userID.Guid);
  80. RestSessionObjectPosterResponse<Guid, InventoryCollection> requester
  81. = new RestSessionObjectPosterResponse<Guid, InventoryCollection>();
  82. requester.ResponseCallback = InventoryResponse;
  83. requester.BeginPostObject(invServer + "/GetInventory/", userID.Guid, session_id.ToString(), userID.ToString());
  84. //Test(userID.Guid);
  85. //RestObjectPosterResponse<InventoryCollection> requester
  86. // = new RestObjectPosterResponse<InventoryCollection>();
  87. //requester.ResponseCallback = InventoryResponse;
  88. //requester.BeginPostObject<Guid>(/*_inventoryServerUrl*/ invServer + "/GetInventory/", userID.Guid);
  89. //RestClient cli = new RestClient(invServer + "/GetInventory/" + userID.Guid);
  90. //Stream reply = cli.Request();
  91. }
  92. catch (WebException e)
  93. {
  94. if (StatsManager.SimExtraStats != null)
  95. StatsManager.SimExtraStats.AddInventoryServiceRetrievalFailure();
  96. m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Request inventory operation failed, {0} {1}",
  97. e.Source, e.Message);
  98. }
  99. }
  100. else
  101. {
  102. m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: RequestInventoryForUser() - could not find user profile for {0}", userID);
  103. }
  104. }
  105. /// <summary>
  106. /// Add a new folder to the user's inventory
  107. /// </summary>
  108. /// <param name="folder"></param>
  109. /// <returns>true if the folder was successfully added</returns>
  110. public bool AddFolder(InventoryFolderBase folder, UUID session_id)
  111. {
  112. if (IsLocalStandaloneUser(folder.Owner))
  113. {
  114. return base.AddFolder(folder);
  115. }
  116. try
  117. {
  118. string invServ = GetUserInventoryURI(folder.Owner);
  119. return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
  120. "POST", invServ + "/NewFolder/", folder, session_id.ToString(), folder.Owner.ToString());
  121. }
  122. catch (WebException e)
  123. {
  124. m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Add new inventory folder operation failed, {0} {1}",
  125. e.Source, e.Message);
  126. }
  127. return false;
  128. }
  129. /// <summary>
  130. /// Update a folder in the user's inventory
  131. /// </summary>
  132. /// <param name="folder"></param>
  133. /// <returns>true if the folder was successfully updated</returns>
  134. public bool UpdateFolder(InventoryFolderBase folder, UUID session_id)
  135. {
  136. if (IsLocalStandaloneUser(folder.Owner))
  137. {
  138. return base.UpdateFolder(folder);
  139. }
  140. try
  141. {
  142. string invServ = GetUserInventoryURI(folder.Owner);
  143. return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
  144. "POST", invServ + "/UpdateFolder/", folder, session_id.ToString(), folder.Owner.ToString());
  145. }
  146. catch (WebException e)
  147. {
  148. m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Update inventory folder operation failed, {0} {1}",
  149. e.Source, e.Message);
  150. }
  151. return false;
  152. }
  153. /// <summary>
  154. /// Move an inventory folder to a new location
  155. /// </summary>
  156. /// <param name="folder">A folder containing the details of the new location</param>
  157. /// <returns>true if the folder was successfully moved</returns>
  158. public bool MoveFolder(InventoryFolderBase folder, UUID session_id)
  159. {
  160. if (IsLocalStandaloneUser(folder.Owner))
  161. {
  162. return base.MoveFolder(folder);
  163. }
  164. try
  165. {
  166. string invServ = GetUserInventoryURI(folder.Owner);
  167. return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
  168. "POST", invServ + "/MoveFolder/", folder, session_id.ToString(), folder.Owner.ToString());
  169. }
  170. catch (WebException e)
  171. {
  172. m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Move inventory folder operation failed, {0} {1}",
  173. e.Source, e.Message);
  174. }
  175. return false;
  176. }
  177. /// <summary>
  178. /// Purge an inventory folder of all its items and subfolders.
  179. /// </summary>
  180. /// <param name="folder"></param>
  181. /// <returns>true if the folder was successfully purged</returns>
  182. public bool PurgeFolder(InventoryFolderBase folder, UUID session_id)
  183. {
  184. if (IsLocalStandaloneUser(folder.Owner))
  185. {
  186. return base.PurgeFolder(folder);
  187. }
  188. try
  189. {
  190. string invServ = GetUserInventoryURI(folder.Owner);
  191. return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
  192. "POST", invServ + "/PurgeFolder/", folder, session_id.ToString(), folder.Owner.ToString());
  193. }
  194. catch (WebException e)
  195. {
  196. m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Move inventory folder operation failed, {0} {1}",
  197. e.Source, e.Message);
  198. }
  199. return false;
  200. }
  201. /// <summary>
  202. /// Add a new item to the user's inventory
  203. /// </summary>
  204. /// <param name="item"></param>
  205. /// <returns>true if the item was successfully added</returns>
  206. public bool AddItem(InventoryItemBase item, UUID session_id)
  207. {
  208. if (IsLocalStandaloneUser(item.Owner))
  209. {
  210. return base.AddItem(item);
  211. }
  212. try
  213. {
  214. string invServ = GetUserInventoryURI(item.Owner);
  215. return SynchronousRestSessionObjectPoster<InventoryItemBase, bool>.BeginPostObject(
  216. "POST", invServ + "/NewItem/", item, session_id.ToString(), item.Owner.ToString());
  217. }
  218. catch (WebException e)
  219. {
  220. m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Add new inventory item operation failed, {0} {1}",
  221. e.Source, e.Message);
  222. }
  223. return false;
  224. }
  225. /// <summary>
  226. /// Update an item in the user's inventory
  227. /// </summary>
  228. /// <param name="item"></param>
  229. /// <returns>true if the item was successfully updated</returns>
  230. public bool UpdateItem(InventoryItemBase item, UUID session_id)
  231. {
  232. if (IsLocalStandaloneUser(item.Owner))
  233. {
  234. return base.UpdateItem(item);
  235. }
  236. try
  237. {
  238. string invServ = GetUserInventoryURI(item.Owner);
  239. return SynchronousRestSessionObjectPoster<InventoryItemBase, bool>.BeginPostObject(
  240. "POST", invServ + "/NewItem/", item, session_id.ToString(), item.Owner.ToString());
  241. }
  242. catch (WebException e)
  243. {
  244. m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Update new inventory item operation failed, {0} {1}",
  245. e.Source, e.Message);
  246. }
  247. return false;
  248. }
  249. /// <summary>
  250. /// Delete an item from the user's inventory
  251. /// </summary>
  252. /// <param name="item"></param>
  253. /// <returns>true if the item was successfully deleted</returns>
  254. public bool DeleteItem(InventoryItemBase item, UUID session_id)
  255. {
  256. if (IsLocalStandaloneUser(item.Owner))
  257. {
  258. return base.DeleteItem(item);
  259. }
  260. try
  261. {
  262. string invServ = GetUserInventoryURI(item.Owner);
  263. return SynchronousRestSessionObjectPoster<InventoryItemBase, bool>.BeginPostObject(
  264. "POST", invServ + "/DeleteItem/", item, session_id.ToString(), item.Owner.ToString());
  265. }
  266. catch (WebException e)
  267. {
  268. m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Delete inventory item operation failed, {0} {1}",
  269. e.Source, e.Message);
  270. }
  271. return false;
  272. }
  273. #endregion
  274. #region Methods common to ISecureInventoryService and IInventoryService
  275. /// <summary>
  276. /// Does the given user have an inventory structure?
  277. /// </summary>
  278. /// <param name="userID"></param>
  279. /// <returns></returns>
  280. public override bool HasInventoryForUser(UUID userID)
  281. {
  282. if (IsLocalStandaloneUser(userID))
  283. {
  284. return base.HasInventoryForUser(userID);
  285. }
  286. return false;
  287. }
  288. /// <summary>
  289. /// Retrieve the root inventory folder for the given user.
  290. /// </summary>
  291. /// <param name="userID"></param>
  292. /// <returns>null if no root folder was found</returns>
  293. public override InventoryFolderBase RequestRootFolder(UUID userID)
  294. {
  295. if (IsLocalStandaloneUser(userID))
  296. {
  297. return base.RequestRootFolder(userID);
  298. }
  299. return null;
  300. }
  301. #endregion
  302. /// <summary>
  303. /// Callback used by the inventory server GetInventory request
  304. /// </summary>
  305. /// <param name="userID"></param>
  306. private void InventoryResponse(InventoryCollection response)
  307. {
  308. UUID userID = response.UserID;
  309. if (m_RequestingInventory.ContainsKey(userID))
  310. {
  311. m_log.InfoFormat("[HGrid INVENTORY SERVICE]: " +
  312. "Received inventory response for user {0} containing {1} folders and {2} items",
  313. userID, response.Folders.Count, response.Items.Count);
  314. InventoryFolderImpl rootFolder = null;
  315. InventoryReceiptCallback callback = m_RequestingInventory[userID];
  316. ICollection<InventoryFolderImpl> folders = new List<InventoryFolderImpl>();
  317. ICollection<InventoryItemBase> items = new List<InventoryItemBase>();
  318. foreach (InventoryFolderBase folder in response.Folders)
  319. {
  320. if (folder.ParentID == UUID.Zero)
  321. {
  322. rootFolder = new InventoryFolderImpl(folder);
  323. folders.Add(rootFolder);
  324. break;
  325. }
  326. }
  327. if (rootFolder != null)
  328. {
  329. foreach (InventoryFolderBase folder in response.Folders)
  330. {
  331. if (folder.ID != rootFolder.ID)
  332. {
  333. folders.Add(new InventoryFolderImpl(folder));
  334. }
  335. }
  336. foreach (InventoryItemBase item in response.Items)
  337. {
  338. items.Add(item);
  339. }
  340. }
  341. else
  342. {
  343. m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Did not get back an inventory containing a root folder for user {0}", userID);
  344. }
  345. callback(folders, items);
  346. m_RequestingInventory.Remove(userID);
  347. }
  348. else
  349. {
  350. m_log.WarnFormat(
  351. "[HGrid INVENTORY SERVICE]: " +
  352. "Received inventory response for {0} for which we do not have a record of requesting!",
  353. userID);
  354. }
  355. }
  356. private bool IsLocalStandaloneUser(UUID userID)
  357. {
  358. CachedUserInfo uinfo = m_userProfileCache.GetUserDetails(userID);
  359. if (uinfo == null)
  360. return true;
  361. string userInventoryServerURI = HGNetworkServersInfo.ServerURI(uinfo.UserProfile.UserInventoryURI);
  362. if ((!m_gridmode) && ((userInventoryServerURI == _inventoryServerUrl)) || (userInventoryServerURI == ""))
  363. {
  364. return true;
  365. }
  366. return false;
  367. }
  368. private string GetUserInventoryURI(UUID userID)
  369. {
  370. string invURI = _inventoryServerUrl;
  371. CachedUserInfo uinfo = m_userProfileCache.GetUserDetails(userID);
  372. if ((uinfo == null) || (uinfo.UserProfile == null))
  373. return invURI;
  374. string userInventoryServerURI = HGNetworkServersInfo.ServerURI(uinfo.UserProfile.UserInventoryURI);
  375. if ((userInventoryServerURI != null) &&
  376. (userInventoryServerURI != ""))
  377. invURI = userInventoryServerURI;
  378. return invURI;
  379. }
  380. }
  381. }