diff --git a/example/ci-pipeline.cmd b/example/ci-pipeline.cmd new file mode 100644 index 0000000..09aff24 --- /dev/null +++ b/example/ci-pipeline.cmd @@ -0,0 +1,4 @@ +dotnet build || exit -1 +dotnet test || exit -2 +dotnet policy-transformer --dllFile ./source/bin/Debug/.net7/Source.Example.dll --out ./target --format true || exit -3 +az deployment group create --resource-group rmielowski-current-wus2 --template-file .\deployment.bicep --parameters servicename=rmielowski-current-premium --name deploy-1 || exit -4 diff --git a/example/deployment.bicep b/example/deployment.bicep new file mode 100644 index 0000000..5fa456e --- /dev/null +++ b/example/deployment.bicep @@ -0,0 +1,25 @@ +param servicename string + +resource service 'Microsoft.ApiManagement/service@2023-03-01-preview' existing = { + name: servicename + scope: resourceGroup() +} + +resource echoApi 'Microsoft.ApiManagement/service/apis@2023-03-01-preview' existing = { + parent: service + name: 'echo-api' +} + +resource retrieveResource 'Microsoft.ApiManagement/service/apis/operations@2023-03-01-preview' existing = { + parent: echoApi + name: 'retrieve-resource' +} + +resource retrieveResourcePolicy 'Microsoft.ApiManagement/service/apis/operations/policies@2023-03-01-preview' = { + parent: retrieveResource + name: 'policy' + properties: { + format: 'rawxml' + value: loadTextContent('./target/${echoApi.name}.${retrieveResource.name}.xml', 'utf-8') + } +} diff --git a/example/source/EchoApi.cs b/example/source/ComplexEchoApi.cs similarity index 93% rename from example/source/EchoApi.cs rename to example/source/ComplexEchoApi.cs index 4014f93..c9ebd58 100644 --- a/example/source/EchoApi.cs +++ b/example/source/ComplexEchoApi.cs @@ -1,76 +1,76 @@ -using Mielek.Azure.ApiManagement.PolicyToolkit.Attributes; -using Mielek.Azure.ApiManagement.PolicyToolkit.Builders; -using Mielek.Azure.ApiManagement.PolicyToolkit.Expressions.Context; - -using Newtonsoft.Json.Linq; - -using System.Xml.Linq; - -using static Mielek.Azure.ApiManagement.PolicyToolkit.Builders.Policies.SetHeaderPolicyBuilder; - -namespace Contoso.Apis; - -[Library(Name = "echo-api")] -public class EchoApi -{ - [Document(Name = "retrieve-resource")] - public XElement RetrieveResource() - { - return Policy.Document() - .Inbound(policies => - { - policies - .CheckHeader(policy => - policy.Name("X-Checked") - .FailedCheckHttpCode(400) - .FailedCheckErrorMessage("Bad request") - .IgnoreCase(IsVariableSet) - .Value("Test") - .Value("Other-Test")) - .Base() - .SetHeader(policy => - policy.Name("X-Test").ExistsAction(ExistsActionType.Append) - .Value("Test") - .Value(context => context.Deployment.Region) - .Value((context) => - { - if (context.Variables.ContainsKey("Variable")) - { - return "ContainsVariable"; - } - - return "NotContainVariable"; - }) - .Value(GetKnownGUIDOrGenerateNew)); - }) - .Outbound(policies => policies.Base().SetBody(policy => policy.Body(Test.FilterBody2))) - .Create(); - } - - [Expression] - public bool IsVariableSet(IContext context) => context.Variables.ContainsKey("Variable"); - - [Expression] - public string GetKnownGUIDOrGenerateNew(IContext context) - { - if (!context.Variables - .TryGetValue("KnownGUID", out var guid)) - { - guid = Guid.NewGuid(); - } - - return $"{guid}"; - } - - [Expression] - public string FilterBody(IContext context) - { - var response = context.Response.Body.As(); - foreach (var key in new[] { "current", "minutely", "hourly", "daily", "alerts" }) - { - response.Property(key)?.Remove(); - } - - return response.ToString(); - } +using Mielek.Azure.ApiManagement.PolicyToolkit.Attributes; +using Mielek.Azure.ApiManagement.PolicyToolkit.Builders; +using Mielek.Azure.ApiManagement.PolicyToolkit.Expressions.Context; + +using Newtonsoft.Json.Linq; + +using System.Xml.Linq; + +using static Mielek.Azure.ApiManagement.PolicyToolkit.Builders.Policies.SetHeaderPolicyBuilder; + +namespace Contoso.Apis; + +[Library(Name = "echo-api")] +public class ComplexEchoApi +{ + [Document(Name = "modify-resource")] + public XElement RetrieveResource() + { + return Policy.Document() + .Inbound(policies => + { + policies + .CheckHeader(policy => + policy.Name("X-Checked") + .FailedCheckHttpCode(400) + .FailedCheckErrorMessage("Bad request") + .IgnoreCase(IsVariableSet) + .Value("Test") + .Value("Other-Test")) + .Base() + .SetHeader(policy => + policy.Name("X-Test").ExistsAction(ExistsActionType.Append) + .Value("Test") + .Value(context => context.Deployment.Region) + .Value((context) => + { + if (context.Variables.ContainsKey("Variable")) + { + return "ContainsVariable"; + } + + return "NotContainVariable"; + }) + .Value(GetKnownGUIDOrGenerateNew)); + }) + .Outbound(policies => policies.Base().SetBody(policy => policy.Body(ExternalExpressions.FilterBody))) + .Create(); + } + + [Expression] + public bool IsVariableSet(IContext context) => context.Variables.ContainsKey("Variable"); + + [Expression] + public string GetKnownGUIDOrGenerateNew(IContext context) + { + if (!context.Variables + .TryGetValue("KnownGUID", out var guid)) + { + guid = Guid.NewGuid(); + } + + return $"{guid}"; + } + + [Expression] + public string FilterBody(IContext context) + { + var response = context.Response.Body.As(); + foreach (var key in new[] { "current", "minutely", "hourly", "daily", "alerts" }) + { + response.Property(key)?.Remove(); + } + + return response.ToString(); + } } \ No newline at end of file diff --git a/example/source/ExternalExpressions.cs b/example/source/ExternalExpressions.cs new file mode 100644 index 0000000..59255b9 --- /dev/null +++ b/example/source/ExternalExpressions.cs @@ -0,0 +1,24 @@ + +using Mielek.Azure.ApiManagement.PolicyToolkit.Attributes; +using Mielek.Azure.ApiManagement.PolicyToolkit.Expressions.Context; + +using Newtonsoft.Json.Linq; + +namespace Contoso.Apis; + +public static class ExternalExpressions +{ + [Expression] + public static string FilterBody(IContext context) + { + var body = context.Response.Body.As(); + foreach (var internalProperty in new string[]{ "location", "secret" }) + { + if (body.ContainsKey(internalProperty)) + { + body.Remove(internalProperty); + } + } + return body.ToString(); + } +} \ No newline at end of file diff --git a/example/source/SimpleEchoApi.cs b/example/source/SimpleEchoApi.cs new file mode 100644 index 0000000..3938d2c --- /dev/null +++ b/example/source/SimpleEchoApi.cs @@ -0,0 +1,37 @@ +using System.Xml.Linq; + +using Mielek.Azure.ApiManagement.PolicyToolkit.Attributes; +using Mielek.Azure.ApiManagement.PolicyToolkit.Builders; +using Mielek.Azure.ApiManagement.PolicyToolkit.Expressions.Context; + +using Newtonsoft.Json.Linq; + +namespace Contoso.Apis; + +[Library(Name = "echo-api")] +public class SimpleEchoApi +{ + [Document(Name = "retrieve-resource")] + public XElement RetrieveResourcePolicyDocument() + { + return Policy.Document() + .Outbound(o => o + .Base() + .SetBody(p => p.Body(FilterBody))) + .Create(); + } + + [Expression] + public string FilterBody(IContext context) + { + var body = context.Response.Body.As(); + foreach (var internalProperty in new string[]{ "location", "secret" }) + { + if (body.ContainsKey(internalProperty)) + { + body.Remove(internalProperty); + } + } + return body.ToString(); + } +} \ No newline at end of file diff --git a/example/source/Source.Example.csproj b/example/source/Source.Example.csproj index 21d3fb9..e5fd0ec 100644 --- a/example/source/Source.Example.csproj +++ b/example/source/Source.Example.csproj @@ -14,8 +14,4 @@ - - - - \ No newline at end of file diff --git a/example/source/Test.cs b/example/source/Test.cs deleted file mode 100644 index 9c6724c..0000000 --- a/example/source/Test.cs +++ /dev/null @@ -1,21 +0,0 @@ - -using Mielek.Azure.ApiManagement.PolicyToolkit.Attributes; -using Mielek.Azure.ApiManagement.PolicyToolkit.Expressions.Context; - -using Newtonsoft.Json.Linq; - -namespace Contoso.Apis; - -public class Test -{ - [Expression] - public static string FilterBody2(IContext context) - { - var response = context.Response.Body.As(); - foreach (var key in new[] { "current", "minutely", "hourly", "daily", "alerts" }) - { - response.Property(key)?.Remove(); - } - return response.ToString(); - } -} \ No newline at end of file diff --git a/example/test/EchoApiBuildTests.cs b/example/test/EchoApiBuildTests.cs index 48ab57e..d8a784a 100644 --- a/example/test/EchoApiBuildTests.cs +++ b/example/test/EchoApiBuildTests.cs @@ -8,6 +8,6 @@ public class EchoApiBuildTests [TestMethod] public void ShouldBuildCorrectly() { - new EchoApi().RetrieveResource(); + new SimpleEchoApi().RetrieveResourcePolicyDocument(); } } \ No newline at end of file diff --git a/example/test/EchoApiExpressionTests.cs b/example/test/EchoApiExpressionTests.cs index 4682621..96ba651 100644 --- a/example/test/EchoApiExpressionTests.cs +++ b/example/test/EchoApiExpressionTests.cs @@ -12,48 +12,22 @@ public class EchoApiExpressionTests public void FilterBody() { var context = new MockContext(); - context.MockResponse.MockBody.Content = "{ \"current\": \"some current content\", \"other\": \"some other content\" }"; - var echoApi = new EchoApi(); - - var result = echoApi.FilterBody(context); - - var actual = JObject.Parse(result); - var expected = JObject.Parse("{ \"other\": \"some other content\" }"); - - Assert.IsTrue(JObject.DeepEquals(actual, expected)); - } - - [TestMethod] - public void ShouldBeGuid() - { - var echoApi = new EchoApi(); - var result = echoApi.GetKnownGUIDOrGenerateNew(new MockContext()); - - Guid.Parse(result); - } - - [TestMethod] - public void ShouldProduceDifferentGuids() - { - var echoApi = new EchoApi(); - var first = echoApi.GetKnownGUIDOrGenerateNew(new MockContext()); - var second = echoApi.GetKnownGUIDOrGenerateNew(new MockContext()); - - Assert.AreNotEqual(first, second); - } - - [TestMethod] - public void ShouldProduceKnownGuid() - { - var echoApi = new EchoApi(); - var knownGuid = Guid.NewGuid().ToString(); - var context = new MockContext(); - context.MockVariables["KnownGUID"] = knownGuid; - - var guidOne = echoApi.GetKnownGUIDOrGenerateNew(context); - var guidTwo = echoApi.GetKnownGUIDOrGenerateNew(context); - - Assert.AreEqual(knownGuid, guidOne); - Assert.AreEqual(guidOne, guidTwo); + context.MockResponse.MockBody.Content = + """ + { + "title": "Software Engineer", + "location": "Redmond", + "secret": "42", + "name": "John Doe" + } + """; + + var newBody = new SimpleEchoApi().FilterBody(context); + Assert.IsTrue(JObject.DeepEquals(JObject.Parse(newBody), JObject.Parse(""" + { + "title": "Software Engineer", + "name": "John Doe" + } + """))); } } \ No newline at end of file