OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
JsonStoreModule.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors
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 OpenSim 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 Mono.Addins;
28 
29 using System;
30 using System.Reflection;
31 using System.Threading;
32 using System.Text;
33 using System.Net;
34 using System.Net.Sockets;
35 using log4net;
36 using Nini.Config;
37 using OpenMetaverse;
38 using OpenMetaverse.StructuredData;
39 using OpenSim.Framework;
40 using OpenSim.Region.Framework.Interfaces;
41 using OpenSim.Region.Framework.Scenes;
42 using System.Collections.Generic;
43 using System.Text.RegularExpressions;
44 
45 namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
46 {
47  [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "JsonStoreModule")]
48 
50  {
51  private static readonly ILog m_log =
52  LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53 
54  private IConfig m_config = null;
55  private bool m_enabled = false;
56  private bool m_enableObjectStore = false;
57  private int m_maxStringSpace = Int32.MaxValue;
58 
59  private Scene m_scene = null;
60 
61  private Dictionary<UUID,JsonStore> m_JsonValueStore;
62 
63  private UUID m_sharedStore;
64 
65 #region Region Module interface
66 
67  // -----------------------------------------------------------------
71  // -----------------------------------------------------------------
72  public string Name
73  {
74  get { return this.GetType().Name; }
75  }
76 
77  // -----------------------------------------------------------------
83  // -----------------------------------------------------------------
84  public void Initialise(IConfigSource config)
85  {
86  try
87  {
88  if ((m_config = config.Configs["JsonStore"]) == null)
89  {
90  // There is no configuration, the module is disabled
91  // m_log.InfoFormat("[JsonStore] no configuration info");
92  return;
93  }
94 
95  m_enabled = m_config.GetBoolean("Enabled", m_enabled);
96  m_enableObjectStore = m_config.GetBoolean("EnableObjectStore", m_enableObjectStore);
97  m_maxStringSpace = m_config.GetInt("MaxStringSpace", m_maxStringSpace);
98  if (m_maxStringSpace == 0)
99  m_maxStringSpace = Int32.MaxValue;
100  }
101  catch (Exception e)
102  {
103  m_log.Error("[JsonStore]: initialization error: {0}", e);
104  return;
105  }
106 
107  if (m_enabled)
108  m_log.DebugFormat("[JsonStore]: module is enabled");
109  }
110 
111  // -----------------------------------------------------------------
115  // -----------------------------------------------------------------
116  public void PostInitialise()
117  {
118  }
119 
120  // -----------------------------------------------------------------
124  // -----------------------------------------------------------------
125  public void Close()
126  {
127  }
128 
129  // -----------------------------------------------------------------
132  // -----------------------------------------------------------------
133  public void AddRegion(Scene scene)
134  {
135  if (m_enabled)
136  {
137  m_scene = scene;
138  m_scene.RegisterModuleInterface<IJsonStoreModule>(this);
139 
140  m_sharedStore = UUID.Zero;
141  m_JsonValueStore = new Dictionary<UUID,JsonStore>();
142  m_JsonValueStore.Add(m_sharedStore,new JsonStore(""));
143 
144  scene.EventManager.OnObjectBeingRemovedFromScene += EventManagerOnObjectBeingRemovedFromScene;
145  }
146  }
147 
148  // -----------------------------------------------------------------
151  // -----------------------------------------------------------------
152  public void RemoveRegion(Scene scene)
153  {
154  scene.EventManager.OnObjectBeingRemovedFromScene -= EventManagerOnObjectBeingRemovedFromScene;
155 
156  // need to remove all references to the scene in the subscription
157  // list to enable full garbage collection of the scene object
158  }
159 
160  // -----------------------------------------------------------------
165  // -----------------------------------------------------------------
166  public void RegionLoaded(Scene scene)
167  {
168  if (m_enabled)
169  {
170  }
171  }
172 
176  // -----------------------------------------------------------------
177  public Type ReplaceableInterface
178  {
179  get { return null; }
180  }
181 
182 #endregion
183 
184 #region SceneEvents
185  // -----------------------------------------------------------------
189  // -----------------------------------------------------------------
191  {
192  obj.ForEachPart(delegate(SceneObjectPart sop) { DestroyStore(sop.UUID); } );
193  }
194 
195 #endregion
196 
197 #region ScriptInvocationInteface
198 
199 
200  // -----------------------------------------------------------------
204  // -----------------------------------------------------------------
206  {
207  JsonStoreStats stats;
208 
209  lock (m_JsonValueStore)
210  {
211  stats.StoreCount = m_JsonValueStore.Count;
212  }
213 
214  return stats;
215  }
216 
217  // -----------------------------------------------------------------
221  // -----------------------------------------------------------------
222  public bool AttachObjectStore(UUID objectID)
223  {
224  if (! m_enabled) return false;
225  if (! m_enableObjectStore) return false;
226 
227  SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID);
228  if (sop == null)
229  {
230  m_log.ErrorFormat("[JsonStore] unable to attach to unknown object; {0}", objectID);
231  return false;
232  }
233 
234  lock (m_JsonValueStore)
235  {
236  if (m_JsonValueStore.ContainsKey(objectID))
237  return true;
238 
239  JsonStore map = new JsonObjectStore(m_scene,objectID);
240  m_JsonValueStore.Add(objectID,map);
241  }
242 
243  return true;
244  }
245 
246  // -----------------------------------------------------------------
250  // -----------------------------------------------------------------
251  public bool CreateStore(string value, ref UUID result)
252  {
253  if (result == UUID.Zero)
254  result = UUID.Random();
255 
256  JsonStore map = null;
257 
258  if (! m_enabled) return false;
259 
260 
261  try
262  {
263  map = new JsonStore(value);
264  }
265  catch (Exception)
266  {
267  m_log.ErrorFormat("[JsonStore]: Unable to initialize store from {0}", value);
268  return false;
269  }
270 
271  lock (m_JsonValueStore)
272  m_JsonValueStore.Add(result,map);
273 
274  return true;
275  }
276 
277  // -----------------------------------------------------------------
281  // -----------------------------------------------------------------
282  public bool DestroyStore(UUID storeID)
283  {
284  if (! m_enabled) return false;
285 
286  lock (m_JsonValueStore)
287  return m_JsonValueStore.Remove(storeID);
288  }
289 
290  // -----------------------------------------------------------------
294  // -----------------------------------------------------------------
295  public bool TestStore(UUID storeID)
296  {
297  if (! m_enabled) return false;
298 
299  lock (m_JsonValueStore)
300  return m_JsonValueStore.ContainsKey(storeID);
301  }
302 
303  // -----------------------------------------------------------------
307  // -----------------------------------------------------------------
308  public JsonStoreNodeType GetNodeType(UUID storeID, string path)
309  {
310  if (! m_enabled) return JsonStoreNodeType.Undefined;
311 
312  JsonStore map = null;
313  lock (m_JsonValueStore)
314  {
315  if (! m_JsonValueStore.TryGetValue(storeID,out map))
316  {
317  m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
318  return JsonStoreNodeType.Undefined;
319  }
320  }
321 
322  try
323  {
324  lock (map)
325  return map.GetNodeType(path);
326  }
327  catch (Exception e)
328  {
329  m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e);
330  }
331 
332  return JsonStoreNodeType.Undefined;
333  }
334 
335  // -----------------------------------------------------------------
339  // -----------------------------------------------------------------
340  public JsonStoreValueType GetValueType(UUID storeID, string path)
341  {
342  if (! m_enabled) return JsonStoreValueType.Undefined;
343 
344  JsonStore map = null;
345  lock (m_JsonValueStore)
346  {
347  if (! m_JsonValueStore.TryGetValue(storeID,out map))
348  {
349  m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
350  return JsonStoreValueType.Undefined;
351  }
352  }
353 
354  try
355  {
356  lock (map)
357  return map.GetValueType(path);
358  }
359  catch (Exception e)
360  {
361  m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e);
362  }
363 
364  return JsonStoreValueType.Undefined;
365  }
366 
367  // -----------------------------------------------------------------
371  // -----------------------------------------------------------------
372  public bool SetValue(UUID storeID, string path, string value, bool useJson)
373  {
374  if (! m_enabled) return false;
375 
376  JsonStore map = null;
377  lock (m_JsonValueStore)
378  {
379  if (! m_JsonValueStore.TryGetValue(storeID,out map))
380  {
381  m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
382  return false;
383  }
384  }
385 
386  try
387  {
388  lock (map)
389  {
390  if (map.StringSpace > m_maxStringSpace)
391  {
392  m_log.WarnFormat("[JsonStore] {0} exceeded string size; {1} bytes used of {2} limit",
393  storeID,map.StringSpace,m_maxStringSpace);
394  return false;
395  }
396 
397  return map.SetValue(path,value,useJson);
398  }
399  }
400  catch (Exception e)
401  {
402  m_log.Error(string.Format("[JsonStore]: Unable to assign {0} to {1} in {2}", value, path, storeID), e);
403  }
404 
405  return false;
406  }
407 
408  // -----------------------------------------------------------------
412  // -----------------------------------------------------------------
413  public bool RemoveValue(UUID storeID, string path)
414  {
415  if (! m_enabled) return false;
416 
417  JsonStore map = null;
418  lock (m_JsonValueStore)
419  {
420  if (! m_JsonValueStore.TryGetValue(storeID,out map))
421  {
422  m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
423  return false;
424  }
425  }
426 
427  try
428  {
429  lock (map)
430  return map.RemoveValue(path);
431  }
432  catch (Exception e)
433  {
434  m_log.Error(string.Format("[JsonStore]: Unable to remove {0} in {1}", path, storeID), e);
435  }
436 
437  return false;
438  }
439 
440  // -----------------------------------------------------------------
444  // -----------------------------------------------------------------
445  public int GetArrayLength(UUID storeID, string path)
446  {
447  if (! m_enabled) return -1;
448 
449  JsonStore map = null;
450  lock (m_JsonValueStore)
451  {
452  if (! m_JsonValueStore.TryGetValue(storeID,out map))
453  return -1;
454  }
455 
456  try
457  {
458  lock (map)
459  {
460  return map.ArrayLength(path);
461  }
462  }
463  catch (Exception e)
464  {
465  m_log.Error("[JsonStore]: unable to retrieve value", e);
466  }
467 
468  return -1;
469  }
470 
471  // -----------------------------------------------------------------
475  // -----------------------------------------------------------------
476  public bool GetValue(UUID storeID, string path, bool useJson, out string value)
477  {
478  value = String.Empty;
479 
480  if (! m_enabled) return false;
481 
482  JsonStore map = null;
483  lock (m_JsonValueStore)
484  {
485  if (! m_JsonValueStore.TryGetValue(storeID,out map))
486  return false;
487  }
488 
489  try
490  {
491  lock (map)
492  {
493  return map.GetValue(path, out value, useJson);
494  }
495  }
496  catch (Exception e)
497  {
498  m_log.Error("[JsonStore]: unable to retrieve value", e);
499  }
500 
501  return false;
502  }
503 
504  // -----------------------------------------------------------------
508  // -----------------------------------------------------------------
509  public void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback)
510  {
511  if (! m_enabled)
512  {
513  cback(String.Empty);
514  return;
515  }
516 
517  JsonStore map = null;
518  lock (m_JsonValueStore)
519  {
520  if (! m_JsonValueStore.TryGetValue(storeID,out map))
521  {
522  cback(String.Empty);
523  return;
524  }
525  }
526 
527  try
528  {
529  lock (map)
530  {
531  map.TakeValue(path, useJson, cback);
532  return;
533  }
534  }
535  catch (Exception e)
536  {
537  m_log.Error("[JsonStore] unable to retrieve value", e);
538  }
539 
540  cback(String.Empty);
541  }
542 
543  // -----------------------------------------------------------------
547  // -----------------------------------------------------------------
548  public void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback)
549  {
550  if (! m_enabled)
551  {
552  cback(String.Empty);
553  return;
554  }
555 
556  JsonStore map = null;
557  lock (m_JsonValueStore)
558  {
559  if (! m_JsonValueStore.TryGetValue(storeID,out map))
560  {
561  cback(String.Empty);
562  return;
563  }
564  }
565 
566  try
567  {
568  lock (map)
569  {
570  map.ReadValue(path, useJson, cback);
571  return;
572  }
573  }
574  catch (Exception e)
575  {
576  m_log.Error("[JsonStore]: unable to retrieve value", e);
577  }
578 
579  cback(String.Empty);
580  }
581 
582 #endregion
583  }
584 }
void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback)
void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback)
int StringSpace
This is a simple estimator for the size of the stored data, it is not precise, but should be close en...
Definition: JsonStore.cs:100
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
void PostInitialise()
everything is loaded, perform post load configuration
delegate void TakeValueCallback(string s)
bool GetValue(UUID storeID, string path, bool useJson, out string value)
bool SetValue(UUID storeID, string path, string value, bool useJson)
JsonStoreValueType GetValueType(UUID storeID, string path)
void Initialise(IConfigSource config)
Initialise this shared module
JsonStoreNodeType GetNodeType(UUID storeID, string path)
void RegionLoaded(Scene scene)
Called when all modules have been added for a region. This is where we hook up events ...