Skip to content

Commit

Permalink
Choice & Case fixes (Chained cases & choices within one another were …
Browse files Browse the repository at this point in the history
…not picked up by the parsing)
  • Loading branch information
carl-andersson-at-westermo committed Jun 11, 2024
1 parent 9548de2 commit ff44e6c
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 54 deletions.
5 changes: 4 additions & 1 deletion YangParser/SemanticModel/Case.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ public class {{ClassName}}
public string TargetName => MakeName(Argument) + "CaseValue";

public IEnumerable<string> SubTargets =>
Children.Where(c => c is IXMLParseable or IXMLReadValue).Select(c => c.XmlObjectName).Distinct();
Children
.Where(c => c is (IXMLParseable or IXMLReadValue) and not Choice)
.Select(c => c.XmlObjectName)
.Concat(Children.OfType<Choice>().SelectMany(ch => ch.SubTargets)).Distinct();

public string ClassName => TargetName + "Case";
}
7 changes: 2 additions & 5 deletions YangParser/SemanticModel/Choice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@ public class {{TargetName}}Choice
private IEnumerable<IStatement> directChildren =>
Children.Where(c => c is (IXMLParseable or IXMLReadValue) and not Case);

private IEnumerable<IStatement> caseChildren =>
Children.OfType<Case>().SelectMany(c => c.Children).Where(c => c is IXMLParseable or IXMLReadValue);

