/// <summary> /// Constrcutor to initiate the reflective filter's 'filtering' operation. /// /// object type of holding property value /// the type of collection to add the object back into if filtered /// the optional clause of == or != to /// the FilterPropertiesCollection that contains /// all of the property names and values that we need to match /// /// the filter operand. Either an OR or AND /// </summary> public FilterOperation(Type typeOfObject, Type typeOfCollection, FilterClause clause, FilterPropertyCollection propertiesAndValues, FilterOperand operand) { _ObjectType = typeOfObject; _CollectionType = typeOfCollection; _FilterClause = clause; _PropertiesAndValues = propertiesAndValues; _Operand = operand; }
private FilterOperand GetLhs(FilterParser.Elem_opContext elem_opContext) { FilterOperand lhs = Evaluate(elem_opContext.elem_op()?[0]); if (lhs == null) { lhs = Evaluate(elem_opContext.attr_op().First()); } return(lhs); }
/// <see cref="BaseListCtrl.UpdateItem" /> protected override void UpdateItem(ListViewItem listItem, object item, int index) { FilterOperand operand = item as FilterOperand; if (operand == null) { base.UpdateItem(listItem, item); return; } listItem.SubItems[0].Text = String.Format("[{0}]", index); listItem.SubItems[1].Text = operand.ToString(m_session.NodeCache); listItem.Tag = operand; }
/// <summary> /// Returns the list of operands in the control. /// </summary> public List <FilterOperand> GetOperands() { List <FilterOperand> operands = new List <FilterOperand>(); for (int ii = 0; ii < ItemsLV.Items.Count; ii++) { FilterOperand operand = ItemsLV.Items[ii].Tag as FilterOperand; if (operand != null) { operands.Add(operand); } } return(operands); }
public ReflectiveFilter(Type typeOfObject, Type typeOfCollection, FilterOperand operand) { _FilterList = new FilterPropertyCollection(); _ObjectType = typeOfObject; _CollectionType = typeOfCollection; _Operand = operand; try { // create the concrete collection type _FilteredCollection = (IList)Activator.CreateInstance(_CollectionType); } catch (System.MemberAccessException) { throw new MemberAccessException("You must specify a collection that is not abstract"); } }
private FilterOperand GetRhs(FilterParser.Elem_opContext elem_opContext) { FilterOperand rhs = Evaluate(elem_opContext.lit_op()); if (rhs == null) { rhs = Evaluate(elem_opContext.attr_op().Last()); } if (rhs == null) { var elem = elem_opContext.elem_op(); if (elem?.Length == 2) { rhs = Evaluate(elem_opContext.elem_op()?[1]); } } return(rhs); }
/// <summary> /// Convert to service model /// </summary> /// <param name="model"></param> /// <param name="encoder"></param> /// <returns></returns> public static FilterOperandModel Encode(this IVariantEncoder encoder, FilterOperand model) { if (model == null) { return(null); } switch (model) { case ElementOperand elem: return(new FilterOperandModel { Index = elem.Index }); case LiteralOperand lit: return(new FilterOperandModel { Value = encoder.Encode(lit.Value, out _) }); case AttributeOperand attr: return(new FilterOperandModel { NodeId = attr.NodeId.AsString(encoder.Context), AttributeId = (NodeAttribute)attr.AttributeId, BrowsePath = attr.BrowsePath.AsString(encoder.Context), IndexRange = attr.IndexRange, Alias = attr.Alias }); case SimpleAttributeOperand sattr: return(new FilterOperandModel { NodeId = sattr.TypeDefinitionId.AsString(encoder.Context), AttributeId = (NodeAttribute)sattr.AttributeId, BrowsePath = sattr.BrowsePath? .Select(p => p.AsString(encoder.Context)) .ToArray(), IndexRange = sattr.IndexRange }); default: throw new NotSupportedException("Operand not supported"); } }
public static string GetSqlOperation(this FilterOperand operand) { switch (operand) { case FilterOperand.GreaterThan: return(">"); case FilterOperand.GreaterThanEqual: return(">="); case FilterOperand.LessThan: return("<"); case FilterOperand.LessThanEqual: return("<="); case FilterOperand.Equals: return("="); default: return("="); } }
public QueryFilter(string fieldName, FilterOperand operand, string value) { this._fieldName = fieldName; this._operand = operand; this._value = value; }
/// <summary> /// Displays the dialog. /// </summary> public FilterOperand ShowDialog( Session session, IList <ContentFilterElement> elements, int index, FilterOperand operand) { if (session == null) { throw new ArgumentNullException("session"); } if (elements == null) { throw new ArgumentNullException("elements"); } m_session = session; TypeDefinitionIdCTRL.Browser = new Browser(session); TypeDefinitionIdCTRL.RootId = ObjectTypes.BaseEventType; OperandTypeCB.SelectedItem = typeof(LiteralOperand).Name; if (operand != null) { OperandTypeCB.SelectedItem = operand.GetType().Name; } ElementsCB.Items.Clear(); for (int ii = index + 1; ii < elements.Count; ii++) { ElementsCB.Items.Add(elements[ii].ToString(m_session.NodeCache)); } ElementOperand elementOperand = operand as ElementOperand; if (elementOperand != null) { ElementsCB.SelectedIndex = (int)elementOperand.Index - index - 1; } AttributeOperand attributeOperand = operand as AttributeOperand; if (attributeOperand != null) { TypeDefinitionIdCTRL.Identifier = attributeOperand.NodeId; BrowsePathTB.Text = attributeOperand.BrowsePath.Format(session.NodeCache.TypeTree); AttributeIdCB.SelectedItem = Attributes.GetBrowseName(attributeOperand.AttributeId); IndexRangeTB.Text = attributeOperand.IndexRange; AliasTB.Text = attributeOperand.Alias; } LiteralOperand literalOperand = operand as LiteralOperand; if (literalOperand != null) { NodeId datatypeId = TypeInfo.GetDataTypeId(literalOperand.Value.Value); DataTypeCB.SelectedItem = TypeInfo.GetBuiltInType(datatypeId); StringBuilder buffer = new StringBuilder(); Array array = literalOperand.Value.Value as Array; if (array != null) { for (int ii = 0; ii < array.Length; ii++) { if (ii > 0) { buffer.Append("\r\n"); } buffer.AppendFormat("{0}", new Variant(array.GetValue(ii))); } } else { buffer.AppendFormat("{0}", literalOperand.Value); } ValueTB.Text = buffer.ToString(); } if (ShowDialog() != DialogResult.OK) { return(null); } return(operand); }
/// <summary> /// Applys the filter. /// </summary> /// <param name="property">Property.</param> /// <param name="compareValue">Compare value.</param> public void ApplyFilter(string property, object compareValue, FilterOperand operand) { PropertyDescriptor filterBy = GetPropertyDescriptor(property); filteredList = new ArrayList(); foreach (object obj in baseList) { switch (operand) { case FilterOperand.Equals: { if(filterBy.GetValue(obj).Equals(compareValue)) filteredList.Add(obj); break; } case FilterOperand.NotEquals: { if(!(filterBy.GetValue(obj).Equals(compareValue))) filteredList.Add(obj); break; } } } isFiltered = true; if(ListChanged != null) { ListChanged(this, new ListChangedEventArgs(ListChangedType.Reset, 0)); } }
/// <summary> /// Displays the dialog. /// </summary> public FilterOperand ShowDialog( Session session, IList<ContentFilterElement> elements, int index, FilterOperand operand) { if (session == null) throw new ArgumentNullException("session"); if (elements == null) throw new ArgumentNullException("elements"); m_session = session; TypeDefinitionIdCTRL.Browser = new Browser(session); TypeDefinitionIdCTRL.RootId = ObjectTypes.BaseEventType; OperandTypeCB.SelectedItem = typeof(LiteralOperand).Name; if (operand != null) { OperandTypeCB.SelectedItem = operand.GetType().Name; } ElementsCB.Items.Clear(); for (int ii = index+1; ii < elements.Count; ii++) { ElementsCB.Items.Add(elements[ii].ToString(m_session.NodeCache)); } ElementOperand elementOperand = operand as ElementOperand; if (elementOperand != null) { ElementsCB.SelectedIndex = (int)elementOperand.Index - index -1; } AttributeOperand attributeOperand = operand as AttributeOperand; if (attributeOperand != null) { TypeDefinitionIdCTRL.Identifier = attributeOperand.NodeId; BrowsePathTB.Text = attributeOperand.BrowsePath.Format(session.NodeCache.TypeTree); AttributeIdCB.SelectedItem = Attributes.GetBrowseName(attributeOperand.AttributeId); IndexRangeTB.Text = attributeOperand.IndexRange; AliasTB.Text = attributeOperand.Alias; } LiteralOperand literalOperand = operand as LiteralOperand; if (literalOperand != null) { NodeId datatypeId = TypeInfo.GetDataTypeId(literalOperand.Value.Value); DataTypeCB.SelectedItem = TypeInfo.GetBuiltInType(datatypeId); StringBuilder buffer = new StringBuilder(); Array array = literalOperand.Value.Value as Array; if (array != null) { for (int ii = 0; ii < array.Length; ii++) { if (ii > 0) { buffer.Append("\r\n"); } buffer.AppendFormat("{0}", new Variant(array.GetValue(ii))); } } else { buffer.AppendFormat("{0}", literalOperand.Value); } ValueTB.Text = buffer.ToString(); } if (ShowDialog() != DialogResult.OK) { return null; } return operand; }
String BuildFilterCondition(FilterOperationBase filter) { StringBuilder builder = new StringBuilder(); if (filter != null) { // Опрерация FilterOperation operation = filter as FilterOperation; if (operation != null) { List <String> operands = new List <string>(); foreach (FilterOperationBase child in operation.Children) { String x = BuildFilterCondition(child); if (!String.IsNullOrEmpty(x)) { operands.Add(String.Format("({0})", x)); } } if (operands.Count > 1) { builder.Append("("); } for (int i = 0; i < operands.Count; i++) { if (i > 0) { builder.AppendFormat(" {0} ", operation.Operation.ToString()); } builder.Append(operands[i]); } if (operands.Count > 1) { builder.Append(")"); } } FilterOperand operand = filter as FilterOperand; if (operand != null) { // Если свойство не является общим для всех уровней - (общие: Caption, UniqueName, Name) // То при формировании нужно обязательно проверять чтобы текущий уровень был именно тем, на котором это свойство есть // Исключение составляют случаи когда измерение Parent-Child bool isParentChild = false; // XXX //try //{ // OlapMetadataProvider provider = new OlapMetadataProvider(QueryExecuter.Connection); // HierarchyInfo hierarchy = provider.GetHierarchy(cubeName, String.Empty, hierarchyUniqueName); // if(hierarchy != null && hierarchy.HierarchyOrigin == HierarchyInfoOrigin.ParentChildHierarchy) // { // isParentChild = true; // } //} //catch { } // Свойство с одним и тем же именем может присутствовать на нескольких уровнях. В данном случае operand.PropertyLevels содержит коллекцию уникальных имен уровней. Их все нужно учесть if (operand.PropertyLevels.Count != 0 && !isParentChild) { int i = 0; builder.Append("("); foreach (String levelUniqueName in operand.PropertyLevels) { if (i > 0) { builder.Append("or "); } builder.AppendFormat("({0}.Level is {1}) ", HierarchyUniqueName, levelUniqueName); i++; } builder.Append(")"); builder.Append(" and "); } switch (operand.Condition) { case ConditionTypes.Equal: builder.AppendFormat("{0}.Properties(\"{1}\")='{2}'", HierarchyUniqueName, operand.Property, operand.Value); break; case ConditionTypes.Contains: builder.AppendFormat("InStr({0}.Properties(\"{1}\"),'{2}') <> 0", HierarchyUniqueName, operand.Property, operand.Value); break; case ConditionTypes.BeginWith: //Позиция при использовании InStr начинается с 1 builder.AppendFormat("InStr({0}.Properties(\"{1}\"),'{2}') = 1", HierarchyUniqueName, operand.Property, operand.Value); break; } } } return(builder.ToString()); }
/// <summary> /// Monitoring for an event source starts if it is required. /// </summary> public async Task MonitorEventsAsync(CancellationToken ct) { bool sessionLocked = false; try { try { sessionLocked = await LockSessionAsync().ConfigureAwait(false); // if the session is not connected or shutdown in progress, return if (!sessionLocked || ct.IsCancellationRequested || State != SessionState.Connected) { return; } } catch (Exception) { throw; } // ensure all nodes in all subscriptions of this session are monitored. foreach (var opcEventSubscription in OpcEventSubscriptions) { // create the subscription, if it is not yet there. if (opcEventSubscription.OpcUaClientSubscription == null) { opcEventSubscription.OpcUaClientSubscription = CreateSubscription(opcEventSubscription.RequestedPublishingInterval, out int revisedPublishingInterval); opcEventSubscription.PublishingInterval = revisedPublishingInterval; Logger.Information($"Create Event subscription on endpoint '{EndpointUrl}' requested OPC publishing interval is {opcEventSubscription.RequestedPublishingInterval} ms. (revised: {revisedPublishingInterval} ms)"); } // process all unmonitored events. var unmonitoredEvents = opcEventSubscription.OpcMonitoredItems.Where(i => (i.State == OpcMonitoredItemState.Unmonitored || i.State == OpcMonitoredItemState.UnmonitoredNamespaceUpdateRequested)); int additionalMonitoredEventsCount = 0; int monitoredEventsCount = 0; bool haveUnmonitoredEvents = false; if (unmonitoredEvents.Count() != 0) { haveUnmonitoredEvents = true; monitoredEventsCount = opcEventSubscription.OpcMonitoredItems.Count(i => (i.State == OpcMonitoredItemState.Monitored)); Logger.Information($"Start monitoring events on endpoint '{EndpointUrl}'. Currently monitoring {monitoredEventsCount} events."); } // init perf data Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); foreach (var unmonitoredEvent in unmonitoredEvents) { // if the session is not connected or a shutdown is in progress, we stop trying and wait for the next cycle if (ct.IsCancellationRequested || State != SessionState.Connected) { break; } NodeId currentNodeId = null; try { // update the namespace of the node if requested. there are two cases where this is requested: // 1) publishing requests via the OPC server method are raised using a NodeId format. for those // the NodeId format is converted into an ExpandedNodeId format // 2) ExpandedNodeId configuration file entries do not have at parsing time a session to get // the namespace index. this is set now. if (unmonitoredEvent.State == OpcMonitoredItemState.UnmonitoredNamespaceUpdateRequested) { if (unmonitoredEvent.ConfigType == OpcMonitoredItemConfigurationType.ExpandedNodeId) { ExpandedNodeId expandedNodeId = ExpandedNodeId.Parse(unmonitoredEvent.Id); int namespaceIndex = _namespaceTable.GetIndex(expandedNodeId.NamespaceUri); if (namespaceIndex < 0) { Logger.Information($"The namespace URI of node '{expandedNodeId.ToString()}' can be not mapped to a namespace index."); } else { unmonitoredEvent.IdAsExpandedNodeId = expandedNodeId; } } if (unmonitoredEvent.ConfigType == OpcMonitoredItemConfigurationType.NodeId) { NodeId nodeId = NodeId.Parse(unmonitoredEvent.Id); string namespaceUri = _namespaceTable.ToArray().ElementAtOrDefault(nodeId.NamespaceIndex); if (string.IsNullOrEmpty(namespaceUri)) { Logger.Information($"The namespace index of node '{nodeId.ToString()}' is invalid and the node format can not be updated."); } else { unmonitoredEvent.IdAsExpandedNodeId = new ExpandedNodeId(nodeId.Identifier, nodeId.NamespaceIndex, namespaceUri, 0); unmonitoredEvent.ConfigType = OpcMonitoredItemConfigurationType.ExpandedNodeId; } } unmonitoredEvent.State = OpcMonitoredItemState.Unmonitored; } // lookup namespace index if ExpandedNodeId format has been used and build NodeId identifier. if (unmonitoredEvent.ConfigType == OpcMonitoredItemConfigurationType.ExpandedNodeId) { ExpandedNodeId expandedNodeId = ExpandedNodeId.Parse(unmonitoredEvent.Id); int namespaceIndex = _namespaceTable.GetIndex(expandedNodeId.NamespaceUri); if (namespaceIndex < 0) { Logger.Warning($"Syntax or namespace URI of ExpandedNodeId '{expandedNodeId.ToString()}' is invalid and will be ignored."); continue; } unmonitoredEvent.IdAsNodeId = new NodeId(expandedNodeId.Identifier, expandedNodeId.NamespaceIndex); currentNodeId = unmonitoredEvent.IdAsNodeId; } else { NodeId nodeId = NodeId.Parse(unmonitoredEvent.Id); string namespaceUri = _namespaceTable.ToArray().ElementAtOrDefault(nodeId.NamespaceIndex); if (string.IsNullOrEmpty(namespaceUri)) { Logger.Information($"The namespace index of node '{nodeId.ToString()}' is invalid and the node format can not be updated."); } else { unmonitoredEvent.IdAsExpandedNodeId = new ExpandedNodeId(nodeId.Identifier, nodeId.NamespaceIndex, namespaceUri, 0); currentNodeId = nodeId; } } // if configured, get the key for the node, otherwise use the nodeId Node node; if (string.IsNullOrEmpty(unmonitoredEvent.Key)) { if (FetchOpcNodeDisplayName == true) { node = OpcUaClientSession.ReadNode(currentNodeId); unmonitoredEvent.Key = node.DisplayName.Text ?? currentNodeId.ToString(); } else { unmonitoredEvent.Key = currentNodeId.ToString(); } } // resolve all node and namespace references in the select and where clauses EventFilter eventFilter = new EventFilter(); foreach (var selectClause in unmonitoredEvent.EventConfiguration.SelectClauses) { SimpleAttributeOperand simpleAttributeOperand = new SimpleAttributeOperand(); simpleAttributeOperand.AttributeId = selectClause.AttributeId.ResolveAttributeId(); simpleAttributeOperand.IndexRange = selectClause.IndexRange; NodeId typeId = selectClause.TypeId.ToNodeId(_namespaceTable); simpleAttributeOperand.TypeDefinitionId = new NodeId(typeId); QualifiedNameCollection browsePaths = new QualifiedNameCollection(); foreach (var browsePath in selectClause.BrowsePaths) { browsePaths.Add(QualifiedName.Parse(browsePath)); } simpleAttributeOperand.BrowsePath = browsePaths; eventFilter.SelectClauses.Add(simpleAttributeOperand); } foreach (var whereClauseElement in unmonitoredEvent.EventConfiguration.WhereClause) { ContentFilterElement contentFilterElement = new ContentFilterElement(); contentFilterElement.FilterOperator = whereClauseElement.Operator.ResolveFilterOperator(); switch (contentFilterElement.FilterOperator) { case FilterOperator.OfType: case FilterOperator.InView: if (whereClauseElement.Operands.Count != 1) { Logger.Error($"The where clause element '{whereClauseElement.ToString()}' must contain 1 operands."); continue; } FilterOperand[] filterOperands = new FilterOperand[1]; TypeInfo typeInfo = new TypeInfo(BuiltInType.NodeId, ValueRanks.Scalar); filterOperands[0] = whereClauseElement.Operands[0].GetOperand(typeInfo); eventFilter.WhereClause.Push(contentFilterElement.FilterOperator, filterOperands); break; case FilterOperator.Equals: case FilterOperator.IsNull: case FilterOperator.GreaterThan: case FilterOperator.LessThan: case FilterOperator.GreaterThanOrEqual: case FilterOperator.LessThanOrEqual: case FilterOperator.Like: case FilterOperator.Not: case FilterOperator.Between: case FilterOperator.InList: case FilterOperator.And: case FilterOperator.Or: case FilterOperator.Cast: case FilterOperator.BitwiseAnd: case FilterOperator.BitwiseOr: case FilterOperator.RelatedTo: default: Logger.Error($"The operator '{contentFilterElement.FilterOperator.ToString()}' is not supported."); break; } } // add the new monitored event. IOpcUaMonitoredItem monitoredItem = new OpcUaMonitoredItem() { StartNodeId = currentNodeId, AttributeId = Attributes.EventNotifier, DisplayName = unmonitoredEvent.Key, MonitoringMode = unmonitoredEvent.MonitoringMode, SamplingInterval = 0, QueueSize = unmonitoredEvent.QueueSize, DiscardOldest = unmonitoredEvent.DiscardOldest, Filter = eventFilter }; monitoredItem.Notification += unmonitoredEvent.NotificationEventHandler; opcEventSubscription.OpcUaClientSubscription.AddItem(monitoredItem); unmonitoredEvent.OpcUaClientMonitoredItem = monitoredItem; unmonitoredEvent.State = OpcMonitoredItemState.Monitored; unmonitoredEvent.EndpointUrl = EndpointUrl; Logger.Verbose($"Created monitored event for node '{currentNodeId.ToString()}' in subscription with id '{opcEventSubscription.OpcUaClientSubscription.Id}' on endpoint '{EndpointUrl}' (version: {NodeConfigVersion:X8})"); if (unmonitoredEvent.RequestedSamplingInterval != monitoredItem.SamplingInterval) { Logger.Information($"Sampling interval: requested: {unmonitoredEvent.RequestedSamplingInterval}; revised: {monitoredItem.SamplingInterval}"); unmonitoredEvent.SamplingInterval = monitoredItem.SamplingInterval; } if (additionalMonitoredEventsCount % 10000 == 0) { Logger.Information($"Now monitoring {monitoredEventsCount + additionalMonitoredEventsCount} events in subscription with id '{opcEventSubscription.OpcUaClientSubscription.Id}'"); } } catch (Exception e) when(e.GetType() == typeof(ServiceResultException)) { ServiceResultException sre = (ServiceResultException)e; switch ((uint)sre.Result.StatusCode) { case StatusCodes.BadSessionIdInvalid: { Logger.Information($"Session with Id {OpcUaClientSession.SessionId} is no longer available on endpoint '{EndpointUrl}'. Cleaning up."); // clean up the session InternalDisconnect(); break; } case StatusCodes.BadNodeIdInvalid: case StatusCodes.BadNodeIdUnknown: { Logger.Error($"Failed to monitor node '{currentNodeId}' on endpoint '{EndpointUrl}'."); Logger.Error($"OPC UA ServiceResultException is '{sre.Result}'. Please check your publisher configuration for this node."); break; } default: { Logger.Error($"Unhandled OPC UA ServiceResultException '{sre.Result}' when monitoring node '{currentNodeId}' on endpoint '{EndpointUrl}'. Continue."); break; } } } catch (Exception e) { Logger.Error(e, $"Failed to monitor node '{currentNodeId}' on endpoint '{EndpointUrl}'"); } } opcEventSubscription.OpcUaClientSubscription.SetPublishingMode(true); opcEventSubscription.OpcUaClientSubscription.ApplyChanges(); stopWatch.Stop(); if (haveUnmonitoredEvents == true) { monitoredEventsCount = opcEventSubscription.OpcMonitoredItems.Count(i => (i.State == OpcMonitoredItemState.Monitored)); Logger.Information($"Done processing unmonitored events on endpoint '{EndpointUrl}' took {stopWatch.ElapsedMilliseconds} msec. Now monitoring {monitoredEventsCount} events in subscription with id '{opcEventSubscription.OpcUaClientSubscription.Id}'."); } } } catch (Exception e) { Logger.Error(e, "Exception"); } finally { if (sessionLocked) { ReleaseSession(); } } }