OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
EstateDataConnector.cs
Go to the documentation of this file.
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 using System;
28 using System.Collections.Generic;
29 using System.Net;
30 using System.Reflection;
31 
32 using log4net;
33 
34 using OpenMetaverse;
35 using Nini.Config;
36 
37 using OpenSim.Framework;
38 using OpenSim.Framework.ServiceAuth;
39 using OpenSim.Services.Connectors;
40 using OpenSim.Services.Interfaces;
41 using OpenSim.Server.Base;
42 
43 namespace OpenSim.Services.Connectors
44 {
46  {
47  private static readonly ILog m_log =
48  LogManager.GetLogger(
49  MethodBase.GetCurrentMethod().DeclaringType);
50 
51  private string m_ServerURI = String.Empty;
52  private ExpiringCache<string, List<EstateSettings>> m_EstateCache = new ExpiringCache<string, List<EstateSettings>>();
53  private const int EXPIRATION = 5 * 60; // 5 minutes in secs
54 
55  public EstateDataRemoteConnector(IConfigSource source)
56  {
57  Initialise(source);
58  }
59 
60  public virtual void Initialise(IConfigSource source)
61  {
62  IConfig gridConfig = source.Configs["EstateService"];
63  if (gridConfig == null)
64  {
65  m_log.Error("[ESTATE CONNECTOR]: EstateService missing from OpenSim.ini");
66  throw new Exception("Estate connector init error");
67  }
68 
69  string serviceURI = gridConfig.GetString("EstateServerURI",
70  String.Empty);
71 
72  if (serviceURI == String.Empty)
73  {
74  m_log.Error("[ESTATE CONNECTOR]: No Server URI named in section EstateService");
75  throw new Exception("Estate connector init error");
76  }
77  m_ServerURI = serviceURI;
78 
79  base.Initialise(source, "EstateService");
80  }
81 
82  #region IEstateDataService
83 
84  public List<EstateSettings> LoadEstateSettingsAll()
85  {
86  string reply = string.Empty;
87  string uri = m_ServerURI + "/estates";
88 
89  reply = MakeRequest("GET", uri, string.Empty);
90  if (String.IsNullOrEmpty(reply))
91  return new List<EstateSettings>();
92 
93  Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
94 
95  List<EstateSettings> estates = new List<EstateSettings>();
96  if (replyData != null && replyData.Count > 0)
97  {
98  m_log.DebugFormat("[ESTATE CONNECTOR]: LoadEstateSettingsAll returned {0} elements", replyData.Count);
99  Dictionary<string, object>.ValueCollection estateData = replyData.Values;
100  foreach (object r in estateData)
101  {
102  if (r is Dictionary<string, object>)
103  {
104  EstateSettings es = new EstateSettings((Dictionary<string, object>)r);
105  estates.Add(es);
106  }
107  }
108  m_EstateCache.AddOrUpdate("estates", estates, EXPIRATION);
109  }
110  else
111  m_log.DebugFormat("[ESTATE CONNECTOR]: LoadEstateSettingsAll from {0} received null or zero response", uri);
112 
113  return estates;
114 
115  }
116 
117  public List<int> GetEstatesAll()
118  {
119  List<int> eids = new List<int>();
120  // If we don't have them, load them from the server
121  List<EstateSettings> estates = null;
122  if (!m_EstateCache.TryGetValue("estates", out estates))
123  LoadEstateSettingsAll();
124 
125  foreach (EstateSettings es in estates)
126  eids.Add((int)es.EstateID);
127 
128  return eids;
129  }
130 
131  public List<int> GetEstates(string search)
132  {
133  // If we don't have them, load them from the server
134  List<EstateSettings> estates = null;
135  if (!m_EstateCache.TryGetValue("estates", out estates))
136  LoadEstateSettingsAll();
137 
138  List<int> eids = new List<int>();
139  foreach (EstateSettings es in estates)
140  if (es.EstateName == search)
141  eids.Add((int)es.EstateID);
142 
143  return eids;
144  }
145 
146  public List<int> GetEstatesByOwner(UUID ownerID)
147  {
148  // If we don't have them, load them from the server
149  List<EstateSettings> estates = null;
150  if (!m_EstateCache.TryGetValue("estates", out estates))
151  LoadEstateSettingsAll();
152 
153  List<int> eids = new List<int>();
154  foreach (EstateSettings es in estates)
155  if (es.EstateOwner == ownerID)
156  eids.Add((int)es.EstateID);
157 
158  return eids;
159  }
160 
161  public List<UUID> GetRegions(int estateID)
162  {
163  string reply = string.Empty;
164  // /estates/regions/?eid=int
165  string uri = m_ServerURI + "/estates/regions/?eid=" + estateID.ToString();
166 
167  reply = MakeRequest("GET", uri, string.Empty);
168  if (String.IsNullOrEmpty(reply))
169  return new List<UUID>();
170 
171  Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
172 
173  List<UUID> regions = new List<UUID>();
174  if (replyData != null && replyData.Count > 0)
175  {
176  m_log.DebugFormat("[ESTATE CONNECTOR]: GetRegions for estate {0} returned {1} elements", estateID, replyData.Count);
177  Dictionary<string, object>.ValueCollection data = replyData.Values;
178  foreach (object r in data)
179  {
180  UUID uuid = UUID.Zero;
181  if (UUID.TryParse(r.ToString(), out uuid))
182  regions.Add(uuid);
183  }
184  }
185  else
186  m_log.DebugFormat("[ESTATE CONNECTOR]: GetRegions from {0} received null or zero response", uri);
187 
188  return regions;
189  }
190 
191  public EstateSettings LoadEstateSettings(UUID regionID, bool create)
192  {
193  string reply = string.Empty;
194  // /estates/estate/?region=uuid&create=[t|f]
195  string uri = m_ServerURI + string.Format("/estates/estate/?region={0}&create={1}", regionID, create);
196 
197  reply = MakeRequest("GET", uri, string.Empty);
198  if (String.IsNullOrEmpty(reply))
199  return null;
200 
201  Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
202 
203  if (replyData != null && replyData.Count > 0)
204  {
205  m_log.DebugFormat("[ESTATE CONNECTOR]: LoadEstateSettings({0}) returned {1} elements", regionID, replyData.Count);
206  EstateSettings es = new EstateSettings(replyData);
207  return es;
208  }
209  else
210  m_log.DebugFormat("[ESTATE CONNECTOR]: LoadEstateSettings(regionID) from {0} received null or zero response", uri);
211 
212  return null;
213  }
214 
215  public EstateSettings LoadEstateSettings(int estateID)
216  {
217  string reply = string.Empty;
218  // /estates/estate/?eid=int
219  string uri = m_ServerURI + string.Format("/estates/estate/?eid={0}", estateID);
220 
221  reply = MakeRequest("GET", uri, string.Empty);
222  if (String.IsNullOrEmpty(reply))
223  return null;
224 
225  Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
226 
227  if (replyData != null && replyData.Count > 0)
228  {
229  m_log.DebugFormat("[ESTATE CONNECTOR]: LoadEstateSettings({0}) returned {1} elements", estateID, replyData.Count);
230  EstateSettings es = new EstateSettings(replyData);
231  return es;
232  }
233  else
234  m_log.DebugFormat("[ESTATE CONNECTOR]: LoadEstateSettings(estateID) from {0} received null or zero response", uri);
235 
236  return null;
237  }
238 
244  {
245  // No can do
246  return null;
247  }
248 
250  {
251  // /estates/estate/
252  string uri = m_ServerURI + ("/estates/estate");
253 
254  Dictionary<string, object> formdata = es.ToMap();
255  formdata["OP"] = "STORE";
256 
257  PostRequest(uri, formdata);
258  }
259 
260  public bool LinkRegion(UUID regionID, int estateID)
261  {
262  // /estates/estate/?eid=int&region=uuid
263  string uri = m_ServerURI + String.Format("/estates/estate/?eid={0}&region={1}", estateID, regionID);
264 
265  Dictionary<string, object> formdata = new Dictionary<string, object>();
266  formdata["OP"] = "LINK";
267  return PostRequest(uri, formdata);
268  }
269 
270  private bool PostRequest(string uri, Dictionary<string, object> sendData)
271  {
272  string reqString = ServerUtils.BuildQueryString(sendData);
273 
274  string reply = MakeRequest("POST", uri, reqString);
275  if (String.IsNullOrEmpty(reply))
276  return false;
277 
278  Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
279 
280  bool result = false;
281  if (replyData != null && replyData.Count > 0)
282  {
283  if (replyData.ContainsKey("Result"))
284  {
285  if (Boolean.TryParse(replyData["Result"].ToString(), out result))
286  m_log.DebugFormat("[ESTATE CONNECTOR]: PostRequest {0} returned {1}", uri, result);
287  }
288  }
289  else
290  m_log.DebugFormat("[ESTATE CONNECTOR]: PostRequest {0} received null or zero response", uri);
291 
292  return result;
293  }
294 
299  public bool DeleteEstate(int estateID)
300  {
301  return false;
302  }
303 
304  #endregion
305 
306  private string MakeRequest(string verb, string uri, string formdata)
307  {
308  string reply = string.Empty;
309  try
310  {
311  reply = SynchronousRestFormsRequester.MakeRequest(verb, uri, formdata, m_Auth);
312  }
313  catch (WebException e)
314  {
315  using (HttpWebResponse hwr = (HttpWebResponse)e.Response)
316  {
317  if (hwr != null)
318  {
319  if (hwr.StatusCode == HttpStatusCode.NotFound)
320  m_log.Error(string.Format("[ESTATE CONNECTOR]: Resource {0} not found ", uri));
321  if (hwr.StatusCode == HttpStatusCode.Unauthorized)
322  m_log.Error(string.Format("[ESTATE CONNECTOR]: Web request {0} requires authentication ", uri));
323  }
324  else
325  m_log.Error(string.Format(
326  "[ESTATE CONNECTOR]: WebException for {0} {1} {2} ",
327  verb, uri, formdata, e));
328  }
329  }
330  catch (Exception e)
331  {
332  m_log.DebugFormat("[ESTATE CONNECTOR]: Exception when contacting estate server at {0}: {1}", uri, e.Message);
333  }
334 
335  return reply;
336  }
337  }
338 }
List< UUID > GetRegions(int estateID)
Get the UUIDs of all the regions in an estate.
EstateSettings CreateNewEstate()
Forbidden operation
void StoreEstateSettings(EstateSettings es)
Store estate settings.
bool DeleteEstate(int estateID)
Forbidden operation
List< int > GetEstates(string search)
Get estate IDs.
List< int > GetEstatesAll()
Get the IDs of all estates.
List< int > GetEstatesByOwner(UUID ownerID)
Get the IDs of all estates owned by the given user.
EstateSettings LoadEstateSettings(UUID regionID, bool create)
Load estate settings for a region.
EstateSettings LoadEstateSettings(int estateID)
Load estate settings for an estate ID.
List< EstateSettings > LoadEstateSettingsAll()
Load/Get all estate settings.
bool LinkRegion(UUID regionID, int estateID)
Link a region to an estate.