public IEnumerable<string> SubTargets => directChildren.Concat(caseChildren)
.Select(c => c.XmlObjectName).Distinct();
public IEnumerable<string> SubTargets => directChildren
.Select(c => c.XmlObjectName).Concat(Children.OfType<Case>().SelectMany(c => c.SubTargets)).Distinct();
}
103 changes: 55 additions & 48 deletions YangParser/SemanticModel/CompilationUnit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public static class IYangServerExtensions
public static async Task Receive(this IYangServer server, global::System.IO.Stream input, global::System.IO.Stream output)
{
var initialPosition = output.Position;
var initialLength = output.Length;
string? id = null;
using XmlReader reader = XmlReader.Create(input, SerializationHelper.GetStandardReaderSettings());
using XmlWriter writer = XmlWriter.Create(output, SerializationHelper.GetStandardWriterSettings());
Expand Down Expand Up @@ -150,91 +151,97 @@ public static async Task Receive(this IYangServer server, global::System.IO.Stre
}
catch(RpcException ex)
{
await writer.FlushAsync();
output.Position = initialPosition;
await writer.WriteStartElementAsync(null, "rpc-reply", "urn:ietf:params:xml:ns:netconf:base:1.0");
output.SetLength(initialLength);
using var exceptionWriter = XmlWriter.Create(output, SerializationHelper.GetStandardWriterSettings());
await exceptionWriter.WriteStartElementAsync(null, "rpc-reply", "urn:ietf:params:xml:ns:netconf:base:1.0");
if(id != null)
{
await writer.WriteAttributeStringAsync(null, "message-id", null, id);
await exceptionWriter.WriteAttributeStringAsync(null, "message-id", null, id);
}
await writer.WriteStartElementAsync(null, "rpc-error", "urn:ietf:params:xml:ns:netconf:base:1.0");
await writer.WriteStartElementAsync(null, "error-type", "urn:ietf:params:xml:ns:netconf:base:1.0");
await writer.WriteStringAsync(ex.Type switch {
await exceptionWriter.WriteStartElementAsync(null, "rpc-error", "urn:ietf:params:xml:ns:netconf:base:1.0");
await exceptionWriter.WriteStartElementAsync(null, "error-type", "urn:ietf:params:xml:ns:netconf:base:1.0");
await exceptionWriter.WriteStringAsync(ex.Type switch {
ErrorType.Transport => "transport",
ErrorType.Rpc => "rpc",
ErrorType.Protocol => "protocol",
ErrorType.Application => "application"
});
await writer.WriteEndElementAsync();
await writer.WriteStartElementAsync(null, "error-tag", "urn:ietf:params:xml:ns:netconf:base:1.0");
await writer.WriteStringAsync(ex.Tag);
await writer.WriteEndElementAsync();
await writer.WriteStartElementAsync(null, "error-severity", "urn:ietf:params:xml:ns:netconf:base:1.0");
await writer.WriteStringAsync(ex.Severity switch {
await exceptionWriter.WriteEndElementAsync();
await exceptionWriter.WriteStartElementAsync(null, "error-tag", "urn:ietf:params:xml:ns:netconf:base:1.0");
await exceptionWriter.WriteStringAsync(ex.Tag);
await exceptionWriter.WriteEndElementAsync();
await exceptionWriter.WriteStartElementAsync(null, "error-severity", "urn:ietf:params:xml:ns:netconf:base:1.0");
await exceptionWriter.WriteStringAsync(ex.Severity switch {
Severity.Error => "error",
Severity.Warning => "warning"
});
await writer.WriteEndElementAsync();
await exceptionWriter.WriteEndElementAsync();
if(ex.ApplicationTag != null)
{
await writer.WriteStartElementAsync(null, "error-app-tag", "urn:ietf:params:xml:ns:netconf:base:1.0");
await writer.WriteStringAsync(ex.ApplicationTag);
await writer.WriteEndElementAsync();
await exceptionWriter.WriteStartElementAsync(null, "error-app-tag", "urn:ietf:params:xml:ns:netconf:base:1.0");
await exceptionWriter.WriteStringAsync(ex.ApplicationTag);
await exceptionWriter.WriteEndElementAsync();
}
if(ex.XPath != null)
{
await writer.WriteStartElementAsync(null, "error-path", "urn:ietf:params:xml:ns:netconf:base:1.0");
await writer.WriteStringAsync(ex.XPath);
await writer.WriteEndElementAsync();
await exceptionWriter.WriteStartElementAsync(null, "error-path", "urn:ietf:params:xml:ns:netconf:base:1.0");
await exceptionWriter.WriteStringAsync(ex.XPath);
await exceptionWriter.WriteEndElementAsync();
}
if(ex.Message != null)
{
await writer.WriteStartElementAsync(null, "error-message", "urn:ietf:params:xml:ns:netconf:base:1.0");
await writer.WriteStringAsync(ex.Message);
await writer.WriteEndElementAsync();
await exceptionWriter.WriteStartElementAsync(null, "error-message", "urn:ietf:params:xml:ns:netconf:base:1.0");
await exceptionWriter.WriteStringAsync(ex.Message);
await exceptionWriter.WriteEndElementAsync();
}
if(ex.Info != null)
{
await writer.WriteStartElementAsync(null, "error-info", "urn:ietf:params:xml:ns:netconf:base:1.0");
await exceptionWriter.WriteStartElementAsync(null, "error-info", "urn:ietf:params:xml:ns:netconf:base:1.0");
foreach(var info in ex.Info)
{
await writer.WriteStartElementAsync(null, info.Key, "urn:ietf:params:xml:ns:netconf:base:1.0");
await writer.WriteStringAsync(info.Value);
await writer.WriteEndElementAsync();
await exceptionWriter.WriteStartElementAsync(null, info.Key, "urn:ietf:params:xml:ns:netconf:base:1.0");
await exceptionWriter.WriteStringAsync(info.Value);
await exceptionWriter.WriteEndElementAsync();
}
await writer.WriteEndElementAsync();
await exceptionWriter.WriteEndElementAsync();
}
await writer.WriteEndElementAsync();
await writer.WriteEndElementAsync();
await exceptionWriter.WriteEndElementAsync();
await exceptionWriter.WriteEndElementAsync();
}
catch(Exception ex)
{
await writer.FlushAsync();
output.Position = initialPosition;
await writer.WriteStartElementAsync(null, "rpc-reply", "urn:ietf:params:xml:ns:netconf:base:1.0");
output.SetLength(initialLength);
using var exceptionWriter = XmlWriter.Create(output, SerializationHelper.GetStandardWriterSettings());
await exceptionWriter.WriteStartElementAsync(null, "rpc-reply", "urn:ietf:params:xml:ns:netconf:base:1.0");
if(id != null)
{
await writer.WriteAttributeStringAsync(null, "message-id", null, id);
await exceptionWriter.WriteAttributeStringAsync(null, "message-id", null, id);
}
await writer.WriteStartElementAsync(null, "rpc-error", "urn:ietf:params:xml:ns:netconf:base:1.0");
await writer.WriteStartElementAsync(null, "error-type", "urn:ietf:params:xml:ns:netconf:base:1.0");
await writer.WriteStringAsync("application");
await writer.WriteEndElementAsync();
await writer.WriteStartElementAsync(null, "error-tag", "urn:ietf:params:xml:ns:netconf:base:1.0");
await writer.WriteStringAsync("unknown");
await writer.WriteEndElementAsync();
await writer.WriteStartElementAsync(null, "error-severity", "urn:ietf:params:xml:ns:netconf:base:1.0");
await writer.WriteStringAsync("error");
await writer.WriteEndElementAsync();
await writer.WriteStartElementAsync(null, "error-app-tag", "urn:ietf:params:xml:ns:netconf:base:1.0");
await writer.WriteStringAsync(ex.GetType().Name);
await writer.WriteEndElementAsync();
await exceptionWriter.WriteStartElementAsync(null, "rpc-error", "urn:ietf:params:xml:ns:netconf:base:1.0");
await exceptionWriter.WriteStartElementAsync(null, "error-type", "urn:ietf:params:xml:ns:netconf:base:1.0");
await exceptionWriter.WriteStringAsync("application");
await exceptionWriter.WriteEndElementAsync();
await exceptionWriter.WriteStartElementAsync(null, "error-tag", "urn:ietf:params:xml:ns:netconf:base:1.0");
await exceptionWriter.WriteStringAsync("unknown");
await exceptionWriter.WriteEndElementAsync();
await exceptionWriter.WriteStartElementAsync(null, "error-severity", "urn:ietf:params:xml:ns:netconf:base:1.0");
await exceptionWriter.WriteStringAsync("error");
await exceptionWriter.WriteEndElementAsync();
await exceptionWriter.WriteStartElementAsync(null, "error-app-tag", "urn:ietf:params:xml:ns:netconf:base:1.0");
await exceptionWriter.WriteStringAsync(ex.GetType().Name);
await exceptionWriter.WriteEndElementAsync();
if(ex.Message != null)
{
await writer.WriteStartElementAsync(null, "error-message", "urn:ietf:params:xml:ns:netconf:base:1.0");
await writer.WriteStringAsync(ex.Message);
await writer.WriteEndElementAsync();
await exceptionWriter.WriteStartElementAsync(null, "error-message", "urn:ietf:params:xml:ns:netconf:base:1.0");
await exceptionWriter.WriteStringAsync(ex.Message);
await exceptionWriter.WriteEndElementAsync();
}
await writer.WriteEndElementAsync();
await writer.WriteEndElementAsync();
await exceptionWriter.WriteEndElementAsync();
await exceptionWriter.WriteEndElementAsync();
}
}
public static async Task ReceiveRPC(this IYangServer server, XmlReader reader, XmlWriter writer)
Expand Down
52 changes: 52 additions & 0 deletions YangSourceTests/RpcTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,56 @@ public async Task ExceptionGeneratingTest()
outputHelper.WriteLine(channel.LastWritten);
Assert.Contains("rpc-error", channel.LastWritten);
}

[Fact]
public async Task ExceptionThrowingTest()
{
var channel = new TestChannel
{
MessageID = Random.Shared.Next()
};
try
{
var result = await Ietf.Subscribed.Notifications.YangNode.EstablishSubscription(channel, channel.MessageID,
new Ietf.Subscribed.Notifications.YangNode.EstablishSubscriptionInput
{
Target = new Ietf.Subscribed.Notifications.YangNode.EstablishSubscriptionInput.TargetChoice
{
StreamCaseValue =
new Ietf.Subscribed.Notifications.YangNode.EstablishSubscriptionInput.TargetChoice.
StreamCaseValueCase
{
StreamFilter =
new Ietf.Subscribed.Notifications.YangNode.EstablishSubscriptionInput.
TargetChoice.StreamCaseValueCase.StreamFilterChoice
{
ByReferenceCaseValue =
new Ietf.Subscribed.Notifications.YangNode.
EstablishSubscriptionInput.TargetChoice.StreamCaseValueCase.
StreamFilterChoice.ByReferenceCaseValueCase()
{
StreamFilterName =
new Ietf.Subscribed.Notifications.YangNode.
StreamFilterRef()
}
}
}
}
});
}
catch (RpcException e)
{
outputHelper.WriteLine(e.Message);
Assert.True(true);
return;
}
catch (Exception e)
{
outputHelper.WriteLine(channel.LastXML);
outputHelper.WriteLine("_____________________________________");
outputHelper.WriteLine(channel.LastWritten);
throw;
}
Assert.Fail();
}
}

0 comments on commit ff44e6c

Please sign in to comment.