aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Addons/Groups/Remote
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs696
-rw-r--r--OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs408
-rw-r--r--OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs816
-rw-r--r--OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs888
4 files changed, 2808 insertions, 0 deletions
diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs
new file mode 100644
index 0000000..7450c14
--- /dev/null
+++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs
@@ -0,0 +1,696 @@
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 System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Reflection;
32using System.Text;
33
34using OpenSim.Framework;
35using OpenSim.Framework.ServiceAuth;
36using OpenSim.Server.Base;
37
38using OpenMetaverse;
39using log4net;
40using Nini.Config;
41
42namespace OpenSim.Groups
43{
44 public class GroupsServiceRemoteConnector
45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 private string m_ServerURI;
49 private IServiceAuth m_Auth;
50 private object m_Lock = new object();
51
52 public GroupsServiceRemoteConnector(IConfigSource config)
53 {
54 IConfig groupsConfig = config.Configs["Groups"];
55 string url = groupsConfig.GetString("GroupsServerURI", string.Empty);
56 if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
57 throw new Exception(string.Format("[Groups.RemoteConnector]: Malformed groups server URL {0}. Fix it or disable the Groups feature.", url));
58
59 m_ServerURI = url;
60 if (!m_ServerURI.EndsWith("/"))
61 m_ServerURI += "/";
62
63 /// This is from BaseServiceConnector
64 string authType = Util.GetConfigVarFromSections<string>(config, "AuthType", new string[] { "Network", "Groups" }, "None");
65
66 switch (authType)
67 {
68 case "BasicHttpAuthentication":
69 m_Auth = new BasicHttpAuthentication(config, "Groups");
70 break;
71 }
72 ///
73
74 m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}, authentication {1}",
75 m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString()));
76 }
77
78 public ExtendedGroupRecord CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
79 bool allowPublish, bool maturePublish, UUID founderID, out string reason)
80 {
81 reason = string.Empty;
82
83 ExtendedGroupRecord rec = new ExtendedGroupRecord();
84 rec.AllowPublish = allowPublish;
85 rec.Charter = charter;
86 rec.FounderID = founderID;
87 rec.GroupName = name;
88 rec.GroupPicture = insigniaID;
89 rec.MaturePublish = maturePublish;
90 rec.MembershipFee = membershipFee;
91 rec.OpenEnrollment = openEnrollment;
92 rec.ShowInList = showInList;
93
94 Dictionary<string, object> sendData = GroupsDataUtils.GroupRecord(rec);
95 sendData["RequestingAgentID"] = RequestingAgentID;
96 sendData["OP"] = "ADD";
97 Dictionary<string, object> ret = MakeRequest("PUTGROUP", sendData);
98
99 if (ret == null)
100 return null;
101
102 if (ret["RESULT"].ToString() == "NULL")
103 {
104 reason = ret["REASON"].ToString();
105 return null;
106 }
107
108 return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
109
110 }
111
112 public ExtendedGroupRecord UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish)
113 {
114 ExtendedGroupRecord rec = new ExtendedGroupRecord();
115 rec.AllowPublish = allowPublish;
116 rec.Charter = charter;
117 rec.GroupPicture = insigniaID;
118 rec.MaturePublish = maturePublish;
119 rec.GroupID = groupID;
120 rec.MembershipFee = membershipFee;
121 rec.OpenEnrollment = openEnrollment;
122 rec.ShowInList = showInList;
123
124 Dictionary<string, object> sendData = GroupsDataUtils.GroupRecord(rec);
125 sendData["RequestingAgentID"] = RequestingAgentID;
126 sendData["OP"] = "UPDATE";
127 Dictionary<string, object> ret = MakeRequest("PUTGROUP", sendData);
128
129 if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
130 return null;
131
132 return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
133 }
134
135 public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName)
136 {
137 if (GroupID == UUID.Zero && (GroupName == null || (GroupName != null && GroupName == string.Empty)))
138 return null;
139
140 Dictionary<string, object> sendData = new Dictionary<string, object>();
141 if (GroupID != UUID.Zero)
142 sendData["GroupID"] = GroupID.ToString();
143 if (!string.IsNullOrEmpty(GroupName))
144 sendData["Name"] = GroupsDataUtils.Sanitize(GroupName);
145
146 sendData["RequestingAgentID"] = RequestingAgentID;
147
148 Dictionary<string, object> ret = MakeRequest("GETGROUP", sendData);
149
150 if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
151 return null;
152
153 return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
154 }
155
156 public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string query)
157 {
158 List<DirGroupsReplyData> hits = new List<DirGroupsReplyData>();
159 if (string.IsNullOrEmpty(query))
160 return hits;
161
162 Dictionary<string, object> sendData = new Dictionary<string, object>();
163 sendData["Query"] = query;
164 sendData["RequestingAgentID"] = RequestingAgentID;
165
166 Dictionary<string, object> ret = MakeRequest("FINDGROUPS", sendData);
167
168 if (ret == null)
169 return hits;
170
171 if (!ret.ContainsKey("RESULT"))
172 return hits;
173
174 if (ret["RESULT"].ToString() == "NULL")
175 return hits;
176
177 foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
178 {
179 DirGroupsReplyData m = GroupsDataUtils.DirGroupsReplyData((Dictionary<string, object>)v);
180 hits.Add(m);
181 }
182
183 return hits;
184 }
185
186 public GroupMembershipData AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
187 {
188 reason = string.Empty;
189
190 Dictionary<string, object> sendData = new Dictionary<string,object>();
191 sendData["AgentID"] = AgentID;
192 sendData["GroupID"] = GroupID.ToString();
193 sendData["RoleID"] = RoleID.ToString();
194 sendData["RequestingAgentID"] = RequestingAgentID;
195 sendData["AccessToken"] = token;
196 Dictionary<string, object> ret = MakeRequest("ADDAGENTTOGROUP", sendData);
197
198 if (ret == null)
199 return null;
200
201 if (!ret.ContainsKey("RESULT"))
202 return null;
203
204 if (ret["RESULT"].ToString() == "NULL")
205 {
206 reason = ret["REASON"].ToString();
207 return null;
208 }
209
210 return GroupsDataUtils.GroupMembershipData((Dictionary<string, object>)ret["RESULT"]);
211
212 }
213
214 public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
215 {
216 Dictionary<string, object> sendData = new Dictionary<string, object>();
217 sendData["AgentID"] = AgentID;
218 sendData["GroupID"] = GroupID.ToString();
219 sendData["RequestingAgentID"] = RequestingAgentID;
220 MakeRequest("REMOVEAGENTFROMGROUP", sendData);
221 }
222
223 public ExtendedGroupMembershipData GetMembership(string RequestingAgentID, string AgentID, UUID GroupID)
224 {
225 Dictionary<string, object> sendData = new Dictionary<string, object>();
226 sendData["AgentID"] = AgentID;
227 if (GroupID != UUID.Zero)
228 sendData["GroupID"] = GroupID.ToString();
229 sendData["RequestingAgentID"] = RequestingAgentID;
230 Dictionary<string, object> ret = MakeRequest("GETMEMBERSHIP", sendData);
231
232 if (ret == null)
233 return null;
234
235 if (!ret.ContainsKey("RESULT"))
236 return null;
237
238 if (ret["RESULT"].ToString() == "NULL")
239 return null;
240
241 return GroupsDataUtils.GroupMembershipData((Dictionary<string, object>)ret["RESULT"]);
242 }
243
244 public List<GroupMembershipData> GetMemberships(string RequestingAgentID, string AgentID)
245 {
246 List<GroupMembershipData> memberships = new List<GroupMembershipData>();
247
248 Dictionary<string, object> sendData = new Dictionary<string, object>();
249 sendData["AgentID"] = AgentID;
250 sendData["ALL"] = "true";
251 sendData["RequestingAgentID"] = RequestingAgentID;
252 Dictionary<string, object> ret = MakeRequest("GETMEMBERSHIP", sendData);
253
254 if (ret == null)
255 return memberships;
256
257 if (!ret.ContainsKey("RESULT"))
258 return memberships;
259
260 if (ret["RESULT"].ToString() == "NULL")
261 return memberships;
262
263 foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
264 {
265 GroupMembershipData m = GroupsDataUtils.GroupMembershipData((Dictionary<string, object>)v);
266 memberships.Add(m);
267 }
268
269 return memberships;
270 }
271
272 public List<ExtendedGroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
273 {
274 List<ExtendedGroupMembersData> members = new List<ExtendedGroupMembersData>();
275
276 Dictionary<string, object> sendData = new Dictionary<string, object>();
277 sendData["GroupID"] = GroupID.ToString();
278 sendData["RequestingAgentID"] = RequestingAgentID;
279
280 Dictionary<string, object> ret = MakeRequest("GETGROUPMEMBERS", sendData);
281
282 if (ret == null)
283 return members;
284
285 if (!ret.ContainsKey("RESULT"))
286 return members;
287
288 if (ret["RESULT"].ToString() == "NULL")
289 return members;
290
291 foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
292 {
293 ExtendedGroupMembersData m = GroupsDataUtils.GroupMembersData((Dictionary<string, object>)v);
294 members.Add(m);
295 }
296
297 return members;
298 }
299
300 public bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason)
301 {
302 reason = string.Empty;
303
304 Dictionary<string, object> sendData = new Dictionary<string, object>();
305 sendData["GroupID"] = groupID.ToString();
306 sendData["RoleID"] = roleID.ToString();
307 sendData["Name"] = GroupsDataUtils.Sanitize(name);
308 sendData["Description"] = GroupsDataUtils.Sanitize(description);
309 sendData["Title"] = GroupsDataUtils.Sanitize(title);
310 sendData["Powers"] = powers.ToString();
311 sendData["RequestingAgentID"] = RequestingAgentID;
312 sendData["OP"] = "ADD";
313 Dictionary<string, object> ret = MakeRequest("PUTROLE", sendData);
314
315 if (ret == null)
316 return false;
317
318 if (!ret.ContainsKey("RESULT"))
319 return false;
320
321 if (ret["RESULT"].ToString().ToLower() != "true")
322 {
323 reason = ret["REASON"].ToString();
324 return false;
325 }
326
327 return true;
328 }
329
330 public bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers)
331 {
332 Dictionary<string, object> sendData = new Dictionary<string, object>();
333 sendData["GroupID"] = groupID.ToString();
334 sendData["RoleID"] = roleID.ToString();
335 sendData["Name"] = GroupsDataUtils.Sanitize(name);
336 sendData["Description"] = GroupsDataUtils.Sanitize(description);
337 sendData["Title"] = GroupsDataUtils.Sanitize(title);
338 sendData["Powers"] = powers.ToString();
339 sendData["RequestingAgentID"] = RequestingAgentID;
340 sendData["OP"] = "UPDATE";
341 Dictionary<string, object> ret = MakeRequest("PUTROLE", sendData);
342
343 if (ret == null)
344 return false;
345
346 if (!ret.ContainsKey("RESULT"))
347 return false;
348
349 if (ret["RESULT"].ToString().ToLower() != "true")
350 return false;
351
352 return true;
353 }
354
355 public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID)
356 {
357 Dictionary<string, object> sendData = new Dictionary<string, object>();
358 sendData["GroupID"] = groupID.ToString();
359 sendData["RoleID"] = roleID.ToString();
360 sendData["RequestingAgentID"] = RequestingAgentID;
361 MakeRequest("REMOVEROLE", sendData);
362 }
363
364 public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID)
365 {
366 List<GroupRolesData> roles = new List<GroupRolesData>();
367
368 Dictionary<string, object> sendData = new Dictionary<string, object>();
369 sendData["GroupID"] = GroupID.ToString();
370 sendData["RequestingAgentID"] = RequestingAgentID;
371 Dictionary<string, object> ret = MakeRequest("GETGROUPROLES", sendData);
372
373 if (ret == null)
374 return roles;
375
376 if (!ret.ContainsKey("RESULT"))
377 return roles;
378
379 if (ret["RESULT"].ToString() == "NULL")
380 return roles;
381
382 foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
383 {
384 GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary<string, object>)v);
385 roles.Add(m);
386 }
387
388 return roles;
389 }
390
391 public List<ExtendedGroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID)
392 {
393 List<ExtendedGroupRoleMembersData> rmembers = new List<ExtendedGroupRoleMembersData>();
394
395 Dictionary<string, object> sendData = new Dictionary<string, object>();
396 sendData["GroupID"] = GroupID.ToString();
397 sendData["RequestingAgentID"] = RequestingAgentID;
398 Dictionary<string, object> ret = MakeRequest("GETROLEMEMBERS", sendData);
399
400 if (ret == null)
401 return rmembers;
402
403 if (!ret.ContainsKey("RESULT"))
404 return rmembers;
405
406 if (ret["RESULT"].ToString() == "NULL")
407 return rmembers;
408
409 foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
410 {
411 ExtendedGroupRoleMembersData m = GroupsDataUtils.GroupRoleMembersData((Dictionary<string, object>)v);
412 rmembers.Add(m);
413 }
414
415 return rmembers;
416 }
417
418 public bool AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
419 {
420 Dictionary<string, object> sendData = new Dictionary<string, object>();
421 sendData["AgentID"] = AgentID.ToString();
422 sendData["GroupID"] = GroupID.ToString();
423 sendData["RoleID"] = RoleID.ToString();
424 sendData["RequestingAgentID"] = RequestingAgentID;
425 sendData["OP"] = "ADD";
426
427 Dictionary<string, object> ret = MakeRequest("AGENTROLE", sendData);
428
429 if (ret == null)
430 return false;
431
432 if (!ret.ContainsKey("RESULT"))
433 return false;
434
435 if (ret["RESULT"].ToString().ToLower() != "true")
436 return false;
437
438 return true;
439 }
440
441 public bool RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
442 {
443 Dictionary<string, object> sendData = new Dictionary<string, object>();
444 sendData["AgentID"] = AgentID.ToString();
445 sendData["GroupID"] = GroupID.ToString();
446 sendData["RoleID"] = RoleID.ToString();
447 sendData["RequestingAgentID"] = RequestingAgentID;
448 sendData["OP"] = "DELETE";
449
450 Dictionary<string, object> ret = MakeRequest("AGENTROLE", sendData);
451
452 if (ret == null)
453 return false;
454
455 if (!ret.ContainsKey("RESULT"))
456 return false;
457
458 if (ret["RESULT"].ToString().ToLower() != "true")
459 return false;
460
461 return true;
462 }
463
464 public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID)
465 {
466 List<GroupRolesData> roles = new List<GroupRolesData>();
467
468 Dictionary<string, object> sendData = new Dictionary<string, object>();
469 sendData["AgentID"] = AgentID.ToString();
470 sendData["GroupID"] = GroupID.ToString();
471 sendData["RequestingAgentID"] = RequestingAgentID;
472 Dictionary<string, object> ret = MakeRequest("GETAGENTROLES", sendData);
473
474 if (ret == null)
475 return roles;
476
477 if (!ret.ContainsKey("RESULT"))
478 return roles;
479
480 if (ret["RESULT"].ToString() == "NULL")
481 return roles;
482
483 foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
484 {
485 GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary<string, object>)v);
486 roles.Add(m);
487 }
488
489 return roles;
490 }
491
492 public GroupMembershipData SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID)
493 {
494 Dictionary<string, object> sendData = new Dictionary<string, object>();
495 sendData["AgentID"] = AgentID.ToString();
496 sendData["GroupID"] = GroupID.ToString();
497 sendData["RequestingAgentID"] = RequestingAgentID;
498 sendData["OP"] = "GROUP";
499
500 Dictionary<string, object> ret = MakeRequest("SETACTIVE", sendData);
501
502 if (ret == null)
503 return null;
504
505 if (!ret.ContainsKey("RESULT"))
506 return null;
507
508 if (ret["RESULT"].ToString() == "NULL")
509 return null;
510
511 return GroupsDataUtils.GroupMembershipData((Dictionary<string, object>)ret["RESULT"]);
512 }
513
514 public void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
515 {
516 Dictionary<string, object> sendData = new Dictionary<string, object>();
517 sendData["AgentID"] = AgentID.ToString();
518 sendData["GroupID"] = GroupID.ToString();
519 sendData["RoleID"] = RoleID.ToString();
520 sendData["RequestingAgentID"] = RequestingAgentID;
521 sendData["OP"] = "ROLE";
522
523 MakeRequest("SETACTIVE", sendData);
524 }
525
526 public void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile)
527 {
528 Dictionary<string, object> sendData = new Dictionary<string, object>();
529 sendData["AgentID"] = AgentID.ToString();
530 sendData["GroupID"] = GroupID.ToString();
531 sendData["AcceptNotices"] = AcceptNotices.ToString();
532 sendData["ListInProfile"] = ListInProfile.ToString();
533 sendData["RequestingAgentID"] = RequestingAgentID;
534 MakeRequest("UPDATEMEMBERSHIP", sendData);
535 }
536
537 public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
538 {
539 Dictionary<string, object> sendData = new Dictionary<string, object>();
540 sendData["InviteID"] = inviteID.ToString();
541 sendData["GroupID"] = groupID.ToString();
542 sendData["RoleID"] = roleID.ToString();
543 sendData["AgentID"] = agentID.ToString();
544 sendData["RequestingAgentID"] = RequestingAgentID;
545 sendData["OP"] = "ADD";
546
547 Dictionary<string, object> ret = MakeRequest("INVITE", sendData);
548
549 if (ret == null)
550 return false;
551
552 if (!ret.ContainsKey("RESULT"))
553 return false;
554
555 if (ret["RESULT"].ToString().ToLower() != "true") // it may return "NULL"
556 return false;
557
558 return true;
559 }
560
561 public GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
562 {
563 Dictionary<string, object> sendData = new Dictionary<string, object>();
564 sendData["InviteID"] = inviteID.ToString();
565 sendData["RequestingAgentID"] = RequestingAgentID;
566 sendData["OP"] = "GET";
567
568 Dictionary<string, object> ret = MakeRequest("INVITE", sendData);
569
570 if (ret == null)
571 return null;
572
573 if (!ret.ContainsKey("RESULT"))
574 return null;
575
576 if (ret["RESULT"].ToString() == "NULL")
577 return null;
578
579 return GroupsDataUtils.GroupInviteInfo((Dictionary<string, object>)ret["RESULT"]);
580 }
581
582 public void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
583 {
584 Dictionary<string, object> sendData = new Dictionary<string, object>();
585 sendData["InviteID"] = inviteID.ToString();
586 sendData["RequestingAgentID"] = RequestingAgentID;
587 sendData["OP"] = "DELETE";
588
589 MakeRequest("INVITE", sendData);
590 }
591
592 public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
593 bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
594 {
595 Dictionary<string, object> sendData = new Dictionary<string, object>();
596 sendData["GroupID"] = groupID.ToString();
597 sendData["NoticeID"] = noticeID.ToString();
598 sendData["FromName"] = GroupsDataUtils.Sanitize(fromName);
599 sendData["Subject"] = GroupsDataUtils.Sanitize(subject);
600 sendData["Message"] = GroupsDataUtils.Sanitize(message);
601 sendData["HasAttachment"] = hasAttachment.ToString();
602 if (hasAttachment)
603 {
604 sendData["AttachmentType"] = attType.ToString();
605 sendData["AttachmentName"] = attName.ToString();
606 sendData["AttachmentItemID"] = attItemID.ToString();
607 sendData["AttachmentOwnerID"] = attOwnerID;
608 }
609 sendData["RequestingAgentID"] = RequestingAgentID;
610
611 Dictionary<string, object> ret = MakeRequest("ADDNOTICE", sendData);
612
613 if (ret == null)
614 return false;
615
616 if (!ret.ContainsKey("RESULT"))
617 return false;
618
619 if (ret["RESULT"].ToString().ToLower() != "true")
620 return false;
621
622 return true;
623 }
624
625 public GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID)
626 {
627 Dictionary<string, object> sendData = new Dictionary<string, object>();
628 sendData["NoticeID"] = noticeID.ToString();
629 sendData["RequestingAgentID"] = RequestingAgentID;
630
631 Dictionary<string, object> ret = MakeRequest("GETNOTICES", sendData);
632
633 if (ret == null)
634 return null;
635
636 if (!ret.ContainsKey("RESULT"))
637 return null;
638
639 if (ret["RESULT"].ToString() == "NULL")
640 return null;
641
642 return GroupsDataUtils.GroupNoticeInfo((Dictionary<string, object>)ret["RESULT"]);
643 }
644
645 public List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID)
646 {
647 List<ExtendedGroupNoticeData> notices = new List<ExtendedGroupNoticeData>();
648
649 Dictionary<string, object> sendData = new Dictionary<string, object>();
650 sendData["GroupID"] = GroupID.ToString();
651 sendData["RequestingAgentID"] = RequestingAgentID;
652 Dictionary<string, object> ret = MakeRequest("GETNOTICES", sendData);
653
654 if (ret == null)
655 return notices;
656
657 if (!ret.ContainsKey("RESULT"))
658 return notices;
659
660 if (ret["RESULT"].ToString() == "NULL")
661 return notices;
662
663 foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
664 {
665 ExtendedGroupNoticeData m = GroupsDataUtils.GroupNoticeData((Dictionary<string, object>)v);
666 notices.Add(m);
667 }
668
669 return notices;
670 }
671
672 #region Make Request
673
674 private Dictionary<string, object> MakeRequest(string method, Dictionary<string, object> sendData)
675 {
676 sendData["METHOD"] = method;
677
678 string reply = string.Empty;
679 lock (m_Lock)
680 reply = SynchronousRestFormsRequester.MakeRequest("POST",
681 m_ServerURI + "groups",
682 ServerUtils.BuildQueryString(sendData),
683 m_Auth);
684
685 if (reply == string.Empty)
686 return null;
687
688 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
689 reply);
690
691 return replyData;
692 }
693
694 #endregion
695 }
696} \ No newline at end of file
diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs
new file mode 100644
index 0000000..d4739c6
--- /dev/null
+++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs
@@ -0,0 +1,408 @@
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 System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Reflection;
32using System.Threading;
33using System.Text;
34
35using OpenSim.Framework;
36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Server.Base;
39using OpenSim.Services.Interfaces;
40
41using OpenMetaverse;
42using Mono.Addins;
43using log4net;
44using Nini.Config;
45
46namespace OpenSim.Groups
47{
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsServiceRemoteConnectorModule")]
49 public class GroupsServiceRemoteConnectorModule : ISharedRegionModule, IGroupsServicesConnector
50 {
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
53 private bool m_Enabled = false;
54 private GroupsServiceRemoteConnector m_GroupsService;
55 private IUserManagement m_UserManagement;
56 private List<Scene> m_Scenes;
57
58 private RemoteConnectorCacheWrapper m_CacheWrapper;
59
60 #region constructors
61 public GroupsServiceRemoteConnectorModule()
62 {
63 }
64
65 public GroupsServiceRemoteConnectorModule(IConfigSource config, IUserManagement uman)
66 {
67 Init(config);
68 m_UserManagement = uman;
69 m_CacheWrapper = new RemoteConnectorCacheWrapper(m_UserManagement);
70
71 }
72 #endregion
73
74 private void Init(IConfigSource config)
75 {
76 m_GroupsService = new GroupsServiceRemoteConnector(config);
77 m_Scenes = new List<Scene>();
78
79 }
80
81 #region ISharedRegionModule
82
83 public void Initialise(IConfigSource config)
84 {
85 IConfig groupsConfig = config.Configs["Groups"];
86 if (groupsConfig == null)
87 return;
88
89 if ((groupsConfig.GetBoolean("Enabled", false) == false)
90 || (groupsConfig.GetString("ServicesConnectorModule", string.Empty) != Name))
91 {
92 return;
93 }
94
95 Init(config);
96
97 m_Enabled = true;
98 m_log.DebugFormat("[Groups.RemoteConnector]: Initializing {0}", this.Name);
99 }
100
101 public string Name
102 {
103 get { return "Groups Remote Service Connector"; }
104 }
105
106 public Type ReplaceableInterface
107 {
108 get { return null; }
109 }
110
111 public void AddRegion(Scene scene)
112 {
113 if (!m_Enabled)
114 return;
115
116 m_log.DebugFormat("[Groups.RemoteConnector]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
117 scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
118 m_Scenes.Add(scene);
119 }
120
121 public void RemoveRegion(Scene scene)
122 {
123 if (!m_Enabled)
124 return;
125
126 scene.UnregisterModuleInterface<IGroupsServicesConnector>(this);
127 m_Scenes.Remove(scene);
128 }
129
130 public void RegionLoaded(Scene scene)
131 {
132 if (!m_Enabled)
133 return;
134
135 if (m_UserManagement == null)
136 {
137 m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
138 m_CacheWrapper = new RemoteConnectorCacheWrapper(m_UserManagement);
139 }
140 }
141
142 public void PostInitialise()
143 {
144 }
145
146 public void Close()
147 {
148 }
149
150 #endregion
151
152 #region IGroupsServicesConnector
153
154 public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
155 bool allowPublish, bool maturePublish, UUID founderID, out string reason)
156 {
157 m_log.DebugFormat("[Groups.RemoteConnector]: Creating group {0}", name);
158 string r = string.Empty;
159
160 UUID groupID = m_CacheWrapper.CreateGroup(RequestingAgentID, delegate
161 {
162 return m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID,
163 membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out r);
164 });
165
166 reason = r;
167 return groupID;
168 }
169
170 public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
171 bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
172 {
173 string r = string.Empty;
174
175 bool success = m_CacheWrapper.UpdateGroup(groupID, delegate
176 {
177 return m_GroupsService.UpdateGroup(RequestingAgentID, groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish);
178 });
179
180 reason = r;
181 return success;
182 }
183
184 public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName)
185 {
186 if (GroupID == UUID.Zero && (GroupName == null || GroupName != null && GroupName == string.Empty))
187 return null;
188
189 return m_CacheWrapper.GetGroupRecord(RequestingAgentID,GroupID,GroupName, delegate
190 {
191 return m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName);
192 });
193 }
194
195 public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
196 {
197 // TODO!
198 return m_GroupsService.FindGroups(RequestingAgentID, search);
199 }
200
201 public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
202 {
203 string agentFullID = AgentID;
204 m_log.DebugFormat("[Groups.RemoteConnector]: Add agent {0} to group {1}", agentFullID, GroupID);
205 string r = string.Empty;
206
207 bool success = m_CacheWrapper.AddAgentToGroup(RequestingAgentID, AgentID, GroupID, delegate
208 {
209 return m_GroupsService.AddAgentToGroup(RequestingAgentID, agentFullID, GroupID, RoleID, token, out r);
210 });
211
212 reason = r;
213 return success;
214 }
215
216 public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
217 {
218 m_CacheWrapper.RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID, delegate
219 {
220 m_GroupsService.RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
221 });
222
223 }
224
225 public void SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID)
226 {
227 m_CacheWrapper.SetAgentActiveGroup(AgentID, delegate
228 {
229 return m_GroupsService.SetAgentActiveGroup(RequestingAgentID, AgentID, GroupID);
230 });
231 }
232
233 public ExtendedGroupMembershipData GetAgentActiveMembership(string RequestingAgentID, string AgentID)
234 {
235 return m_CacheWrapper.GetAgentActiveMembership(AgentID, delegate
236 {
237 return m_GroupsService.GetMembership(RequestingAgentID, AgentID, UUID.Zero);
238 });
239 }
240
241 public ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID)
242 {
243 return m_CacheWrapper.GetAgentGroupMembership(AgentID, GroupID, delegate
244 {
245 return m_GroupsService.GetMembership(RequestingAgentID, AgentID, GroupID);
246 });
247 }
248
249 public List<GroupMembershipData> GetAgentGroupMemberships(string RequestingAgentID, string AgentID)
250 {
251 return m_CacheWrapper.GetAgentGroupMemberships(AgentID, delegate
252 {
253 return m_GroupsService.GetMemberships(RequestingAgentID, AgentID);
254 });
255 }
256
257
258 public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
259 {
260 return m_CacheWrapper.GetGroupMembers(RequestingAgentID, GroupID, delegate
261 {
262 return m_GroupsService.GetGroupMembers(RequestingAgentID, GroupID);
263 });
264 }
265
266 public bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason)
267 {
268 string r = string.Empty;
269 bool success = m_CacheWrapper.AddGroupRole(groupID, roleID, description, name, powers, title, delegate
270 {
271 return m_GroupsService.AddGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers, out r);
272 });
273
274 reason = r;
275 return success;
276 }
277
278 public bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers)
279 {
280 return m_CacheWrapper.UpdateGroupRole(groupID, roleID, name, description, title, powers, delegate
281 {
282 return m_GroupsService.UpdateGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers);
283 });
284 }
285
286 public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID)
287 {
288 m_CacheWrapper.RemoveGroupRole(RequestingAgentID, groupID, roleID, delegate
289 {
290 m_GroupsService.RemoveGroupRole(RequestingAgentID, groupID, roleID);
291 });
292 }
293
294 public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID)
295 {
296 return m_CacheWrapper.GetGroupRoles(RequestingAgentID, GroupID, delegate
297 {
298 return m_GroupsService.GetGroupRoles(RequestingAgentID, GroupID);
299 });
300 }
301
302 public List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID)
303 {
304 return m_CacheWrapper.GetGroupRoleMembers(RequestingAgentID, GroupID, delegate
305 {
306 return m_GroupsService.GetGroupRoleMembers(RequestingAgentID, GroupID);
307 });
308 }
309
310 public void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
311 {
312 m_CacheWrapper.AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID, delegate
313 {
314 return m_GroupsService.AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
315 });
316 }
317
318 public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
319 {
320 m_CacheWrapper.RemoveAgentFromGroupRole(RequestingAgentID, AgentID, GroupID, RoleID, delegate
321 {
322 return m_GroupsService.RemoveAgentFromGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
323 });
324 }
325
326 public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID)
327 {
328 return m_CacheWrapper.GetAgentGroupRoles(RequestingAgentID, AgentID, GroupID, delegate
329 {
330 return m_GroupsService.GetAgentGroupRoles(RequestingAgentID, AgentID, GroupID); ;
331 });
332 }
333
334 public void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
335 {
336 m_CacheWrapper.SetAgentActiveGroupRole(AgentID, GroupID, delegate
337 {
338 m_GroupsService.SetAgentActiveGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
339 });
340 }
341
342 public void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile)
343 {
344 m_CacheWrapper.UpdateMembership(AgentID, GroupID, AcceptNotices, ListInProfile, delegate
345 {
346 m_GroupsService.UpdateMembership(RequestingAgentID, AgentID, GroupID, AcceptNotices, ListInProfile);
347 });
348 }
349
350 public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
351 {
352 return m_GroupsService.AddAgentToGroupInvite(RequestingAgentID, inviteID, groupID, roleID, agentID);
353 }
354
355 public GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
356 {
357 return m_GroupsService.GetAgentToGroupInvite(RequestingAgentID, inviteID);
358 }
359
360 public void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
361 {
362 m_GroupsService.RemoveAgentToGroupInvite(RequestingAgentID, inviteID);
363 }
364
365 public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
366 bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
367 {
368 GroupNoticeInfo notice = new GroupNoticeInfo();
369 notice.GroupID = groupID;
370 notice.Message = message;
371 notice.noticeData = new ExtendedGroupNoticeData();
372 notice.noticeData.AttachmentItemID = attItemID;
373 notice.noticeData.AttachmentName = attName;
374 notice.noticeData.AttachmentOwnerID = attOwnerID.ToString();
375 notice.noticeData.AttachmentType = attType;
376 notice.noticeData.FromName = fromName;
377 notice.noticeData.HasAttachment = hasAttachment;
378 notice.noticeData.NoticeID = noticeID;
379 notice.noticeData.Subject = subject;
380 notice.noticeData.Timestamp = (uint)Util.UnixTimeSinceEpoch();
381
382 return m_CacheWrapper.AddGroupNotice(groupID, noticeID, notice, delegate
383 {
384 return m_GroupsService.AddGroupNotice(RequestingAgentID, groupID, noticeID, fromName, subject, message,
385 hasAttachment, attType, attName, attItemID, attOwnerID);
386 });
387 }
388
389 public GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID)
390 {
391 return m_CacheWrapper.GetGroupNotice(noticeID, delegate
392 {
393 return m_GroupsService.GetGroupNotice(RequestingAgentID, noticeID);
394 });
395 }
396
397 public List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID)
398 {
399 return m_CacheWrapper.GetGroupNotices(GroupID, delegate
400 {
401 return m_GroupsService.GetGroupNotices(RequestingAgentID, GroupID);
402 });
403 }
404
405 #endregion
406 }
407
408}
diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs
new file mode 100644
index 0000000..26e844e
--- /dev/null
+++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs
@@ -0,0 +1,816 @@
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 System;
29using System.Reflection;
30using System.Text;
31using System.Xml;
32using System.Collections.Generic;
33using System.IO;
34using Nini.Config;
35using OpenSim.Framework;
36using OpenSim.Server.Base;
37using OpenSim.Services.Interfaces;
38using OpenSim.Framework.Servers.HttpServer;
39using OpenSim.Framework.ServiceAuth;
40using OpenSim.Server.Handlers.Base;
41using log4net;
42using OpenMetaverse;
43
44namespace OpenSim.Groups
45{
46 public class GroupsServiceRobustConnector : ServiceConnector
47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 private GroupsService m_GroupsService;
51 private string m_ConfigName = "Groups";
52
53 public GroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) :
54 base(config, server, configName)
55 {
56 string key = string.Empty;
57 if (configName != String.Empty)
58 m_ConfigName = configName;
59
60 m_log.DebugFormat("[Groups.RobustConnector]: Starting with config name {0}", m_ConfigName);
61
62 IConfig groupsConfig = config.Configs[m_ConfigName];
63 if (groupsConfig != null)
64 {
65 key = groupsConfig.GetString("SecretKey", string.Empty);
66 m_log.DebugFormat("[Groups.RobustConnector]: Starting with secret key {0}", key);
67 }
68// else
69// m_log.DebugFormat("[Groups.RobustConnector]: Unable to find {0} section in configuration", m_ConfigName);
70
71 m_GroupsService = new GroupsService(config);
72
73 IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName);
74
75 server.AddStreamHandler(new GroupsServicePostHandler(m_GroupsService, auth));
76 }
77 }
78
79 public class GroupsServicePostHandler : BaseStreamHandler
80 {
81 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
82
83 private GroupsService m_GroupsService;
84
85 public GroupsServicePostHandler(GroupsService service, IServiceAuth auth) :
86 base("POST", "/groups", auth)
87 {
88 m_GroupsService = service;
89 }
90
91 protected override byte[] ProcessRequest(string path, Stream requestData,
92 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
93 {
94 StreamReader sr = new StreamReader(requestData);
95 string body = sr.ReadToEnd();
96 sr.Close();
97 body = body.Trim();
98
99 //m_log.DebugFormat("[XXX]: query String: {0}", body);
100
101 try
102 {
103 Dictionary<string, object> request =
104 ServerUtils.ParseQueryString(body);
105
106 if (!request.ContainsKey("METHOD"))
107 return FailureResult();
108
109 string method = request["METHOD"].ToString();
110 request.Remove("METHOD");
111
112// m_log.DebugFormat("[Groups.Handler]: {0}", method);
113 switch (method)
114 {
115 case "PUTGROUP":
116 return HandleAddOrUpdateGroup(request);
117 case "GETGROUP":
118 return HandleGetGroup(request);
119 case "ADDAGENTTOGROUP":
120 return HandleAddAgentToGroup(request);
121 case "REMOVEAGENTFROMGROUP":
122 return HandleRemoveAgentFromGroup(request);
123 case "GETMEMBERSHIP":
124 return HandleGetMembership(request);
125 case "GETGROUPMEMBERS":
126 return HandleGetGroupMembers(request);
127 case "PUTROLE":
128 return HandlePutRole(request);
129 case "REMOVEROLE":
130 return HandleRemoveRole(request);
131 case "GETGROUPROLES":
132 return HandleGetGroupRoles(request);
133 case "GETROLEMEMBERS":
134 return HandleGetRoleMembers(request);
135 case "AGENTROLE":
136 return HandleAgentRole(request);
137 case "GETAGENTROLES":
138 return HandleGetAgentRoles(request);
139 case "SETACTIVE":
140 return HandleSetActive(request);
141 case "UPDATEMEMBERSHIP":
142 return HandleUpdateMembership(request);
143 case "INVITE":
144 return HandleInvite(request);
145 case "ADDNOTICE":
146 return HandleAddNotice(request);
147 case "GETNOTICES":
148 return HandleGetNotices(request);
149 case "FINDGROUPS":
150 return HandleFindGroups(request);
151 }
152 m_log.DebugFormat("[GROUPS HANDLER]: unknown method request: {0}", method);
153 }
154 catch (Exception e)
155 {
156 m_log.Error(string.Format("[GROUPS HANDLER]: Exception {0} ", e.Message), e);
157 }
158
159 return FailureResult();
160 }
161
162 byte[] HandleAddOrUpdateGroup(Dictionary<string, object> request)
163 {
164 Dictionary<string, object> result = new Dictionary<string, object>();
165
166 ExtendedGroupRecord grec = GroupsDataUtils.GroupRecord(request);
167 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("OP"))
168 NullResult(result, "Bad network data");
169
170 else
171 {
172 string RequestingAgentID = request["RequestingAgentID"].ToString();
173 string reason = string.Empty;
174 string op = request["OP"].ToString();
175 if (op == "ADD")
176 {
177 grec.GroupID = m_GroupsService.CreateGroup(RequestingAgentID, grec.GroupName, grec.Charter, grec.ShowInList, grec.GroupPicture, grec.MembershipFee,
178 grec.OpenEnrollment, grec.AllowPublish, grec.MaturePublish, grec.FounderID, out reason);
179
180 }
181 else if (op == "UPDATE")
182 {
183 m_GroupsService.UpdateGroup(RequestingAgentID, grec.GroupID, grec.Charter, grec.ShowInList, grec.GroupPicture, grec.MembershipFee,
184 grec.OpenEnrollment, grec.AllowPublish, grec.MaturePublish);
185
186 }
187
188 if (grec.GroupID != UUID.Zero)
189 {
190 grec = m_GroupsService.GetGroupRecord(RequestingAgentID, grec.GroupID);
191 if (grec == null)
192 NullResult(result, "Internal Error");
193 else
194 result["RESULT"] = GroupsDataUtils.GroupRecord(grec);
195 }
196 else
197 NullResult(result, reason);
198 }
199
200 string xmlString = ServerUtils.BuildXmlResponse(result);
201
202 //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
203 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
204 }
205
206 byte[] HandleGetGroup(Dictionary<string, object> request)
207 {
208 Dictionary<string, object> result = new Dictionary<string, object>();
209
210 if (!request.ContainsKey("RequestingAgentID"))
211 NullResult(result, "Bad network data");
212 else
213 {
214 string RequestingAgentID = request["RequestingAgentID"].ToString();
215 ExtendedGroupRecord grec = null;
216 if (request.ContainsKey("GroupID"))
217 {
218 UUID groupID = new UUID(request["GroupID"].ToString());
219 grec = m_GroupsService.GetGroupRecord(RequestingAgentID, groupID);
220 }
221 else if (request.ContainsKey("Name"))
222 {
223 string name = request["Name"].ToString();
224 grec = m_GroupsService.GetGroupRecord(RequestingAgentID, name);
225 }
226
227 if (grec == null)
228 NullResult(result, "Group not found");
229 else
230 result["RESULT"] = GroupsDataUtils.GroupRecord(grec);
231 }
232
233 string xmlString = ServerUtils.BuildXmlResponse(result);
234
235 //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
236 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
237 }
238
239 byte[] HandleAddAgentToGroup(Dictionary<string, object> request)
240 {
241 Dictionary<string, object> result = new Dictionary<string, object>();
242
243 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AgentID") ||
244 !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID"))
245 NullResult(result, "Bad network data");
246 else
247 {
248 UUID groupID = new UUID(request["GroupID"].ToString());
249 UUID roleID = new UUID(request["RoleID"].ToString());
250 string agentID = request["AgentID"].ToString();
251 string requestingAgentID = request["RequestingAgentID"].ToString();
252 string token = string.Empty;
253 string reason = string.Empty;
254
255 if (request.ContainsKey("AccessToken"))
256 token = request["AccessToken"].ToString();
257
258 if (!m_GroupsService.AddAgentToGroup(requestingAgentID, agentID, groupID, roleID, token, out reason))
259 NullResult(result, reason);
260 else
261 {
262 GroupMembershipData membership = m_GroupsService.GetAgentGroupMembership(requestingAgentID, agentID, groupID);
263 if (membership == null)
264 NullResult(result, "Internal error");
265 else
266 result["RESULT"] = GroupsDataUtils.GroupMembershipData((ExtendedGroupMembershipData)membership);
267 }
268 }
269
270 string xmlString = ServerUtils.BuildXmlResponse(result);
271
272 //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
273 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
274 }
275
276 byte[] HandleRemoveAgentFromGroup(Dictionary<string, object> request)
277 {
278 Dictionary<string, object> result = new Dictionary<string, object>();
279
280 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AgentID") || !request.ContainsKey("GroupID"))
281 NullResult(result, "Bad network data");
282 else
283 {
284 UUID groupID = new UUID(request["GroupID"].ToString());
285 string agentID = request["AgentID"].ToString();
286 string requestingAgentID = request["RequestingAgentID"].ToString();
287
288 if (!m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID))
289 NullResult(result, string.Format("Insufficient permissions.", agentID));
290 else
291 result["RESULT"] = "true";
292 }
293
294 //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
295 return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
296 }
297
298 byte[] HandleGetMembership(Dictionary<string, object> request)
299 {
300 Dictionary<string, object> result = new Dictionary<string, object>();
301
302 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AgentID"))
303 NullResult(result, "Bad network data");
304 else
305 {
306 string agentID = request["AgentID"].ToString();
307 UUID groupID = UUID.Zero;
308 if (request.ContainsKey("GroupID"))
309 groupID = new UUID(request["GroupID"].ToString());
310 string requestingAgentID = request["RequestingAgentID"].ToString();
311 bool all = request.ContainsKey("ALL");
312
313 if (!all)
314 {
315 ExtendedGroupMembershipData membership = null;
316 if (groupID == UUID.Zero)
317 {
318 membership = m_GroupsService.GetAgentActiveMembership(requestingAgentID, agentID);
319 }
320 else
321 {
322 membership = m_GroupsService.GetAgentGroupMembership(requestingAgentID, agentID, groupID);
323 }
324
325 if (membership == null)
326 NullResult(result, "No such membership");
327 else
328 result["RESULT"] = GroupsDataUtils.GroupMembershipData(membership);
329 }
330 else
331 {
332 List<GroupMembershipData> memberships = m_GroupsService.GetAgentGroupMemberships(requestingAgentID, agentID);
333 if (memberships == null || (memberships != null && memberships.Count == 0))
334 {
335 NullResult(result, "No memberships");
336 }
337 else
338 {
339 Dictionary<string, object> dict = new Dictionary<string, object>();
340 int i = 0;
341 foreach (GroupMembershipData m in memberships)
342 dict["m-" + i++] = GroupsDataUtils.GroupMembershipData((ExtendedGroupMembershipData)m);
343
344 result["RESULT"] = dict;
345 }
346 }
347 }
348
349 string xmlString = ServerUtils.BuildXmlResponse(result);
350
351 //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
352 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
353 }
354
355 byte[] HandleGetGroupMembers(Dictionary<string, object> request)
356 {
357 Dictionary<string, object> result = new Dictionary<string, object>();
358
359 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID"))
360 NullResult(result, "Bad network data");
361 else
362 {
363 UUID groupID = new UUID(request["GroupID"].ToString());
364 string requestingAgentID = request["RequestingAgentID"].ToString();
365
366 List<ExtendedGroupMembersData> members = m_GroupsService.GetGroupMembers(requestingAgentID, groupID);
367 if (members == null || (members != null && members.Count == 0))
368 {
369 NullResult(result, "No members");
370 }
371 else
372 {
373 Dictionary<string, object> dict = new Dictionary<string, object>();
374 int i = 0;
375 foreach (ExtendedGroupMembersData m in members)
376 {
377 dict["m-" + i++] = GroupsDataUtils.GroupMembersData(m);
378 }
379
380 result["RESULT"] = dict;
381 }
382 }
383
384 string xmlString = ServerUtils.BuildXmlResponse(result);
385
386 //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
387 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
388 }
389
390 byte[] HandlePutRole(Dictionary<string, object> request)
391 {
392 Dictionary<string, object> result = new Dictionary<string, object>();
393
394 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID") ||
395 !request.ContainsKey("Name") || !request.ContainsKey("Description") || !request.ContainsKey("Title") ||
396 !request.ContainsKey("Powers") || !request.ContainsKey("OP"))
397 NullResult(result, "Bad network data");
398
399 else
400 {
401 string op = request["OP"].ToString();
402 string reason = string.Empty;
403
404 bool success = false;
405 if (op == "ADD")
406 success = m_GroupsService.AddGroupRole(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()),
407 new UUID(request["RoleID"].ToString()), request["Name"].ToString(), request["Description"].ToString(),
408 request["Title"].ToString(), UInt64.Parse(request["Powers"].ToString()), out reason);
409
410 else if (op == "UPDATE")
411 success = m_GroupsService.UpdateGroupRole(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()),
412 new UUID(request["RoleID"].ToString()), request["Name"].ToString(), request["Description"].ToString(),
413 request["Title"].ToString(), UInt64.Parse(request["Powers"].ToString()));
414
415 result["RESULT"] = success.ToString();
416 }
417
418 string xmlString = ServerUtils.BuildXmlResponse(result);
419
420 //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
421 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
422 }
423
424 byte[] HandleRemoveRole(Dictionary<string, object> request)
425 {
426 Dictionary<string, object> result = new Dictionary<string, object>();
427
428 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID"))
429 NullResult(result, "Bad network data");
430
431 else
432 {
433 m_GroupsService.RemoveGroupRole(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()),
434 new UUID(request["RoleID"].ToString()));
435 result["RESULT"] = "true";
436 }
437
438 //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
439 return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
440 }
441
442 byte[] HandleGetGroupRoles(Dictionary<string, object> request)
443 {
444 Dictionary<string, object> result = new Dictionary<string, object>();
445
446 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID"))
447 NullResult(result, "Bad network data");
448 else
449 {
450 UUID groupID = new UUID(request["GroupID"].ToString());
451 string requestingAgentID = request["RequestingAgentID"].ToString();
452
453 List<GroupRolesData> roles = m_GroupsService.GetGroupRoles(requestingAgentID, groupID);
454 if (roles == null || (roles != null && roles.Count == 0))
455 {
456 NullResult(result, "No members");
457 }
458 else
459 {
460 Dictionary<string, object> dict = new Dictionary<string, object>();
461 int i = 0;
462 foreach (GroupRolesData r in roles)
463 dict["r-" + i++] = GroupsDataUtils.GroupRolesData(r);
464
465 result["RESULT"] = dict;
466 }
467 }
468
469 string xmlString = ServerUtils.BuildXmlResponse(result);
470
471 //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
472 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
473 }
474
475 byte[] HandleGetRoleMembers(Dictionary<string, object> request)
476 {
477 Dictionary<string, object> result = new Dictionary<string, object>();
478
479 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID"))
480 NullResult(result, "Bad network data");
481 else
482 {
483 UUID groupID = new UUID(request["GroupID"].ToString());
484 string requestingAgentID = request["RequestingAgentID"].ToString();
485
486 List<ExtendedGroupRoleMembersData> rmembers = m_GroupsService.GetGroupRoleMembers(requestingAgentID, groupID);
487 if (rmembers == null || (rmembers != null && rmembers.Count == 0))
488 {
489 NullResult(result, "No members");
490 }
491 else
492 {
493 Dictionary<string, object> dict = new Dictionary<string, object>();
494 int i = 0;
495 foreach (ExtendedGroupRoleMembersData rm in rmembers)
496 dict["rm-" + i++] = GroupsDataUtils.GroupRoleMembersData(rm);
497
498 result["RESULT"] = dict;
499 }
500 }
501
502 string xmlString = ServerUtils.BuildXmlResponse(result);
503
504 //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
505 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
506 }
507
508 byte[] HandleAgentRole(Dictionary<string, object> request)
509 {
510 Dictionary<string, object> result = new Dictionary<string, object>();
511
512 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID") ||
513 !request.ContainsKey("AgentID") || !request.ContainsKey("OP"))
514 NullResult(result, "Bad network data");
515
516 else
517 {
518 string op = request["OP"].ToString();
519
520 bool success = false;
521 if (op == "ADD")
522 success = m_GroupsService.AddAgentToGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(),
523 new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString()));
524
525 else if (op == "DELETE")
526 success = m_GroupsService.RemoveAgentFromGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(),
527 new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString()));
528
529 result["RESULT"] = success.ToString();
530 }
531
532 string xmlString = ServerUtils.BuildXmlResponse(result);
533
534 //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
535 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
536 }
537
538 byte[] HandleGetAgentRoles(Dictionary<string, object> request)
539 {
540 Dictionary<string, object> result = new Dictionary<string, object>();
541
542 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("AgentID"))
543 NullResult(result, "Bad network data");
544 else
545 {
546 UUID groupID = new UUID(request["GroupID"].ToString());
547 string agentID = request["AgentID"].ToString();
548 string requestingAgentID = request["RequestingAgentID"].ToString();
549
550 List<GroupRolesData> roles = m_GroupsService.GetAgentGroupRoles(requestingAgentID, agentID, groupID);
551 if (roles == null || (roles != null && roles.Count == 0))
552 {
553 NullResult(result, "No members");
554 }
555 else
556 {
557 Dictionary<string, object> dict = new Dictionary<string, object>();
558 int i = 0;
559 foreach (GroupRolesData r in roles)
560 dict["r-" + i++] = GroupsDataUtils.GroupRolesData(r);
561
562 result["RESULT"] = dict;
563 }
564 }
565
566 string xmlString = ServerUtils.BuildXmlResponse(result);
567
568 //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
569 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
570 }
571
572 byte[] HandleSetActive(Dictionary<string, object> request)
573 {
574 Dictionary<string, object> result = new Dictionary<string, object>();
575
576 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") ||
577 !request.ContainsKey("AgentID") || !request.ContainsKey("OP"))
578 {
579 NullResult(result, "Bad network data");
580 string xmlString = ServerUtils.BuildXmlResponse(result);
581 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
582 }
583 else
584 {
585 string op = request["OP"].ToString();
586
587 if (op == "GROUP")
588 {
589 ExtendedGroupMembershipData group = m_GroupsService.SetAgentActiveGroup(request["RequestingAgentID"].ToString(),
590 request["AgentID"].ToString(), new UUID(request["GroupID"].ToString()));
591
592 if (group == null)
593 NullResult(result, "Internal error");
594 else
595 result["RESULT"] = GroupsDataUtils.GroupMembershipData(group);
596
597 string xmlString = ServerUtils.BuildXmlResponse(result);
598
599 //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
600 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
601
602 }
603 else if (op == "ROLE" && request.ContainsKey("RoleID"))
604 {
605 m_GroupsService.SetAgentActiveGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(),
606 new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString()));
607 result["RESULT"] = "true";
608 }
609
610 return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
611 }
612
613 }
614
615 byte[] HandleUpdateMembership(Dictionary<string, object> request)
616 {
617 Dictionary<string, object> result = new Dictionary<string, object>();
618
619 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AgentID") || !request.ContainsKey("GroupID") ||
620 !request.ContainsKey("AcceptNotices") || !request.ContainsKey("ListInProfile"))
621 NullResult(result, "Bad network data");
622
623 else
624 {
625 m_GroupsService.UpdateMembership(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(), new UUID(request["GroupID"].ToString()),
626 bool.Parse(request["AcceptNotices"].ToString()), bool.Parse(request["ListInProfile"].ToString()));
627
628 result["RESULT"] = "true";
629 }
630
631 //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
632 return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
633 }
634
635 byte[] HandleInvite(Dictionary<string, object> request)
636 {
637 Dictionary<string, object> result = new Dictionary<string, object>();
638
639 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("InviteID"))
640 {
641 NullResult(result, "Bad network data");
642 string xmlString = ServerUtils.BuildXmlResponse(result);
643 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
644 }
645 else
646 {
647 string op = request["OP"].ToString();
648
649 if (op == "ADD" && request.ContainsKey("GroupID") && request.ContainsKey("RoleID") && request.ContainsKey("AgentID"))
650 {
651 bool success = m_GroupsService.AddAgentToGroupInvite(request["RequestingAgentID"].ToString(),
652 new UUID(request["InviteID"].ToString()), new UUID(request["GroupID"].ToString()),
653 new UUID(request["RoleID"].ToString()), request["AgentID"].ToString());
654
655 result["RESULT"] = success.ToString();
656 return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
657
658 }
659 else if (op == "DELETE")
660 {
661 m_GroupsService.RemoveAgentToGroupInvite(request["RequestingAgentID"].ToString(), new UUID(request["InviteID"].ToString()));
662 result["RESULT"] = "true";
663 return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
664 }
665 else if (op == "GET")
666 {
667 GroupInviteInfo invite = m_GroupsService.GetAgentToGroupInvite(request["RequestingAgentID"].ToString(),
668 new UUID(request["InviteID"].ToString()));
669
670 if (invite != null)
671 result["RESULT"] = GroupsDataUtils.GroupInviteInfo(invite);
672 else
673 result["RESULT"] = "NULL";
674
675 return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
676 }
677
678 NullResult(result, "Bad OP in request");
679 return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
680 }
681
682 }
683
684 byte[] HandleAddNotice(Dictionary<string, object> request)
685 {
686 Dictionary<string, object> result = new Dictionary<string, object>();
687
688 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("NoticeID") ||
689 !request.ContainsKey("FromName") || !request.ContainsKey("Subject") || !request.ContainsKey("Message") ||
690 !request.ContainsKey("HasAttachment"))
691 NullResult(result, "Bad network data");
692
693 else
694 {
695
696 bool hasAtt = bool.Parse(request["HasAttachment"].ToString());
697 byte attType = 0;
698 string attName = string.Empty;
699 string attOwner = string.Empty;
700 UUID attItem = UUID.Zero;
701 if (request.ContainsKey("AttachmentType"))
702 attType = byte.Parse(request["AttachmentType"].ToString());
703 if (request.ContainsKey("AttachmentName"))
704 attName = request["AttachmentName"].ToString();
705 if (request.ContainsKey("AttachmentItemID"))
706 attItem = new UUID(request["AttachmentItemID"].ToString());
707 if (request.ContainsKey("AttachmentOwnerID"))
708 attOwner = request["AttachmentOwnerID"].ToString();
709
710 bool success = m_GroupsService.AddGroupNotice(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()),
711 new UUID(request["NoticeID"].ToString()), request["FromName"].ToString(), request["Subject"].ToString(),
712 request["Message"].ToString(), hasAtt, attType, attName, attItem, attOwner);
713
714 result["RESULT"] = success.ToString();
715 }
716
717 string xmlString = ServerUtils.BuildXmlResponse(result);
718
719 //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
720 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
721 }
722
723 byte[] HandleGetNotices(Dictionary<string, object> request)
724 {
725 Dictionary<string, object> result = new Dictionary<string, object>();
726
727 if (!request.ContainsKey("RequestingAgentID"))
728 NullResult(result, "Bad network data");
729
730 else if (request.ContainsKey("NoticeID")) // just one
731 {
732 GroupNoticeInfo notice = m_GroupsService.GetGroupNotice(request["RequestingAgentID"].ToString(), new UUID(request["NoticeID"].ToString()));
733
734 if (notice == null)
735 NullResult(result, "NO such notice");
736 else
737 result["RESULT"] = GroupsDataUtils.GroupNoticeInfo(notice);
738
739 }
740 else if (request.ContainsKey("GroupID")) // all notices for group
741 {
742 List<ExtendedGroupNoticeData> notices = m_GroupsService.GetGroupNotices(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()));
743
744 if (notices == null || (notices != null && notices.Count == 0))
745 NullResult(result, "No notices");
746 else
747 {
748 Dictionary<string, object> dict = new Dictionary<string, object>();
749 int i = 0;
750 foreach (ExtendedGroupNoticeData n in notices)
751 dict["n-" + i++] = GroupsDataUtils.GroupNoticeData(n);
752
753 result["RESULT"] = dict;
754 }
755
756 }
757 else
758 NullResult(result, "Bad OP in request");
759
760 string xmlString = ServerUtils.BuildXmlResponse(result);
761 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
762 }
763
764 byte[] HandleFindGroups(Dictionary<string, object> request)
765 {
766 Dictionary<string, object> result = new Dictionary<string, object>();
767
768 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("Query"))
769 NullResult(result, "Bad network data");
770
771 List<DirGroupsReplyData> hits = m_GroupsService.FindGroups(request["RequestingAgentID"].ToString(), request["Query"].ToString());
772
773 if (hits == null || (hits != null && hits.Count == 0))
774 NullResult(result, "No hits");
775 else
776 {
777 Dictionary<string, object> dict = new Dictionary<string, object>();
778 int i = 0;
779 foreach (DirGroupsReplyData n in hits)
780 dict["n-" + i++] = GroupsDataUtils.DirGroupsReplyData(n);
781
782 result["RESULT"] = dict;
783 }
784
785
786 string xmlString = ServerUtils.BuildXmlResponse(result);
787 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
788 }
789
790
791 #region Helpers
792
793 private void NullResult(Dictionary<string, object> result, string reason)
794 {
795 result["RESULT"] = "NULL";
796 result["REASON"] = reason;
797 }
798
799 private byte[] FailureResult()
800 {
801 Dictionary<string, object> result = new Dictionary<string, object>();
802 NullResult(result, "Unknown method");
803 string xmlString = ServerUtils.BuildXmlResponse(result);
804 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
805 }
806
807 private byte[] FailureResult(string reason)
808 {
809 Dictionary<string, object> result = new Dictionary<string, object>();
810 NullResult(result, reason);
811 string xmlString = ServerUtils.BuildXmlResponse(result);
812 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
813 }
814 #endregion
815 }
816}
diff --git a/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs b/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs
new file mode 100644
index 0000000..813f796
--- /dev/null
+++ b/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs
@@ -0,0 +1,888 @@
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 System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Threading;
32
33using OpenSim.Framework;
34//using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Services.Interfaces;
36
37using OpenMetaverse;
38
39namespace OpenSim.Groups
40{
41 public delegate ExtendedGroupRecord GroupRecordDelegate();
42 public delegate GroupMembershipData GroupMembershipDelegate();
43 public delegate List<GroupMembershipData> GroupMembershipListDelegate();
44 public delegate List<ExtendedGroupMembersData> GroupMembersListDelegate();
45 public delegate List<GroupRolesData> GroupRolesListDelegate();
46 public delegate List<ExtendedGroupRoleMembersData> RoleMembersListDelegate();
47 public delegate GroupNoticeInfo NoticeDelegate();
48 public delegate List<ExtendedGroupNoticeData> NoticeListDelegate();
49 public delegate void VoidDelegate();
50 public delegate bool BooleanDelegate();
51
52 public class RemoteConnectorCacheWrapper
53 {
54 private ForeignImporter m_ForeignImporter;
55
56 private Dictionary<string, bool> m_ActiveRequests = new Dictionary<string, bool>();
57 private const int GROUPS_CACHE_TIMEOUT = 1 * 60; // 1 minutes
58
59 // This all important cache cahces objects of different types:
60 // group-<GroupID> or group-<Name> => ExtendedGroupRecord
61 // active-<AgentID> => GroupMembershipData
62 // membership-<AgentID>-<GroupID> => GroupMembershipData
63 // memberships-<AgentID> => List<GroupMembershipData>
64 // members-<RequestingAgentID>-<GroupID> => List<ExtendedGroupMembersData>
65 // role-<RoleID> => GroupRolesData
66 // roles-<GroupID> => List<GroupRolesData> ; all roles in the group
67 // roles-<GroupID>-<AgentID> => List<GroupRolesData> ; roles that the agent has
68 // rolemembers-<RequestingAgentID>-<GroupID> => List<ExtendedGroupRoleMembersData>
69 // notice-<noticeID> => GroupNoticeInfo
70 // notices-<GroupID> => List<ExtendedGroupNoticeData>
71 private ExpiringCache<string, object> m_Cache = new ExpiringCache<string, object>();
72
73 public RemoteConnectorCacheWrapper(IUserManagement uman)
74 {
75 m_ForeignImporter = new ForeignImporter(uman);
76 }
77
78 public UUID CreateGroup(UUID RequestingAgentID, GroupRecordDelegate d)
79 {
80 //m_log.DebugFormat("[Groups.RemoteConnector]: Creating group {0}", name);
81 //reason = string.Empty;
82
83 //ExtendedGroupRecord group = m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID,
84 // membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
85 ExtendedGroupRecord group = d();
86
87 if (group == null)
88 return UUID.Zero;
89
90 if (group.GroupID != UUID.Zero)
91 lock (m_Cache)
92 {
93 m_Cache.Add("group-" + group.GroupID.ToString(), group, GROUPS_CACHE_TIMEOUT);
94 if (m_Cache.Contains("memberships-" + RequestingAgentID.ToString()))
95 m_Cache.Remove("memberships-" + RequestingAgentID.ToString());
96 }
97
98 return group.GroupID;
99 }
100
101 public bool UpdateGroup(UUID groupID, GroupRecordDelegate d)
102 {
103 //reason = string.Empty;
104 //ExtendedGroupRecord group = m_GroupsService.UpdateGroup(RequestingAgentID, groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish);
105 ExtendedGroupRecord group = d();
106
107 if (group != null && group.GroupID != UUID.Zero)
108 lock (m_Cache)
109 m_Cache.AddOrUpdate("group-" + group.GroupID.ToString(), group, GROUPS_CACHE_TIMEOUT);
110 return true;
111 }
112
113 public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName, GroupRecordDelegate d)
114 {
115 //if (GroupID == UUID.Zero && (GroupName == null || GroupName != null && GroupName == string.Empty))
116 // return null;
117
118 object group = null;
119 bool firstCall = false;
120 string cacheKey = "group-";
121 if (GroupID != UUID.Zero)
122 cacheKey += GroupID.ToString();
123 else
124 cacheKey += GroupName;
125
126 //m_log.DebugFormat("[XXX]: GetGroupRecord {0}", cacheKey);
127
128 while (true)
129 {
130 lock (m_Cache)
131 {
132 if (m_Cache.TryGetValue(cacheKey, out group))
133 {
134 //m_log.DebugFormat("[XXX]: GetGroupRecord {0} cached!", cacheKey);
135 return (ExtendedGroupRecord)group;
136 }
137
138 // not cached
139 if (!m_ActiveRequests.ContainsKey(cacheKey))
140 {
141 m_ActiveRequests.Add(cacheKey, true);
142 firstCall = true;
143 }
144 }
145
146 if (firstCall)
147 {
148 try
149 {
150 //group = m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName);
151 group = d();
152
153 lock (m_Cache)
154 {
155 m_Cache.AddOrUpdate(cacheKey, group, GROUPS_CACHE_TIMEOUT);
156 return (ExtendedGroupRecord)group;
157 }
158 }
159 finally
160 {
161 m_ActiveRequests.Remove(cacheKey);
162 }
163 }
164 else
165 Thread.Sleep(50);
166 }
167 }
168
169 public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, GroupMembershipDelegate d)
170 {
171 GroupMembershipData membership = d();
172 if (membership == null)
173 return false;
174
175 lock (m_Cache)
176 {
177 // first, remove everything! add a user is a heavy-duty op
178 m_Cache.Clear();
179
180 m_Cache.AddOrUpdate("active-" + AgentID.ToString(), membership, GROUPS_CACHE_TIMEOUT);
181 m_Cache.AddOrUpdate("membership-" + AgentID.ToString() + "-" + GroupID.ToString(), membership, GROUPS_CACHE_TIMEOUT);
182 }
183
184
185 return true;
186 }
187
188 public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, VoidDelegate d)
189 {
190 d();
191
192 lock (m_Cache)
193 {
194 string cacheKey = "active-" + AgentID.ToString();
195 if (m_Cache.Contains(cacheKey))
196 m_Cache.Remove(cacheKey);
197
198 cacheKey = "memberships-" + AgentID.ToString();
199 if (m_Cache.Contains(cacheKey))
200 m_Cache.Remove(cacheKey);
201
202 cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
203 if (m_Cache.Contains(cacheKey))
204 m_Cache.Remove(cacheKey);
205
206 cacheKey = "members-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
207 if (m_Cache.Contains(cacheKey))
208 m_Cache.Remove(cacheKey);
209
210 cacheKey = "roles-" + "-" + GroupID.ToString() + "-" + AgentID.ToString();
211 if (m_Cache.Contains(cacheKey))
212 m_Cache.Remove(cacheKey);
213 }
214 }
215
216 public void SetAgentActiveGroup(string AgentID, GroupMembershipDelegate d)
217 {
218 GroupMembershipData activeGroup = d();
219 string cacheKey = "active-" + AgentID.ToString();
220 lock (m_Cache)
221 if (m_Cache.Contains(cacheKey))
222 m_Cache.AddOrUpdate(cacheKey, activeGroup, GROUPS_CACHE_TIMEOUT);
223 }
224
225 public ExtendedGroupMembershipData GetAgentActiveMembership(string AgentID, GroupMembershipDelegate d)
226 {
227 object membership = null;
228 bool firstCall = false;
229 string cacheKey = "active-" + AgentID.ToString();
230
231 //m_log.DebugFormat("[XXX]: GetAgentActiveMembership {0}", cacheKey);
232
233 while (true)
234 {
235 lock (m_Cache)
236 {
237 if (m_Cache.TryGetValue(cacheKey, out membership))
238 {
239 //m_log.DebugFormat("[XXX]: GetAgentActiveMembership {0} cached!", cacheKey);
240 return (ExtendedGroupMembershipData)membership;
241 }
242
243 // not cached
244 if (!m_ActiveRequests.ContainsKey(cacheKey))
245 {
246 m_ActiveRequests.Add(cacheKey, true);
247 firstCall = true;
248 }
249 }
250
251 if (firstCall)
252 {
253 try
254 {
255 membership = d();
256
257 lock (m_Cache)
258 {
259 m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
260 return (ExtendedGroupMembershipData)membership;
261 }
262 }
263 finally
264 {
265 m_ActiveRequests.Remove(cacheKey);
266 }
267 }
268 else
269 Thread.Sleep(50);
270 }
271
272 }
273
274 public ExtendedGroupMembershipData GetAgentGroupMembership(string AgentID, UUID GroupID, GroupMembershipDelegate d)
275 {
276 object membership = null;
277 bool firstCall = false;
278 string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
279
280 //m_log.DebugFormat("[XXX]: GetAgentGroupMembership {0}", cacheKey);
281
282 while (true)
283 {
284 lock (m_Cache)
285 {
286 if (m_Cache.TryGetValue(cacheKey, out membership))
287 {
288 //m_log.DebugFormat("[XXX]: GetAgentGroupMembership {0}", cacheKey);
289 return (ExtendedGroupMembershipData)membership;
290 }
291
292 // not cached
293 if (!m_ActiveRequests.ContainsKey(cacheKey))
294 {
295 m_ActiveRequests.Add(cacheKey, true);
296 firstCall = true;
297 }
298 }
299
300 if (firstCall)
301 {
302 try
303 {
304 membership = d();
305 lock (m_Cache)
306 {
307 m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
308 return (ExtendedGroupMembershipData)membership;
309 }
310 }
311 finally
312 {
313 m_ActiveRequests.Remove(cacheKey);
314 }
315 }
316 else
317 Thread.Sleep(50);
318 }
319 }
320
321 public List<GroupMembershipData> GetAgentGroupMemberships(string AgentID, GroupMembershipListDelegate d)
322 {
323 object memberships = null;
324 bool firstCall = false;
325 string cacheKey = "memberships-" + AgentID.ToString();
326
327 //m_log.DebugFormat("[XXX]: GetAgentGroupMemberships {0}", cacheKey);
328
329 while (true)
330 {
331 lock (m_Cache)
332 {
333 if (m_Cache.TryGetValue(cacheKey, out memberships))
334 {
335 //m_log.DebugFormat("[XXX]: GetAgentGroupMemberships {0} cached!", cacheKey);
336 return (List<GroupMembershipData>)memberships;
337 }
338
339 // not cached
340 if (!m_ActiveRequests.ContainsKey(cacheKey))
341 {
342 m_ActiveRequests.Add(cacheKey, true);
343 firstCall = true;
344 }
345 }
346
347 if (firstCall)
348 {
349 try
350 {
351 memberships = d();
352 lock (m_Cache)
353 {
354 m_Cache.AddOrUpdate(cacheKey, memberships, GROUPS_CACHE_TIMEOUT);
355 return (List<GroupMembershipData>)memberships;
356 }
357 }
358 finally
359 {
360 m_ActiveRequests.Remove(cacheKey);
361 }
362 }
363 else
364 Thread.Sleep(50);
365 }
366 }
367
368 public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID, GroupMembersListDelegate d)
369 {
370 object members = null;
371 bool firstCall = false;
372 // we need to key in also on the requester, because different ppl have different view privileges
373 string cacheKey = "members-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
374
375 //m_log.DebugFormat("[XXX]: GetGroupMembers {0}", cacheKey);
376
377 while (true)
378 {
379 lock (m_Cache)
380 {
381 if (m_Cache.TryGetValue(cacheKey, out members))
382 {
383 List<ExtendedGroupMembersData> xx = (List<ExtendedGroupMembersData>)members;
384 return xx.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData));
385 }
386
387 // not cached
388 if (!m_ActiveRequests.ContainsKey(cacheKey))
389 {
390 m_ActiveRequests.Add(cacheKey, true);
391 firstCall = true;
392 }
393 }
394
395 if (firstCall)
396 {
397 try
398 {
399 List<ExtendedGroupMembersData> _members = d();
400
401 if (_members != null && _members.Count > 0)
402 members = _members.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData));
403 else
404 members = new List<GroupMembersData>();
405
406 lock (m_Cache)
407 {
408 //m_Cache.AddOrUpdate(cacheKey, members, GROUPS_CACHE_TIMEOUT);
409 m_Cache.AddOrUpdate(cacheKey, _members, GROUPS_CACHE_TIMEOUT);
410
411 return (List<GroupMembersData>)members;
412 }
413 }
414 finally
415 {
416 m_ActiveRequests.Remove(cacheKey);
417 }
418 }
419 else
420 Thread.Sleep(50);
421 }
422 }
423
424 public bool AddGroupRole(UUID groupID, UUID roleID, string description, string name, ulong powers, string title, BooleanDelegate d)
425 {
426 if (d())
427 {
428 GroupRolesData role = new GroupRolesData();
429 role.Description = description;
430 role.Members = 0;
431 role.Name = name;
432 role.Powers = powers;
433 role.RoleID = roleID;
434 role.Title = title;
435
436 lock (m_Cache)
437 {
438 m_Cache.AddOrUpdate("role-" + roleID.ToString(), role, GROUPS_CACHE_TIMEOUT);
439
440 // also remove this list
441 if (m_Cache.Contains("roles-" + groupID.ToString()))
442 m_Cache.Remove("roles-" + groupID.ToString());
443
444 }
445
446 return true;
447 }
448
449 return false;
450 }
451
452 public bool UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers, BooleanDelegate d)
453 {
454 if (d())
455 {
456 object role;
457 lock (m_Cache)
458 if (m_Cache.TryGetValue("role-" + roleID.ToString(), out role))
459 {
460 GroupRolesData r = (GroupRolesData)role;
461 r.Description = description;
462 r.Name = name;
463 r.Powers = powers;
464 r.Title = title;
465
466 m_Cache.Update("role-" + roleID.ToString(), r, GROUPS_CACHE_TIMEOUT);
467 }
468 return true;
469 }
470 else
471 {
472 lock (m_Cache)
473 {
474 if (m_Cache.Contains("role-" + roleID.ToString()))
475 m_Cache.Remove("role-" + roleID.ToString());
476
477 // also remove these lists, because they will have an outdated role
478 if (m_Cache.Contains("roles-" + groupID.ToString()))
479 m_Cache.Remove("roles-" + groupID.ToString());
480
481 }
482
483 return false;
484 }
485 }
486
487 public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, VoidDelegate d)
488 {
489 d();
490
491 lock (m_Cache)
492 {
493 if (m_Cache.Contains("role-" + roleID.ToString()))
494 m_Cache.Remove("role-" + roleID.ToString());
495
496 // also remove the list, because it will have an removed role
497 if (m_Cache.Contains("roles-" + groupID.ToString()))
498 m_Cache.Remove("roles-" + groupID.ToString());
499
500 if (m_Cache.Contains("roles-" + groupID.ToString() + "-" + RequestingAgentID.ToString()))
501 m_Cache.Remove("roles-" + groupID.ToString() + "-" + RequestingAgentID.ToString());
502
503 if (m_Cache.Contains("rolemembers-" + RequestingAgentID.ToString() + "-" + groupID.ToString()))
504 m_Cache.Remove("rolemembers-" + RequestingAgentID.ToString() + "-" + groupID.ToString());
505 }
506 }
507
508 public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID, GroupRolesListDelegate d)
509 {
510 object roles = null;
511 bool firstCall = false;
512 string cacheKey = "roles-" + GroupID.ToString();
513
514 while (true)
515 {
516 lock (m_Cache)
517 {
518 if (m_Cache.TryGetValue(cacheKey, out roles))
519 return (List<GroupRolesData>)roles;
520
521 // not cached
522 if (!m_ActiveRequests.ContainsKey(cacheKey))
523 {
524 m_ActiveRequests.Add(cacheKey, true);
525 firstCall = true;
526 }
527 }
528
529 if (firstCall)
530 {
531 try
532 {
533 roles = d();
534 if (roles != null)
535 {
536 lock (m_Cache)
537 {
538 m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
539 return (List<GroupRolesData>)roles;
540 }
541 }
542 }
543 finally
544 {
545 m_ActiveRequests.Remove(cacheKey);
546 }
547 }
548 else
549 Thread.Sleep(50);
550 }
551 }
552
553 public List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID, RoleMembersListDelegate d)
554 {
555 object rmembers = null;
556 bool firstCall = false;
557 // we need to key in also on the requester, because different ppl have different view privileges
558 string cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
559
560 //m_log.DebugFormat("[XXX]: GetGroupRoleMembers {0}", cacheKey);
561 while (true)
562 {
563 lock (m_Cache)
564 {
565 if (m_Cache.TryGetValue(cacheKey, out rmembers))
566 {
567 List<ExtendedGroupRoleMembersData> xx = (List<ExtendedGroupRoleMembersData>)rmembers;
568 return xx.ConvertAll<GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData);
569 }
570
571 // not cached
572 if (!m_ActiveRequests.ContainsKey(cacheKey))
573 {
574 m_ActiveRequests.Add(cacheKey, true);
575 firstCall = true;
576 }
577 }
578
579 if (firstCall)
580 {
581 try
582 {
583 List<ExtendedGroupRoleMembersData> _rmembers = d();
584
585 if (_rmembers != null && _rmembers.Count > 0)
586 rmembers = _rmembers.ConvertAll<GroupRoleMembersData>(new Converter<ExtendedGroupRoleMembersData, GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData));
587 else
588 rmembers = new List<GroupRoleMembersData>();
589
590 lock (m_Cache)
591 {
592 // For some strange reason, when I cache the list of GroupRoleMembersData,
593 // it gets emptied out. The TryGet gets an empty list...
594 //m_Cache.AddOrUpdate(cacheKey, rmembers, GROUPS_CACHE_TIMEOUT);
595 // Caching the list of ExtendedGroupRoleMembersData doesn't show that issue
596 // I don't get it.
597 m_Cache.AddOrUpdate(cacheKey, _rmembers, GROUPS_CACHE_TIMEOUT);
598 return (List<GroupRoleMembersData>)rmembers;
599 }
600 }
601 finally
602 {
603 m_ActiveRequests.Remove(cacheKey);
604 }
605 }
606 else
607 Thread.Sleep(50);
608 }
609 }
610
611 public void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, BooleanDelegate d)
612 {
613 if (d())
614 {
615 lock (m_Cache)
616 {
617 // update the cached role
618 string cacheKey = "role-" + RoleID.ToString();
619 object obj;
620 if (m_Cache.TryGetValue(cacheKey, out obj))
621 {
622 GroupRolesData r = (GroupRolesData)obj;
623 r.Members++;
624 }
625
626 // add this agent to the list of role members
627 cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
628 if (m_Cache.TryGetValue(cacheKey, out obj))
629 {
630 try
631 {
632 // This may throw an exception, in which case the agentID is not a UUID but a full ID
633 // In that case, let's just remove the whoe things from the cache
634 UUID id = new UUID(AgentID);
635 List<ExtendedGroupRoleMembersData> xx = (List<ExtendedGroupRoleMembersData>)obj;
636 List<GroupRoleMembersData> rmlist = xx.ConvertAll<GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData);
637 GroupRoleMembersData rm = new GroupRoleMembersData();
638 rm.MemberID = id;
639 rm.RoleID = RoleID;
640 rmlist.Add(rm);
641 }
642 catch
643 {
644 m_Cache.Remove(cacheKey);
645 }
646 }
647
648 // Remove the cached info about this agent's roles
649 // because we don't have enough local info about the new role
650 cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
651 if (m_Cache.Contains(cacheKey))
652 m_Cache.Remove(cacheKey);
653
654 }
655 }
656 }
657
658 public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, BooleanDelegate d)
659 {
660 if (d())
661 {
662 lock (m_Cache)
663 {
664 // update the cached role
665 string cacheKey = "role-" + RoleID.ToString();
666 object obj;
667 if (m_Cache.TryGetValue(cacheKey, out obj))
668 {
669 GroupRolesData r = (GroupRolesData)obj;
670 r.Members--;
671 }
672
673 cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
674 if (m_Cache.Contains(cacheKey))
675 m_Cache.Remove(cacheKey);
676
677 cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
678 if (m_Cache.Contains(cacheKey))
679 m_Cache.Remove(cacheKey);
680 }
681 }
682 }
683
684 public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID, GroupRolesListDelegate d)
685 {
686 object roles = null;
687 bool firstCall = false;
688 string cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
689
690 //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0}", cacheKey);
691
692 while (true)
693 {
694 lock (m_Cache)
695 {
696 if (m_Cache.TryGetValue(cacheKey, out roles))
697 {
698 //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0} cached!", cacheKey);
699 return (List<GroupRolesData>)roles;
700 }
701
702 // not cached
703 if (!m_ActiveRequests.ContainsKey(cacheKey))
704 {
705 m_ActiveRequests.Add(cacheKey, true);
706 firstCall = true;
707 }
708 }
709
710 if (firstCall)
711 {
712 try
713 {
714 roles = d();
715 lock (m_Cache)
716 {
717 m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
718 m_ActiveRequests.Remove(cacheKey);
719 return (List<GroupRolesData>)roles;
720 }
721 }
722 finally
723 {
724 m_ActiveRequests.Remove(cacheKey);
725 }
726 }
727 else
728 Thread.Sleep(50);
729 }
730 }
731
732 public void SetAgentActiveGroupRole(string AgentID, UUID GroupID, VoidDelegate d)
733 {
734 d();
735
736 lock (m_Cache)
737 {
738 // Invalidate cached info, because it has ActiveRoleID and Powers
739 string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
740 if (m_Cache.Contains(cacheKey))
741 m_Cache.Remove(cacheKey);
742
743 cacheKey = "memberships-" + AgentID.ToString();
744 if (m_Cache.Contains(cacheKey))
745 m_Cache.Remove(cacheKey);
746 }
747 }
748
749 public void UpdateMembership(string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile, VoidDelegate d)
750 {
751 d();
752
753 lock (m_Cache)
754 {
755 string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
756 if (m_Cache.Contains(cacheKey))
757 m_Cache.Remove(cacheKey);
758
759 cacheKey = "memberships-" + AgentID.ToString();
760 if (m_Cache.Contains(cacheKey))
761 m_Cache.Remove(cacheKey);
762
763 cacheKey = "active-" + AgentID.ToString();
764 object m = null;
765 if (m_Cache.TryGetValue(cacheKey, out m))
766 {
767 GroupMembershipData membership = (GroupMembershipData)m;
768 membership.ListInProfile = ListInProfile;
769 membership.AcceptNotices = AcceptNotices;
770 }
771 }
772 }
773
774 public bool AddGroupNotice(UUID groupID, UUID noticeID, GroupNoticeInfo notice, BooleanDelegate d)
775 {
776 if (d())
777 {
778 lock (m_Cache)
779 {
780 m_Cache.AddOrUpdate("notice-" + noticeID.ToString(), notice, GROUPS_CACHE_TIMEOUT);
781 string cacheKey = "notices-" + groupID.ToString();
782 if (m_Cache.Contains(cacheKey))
783 m_Cache.Remove(cacheKey);
784
785 }
786
787 return true;
788 }
789
790 return false;
791 }
792
793 public GroupNoticeInfo GetGroupNotice(UUID noticeID, NoticeDelegate d)
794 {
795 object notice = null;
796 bool firstCall = false;
797 string cacheKey = "notice-" + noticeID.ToString();
798
799 //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0}", cacheKey);
800
801 while (true)
802 {
803 lock (m_Cache)
804 {
805 if (m_Cache.TryGetValue(cacheKey, out notice))
806 {
807 return (GroupNoticeInfo)notice;
808 }
809
810 // not cached
811 if (!m_ActiveRequests.ContainsKey(cacheKey))
812 {
813 m_ActiveRequests.Add(cacheKey, true);
814 firstCall = true;
815 }
816 }
817
818 if (firstCall)
819 {
820 try
821 {
822 GroupNoticeInfo _notice = d();
823
824 lock (m_Cache)
825 {
826 m_Cache.AddOrUpdate(cacheKey, _notice, GROUPS_CACHE_TIMEOUT);
827 return _notice;
828 }
829 }
830 finally
831 {
832 m_ActiveRequests.Remove(cacheKey);
833 }
834 }
835 else
836 Thread.Sleep(50);
837 }
838 }
839
840 public List<ExtendedGroupNoticeData> GetGroupNotices(UUID GroupID, NoticeListDelegate d)
841 {
842 object notices = null;
843 bool firstCall = false;
844 string cacheKey = "notices-" + GroupID.ToString();
845
846 //m_log.DebugFormat("[XXX]: GetGroupNotices {0}", cacheKey);
847
848 while (true)
849 {
850 lock (m_Cache)
851 {
852 if (m_Cache.TryGetValue(cacheKey, out notices))
853 {
854 //m_log.DebugFormat("[XXX]: GetGroupNotices {0} cached!", cacheKey);
855 return (List<ExtendedGroupNoticeData>)notices;
856 }
857
858 // not cached
859 if (!m_ActiveRequests.ContainsKey(cacheKey))
860 {
861 m_ActiveRequests.Add(cacheKey, true);
862 firstCall = true;
863 }
864 }
865
866 if (firstCall)
867 {
868 try
869 {
870 notices = d();
871
872 lock (m_Cache)
873 {
874 m_Cache.AddOrUpdate(cacheKey, notices, GROUPS_CACHE_TIMEOUT);
875 return (List<ExtendedGroupNoticeData>)notices;
876 }
877 }
878 finally
879 {
880 m_ActiveRequests.Remove(cacheKey);
881 }
882 }
883 else
884 Thread.Sleep(50);
885 }
886 }
887 }
888} \ No newline at end of file