mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-29 15:11:53 +08:00
Session.Load doesn't create the monitored items. Opt-in to support load for subscription transfer. (#2113)
- Added a flag to the Session.Load function to indicate that a session transfer should be supported. Otherwise the serverId is reset after load, to support that the subscription is recreated on the server after load. - A user has to opt-in to get the transfer session support.
This commit is contained in:
@@ -296,15 +296,17 @@ namespace Opc.Ua.Client
|
||||
/// Load the list of subscriptions saved in a file.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream.</param>
|
||||
/// <param name="transferSubscriptions">Load the subscriptions for transfer after load.</param>
|
||||
/// <returns>The list of loaded subscriptions</returns>
|
||||
IEnumerable<Subscription> Load(Stream stream);
|
||||
IEnumerable<Subscription> Load(Stream stream, bool transferSubscriptions = false);
|
||||
|
||||
/// <summary>
|
||||
/// Load the list of subscriptions saved in a file.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The file path.</param>
|
||||
/// <param name="transferSubscriptions">Load the subscriptions for transfer after load.</param>
|
||||
/// <returns>The list of loaded subscriptions</returns>
|
||||
IEnumerable<Subscription> Load(string filePath);
|
||||
IEnumerable<Subscription> Load(string filePath, bool transferSubscriptions = false);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the local copy of the server's namespace uri and server uri tables.
|
||||
|
||||
@@ -1412,8 +1412,9 @@ namespace Opc.Ua.Client
|
||||
/// Load the list of subscriptions saved in a stream.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream.</param>
|
||||
/// <param name="transferSubscriptions">Load the subscriptions for transfer after load.</param>
|
||||
/// <returns>The list of loaded subscriptions</returns>
|
||||
public IEnumerable<Subscription> Load(Stream stream)
|
||||
public IEnumerable<Subscription> Load(Stream stream, bool transferSubscriptions = false)
|
||||
{
|
||||
// secure settings
|
||||
XmlReaderSettings settings = Utils.DefaultXmlReaderSettings();
|
||||
@@ -1425,6 +1426,15 @@ namespace Opc.Ua.Client
|
||||
SubscriptionCollection subscriptions = (SubscriptionCollection)serializer.ReadObject(reader);
|
||||
foreach (Subscription subscription in subscriptions)
|
||||
{
|
||||
if (!transferSubscriptions)
|
||||
{
|
||||
// ServerId must be reset if the saved list of subscriptions
|
||||
// is not used to transfer a subscription
|
||||
foreach (var monitoredItem in subscription.MonitoredItems)
|
||||
{
|
||||
monitoredItem.ServerId = 0;
|
||||
}
|
||||
}
|
||||
AddSubscription(subscription);
|
||||
}
|
||||
return subscriptions;
|
||||
@@ -1435,12 +1445,13 @@ namespace Opc.Ua.Client
|
||||
/// Load the list of subscriptions saved in a file.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The file path.</param>
|
||||
/// <param name="transferSubscriptions">Load the subscriptions for transfer after load.</param>
|
||||
/// <returns>The list of loaded subscriptions</returns>
|
||||
public IEnumerable<Subscription> Load(string filePath)
|
||||
public IEnumerable<Subscription> Load(string filePath, bool transferSubscriptions = false)
|
||||
{
|
||||
using (FileStream stream = File.OpenRead(filePath))
|
||||
{
|
||||
return Load(stream);
|
||||
return Load(stream, transferSubscriptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using Opc.Ua.Server.Tests;
|
||||
|
||||
namespace Opc.Ua.Client.Tests
|
||||
{
|
||||
@@ -131,15 +130,18 @@ namespace Opc.Ua.Client.Tests
|
||||
new MonitoredItem(subscription.DefaultItem)
|
||||
{
|
||||
DisplayName = "ServerStatusState", StartNodeId = VariableIds.Server_ServerStatus_State
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var simulatedNodes = GetTestSetSimulation(Session.NamespaceUris);
|
||||
list2.AddRange(CreateMonitoredItemTestSet(subscription, simulatedNodes));
|
||||
list2.ForEach(i => i.Notification += (MonitoredItem item, MonitoredItemNotificationEventArgs e) => {
|
||||
foreach (var value in item.DequeueValues())
|
||||
{
|
||||
TestContext.Out.WriteLine("{0}: {1}, {2}, {3}", item.DisplayName, value.Value, value.SourceTimestamp, value.StatusCode);
|
||||
}
|
||||
});
|
||||
subscription.AddItems(list);
|
||||
subscription.AddItems(list2);
|
||||
subscription.ApplyChanges();
|
||||
subscription.SetPublishingMode(false);
|
||||
Assert.False(subscription.PublishingEnabled);
|
||||
@@ -221,15 +223,18 @@ namespace Opc.Ua.Client.Tests
|
||||
new MonitoredItem(subscription.DefaultItem)
|
||||
{
|
||||
DisplayName = "ServerStatusState", StartNodeId = VariableIds.Server_ServerStatus_State
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var simulatedNodes = GetTestSetSimulation(Session.NamespaceUris);
|
||||
list2.AddRange(CreateMonitoredItemTestSet(subscription, simulatedNodes));
|
||||
list2.ForEach(i => i.Notification += (MonitoredItem item, MonitoredItemNotificationEventArgs e) => {
|
||||
foreach (var value in item.DequeueValues())
|
||||
{
|
||||
TestContext.Out.WriteLine("{0}: {1}, {2}, {3}", item.DisplayName, value.Value, value.SourceTimestamp, value.StatusCode);
|
||||
}
|
||||
});
|
||||
subscription.AddItems(list);
|
||||
subscription.AddItems(list2);
|
||||
await subscription.ApplyChangesAsync().ConfigureAwait(false);
|
||||
await subscription.SetPublishingModeAsync(false).ConfigureAwait(false);
|
||||
Assert.False(subscription.PublishingEnabled);
|
||||
@@ -261,7 +266,7 @@ namespace Opc.Ua.Client.Tests
|
||||
|
||||
|
||||
[Test, Order(200)]
|
||||
public void LoadSubscription()
|
||||
public async Task LoadSubscriptionAsync()
|
||||
{
|
||||
if (!File.Exists(m_subscriptionTestXml)) Assert.Ignore("Save file {0} does not exist yet", m_subscriptionTestXml);
|
||||
|
||||
@@ -270,22 +275,36 @@ namespace Opc.Ua.Client.Tests
|
||||
Assert.NotNull(subscriptions);
|
||||
Assert.IsNotEmpty(subscriptions);
|
||||
|
||||
int valueChanges = 0;
|
||||
|
||||
foreach (var subscription in subscriptions)
|
||||
{
|
||||
var list = subscription.MonitoredItems.ToList();
|
||||
list.ForEach(i => i.Notification += (MonitoredItem item, MonitoredItemNotificationEventArgs e) => {
|
||||
foreach (var value in item.DequeueValues())
|
||||
{
|
||||
valueChanges++;
|
||||
TestContext.Out.WriteLine("{0}: {1}, {2}, {3}", item.DisplayName, value.Value, value.SourceTimestamp, value.StatusCode);
|
||||
}
|
||||
});
|
||||
|
||||
Session.AddSubscription(subscription);
|
||||
subscription.Create();
|
||||
await subscription.CreateAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
Thread.Sleep(5000);
|
||||
await Task.Delay(5000);
|
||||
|
||||
foreach (var subscription in subscriptions)
|
||||
TestContext.Out.WriteLine("{0} value changes.", valueChanges);
|
||||
|
||||
Assert.GreaterOrEqual(valueChanges, 10);
|
||||
|
||||
foreach (var subscription in Session.Subscriptions)
|
||||
{
|
||||
OutputSubscriptionInfo(TestContext.Out, subscription);
|
||||
}
|
||||
|
||||
var result = Session.RemoveSubscriptions(subscriptions);
|
||||
var result = await Session.RemoveSubscriptionsAsync(subscriptions).ConfigureAwait(false);
|
||||
Assert.True(result);
|
||||
|
||||
}
|
||||
|
||||
[Theory, Order(300)]
|
||||
@@ -477,7 +496,7 @@ namespace Opc.Ua.Client.Tests
|
||||
/// <summary>
|
||||
/// The origin session gets network disconnected,
|
||||
/// after transfer available sequence numbers are
|
||||
/// just ackoledged.
|
||||
/// just acknoledged.
|
||||
/// </summary>
|
||||
DisconnectedAck,
|
||||
/// <summary>
|
||||
@@ -586,8 +605,8 @@ namespace Opc.Ua.Client.Tests
|
||||
var transferSubscriptions = new SubscriptionCollection();
|
||||
if (transferType != TransferType.KeepOpen)
|
||||
{
|
||||
// load
|
||||
transferSubscriptions.AddRange(targetSession.Load(filePath));
|
||||
// load subscriptions for transfer
|
||||
transferSubscriptions.AddRange(targetSession.Load(filePath, true));
|
||||
|
||||
// hook notifications for log output
|
||||
int ii = 0;
|
||||
|
||||
Reference in New Issue
Block a user