clockwerk-opensim – Blame information for rev 1

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