Skip to content

Commit

Permalink
Enforce that initial EventIds are deterministic (#375)
Browse files Browse the repository at this point in the history
* Enforce that initial `EventId`s are deterministic

* Update src/AlarmCondition/Model/SourceState.cs

* Revert "Update src/AlarmCondition/Model/SourceState.cs"

This reverts commit ede5aff.

* Cosmetic

---------

Co-authored-by: Luis Cantero <[email protected]>
Co-authored-by: Luis Cantero <[email protected]>
  • Loading branch information
3 people authored Jul 22, 2024
1 parent ebeb73c commit d1944c9
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
15 changes: 14 additions & 1 deletion src/AlarmCondition/AlarmConditionNodeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@

using System;
using System.Collections.Generic;
using System.Reflection.Emit;
using System.Threading;
using Opc.Ua;
using Opc.Ua.Server;
using Opc.Ua.Test;

namespace AlarmCondition
{
Expand Down Expand Up @@ -271,7 +273,8 @@ private AreaState CreateAndIndexAreas(AreaState parent, AreaConfiguration config
if (!m_sources.TryGetValue(sourcePath, out SourceState source))
{
NodeId sourceId = ModelUtils.ConstructIdForSource(sourcePath, NamespaceIndex);
m_sources[sourcePath] = source = new SourceState(this, sourceId, sourcePath);
ResetRandomGenerator(ii);
m_sources[sourcePath] = source = new SourceState(this, sourceId, sourcePath, m_generator);
}

// HasEventSource and HasNotifier control the propagation of event notifications so
Expand Down Expand Up @@ -456,13 +459,23 @@ protected override NodeState ValidateNode(
cache?.Add(handle.NodeId, target);
}
}

private void ResetRandomGenerator(int seed, int boundaryValueFrequency = 0)
{
m_randomSource = new RandomSource(seed);
m_generator = new DataGenerator(m_randomSource);
m_generator.BoundaryValueFrequency = boundaryValueFrequency;
}

#endregion

#region Private Fields
private readonly UnderlyingSystem m_system;
private readonly Dictionary<string, AreaState> m_areas;
private readonly Dictionary<string, SourceState> m_sources;
private Timer m_simulationTimer;
private RandomSource m_randomSource;
private DataGenerator m_generator;
#endregion
}
}
22 changes: 19 additions & 3 deletions src/AlarmCondition/Model/SourceState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@
* http://opcfoundation.org/License/MIT/1.00/
* ======================================================================*/

using Microsoft.AspNetCore.Hosting.Server;
using Opc.Ua;
using Opc.Ua.Test;
using System;
using System.Collections.Generic;
using System.Reflection.Emit;

namespace AlarmCondition
{
Expand All @@ -45,7 +48,8 @@ public partial class SourceState : BaseObjectState
public SourceState(
AlarmConditionServerNodeManager nodeManager,
NodeId nodeId,
string sourcePath)
string sourcePath,
DataGenerator generator)
:
base(null)
{
Expand All @@ -68,6 +72,7 @@ public SourceState(
EventNotifier = EventNotifiers.None;

// create a dialog.
m_generator = generator;
m_dialog = CreateDialog("OnlineState");

// create the table of conditions.
Expand Down Expand Up @@ -223,7 +228,7 @@ private DialogConditionState CreateDialog(string dialogName)
AddChild(node);

// initialize event information.
node.EventId.Value = Guid.NewGuid().ToByteArray();
node.EventId.Value = GetNextGuidAsByteArray();
node.EventType.Value = node.TypeDefinitionId;
node.SourceNode.Value = NodeId;
node.SourceName.Value = SymbolicName;
Expand Down Expand Up @@ -256,6 +261,16 @@ private DialogConditionState CreateDialog(string dialogName)
return node;
}

private byte[] GetNextGuidAsByteArray()
{
// Unpack the object to Uuid and then explicitly cast to Guid to access the byte[]
// using a random generator with a known seed to get reproducible results.
return ((Guid)((Uuid)m_generator.GetRandom(
NodeId.Parse($"i={(int)BuiltInType.Guid}"),
ValueRanks.Scalar, new uint[] { 1 },
m_nodeManager.Server.TypeTree))).ToByteArray();
}

/// <summary>
/// The responses used with the dialog condition.
/// </summary>
Expand Down Expand Up @@ -411,7 +426,7 @@ private void UpdateAlarm(AlarmConditionState node, UnderlyingSystemAlarm alarm)
}

// update the basic event information (include generating a unique id for the event).
node.EventId.Value = Guid.NewGuid().ToByteArray();
node.EventId.Value = GetNextGuidAsByteArray();
node.Time.Value = DateTime.UtcNow;
node.ReceiveTime.Value = node.Time.Value;

Expand Down Expand Up @@ -727,6 +742,7 @@ private string GetUserName(ISystemContext context)
private readonly Dictionary<string, AlarmConditionState> m_events;
private readonly Dictionary<NodeId, AlarmConditionState> m_branches;
private readonly DialogConditionState m_dialog;
private DataGenerator m_generator;
#endregion
}
}

0 comments on commit d1944c9

Please sign in to comment.