opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 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  
28 using log4net;
29 using Mono.Addins;
30 using Nini.Config;
31 using System;
32 using System.Collections.Generic;
33 using System.Reflection;
34 using OpenSim.Framework;
35  
36 using OpenSim.Server.Base;
37 using OpenSim.Region.Framework.Interfaces;
38 using OpenSim.Region.Framework.Scenes;
39 using OpenSim.Services.Interfaces;
40 using OpenSim.Services.Connectors;
41 using OpenSim.Services.Connectors.SimianGrid;
42 using OpenMetaverse;
43  
44 namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
45 {
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "HGInventoryBroker")]
47 public class HGInventoryBroker : ISharedRegionModule, IInventoryService
48 {
49 private static readonly ILog m_log =
50 LogManager.GetLogger(
51 MethodBase.GetCurrentMethod().DeclaringType);
52  
53 private static bool m_Enabled = false;
54  
55 private static IInventoryService m_LocalGridInventoryService;
56 private Dictionary<string, IInventoryService> m_connectors = new Dictionary<string, IInventoryService>();
57  
58 // A cache of userIDs --> ServiceURLs, for HGBroker only
59 protected Dictionary<UUID, string> m_InventoryURLs = new Dictionary<UUID,string>();
60  
61 private List<Scene> m_Scenes = new List<Scene>();
62  
63 private InventoryCache m_Cache = new InventoryCache();
64  
65 protected IUserManagement m_UserManagement;
66 protected IUserManagement UserManagementModule
67 {
68 get
69 {
70 if (m_UserManagement == null)
71 {
72 m_UserManagement = m_Scenes[0].RequestModuleInterface<IUserManagement>();
73  
74 if (m_UserManagement == null)
75 m_log.ErrorFormat(
76 "[HG INVENTORY CONNECTOR]: Could not retrieve IUserManagement module from {0}",
77 m_Scenes[0].RegionInfo.RegionName);
78 }
79  
80 return m_UserManagement;
81 }
82 }
83  
84 public Type ReplaceableInterface
85 {
86 get { return null; }
87 }
88  
89 public string Name
90 {
91 get { return "HGInventoryBroker"; }
92 }
93  
94 public void Initialise(IConfigSource source)
95 {
96 IConfig moduleConfig = source.Configs["Modules"];
97 if (moduleConfig != null)
98 {
99 string name = moduleConfig.GetString("InventoryServices", "");
100 if (name == Name)
101 {
102 IConfig inventoryConfig = source.Configs["InventoryService"];
103 if (inventoryConfig == null)
104 {
105 m_log.Error("[HG INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini");
106 return;
107 }
108  
109 string localDll = inventoryConfig.GetString("LocalGridInventoryService",
110 String.Empty);
111 //string HGDll = inventoryConfig.GetString("HypergridInventoryService",
112 // String.Empty);
113  
114 if (localDll == String.Empty)
115 {
116 m_log.Error("[HG INVENTORY CONNECTOR]: No LocalGridInventoryService named in section InventoryService");
117 //return;
118 throw new Exception("Unable to proceed. Please make sure your ini files in config-include are updated according to .example's");
119 }
120  
121 Object[] args = new Object[] { source };
122 m_LocalGridInventoryService =
123 ServerUtils.LoadPlugin<IInventoryService>(localDll,
124 args);
125  
126 if (m_LocalGridInventoryService == null)
127 {
128 m_log.Error("[HG INVENTORY CONNECTOR]: Can't load local inventory service");
129 return;
130 }
131  
132 m_Enabled = true;
133 m_log.InfoFormat("[HG INVENTORY CONNECTOR]: HG inventory broker enabled with inner connector of type {0}", m_LocalGridInventoryService.GetType());
134 }
135 }
136 }
137  
138 public void PostInitialise()
139 {
140 }
141  
142 public void Close()
143 {
144 }
145  
146 public void AddRegion(Scene scene)
147 {
148 if (!m_Enabled)
149 return;
150  
151 m_Scenes.Add(scene);
152  
153 scene.RegisterModuleInterface<IInventoryService>(this);
154  
155 if (m_Scenes.Count == 1)
156 {
157 // FIXME: The local connector needs the scene to extract the UserManager. However, it's not enabled so
158 // we can't just add the region. But this approach is super-messy.
159 if (m_LocalGridInventoryService is RemoteXInventoryServicesConnector)
160 {
161 m_log.DebugFormat(
162 "[HG INVENTORY BROKER]: Manually setting scene in RemoteXInventoryServicesConnector to {0}",
163 scene.RegionInfo.RegionName);
164  
165 ((RemoteXInventoryServicesConnector)m_LocalGridInventoryService).Scene = scene;
166 }
167 else if (m_LocalGridInventoryService is LocalInventoryServicesConnector)
168 {
169 m_log.DebugFormat(
170 "[HG INVENTORY BROKER]: Manually setting scene in LocalInventoryServicesConnector to {0}",
171 scene.RegionInfo.RegionName);
172  
173 ((LocalInventoryServicesConnector)m_LocalGridInventoryService).Scene = scene;
174 }
175  
176 scene.EventManager.OnClientClosed += OnClientClosed;
177 }
178 }
179  
180 public void RemoveRegion(Scene scene)
181 {
182 if (!m_Enabled)
183 return;
184  
185 m_Scenes.Remove(scene);
186 }
187  
188 public void RegionLoaded(Scene scene)
189 {
190 if (!m_Enabled)
191 return;
192  
193 m_log.InfoFormat("[HG INVENTORY CONNECTOR]: Enabled HG inventory for region {0}", scene.RegionInfo.RegionName);
194  
195 }
196  
197 #region URL Cache
198  
199 void OnClientClosed(UUID clientID, Scene scene)
200 {
201 if (m_InventoryURLs.ContainsKey(clientID)) // if it's in cache
202 {
203 ScenePresence sp = null;
204 foreach (Scene s in m_Scenes)
205 {
206 s.TryGetScenePresence(clientID, out sp);
207 if ((sp != null) && !sp.IsChildAgent && (s != scene))
208 {
209 m_log.DebugFormat("[INVENTORY CACHE]: OnClientClosed in {0}, but user {1} still in sim. Keeping inventoryURL in cache",
210 scene.RegionInfo.RegionName, clientID);
211 return;
212 }
213 }
214 DropInventoryServiceURL(clientID);
215 }
216 }
217  
218 /// <summary>
219 /// Gets the user's inventory URL from its serviceURLs, if the user is foreign,
220 /// and sticks it in the cache
221 /// </summary>
222 /// <param name="userID"></param>
223 private void CacheInventoryServiceURL(UUID userID)
224 {
225 if (UserManagementModule != null && !UserManagementModule.IsLocalGridUser(userID))
226 {
227 // The user is not local; let's cache its service URL
228 string inventoryURL = string.Empty;
229 ScenePresence sp = null;
230 foreach (Scene scene in m_Scenes)
231 {
232 scene.TryGetScenePresence(userID, out sp);
233 if (sp != null)
234 {
235 AgentCircuitData aCircuit = scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
236 if (aCircuit == null)
237 return;
238 if (aCircuit.ServiceURLs == null)
239 return;
240  
241 if (aCircuit.ServiceURLs.ContainsKey("InventoryServerURI"))
242 {
243 inventoryURL = aCircuit.ServiceURLs["InventoryServerURI"].ToString();
244 if (inventoryURL != null && inventoryURL != string.Empty)
245 {
246 inventoryURL = inventoryURL.Trim(new char[] { '/' });
247 m_InventoryURLs.Add(userID, inventoryURL);
248 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL);
249 return;
250 }
251 }
252 // else
253 // {
254 // m_log.DebugFormat("[HG INVENTORY CONNECTOR]: User {0} does not have InventoryServerURI. OH NOES!", userID);
255 // return;
256 // }
257 }
258 }
259 if (sp == null)
260 {
261 inventoryURL = UserManagementModule.GetUserServerURL(userID, "InventoryServerURI");
262 if (!string.IsNullOrEmpty(inventoryURL))
263 {
264 inventoryURL = inventoryURL.Trim(new char[] { '/' });
265 m_InventoryURLs.Add(userID, inventoryURL);
266 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL);
267 }
268  
269 }
270  
271 }
272 }
273  
274 private void DropInventoryServiceURL(UUID userID)
275 {
276 lock (m_InventoryURLs)
277 if (m_InventoryURLs.ContainsKey(userID))
278 {
279 string url = m_InventoryURLs[userID];
280 m_InventoryURLs.Remove(userID);
281 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Removed {0} from the cache of inventory URLs", url);
282 }
283 }
284  
285 public string GetInventoryServiceURL(UUID userID)
286 {
287 if (m_InventoryURLs.ContainsKey(userID))
288 return m_InventoryURLs[userID];
289  
290 CacheInventoryServiceURL(userID);
291  
292 if (m_InventoryURLs.ContainsKey(userID))
293 return m_InventoryURLs[userID];
294  
295 return null; //it means that the methods should forward to local grid's inventory
296  
297 }
298 #endregion
299  
300 #region IInventoryService
301  
302 public bool CreateUserInventory(UUID userID)
303 {
304 return m_LocalGridInventoryService.CreateUserInventory(userID);
305 }
306  
307 public List<InventoryFolderBase> GetInventorySkeleton(UUID userID)
308 {
309 string invURL = GetInventoryServiceURL(userID);
310  
311 if (invURL == null) // not there, forward to local inventory connector to resolve
312 return m_LocalGridInventoryService.GetInventorySkeleton(userID);
313  
314 IInventoryService connector = GetConnector(invURL);
315  
316 return connector.GetInventorySkeleton(userID);
317 }
318  
319 public InventoryCollection GetUserInventory(UUID userID)
320 {
321 string invURL = GetInventoryServiceURL(userID);
322 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetUserInventory for {0} {1}", userID, invURL);
323  
324 if (invURL == null) // not there, forward to local inventory connector to resolve
325 return m_LocalGridInventoryService.GetUserInventory(userID);
326  
327 InventoryCollection c = m_Cache.GetUserInventory(userID);
328 if (c != null)
329 return c;
330  
331 IInventoryService connector = GetConnector(invURL);
332 c = connector.GetUserInventory(userID);
333  
334 m_Cache.Cache(userID, c);
335 return c;
336 }
337  
338 public void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
339 {
340 }
341  
342 public InventoryFolderBase GetRootFolder(UUID userID)
343 {
344 //m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetRootFolder for {0}", userID);
345 InventoryFolderBase root = m_Cache.GetRootFolder(userID);
346 if (root != null)
347 return root;
348  
349 string invURL = GetInventoryServiceURL(userID);
350  
351 if (invURL == null) // not there, forward to local inventory connector to resolve
352 return m_LocalGridInventoryService.GetRootFolder(userID);
353  
354 IInventoryService connector = GetConnector(invURL);
355  
356 root = connector.GetRootFolder(userID);
357  
358 m_Cache.Cache(userID, root);
359  
360 return root;
361 }
362  
363 public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
364 {
365 //m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetFolderForType {0} type {1}", userID, type);
366 InventoryFolderBase f = m_Cache.GetFolderForType(userID, type);
367 if (f != null)
368 return f;
369  
370 string invURL = GetInventoryServiceURL(userID);
371  
372 if (invURL == null) // not there, forward to local inventory connector to resolve
373 return m_LocalGridInventoryService.GetFolderForType(userID, type);
374  
375 IInventoryService connector = GetConnector(invURL);
376  
377 f = connector.GetFolderForType(userID, type);
378  
379 m_Cache.Cache(userID, type, f);
380  
381 return f;
382 }
383  
384 public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
385 {
386 //m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderContent " + folderID);
387  
388 string invURL = GetInventoryServiceURL(userID);
389  
390 if (invURL == null) // not there, forward to local inventory connector to resolve
391 return m_LocalGridInventoryService.GetFolderContent(userID, folderID);
392  
393 InventoryCollection c = m_Cache.GetFolderContent(userID, folderID);
394 if (c != null)
395 {
396 m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderContent found content in cache " + folderID);
397 return c;
398 }
399  
400 IInventoryService connector = GetConnector(invURL);
401 return connector.GetFolderContent(userID, folderID);
402  
403 }
404  
405 public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
406 {
407 //m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderItems " + folderID);
408  
409 string invURL = GetInventoryServiceURL(userID);
410  
411 if (invURL == null) // not there, forward to local inventory connector to resolve
412 return m_LocalGridInventoryService.GetFolderItems(userID, folderID);
413  
414 List<InventoryItemBase> items = m_Cache.GetFolderItems(userID, folderID);
415 if (items != null)
416 {
417 m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderItems found items in cache " + folderID);
418 return items;
419 }
420  
421 IInventoryService connector = GetConnector(invURL);
422 return connector.GetFolderItems(userID, folderID);
423  
424 }
425  
426 public bool AddFolder(InventoryFolderBase folder)
427 {
428 if (folder == null)
429 return false;
430  
431 //m_log.Debug("[HG INVENTORY CONNECTOR]: AddFolder " + folder.ID);
432  
433 string invURL = GetInventoryServiceURL(folder.Owner);
434  
435 if (invURL == null) // not there, forward to local inventory connector to resolve
436 return m_LocalGridInventoryService.AddFolder(folder);
437  
438 IInventoryService connector = GetConnector(invURL);
439  
440 return connector.AddFolder(folder);
441 }
442  
443 public bool UpdateFolder(InventoryFolderBase folder)
444 {
445 if (folder == null)
446 return false;
447  
448 //m_log.Debug("[HG INVENTORY CONNECTOR]: UpdateFolder " + folder.ID);
449  
450 string invURL = GetInventoryServiceURL(folder.Owner);
451  
452 if (invURL == null) // not there, forward to local inventory connector to resolve
453 return m_LocalGridInventoryService.UpdateFolder(folder);
454  
455 IInventoryService connector = GetConnector(invURL);
456  
457 return connector.UpdateFolder(folder);
458 }
459  
460 public bool DeleteFolders(UUID ownerID, List<UUID> folderIDs)
461 {
462 if (folderIDs == null)
463 return false;
464 if (folderIDs.Count == 0)
465 return false;
466  
467 //m_log.Debug("[HG INVENTORY CONNECTOR]: DeleteFolders for " + ownerID);
468  
469 string invURL = GetInventoryServiceURL(ownerID);
470  
471 if (invURL == null) // not there, forward to local inventory connector to resolve
472 return m_LocalGridInventoryService.DeleteFolders(ownerID, folderIDs);
473  
474 IInventoryService connector = GetConnector(invURL);
475  
476 return connector.DeleteFolders(ownerID, folderIDs);
477 }
478  
479 public bool MoveFolder(InventoryFolderBase folder)
480 {
481 if (folder == null)
482 return false;
483  
484 //m_log.Debug("[HG INVENTORY CONNECTOR]: MoveFolder for " + folder.Owner);
485  
486 string invURL = GetInventoryServiceURL(folder.Owner);
487  
488 if (invURL == null) // not there, forward to local inventory connector to resolve
489 return m_LocalGridInventoryService.MoveFolder(folder);
490  
491 IInventoryService connector = GetConnector(invURL);
492  
493 return connector.MoveFolder(folder);
494 }
495  
496 public bool PurgeFolder(InventoryFolderBase folder)
497 {
498 if (folder == null)
499 return false;
500  
501 //m_log.Debug("[HG INVENTORY CONNECTOR]: PurgeFolder for " + folder.Owner);
502  
503 string invURL = GetInventoryServiceURL(folder.Owner);
504  
505 if (invURL == null) // not there, forward to local inventory connector to resolve
506 return m_LocalGridInventoryService.PurgeFolder(folder);
507  
508 IInventoryService connector = GetConnector(invURL);
509  
510 return connector.PurgeFolder(folder);
511 }
512  
513 public bool AddItem(InventoryItemBase item)
514 {
515 if (item == null)
516 return false;
517  
518 //m_log.Debug("[HG INVENTORY CONNECTOR]: AddItem " + item.ID);
519  
520 string invURL = GetInventoryServiceURL(item.Owner);
521  
522 if (invURL == null) // not there, forward to local inventory connector to resolve
523 return m_LocalGridInventoryService.AddItem(item);
524  
525 IInventoryService connector = GetConnector(invURL);
526  
527 return connector.AddItem(item);
528 }
529  
530 public bool UpdateItem(InventoryItemBase item)
531 {
532 if (item == null)
533 return false;
534  
535 //m_log.Debug("[HG INVENTORY CONNECTOR]: UpdateItem " + item.ID);
536  
537 string invURL = GetInventoryServiceURL(item.Owner);
538  
539 if (invURL == null) // not there, forward to local inventory connector to resolve
540 return m_LocalGridInventoryService.UpdateItem(item);
541  
542 IInventoryService connector = GetConnector(invURL);
543  
544 return connector.UpdateItem(item);
545 }
546  
547 public bool MoveItems(UUID ownerID, List<InventoryItemBase> items)
548 {
549 if (items == null)
550 return false;
551 if (items.Count == 0)
552 return true;
553  
554 //m_log.Debug("[HG INVENTORY CONNECTOR]: MoveItems for " + ownerID);
555  
556 string invURL = GetInventoryServiceURL(ownerID);
557  
558 if (invURL == null) // not there, forward to local inventory connector to resolve
559 return m_LocalGridInventoryService.MoveItems(ownerID, items);
560  
561 IInventoryService connector = GetConnector(invURL);
562  
563 return connector.MoveItems(ownerID, items);
564 }
565  
566 public bool DeleteItems(UUID ownerID, List<UUID> itemIDs)
567 {
568 //m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Delete {0} items for user {1}", itemIDs.Count, ownerID);
569  
570 if (itemIDs == null)
571 return false;
572 if (itemIDs.Count == 0)
573 return true;
574  
575 string invURL = GetInventoryServiceURL(ownerID);
576  
577 if (invURL == null) // not there, forward to local inventory connector to resolve
578 return m_LocalGridInventoryService.DeleteItems(ownerID, itemIDs);
579  
580 IInventoryService connector = GetConnector(invURL);
581  
582 return connector.DeleteItems(ownerID, itemIDs);
583 }
584  
585 public InventoryItemBase GetItem(InventoryItemBase item)
586 {
587 if (item == null)
588 return null;
589 //m_log.Debug("[HG INVENTORY CONNECTOR]: GetItem " + item.ID);
590  
591 string invURL = GetInventoryServiceURL(item.Owner);
592  
593 if (invURL == null) // not there, forward to local inventory connector to resolve
594 return m_LocalGridInventoryService.GetItem(item);
595  
596 IInventoryService connector = GetConnector(invURL);
597  
598 return connector.GetItem(item);
599 }
600  
601 public InventoryFolderBase GetFolder(InventoryFolderBase folder)
602 {
603 if (folder == null)
604 return null;
605  
606 //m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolder " + folder.ID);
607  
608 string invURL = GetInventoryServiceURL(folder.Owner);
609  
610 if (invURL == null) // not there, forward to local inventory connector to resolve
611 return m_LocalGridInventoryService.GetFolder(folder);
612  
613 IInventoryService connector = GetConnector(invURL);
614  
615 return connector.GetFolder(folder);
616 }
617  
618 public bool HasInventoryForUser(UUID userID)
619 {
620 return false;
621 }
622  
623 public List<InventoryItemBase> GetActiveGestures(UUID userId)
624 {
625 return new List<InventoryItemBase>();
626 }
627  
628 public int GetAssetPermissions(UUID userID, UUID assetID)
629 {
630 //m_log.Debug("[HG INVENTORY CONNECTOR]: GetAssetPermissions " + assetID);
631  
632 string invURL = GetInventoryServiceURL(userID);
633  
634 if (invURL == null) // not there, forward to local inventory connector to resolve
635 return m_LocalGridInventoryService.GetAssetPermissions(userID, assetID);
636  
637 IInventoryService connector = GetConnector(invURL);
638  
639 return connector.GetAssetPermissions(userID, assetID);
640 }
641  
642 #endregion
643  
644 private IInventoryService GetConnector(string url)
645 {
646 IInventoryService connector = null;
647 lock (m_connectors)
648 {
649 if (m_connectors.ContainsKey(url))
650 {
651 connector = m_connectors[url];
652 }
653 else
654 {
655 // Still not as flexible as I would like this to be,
656 // but good enough for now
657 string connectorType = new HeloServicesConnector(url).Helo();
658 m_log.DebugFormat("[HG INVENTORY SERVICE]: HELO returned {0}", connectorType);
659 if (connectorType == "opensim-simian")
660 {
661 connector = new SimianInventoryServiceConnector(url);
662 }
663 else
664 {
665 RemoteXInventoryServicesConnector rxisc = new RemoteXInventoryServicesConnector(url);
666 rxisc.Scene = m_Scenes[0];
667 connector = rxisc;
668 }
669  
670 m_connectors.Add(url, connector);
671 }
672 }
673  
674 return connector;
675 }
676 }
677 }