aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs')
-rw-r--r--OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs582
1 files changed, 0 insertions, 582 deletions
diff --git a/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs b/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs
deleted file mode 100644
index f86b453..0000000
--- a/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs
+++ /dev/null
@@ -1,582 +0,0 @@
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 OpenSimulator 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
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Servers.HttpServer;
36using OpenSim.Services.Interfaces;
37using OpenMetaverse;
38
39namespace OpenSim.Services.Connectors
40{
41 public class InventoryServicesConnector : ISessionAuthInventoryService
42 {
43 private static readonly ILog m_log =
44 LogManager.GetLogger(
45 MethodBase.GetCurrentMethod().DeclaringType);
46
47 private string m_ServerURI = String.Empty;
48
49 private Dictionary<UUID, InventoryReceiptCallback> m_RequestingInventory = new Dictionary<UUID, InventoryReceiptCallback>();
50 private Dictionary<UUID, DateTime> m_RequestTime = new Dictionary<UUID, DateTime>();
51
52 public InventoryServicesConnector()
53 {
54 }
55
56 public InventoryServicesConnector(string serverURI)
57 {
58 m_ServerURI = serverURI.TrimEnd('/');
59 }
60
61 public InventoryServicesConnector(IConfigSource source)
62 {
63 Initialise(source);
64 }
65
66 public virtual void Initialise(IConfigSource source)
67 {
68 IConfig inventoryConfig = source.Configs["InventoryService"];
69 if (inventoryConfig == null)
70 {
71 m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini");
72 throw new Exception("InventoryService missing from OpenSim.ini");
73 }
74
75 string serviceURI = inventoryConfig.GetString("InventoryServerURI",
76 String.Empty);
77
78 if (serviceURI == String.Empty)
79 {
80 m_log.Error("[INVENTORY CONNECTOR]: No Server URI named in section InventoryService");
81 throw new Exception("Unable to proceed. Please make sure your ini files in config-include are updated according to .example's");
82 }
83 m_ServerURI = serviceURI.TrimEnd('/');
84 }
85
86 #region ISessionAuthInventoryService
87
88 public string Host
89 {
90 get { return m_ServerURI; }
91 }
92
93 /// <summary>
94 /// Caller must catch eventual Exceptions.
95 /// </summary>
96 /// <param name="userID"></param>
97 /// <param name="sessionID"></param>
98 /// <param name="callback"></param>
99 public void GetUserInventory(string userIDStr, UUID sessionID, InventoryReceiptCallback callback)
100 {
101 UUID userID = UUID.Zero;
102 if (UUID.TryParse(userIDStr, out userID))
103 {
104 lock (m_RequestingInventory)
105 {
106 // *HACK ALERT*
107
108 // If an inventory request times out, it blocks any further requests from the
109 // same user, even after a relog. This is bad, and makes me sad.
110
111 // Really, we should detect a timeout and report a failure to the callback,
112 // BUT in my testing i found that it's hard to detect a timeout.. sometimes,
113 // a partial response is recieved, and sometimes a null response.
114
115 // So, for now, add a timer of ten seconds (which is the request timeout).
116
117 // This should basically have the same effect.
118
119 lock (m_RequestTime)
120 {
121 if (m_RequestTime.ContainsKey(userID))
122 {
123 TimeSpan interval = DateTime.Now - m_RequestTime[userID];
124 if (interval.TotalSeconds > 10)
125 {
126 m_RequestTime.Remove(userID);
127 if (m_RequestingInventory.ContainsKey(userID))
128 {
129 m_RequestingInventory.Remove(userID);
130 }
131 }
132 }
133 if (!m_RequestingInventory.ContainsKey(userID))
134 {
135 m_RequestTime.Add(userID, DateTime.Now);
136 m_RequestingInventory.Add(userID, callback);
137 }
138 else
139 {
140 m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetUserInventory - ignoring repeated request for user {0}", userID);
141 return;
142 }
143 }
144 }
145
146 m_log.InfoFormat(
147 "[INVENTORY CONNECTOR]: Requesting inventory from {0}/GetInventory/ for user {1}",
148 m_ServerURI, userID);
149
150 RestSessionObjectPosterResponse<Guid, InventoryCollection> requester
151 = new RestSessionObjectPosterResponse<Guid, InventoryCollection>();
152 requester.ResponseCallback = InventoryResponse;
153
154 requester.BeginPostObject(m_ServerURI + "/GetInventory/", userID.Guid, sessionID.ToString(), userID.ToString());
155 }
156 }
157
158 /// <summary>
159 /// Gets the user folder for the given folder-type
160 /// </summary>
161 /// <param name="userID"></param>
162 /// <param name="type"></param>
163 /// <returns></returns>
164 public Dictionary<AssetType, InventoryFolderBase> GetSystemFolders(string userID, UUID sessionID)
165 {
166 List<InventoryFolderBase> folders = null;
167 Dictionary<AssetType, InventoryFolderBase> dFolders = new Dictionary<AssetType, InventoryFolderBase>();
168 try
169 {
170 folders = SynchronousRestSessionObjectPoster<Guid, List<InventoryFolderBase>>.BeginPostObject(
171 "POST", m_ServerURI + "/SystemFolders/", new Guid(userID), sessionID.ToString(), userID.ToString());
172
173 foreach (InventoryFolderBase f in folders)
174 dFolders[(AssetType)f.Type] = f;
175
176 return dFolders;
177 }
178 catch (Exception e)
179 {
180 // Maybe we're talking to an old inventory server. Try this other thing.
181 m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetSystemFolders operation failed, {0} {1} (old sever?). Trying GetInventory.",
182 e.Source, e.Message);
183
184 try
185 {
186 InventoryCollection inventory = SynchronousRestSessionObjectPoster<Guid, InventoryCollection>.BeginPostObject(
187 "POST", m_ServerURI + "/GetInventory/", new Guid(userID), sessionID.ToString(), userID.ToString());
188 folders = inventory.Folders;
189 }
190 catch (Exception ex)
191 {
192 m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetInventory operation also failed, {0} {1}. Giving up.",
193 e.Source, ex.Message);
194 }
195
196 if ((folders != null) && (folders.Count > 0))
197 {
198 m_log.DebugFormat("[INVENTORY CONNECTOR]: Received entire inventory ({0} folders) for user {1}",
199 folders.Count, userID);
200 foreach (InventoryFolderBase f in folders)
201 {
202 if ((f.Type != (short)AssetType.Folder) && (f.Type != (short)AssetType.Unknown))
203 dFolders[(AssetType)f.Type] = f;
204 }
205
206 UUID rootFolderID = dFolders[AssetType.Animation].ParentID;
207 InventoryFolderBase rootFolder = new InventoryFolderBase(rootFolderID, new UUID(userID));
208 rootFolder = QueryFolder(userID, rootFolder, sessionID);
209 dFolders[AssetType.Folder] = rootFolder;
210 m_log.DebugFormat("[INVENTORY CONNECTOR]: {0} system folders for user {1}", dFolders.Count, userID);
211 return dFolders;
212 }
213 }
214
215 return new Dictionary<AssetType, InventoryFolderBase>();
216 }
217
218 /// <summary>
219 /// Gets everything (folders and items) inside a folder
220 /// </summary>
221 /// <param name="userId"></param>
222 /// <param name="folderID"></param>
223 /// <returns></returns>
224 public InventoryCollection GetFolderContent(string userID, UUID folderID, UUID sessionID)
225 {
226 try
227 {
228 // normal case
229 return SynchronousRestSessionObjectPoster<Guid, InventoryCollection>.BeginPostObject(
230 "POST", m_ServerURI + "/GetFolderContent/", folderID.Guid, sessionID.ToString(), userID.ToString());
231 }
232 catch (TimeoutException e)
233 {
234 m_log.ErrorFormat(
235 "[INVENTORY CONNECTOR]: GetFolderContent operation to {0} for {1} timed out {2} {3}.",
236 m_ServerURI, folderID, e.Source, e.Message);
237 }
238 catch (Exception e)
239 {
240 m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetFolderContent operation failed for {0}, {1} {2} (old server?).",
241 folderID, e.Source, e.Message);
242 }
243
244 InventoryCollection nullCollection = new InventoryCollection();
245 nullCollection.Folders = new List<InventoryFolderBase>();
246 nullCollection.Items = new List<InventoryItemBase>();
247 nullCollection.UserID = new UUID(userID);
248 return nullCollection;
249 }
250
251 public bool AddFolder(string userID, InventoryFolderBase folder, UUID sessionID)
252 {
253 try
254 {
255 return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
256 "POST", m_ServerURI + "/NewFolder/", folder, sessionID.ToString(), folder.Owner.ToString());
257 }
258 catch (Exception e)
259 {
260 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Add new inventory folder operation failed for {0} {1}, {2} {3}",
261 folder.Name, folder.ID, e.Source, e.Message);
262 }
263
264 return false;
265 }
266
267 public bool UpdateFolder(string userID, InventoryFolderBase folder, UUID sessionID)
268 {
269 try
270 {
271 return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
272 "POST", m_ServerURI + "/UpdateFolder/", folder, sessionID.ToString(), folder.Owner.ToString());
273 }
274 catch (Exception e)
275 {
276 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Update inventory folder operation failed for {0} {1}, {2} {3}",
277 folder.Name, folder.ID, e.Source, e.Message);
278 }
279
280 return false;
281 }
282
283 public bool DeleteFolders(string userID, List<UUID> folderIDs, UUID sessionID)
284 {
285 try
286 {
287 List<Guid> guids = new List<Guid>();
288 foreach (UUID u in folderIDs)
289 guids.Add(u.Guid);
290 return SynchronousRestSessionObjectPoster<List<Guid>, bool>.BeginPostObject(
291 "POST", m_ServerURI + "/DeleteFolders/", guids, sessionID.ToString(), userID);
292 }
293 catch (Exception e)
294 {
295 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Delete inventory folders operation failed, {0} {1}",
296 e.Source, e.Message);
297 }
298
299 return false;
300 }
301
302 public bool MoveFolder(string userID, InventoryFolderBase folder, UUID sessionID)
303 {
304 try
305 {
306 return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
307 "POST", m_ServerURI + "/MoveFolder/", folder, sessionID.ToString(), folder.Owner.ToString());
308 }
309 catch (Exception e)
310 {
311 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Move inventory folder operation failed for {0} {1}, {2} {3}",
312 folder.Name, folder.ID, e.Source, e.Message);
313 }
314
315 return false;
316 }
317
318 public bool PurgeFolder(string userID, InventoryFolderBase folder, UUID sessionID)
319 {
320 try
321 {
322 return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
323 "POST", m_ServerURI + "/PurgeFolder/", folder, sessionID.ToString(), folder.Owner.ToString());
324 }
325 catch (Exception e)
326 {
327 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Purge inventory folder operation failed for {0} {1}, {2} {3}",
328 folder.Name, folder.ID, e.Source, e.Message);
329 }
330
331 return false;
332 }
333
334 public List<InventoryItemBase> GetFolderItems(string userID, UUID folderID, UUID sessionID)
335 {
336 try
337 {
338 InventoryFolderBase folder = new InventoryFolderBase(folderID, new UUID(userID));
339 return SynchronousRestSessionObjectPoster<InventoryFolderBase, List<InventoryItemBase>>.BeginPostObject(
340 "POST", m_ServerURI + "/GetItems/", folder, sessionID.ToString(), userID);
341 }
342 catch (Exception e)
343 {
344 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Get folder items operation failed for folder {0}, {1} {2}",
345 folderID, e.Source, e.Message);
346 }
347
348 return null;
349 }
350
351 public bool AddItem(string userID, InventoryItemBase item, UUID sessionID)
352 {
353 try
354 {
355 return SynchronousRestSessionObjectPoster<InventoryItemBase, bool>.BeginPostObject(
356 "POST", m_ServerURI + "/NewItem/", item, sessionID.ToString(), item.Owner.ToString());
357 }
358 catch (Exception e)
359 {
360 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Add new inventory item operation failed for {0} {1}, {2} {3}",
361 item.Name, item.ID, e.Source, e.Message);
362 }
363
364 return false;
365 }
366
367 public bool UpdateItem(string userID, InventoryItemBase item, UUID sessionID)
368 {
369 try
370 {
371 return SynchronousRestSessionObjectPoster<InventoryItemBase, bool>.BeginPostObject(
372 "POST", m_ServerURI + "/NewItem/", item, sessionID.ToString(), item.Owner.ToString());
373 }
374 catch (Exception e)
375 {
376 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Update new inventory item operation failed for {0} {1}, {2} {3}",
377 item.Name, item.ID, e.Source, e.Message);
378 }
379
380 return false;
381 }
382
383 /**
384 * MoveItems Async group
385 */
386
387 delegate void MoveItemsDelegate(string userID, List<InventoryItemBase> items, UUID sessionID);
388
389 private void MoveItemsAsync(string userID, List<InventoryItemBase> items, UUID sessionID)
390 {
391 if (items == null)
392 {
393 m_log.WarnFormat("[INVENTORY CONNECTOR]: request to move items got a null list.");
394 return;
395 }
396
397 try
398 {
399 //SynchronousRestSessionObjectPoster<List<InventoryItemBase>, bool>.BeginPostObject(
400 // "POST", m_ServerURI + "/MoveItems/", items, sessionID.ToString(), userID.ToString());
401
402 //// Success
403 //return;
404 string uri = m_ServerURI + "/inventory/" + userID;
405 if (SynchronousRestObjectRequester.
406 MakeRequest<List<InventoryItemBase>, bool>("PUT", uri, items))
407 m_log.DebugFormat("[INVENTORY CONNECTOR]: move {0} items poster succeeded {1}", items.Count, uri);
408 else
409 m_log.DebugFormat("[INVENTORY CONNECTOR]: move {0} items poster failed {1}", items.Count, uri); ;
410
411 return;
412
413 }
414 catch (Exception e)
415 {
416 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Move inventory items operation failed, {0} {1} (old server?). Trying slow way.",
417 e.Source, e.Message);
418 }
419
420 }
421
422 private void MoveItemsCompleted(IAsyncResult iar)
423 {
424 MoveItemsDelegate d = (MoveItemsDelegate)iar.AsyncState;
425 d.EndInvoke(iar);
426 }
427
428 public bool MoveItems(string userID, List<InventoryItemBase> items, UUID sessionID)
429 {
430 MoveItemsDelegate d = MoveItemsAsync;
431 d.BeginInvoke(userID, items, sessionID, MoveItemsCompleted, d);
432 return true;
433 }
434
435 public bool DeleteItems(string userID, List<UUID> items, UUID sessionID)
436 {
437 try
438 {
439 List<Guid> guids = new List<Guid>();
440 foreach (UUID u in items)
441 guids.Add(u.Guid);
442 return SynchronousRestSessionObjectPoster<List<Guid>, bool>.BeginPostObject(
443 "POST", m_ServerURI + "/DeleteItem/", guids, sessionID.ToString(), userID);
444 }
445 catch (Exception e)
446 {
447 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Delete inventory items operation failed, {0} {1}",
448 e.Source, e.Message);
449 }
450
451 return false;
452 }
453
454 public InventoryItemBase QueryItem(string userID, InventoryItemBase item, UUID sessionID)
455 {
456 try
457 {
458 return SynchronousRestSessionObjectPoster<InventoryItemBase, InventoryItemBase>.BeginPostObject(
459 "POST", m_ServerURI + "/QueryItem/", item, sessionID.ToString(), item.Owner.ToString());
460 }
461 catch (Exception e)
462 {
463 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Query inventory item operation failed, {0} {1}",
464 e.Source, e.Message);
465 }
466
467 return null;
468 }
469
470 public InventoryFolderBase QueryFolder(string userID, InventoryFolderBase folder, UUID sessionID)
471 {
472 try
473 {
474 return SynchronousRestSessionObjectPoster<InventoryFolderBase, InventoryFolderBase>.BeginPostObject(
475 "POST", m_ServerURI + "/QueryFolder/", folder, sessionID.ToString(), userID);
476 }
477 catch (Exception e)
478 {
479 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Query inventory folder operation failed, {0} {1}",
480 e.Source, e.Message);
481 }
482
483 return null;
484 }
485
486 public int GetAssetPermissions(string userID, UUID assetID, UUID sessionID)
487 {
488 try
489 {
490 InventoryItemBase item = new InventoryItemBase();
491 item.Owner = new UUID(userID);
492 item.AssetID = assetID;
493 return SynchronousRestSessionObjectPoster<InventoryItemBase, int>.BeginPostObject(
494 "POST", m_ServerURI + "/AssetPermissions/", item, sessionID.ToString(), userID);
495 }
496 catch (Exception e)
497 {
498 m_log.ErrorFormat("[INVENTORY CONNECTOR]: AssetPermissions operation failed, {0} {1}",
499 e.Source, e.Message);
500 }
501
502 return 0;
503 }
504
505 #endregion
506
507 /// <summary>
508 /// Callback used by the inventory server GetInventory request
509 /// </summary>
510 /// <param name="userID"></param>
511 private void InventoryResponse(InventoryCollection response)
512 {
513 UUID userID = response.UserID;
514 InventoryReceiptCallback callback = null;
515 lock (m_RequestingInventory)
516 {
517 if (m_RequestingInventory.ContainsKey(userID))
518 {
519 callback = m_RequestingInventory[userID];
520 m_RequestingInventory.Remove(userID);
521 lock (m_RequestTime)
522 {
523 if (m_RequestTime.ContainsKey(userID))
524 {
525 m_RequestTime.Remove(userID);
526 }
527 }
528 }
529 else
530 {
531 m_log.WarnFormat(
532 "[INVENTORY CONNECTOR]: " +
533 "Received inventory response for {0} for which we do not have a record of requesting!",
534 userID);
535 return;
536 }
537 }
538
539 m_log.InfoFormat("[INVENTORY CONNECTOR]: " +
540 "Received inventory response for user {0} containing {1} folders and {2} items",
541 userID, response.Folders.Count, response.Items.Count);
542
543 InventoryFolderImpl rootFolder = null;
544
545 ICollection<InventoryFolderImpl> folders = new List<InventoryFolderImpl>();
546 ICollection<InventoryItemBase> items = new List<InventoryItemBase>();
547
548 foreach (InventoryFolderBase folder in response.Folders)
549 {
550 if (folder.ParentID == UUID.Zero)
551 {
552 rootFolder = new InventoryFolderImpl(folder);
553 folders.Add(rootFolder);
554
555 break;
556 }
557 }
558
559 if (rootFolder != null)
560 {
561 foreach (InventoryFolderBase folder in response.Folders)
562 {
563 if (folder.ID != rootFolder.ID)
564 {
565 folders.Add(new InventoryFolderImpl(folder));
566 }
567 }
568
569 foreach (InventoryItemBase item in response.Items)
570 {
571 items.Add(item);
572 }
573 }
574 else
575 {
576 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Did not get back an inventory containing a root folder for user {0}", userID);
577 }
578
579 callback(folders, items);
580 }
581 }
582}