aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Scripting
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/Scripting')
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs68
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs25
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs79
4 files changed, 150 insertions, 24 deletions
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
index 5808d46..088d0cd 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
@@ -95,6 +95,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
95 95
96 // ----------------------------------------------------------------- 96 // -----------------------------------------------------------------
97 /// <summary> 97 /// <summary>
98 /// This is a simple estimator for the size of the stored data, it
99 /// is not precise, but should be close enough to implement reasonable
100 /// limits on the storage space used
101 /// </summary>
102 // -----------------------------------------------------------------
103 public int StringSpace { get; set; }
104
105 // -----------------------------------------------------------------
106 /// <summary>
98 /// 107 ///
99 /// </summary> 108 /// </summary>
100 // ----------------------------------------------------------------- 109 // -----------------------------------------------------------------
@@ -110,6 +119,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
110 // ----------------------------------------------------------------- 119 // -----------------------------------------------------------------
111 public JsonStore() 120 public JsonStore()
112 { 121 {
122 StringSpace = 0;
113 m_TakeStore = new List<TakeValueCallbackClass>(); 123 m_TakeStore = new List<TakeValueCallbackClass>();
114 m_ReadStore = new List<TakeValueCallbackClass>(); 124 m_ReadStore = new List<TakeValueCallbackClass>();
115 } 125 }
@@ -247,9 +257,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
247 if (path.Count == 0) 257 if (path.Count == 0)
248 { 258 {
249 ValueStore = ovalue; 259 ValueStore = ovalue;
260 StringSpace = 0;
250 return true; 261 return true;
251 } 262 }
252 263
264 // pkey will be the final element in the path, we pull it out here to make sure
265 // that the assignment works correctly
253 string pkey = path.Pop(); 266 string pkey = path.Pop();
254 string pexpr = PathExpressionToKey(path); 267 string pexpr = PathExpressionToKey(path);
255 if (pexpr != "") 268 if (pexpr != "")
@@ -259,7 +272,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
259 if (result == null) 272 if (result == null)
260 return false; 273 return false;
261 274
262 // Check for and extract array references 275 // Check pkey, the last element in the path, for and extract array references
263 MatchCollection amatches = m_ArrayPattern.Matches(pkey,0); 276 MatchCollection amatches = m_ArrayPattern.Matches(pkey,0);
264 if (amatches.Count > 0) 277 if (amatches.Count > 0)
265 { 278 {
@@ -276,8 +289,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
276 { 289 {
277 string npkey = String.Format("[{0}]",amap.Count); 290 string npkey = String.Format("[{0}]",amap.Count);
278 291
279 amap.Add(ovalue); 292 if (ovalue != null)
280 InvokeNextCallback(pexpr + npkey); 293 {
294 StringSpace += ComputeSizeOf(ovalue);
295
296 amap.Add(ovalue);
297 InvokeNextCallback(pexpr + npkey);
298 }
281 return true; 299 return true;
282 } 300 }
283 301
@@ -285,9 +303,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
285 if (0 <= aval && aval < amap.Count) 303 if (0 <= aval && aval < amap.Count)
286 { 304 {
287 if (ovalue == null) 305 if (ovalue == null)
306 {
307 StringSpace -= ComputeSizeOf(amap[aval]);
288 amap.RemoveAt(aval); 308 amap.RemoveAt(aval);
309 }
289 else 310 else
290 { 311 {
312 StringSpace -= ComputeSizeOf(amap[aval]);
313 StringSpace += ComputeSizeOf(ovalue);
291 amap[aval] = ovalue; 314 amap[aval] = ovalue;
292 InvokeNextCallback(pexpr + pkey); 315 InvokeNextCallback(pexpr + pkey);
293 } 316 }
@@ -307,16 +330,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
307 330
308 if (result is OSDMap) 331 if (result is OSDMap)
309 { 332 {
333 // this is the assignment case
310 OSDMap hmap = result as OSDMap; 334 OSDMap hmap = result as OSDMap;
311 if (ovalue != null) 335 if (ovalue != null)
312 { 336 {
337 StringSpace -= ComputeSizeOf(hmap[hkey]);
338 StringSpace += ComputeSizeOf(ovalue);
339
313 hmap[hkey] = ovalue; 340 hmap[hkey] = ovalue;
314 InvokeNextCallback(pexpr + pkey); 341 InvokeNextCallback(pexpr + pkey);
342 return true;
315 } 343 }
316 else if (hmap.ContainsKey(hkey)) 344
345 // this is the remove case
346 if (hmap.ContainsKey(hkey))
347 {
348 StringSpace -= ComputeSizeOf(hmap[hkey]);
317 hmap.Remove(hkey); 349 hmap.Remove(hkey);
318 350 return true;
319 return true; 351 }
352
353 return false;
320 } 354 }
321 355
322 return false; 356 return false;
@@ -522,8 +556,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
522 556
523 return pkey; 557 return pkey;
524 } 558 }
559
560 // -----------------------------------------------------------------
561 /// <summary>
562 ///
563 /// </summary>
564 // -----------------------------------------------------------------
565 protected static int ComputeSizeOf(OSD value)
566 {
567 string sval;
568
569 if (ConvertOutputValue(value,out sval,true))
570 return sval.Length;
571
572 return 0;
573 }
525 } 574 }
526 575
576 // -----------------------------------------------------------------
577 /// <summary>
578 /// </summary>
579 // -----------------------------------------------------------------
527 public class JsonObjectStore : JsonStore 580 public class JsonObjectStore : JsonStore
528 { 581 {
529 private static readonly ILog m_log = 582 private static readonly ILog m_log =
@@ -557,6 +610,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
557 { 610 {
558 m_scene = scene; 611 m_scene = scene;
559 m_objectID = oid; 612 m_objectID = oid;
613
614 // the size limit is imposed on whatever is already in the store
615 StringSpace = ComputeSizeOf(ValueStore);
560 } 616 }
561 } 617 }
562 618
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
index 3b52e44..f1ce856 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
@@ -54,6 +54,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
54 54
55 private IConfig m_config = null; 55 private IConfig m_config = null;
56 private bool m_enabled = false; 56 private bool m_enabled = false;
57 private bool m_enableObjectStore = false;
58 private int m_maxStringSpace = Int32.MaxValue;
59
57 private Scene m_scene = null; 60 private Scene m_scene = null;
58 61
59 private Dictionary<UUID,JsonStore> m_JsonValueStore; 62 private Dictionary<UUID,JsonStore> m_JsonValueStore;
@@ -90,6 +93,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
90 } 93 }
91 94
92 m_enabled = m_config.GetBoolean("Enabled", m_enabled); 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;
93 } 100 }
94 catch (Exception e) 101 catch (Exception e)
95 { 102 {
@@ -178,6 +185,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
178 public bool AttachObjectStore(UUID objectID) 185 public bool AttachObjectStore(UUID objectID)
179 { 186 {
180 if (! m_enabled) return false; 187 if (! m_enabled) return false;
188 if (! m_enableObjectStore) return false;
181 189
182 SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID); 190 SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID);
183 if (sop == null) 191 if (sop == null)
@@ -239,7 +247,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
239 if (! m_enabled) return false; 247 if (! m_enabled) return false;
240 248
241 lock (m_JsonValueStore) 249 lock (m_JsonValueStore)
242 m_JsonValueStore.Remove(storeID); 250 return m_JsonValueStore.Remove(storeID);
243 251
244 return true; 252 return true;
245 } 253 }
@@ -311,8 +319,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
311 try 319 try
312 { 320 {
313 lock (map) 321 lock (map)
314 if (map.SetValue(path,value,useJson)) 322 {
315 return true; 323 if (map.StringSpace > m_maxStringSpace)
324 {
325 m_log.WarnFormat("[JsonStore] {0} exceeded string size; {1} bytes used of {2} limit",
326 storeID,map.StringSpace,m_maxStringSpace);
327 return false;
328 }
329
330 return map.SetValue(path,value,useJson);
331 }
316 } 332 }
317 catch (Exception e) 333 catch (Exception e)
318 { 334 {
@@ -344,8 +360,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
344 try 360 try
345 { 361 {
346 lock (map) 362 lock (map)
347 if (map.RemoveValue(path)) 363 return map.RemoveValue(path);
348 return true;
349 } 364 }
350 catch (Exception e) 365 catch (Exception e)
351 { 366 {
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
index 48b4a9f..d75cd32 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
@@ -504,7 +504,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
504 { 504 {
505 string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data)); 505 string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data));
506 int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0; 506 int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0;
507 m_comms.DispatchReply(scriptID,result, "", reqID.ToString()); 507 m_comms.DispatchReply(scriptID, result, "", reqID.ToString());
508 return; 508 return;
509 } 509 }
510 catch (Exception e) 510 catch (Exception e)
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
index 6658e1e..ca88d1a 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
@@ -283,7 +283,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
283 string notecardName = "nc1"; 283 string notecardName = "nc1";
284 284
285 // Write notecard 285 // Write notecard
286 UUID writeNotecardRequestId = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "/", notecardName); 286 UUID writeNotecardRequestId = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "", notecardName);
287 Assert.That(writeNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); 287 Assert.That(writeNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
288 288
289 TaskInventoryItem nc1Item = so.RootPart.Inventory.GetInventoryItem(notecardName); 289 TaskInventoryItem nc1Item = so.RootPart.Inventory.GetInventoryItem(notecardName);
@@ -292,8 +292,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
292 // TODO: Should independently check the contents. 292 // TODO: Should independently check the contents.
293 } 293 }
294 294
295 // TODO: Write partial test
296
295 { 297 {
296 // Try to write notecard against bad path 298 // Try to write notecard for a bad path
297 // In this case we do get a request id but no notecard is written. 299 // In this case we do get a request id but no notecard is written.
298 string badPathNotecardName = "badPathNotecardName"; 300 string badPathNotecardName = "badPathNotecardName";
299 301
@@ -312,7 +314,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
312 314
313 UUID fakeStoreId = TestHelpers.ParseTail(0x500); 315 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
314 UUID fakeStoreWriteNotecardValue 316 UUID fakeStoreWriteNotecardValue
315 = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, fakeStoreId, "/", fakeStoreNotecardName); 317 = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, fakeStoreId, "", fakeStoreNotecardName);
316 Assert.That(fakeStoreWriteNotecardValue, Is.Not.EqualTo(UUID.Zero)); 318 Assert.That(fakeStoreWriteNotecardValue, Is.Not.EqualTo(UUID.Zero));
317 319
318 TaskInventoryItem fakeStoreItem = so.RootPart.Inventory.GetInventoryItem(fakeStoreNotecardName); 320 TaskInventoryItem fakeStoreItem = so.RootPart.Inventory.GetInventoryItem(fakeStoreNotecardName);
@@ -321,7 +323,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
321 } 323 }
322 324
323 /// <summary> 325 /// <summary>
324 /// Test for reading and writing json to a notecard 326 /// Test for reading json from a notecard
325 /// </summary> 327 /// </summary>
326 /// <remarks> 328 /// <remarks>
327 /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching 329 /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching
@@ -338,20 +340,73 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
338 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1)); 340 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1));
339 m_scene.AddSceneObject(so); 341 m_scene.AddSceneObject(so);
340 342
341 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); 343 UUID creatingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }");
342 344
343 // Write notecard 345 // Write notecard
344 InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "/", notecardName); 346 InvokeOpOnHost("JsonWriteNotecard", so.UUID, creatingStoreId, "", notecardName);
345 347
346 // Read notecard 348 {
347 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ }"); 349 // Read notecard
348 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "/", notecardName); 350 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
349 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); 351 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "", notecardName);
352 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
350 353
351 string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); 354 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
352 Assert.That(value, Is.EqualTo("World")); 355 Assert.That(value, Is.EqualTo("World"));
356 }
357
358 {
359 // Read notecard to new single component path
360 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
361 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make", notecardName);
362 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
363
364 // These don't behave as I expect yet - reading to a path still seems to place the notecard contents at the root.
365 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
366 Assert.That(value, Is.EqualTo(""));
367
368 value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.Hello");
369 Assert.That(value, Is.EqualTo("World"));
370 }
353 371
372 {
373 // Read notecard to new multi-component path
374 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
375 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName);
376 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
377
378 // These don't behave as I expect yet - reading to a path still seems to place the notecard contents at the root.
379 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
380 Assert.That(value, Is.EqualTo(""));
381
382 // TODO: Check that we are not expecting reading to a new path to work.
383 value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello");
384 Assert.That(value, Is.EqualTo(""));
385 }
386
387 {
388 // Read notecard to existing multi-component path
389 UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }");
390 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName);
391 Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
392
393 // These don't behave as I expect yet - reading to a path still seems to place the notecard contents at the root.
394 string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
395 Assert.That(value, Is.EqualTo(""));
354 396
397 value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello");
398 Assert.That(value, Is.EqualTo("World"));
399 }
400
401 {
402 // Try read notecard to fake store.
403 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
404 UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, fakeStoreId, "", notecardName);
405 Assert.That(fakeStoreId, Is.Not.EqualTo(UUID.Zero));
406
407 string value = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello");
408 Assert.That(value, Is.EqualTo(""));
409 }
355 } 410 }
356 411
357 public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; } 412 public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; }