private void CreateMonitoredItemsForEvents(
OperationContext context,
uint subscriptionId,
double publishingInterval,
TimestampsToReturn timestampsToReturn,
IList<MonitoredItemCreateRequest> itemsToCreate,
IList<ServiceResult> errors,
IList<MonitoringFilterResult> filterResults,
IList<IMonitoredItem> monitoredItems,
ref long globalIdCounter)
{
for (int ii = 0; ii < itemsToCreate.Count; ii++)
{
MonitoredItemCreateRequest itemToCreate = itemsToCreate[ii];
// must make sure the filter is not null before checking its type.
if (ExtensionObject.IsNull(itemToCreate.RequestedParameters.Filter))
{
continue;
}
// all event subscriptions required an event filter.
EventFilter filter = itemToCreate.RequestedParameters.Filter.Body as EventFilter;
if (filter == null)
{
continue;
}
itemToCreate.Processed = true;
// only the value attribute may be used with an event subscription.
if (itemToCreate.ItemToMonitor.AttributeId != Attributes.EventNotifier)
{
errors[ii] = StatusCodes.BadFilterNotAllowed;
continue;
}
// the index range parameter has no meaning for event subscriptions.
if (!String.IsNullOrEmpty(itemToCreate.ItemToMonitor.IndexRange))
{
errors[ii] = StatusCodes.BadIndexRangeInvalid;
continue;
}
// the data encoding has no meaning for event subscriptions.
if (!QualifiedName.IsNull(itemToCreate.ItemToMonitor.DataEncoding))
{
errors[ii] = StatusCodes.BadDataEncodingInvalid;
continue;
}
// validate the event filter.
EventFilter.Result result = filter.Validate(new FilterContext(m_server.NamespaceUris, m_server.TypeTree, context));
if (ServiceResult.IsBad(result.Status))
{
errors[ii] = result.Status;
filterResults[ii] = result.ToEventFilterResult(context.DiagnosticsMask, context.StringTable);
continue;
}
// check if a valid node.
INodeManager nodeManager = null;
object handle = GetManagerHandle(itemToCreate.ItemToMonitor.NodeId, out nodeManager);
if (handle == null)
{
errors[ii] = StatusCodes.BadNodeIdUnknown;
continue;
}
// create a globally unique identifier.
uint monitoredItemId = Utils.IncrementIdentifier(ref globalIdCounter);
MonitoredItem monitoredItem = m_server.EventManager.CreateMonitoredItem(
context,
nodeManager,
handle,
subscriptionId,
monitoredItemId,
timestampsToReturn,
publishingInterval,
itemToCreate,
filter);
// subscribe to all node managers.
if (itemToCreate.ItemToMonitor.NodeId == Objects.Server)
{
foreach (INodeManager manager in m_nodeManagers)
{
try
{
manager.SubscribeToAllEvents(context, subscriptionId, monitoredItem, false);
}
catch (Exception e)
{
Utils.Trace(e, "NodeManager threw an exception subscribing to all events. NodeManager={0}", manager);
}
}
}
// only subscribe to the node manager that owns the node.
else
{
ServiceResult error = nodeManager.SubscribeToEvents(context, handle, subscriptionId, monitoredItem, false);
if (ServiceResult.IsBad(error))
{
m_server.EventManager.DeleteMonitoredItem(monitoredItem.Id);
errors[ii] = error;
continue;
}
}
monitoredItems[ii] = monitoredItem;
errors[ii] = StatusCodes.Good;
}
}