private void UpdateClientFilter(ClientRequestInfo requestInfo)
{
const int HighPriority = 2;
if (requestInfo.Request.Arguments.ContainsHelpRequest)
{
StringBuilder helpMessage = new StringBuilder();
helpMessage.Append("Filters status messages coming from the service.");
helpMessage.AppendLine();
helpMessage.AppendLine();
helpMessage.Append(" Usage:");
helpMessage.AppendLine();
helpMessage.Append(" Filter [ { -List |");
helpMessage.AppendLine();
helpMessage.Append(" -Include <FilterDefinition> |");
helpMessage.AppendLine();
helpMessage.Append(" -Exclude <FilterDefinition> |");
helpMessage.AppendLine();
helpMessage.Append(" -Remove <ID> } ... ]");
helpMessage.AppendLine();
helpMessage.AppendLine();
helpMessage.Append(" Filter -?");
helpMessage.AppendLine();
helpMessage.AppendLine();
helpMessage.Append(" FilterDefinition ::= Type { Alarm | Warning | Information } |");
helpMessage.AppendLine();
helpMessage.Append(" Message <FilterSpec> |");
helpMessage.AppendLine();
helpMessage.Append(" Regex <FilterSpec>");
helpMessage.AppendLine();
helpMessage.AppendLine();
helpMessage.Append(" Options:");
helpMessage.AppendLine();
helpMessage.Append(" -List".PadRight(20));
helpMessage.Append("Displays a list of the client's active filters");
helpMessage.AppendLine();
helpMessage.Append(" -Include".PadRight(20));
helpMessage.Append("Defines a filter matching messages to be displayed");
helpMessage.AppendLine();
helpMessage.Append(" -Exclude".PadRight(20));
helpMessage.Append("Defines a filter matching messages to be suppressed");
helpMessage.AppendLine();
helpMessage.Append(" -Remove".PadRight(20));
helpMessage.Append("Removes a filter");
helpMessage.AppendLine();
helpMessage.Append(" -?".PadRight(20));
helpMessage.Append("Displays this help message");
helpMessage.AppendLine();
helpMessage.AppendLine();
UpdateStatus(requestInfo.Sender.ClientID, UpdateType.Information, "{0}", helpMessage.ToString());
return;
}
string[] args = Arguments.ToArgs(requestInfo.Request.Arguments.ToString());
ClientFilter mergeFilter = new ClientFilter();
List<int> removalIDs = new List<int>();
bool argsContainsList = !args.Any();
int i = 0;
while (i < args.Length)
{
if (args[i].Equals("-List", StringComparison.OrdinalIgnoreCase))
{
// Set the boolean flag indicating that
// the client requested a list of filters
argsContainsList = true;
i++;
}
else if (args[i].Equals("-Remove", StringComparison.OrdinalIgnoreCase))
{
int filterID;
// Check for parsing errors with the number of arguments
if (i + 1 >= args.Length)
throw new FormatException("Malformed expression - Missing ID argument in 'Filter -Remove <ID>' command. Type 'Filter -?' to get help with this command.");
// Check for parsing errors in the filter ID
if (!int.TryParse(args[i + 1], out filterID))
throw new FormatException("Malformed expression - ID argument supplied to 'Filter -Remove <ID>' must be an integer. Type 'Filter -?' to get help with this command.");
// Add the ID to the list of filter IDs to be removed from the client's filter
if (i + 1 < args.Length && int.TryParse(args[i + 1], out filterID))
removalIDs.Add(filterID);
i += 2;
}
else if (args[i].Equals("-Include", StringComparison.OrdinalIgnoreCase))
{
string filterType;
string filterSpec;
UpdateType updateType;
// Validate the number of arguments
// associated with the filter
if (i + 2 >= args.Length)
throw new FormatException("Malformed expression - Missing arguments in 'Filter -Include <FilterDefinition>' command. Type 'Filter -?' to get help with this command.");
filterType = args[i + 1];
filterSpec = args[i + 2];
if (filterType.Equals("Message", StringComparison.OrdinalIgnoreCase))
{
// Add message filters to the merge filter
mergeFilter.PatternInclusionFilters.Add(Regex.Escape(filterSpec));
}
else if (args[i + 1].Equals("Type", StringComparison.OrdinalIgnoreCase))
{
// Add type filters to the merge filter
if (!Enum.TryParse(filterSpec, true, out updateType))
throw new FormatException($"Malformed expression - Unrecognized message type '{filterSpec}' in 'Filter -Include <FilterDefinition>' command. Type 'Filter -?' to get help with this command.");
mergeFilter.TypeInclusionFilters.Add(updateType);
}
else if (args[i + 1].Equals("Regex", StringComparison.OrdinalIgnoreCase))
{
// Add pattern filters to the merge filter
mergeFilter.PatternInclusionFilters.Add(filterSpec);
}
else
{
throw new FormatException($"Malformed expression - Unrecognized filter type '{filterType}' in 'Filter -Include <FilterDefinition>' command. Type 'Filter -?' to get help with this command.");
}
i += 3;
}
else if (args[i].Equals("-Exclude", StringComparison.OrdinalIgnoreCase))
{
string filterType;
string filterSpec;
UpdateType updateType;
// Validate the number of arguments
// associated with the filter
if (i + 2 >= args.Length)
throw new FormatException("Malformed expression - Missing arguments in 'Filter -Exclude <FilterDefinition>' command. Type 'Filter -?' to get help with this command.");
filterType = args[i + 1];
filterSpec = args[i + 2];
if (filterType.Equals("Message", StringComparison.OrdinalIgnoreCase))
{
// Add message filters to the merge filter
mergeFilter.PatternExclusionFilters.Add(Regex.Escape(filterSpec));
}
else if (filterType.Equals("Type", StringComparison.OrdinalIgnoreCase))
{
// Add type filters to the merge filter
if (!Enum.TryParse(filterSpec, true, out updateType))
throw new FormatException($"Malformed expression - Unrecognized message type '{filterSpec}' in 'Filter -Exclude <FilterDefinition>' command. Type 'Filter -?' to get help with this command.");
mergeFilter.TypeExclusionFilters.Add(updateType);
}
else if (filterType.Equals("Regex", StringComparison.OrdinalIgnoreCase))
{
// Add pattern filters to the merge filter
mergeFilter.PatternExclusionFilters.Add(filterSpec);
}
else
{
throw new FormatException($"Malformed expression - Unrecognized filter type '{filterType}' in 'Filter -Exclude <FilterDefinition>' command. Type 'Filter -?' to get help with this command.");
}
i += 3;
}
else
{
throw new FormatException($"Malformed expression - Unrecognized argument '{args[i]}'. Type 'Filter -?' to get help with this command.");
}
}
// Determine whether the filter was actually updated
bool filterUpdated = mergeFilter.TypeInclusionFilters.Any() || mergeFilter.TypeExclusionFilters.Any() || mergeFilter.PatternInclusionFilters.Any() || mergeFilter.PatternExclusionFilters.Any() || removalIDs.Any();
if (!filterUpdated && !argsContainsList)
return;
// Use the status update thread to get the
// client's config, then update the filters
m_statusUpdateThread.Push(HighPriority, () =>
{
ClientStatusUpdateConfiguration clientConfig = m_clientStatusUpdateLookup.GetOrAdd(requestInfo.Sender.ClientID, id => new ClientStatusUpdateConfiguration(id, this));
if (filterUpdated)
clientConfig.UpdateFilters(mergeFilter, removalIDs);
if (argsContainsList)
clientConfig.ListFilters(requestInfo);
});
}