- name
- policy-codebase-reference
- description
- Reference guide for the Azure API Management policy toolkit codebase structure. Use this skill when you need to find existing policies, infrastructure, or naming conventions.
# Policy Toolkit Codebase Reference
This skill provides an inventory of the codebase structure, shared infrastructure, reference policy selection, and naming conventions for the Azure API Management policy toolkit.
## File Path Conventions
### Authoring & Compilation
| Artifact | Location | Example |
|---|---|---|
| Config record | `src/Authoring/Configs/{PolicyName}Config.cs` | `RateLimitConfig.cs` |
| Document attribute | `src/Authoring/Attributes/DocumentAttribute.cs` | — |
| Expression attribute | `src/Authoring/Attributes/ExpressionAttribute.cs` | — |
| Expression-allowed attribute | `src/Authoring/Attributes/ExpressionAllowedAttribute.cs` | — |
| Section interfaces | `src/Authoring/I{Section}Context.cs` | `IInboundContext.cs` |
| Compiler class | `src/Core/Compiling/Policy/{PolicyName}Compiler.cs` | `RateLimitCompiler.cs` |
| Compiler test class | `test/Test.Core/Compiling/{PolicyName}Tests.cs` | `RateLimitTests.cs` |
| Available policies doc | `docs/AvailablePolicies.md` | — |
| Compiler utilities | `src/Core/Compiling/CompilerUtils.cs` | — |
| Syntax extensions | `src/Core/Compiling/SyntaxExtensions.cs` | — |
| Diagnostics | `src/Core/Compiling/Diagnostics/CompilationErrors.cs` | — |
| IoC / auto-registration | `src/Core/IoC/CompilerModule.cs` | — |
| Test initialization | `test/Test.Core/CompilerTestInitialize.cs` | — |
| Assertion helpers | `test/Test.Core/Assertions/` | `CompilationResultAssertion.cs` |
| Generic compiler utilities | `src/Core/Compiling/Policy/GenericCompiler.cs` | — |
| Add-policy guide | `docs/AddPolicyGuide.md` | — |
### Gateway Emulator
| Artifact | Location | Example |
|---|---|---|
| Emulator handler class | `src/Testing/Emulator/Policies/{PolicyName}Handler.cs` | `SetHeaderHandler.cs` |
| Handler base classes | `src/Testing/Emulator/Policies/PolicyHandler.cs` | — |
| IPolicyHandler interface | `src/Testing/Emulator/IPolicyHandler.cs` | — |
| Section attribute | `src/Testing/Emulator/Policies/SectionAttribute.cs` | — |
| Argument extensions | `src/Testing/Emulator/Policies/ArgumentsExtensions.cs` | — |
| Policy exception | `src/Testing/Emulator/PolicyExeption.cs` | Note: filename has typo |
| SectionContextProxy | `src/Testing/Emulator/SectionContextProxy.cs` | — |
| GatewayContext | `src/Testing/GatewayContext.cs` | — |
| TestDocument | `src/Testing/TestDocument.cs` | — |
| Emulator test class | `test/Test.Testing/Emulator/Policies/{PolicyName}Tests.cs` | `SetHeaderTests.cs` |
| Emulator policy checklist | `docs/EmulatorPolicyChecklist.md` | — |
## Naming Conventions
### Authoring & Compilation
| Artifact | Convention | Example |
|---|---|---|
| Config record | `{PolicyName}Config` | `RateLimitConfig` |
| Sub-config record | `{DescriptiveName}` | `ApiRateLimit`, `AddressRange` |
| Compiler class | `{PolicyName}Compiler` | `RateLimitCompiler` |
| Compiler test class | `{PolicyName}Tests` | `RateLimitTests` |
| Context method | `{PolicyName}` | `RateLimit` |
| XML element name | kebab-case | `rate-limit` |
| Config namespace | `Microsoft.Azure.ApiManagement.PolicyToolkit.Authoring` | — |
| Compiler namespace | `Microsoft.Azure.ApiManagement.PolicyToolkit.Compiling.Policy` | — |
| Compiler test namespace | `Microsoft.Azure.ApiManagement.PolicyToolkit.Compiling` | — |
### Gateway Emulator
| Artifact | Convention | Example |
|---|---|---|
| Handler class | `{PolicyName}Handler` | `SetHeaderHandler` |
| Emulator test class | `{PolicyName}Tests` | `SetHeaderTests` |
| PolicyName property | PascalCase method name from section interface | `SetHeader` |
| Handler namespace | `Microsoft.Azure.ApiManagement.PolicyToolkit.Testing.Emulator.Policies` | — |
| Emulator test namespace | `Test.Emulator.Emulator.Policies` | — |
> **Note:** `JsonToXmlHandle.cs` is a naming inconsistency in the source (missing the `r` in `Handler`). Do not rename it.
## Copyright Header
Every new `.cs` file must start with:
```csharp
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
```
## Reference Policy Selection Guide
When implementing a new policy, choose the closest structural match as your reference:
| Policy Structure | Reference Config | Reference Compiler | Reference Tests |
|---|---|---|---|
| Simple attributes only | `RateLimitByKeyConfig` | `RateLimitByKeyCompiler` | `RateLimitByKeyTests` |
| Attributes + child elements | `RateLimitConfig` | `RateLimitCompiler` | `RateLimitTests` |
| Attributes + typed child arrays | `IpFilterConfig` | `IpFilterCompiler` | `IpFilterTests` |
| String-list child elements | `ValidateJwtConfig` | `ValidateJwtCompiler` | `ValidateJwtTests` |
| Complex nested configs | `CorsConfig` | `CorsCompiler` | `CorsTests` |
| Direct parameters (no config) | — | `SetMethodCompiler` | `SetMethodTests` |
## Shared Infrastructure Inventory
### Expression Support
- **`[Document]`** attribute (`src/Authoring/Attributes/DocumentAttribute.cs`) — Marks a class as a policy document. Optional `name` parameter; `Scope` and `Type` properties control document scope and type.
- **`[Expression]`** attribute (`src/Authoring/Attributes/ExpressionAttribute.cs`) — Marks a method as a policy expression helper. Captures source file path via `[CallerFilePath]`.
- **`[ExpressionAllowed]`** attribute (`src/Authoring/Attributes/ExpressionAllowedAttribute.cs`) — Marks properties or parameters that accept policy expressions.
- **`Expression<T>`** delegate (`src/Authoring/Expression.cs`) — `delegate T Expression<out T>(IExpressionContext context)`.
- **`IHaveExpressionContext`** interface (`src/Authoring/IHaveExpressionContext.cs`) — Base interface for all section contexts, providing `IExpressionContext ExpressionContext { get; }`.
### Compiler Infrastructure
- **`IMethodPolicyHandler`** interface (`src/Core/Compiling/IMethodPolicyHandler.cs`) — The primary compiler interface. Properties: `string MethodName { get; }`. Method: `void Handle(IDocumentCompilationContext context, InvocationExpressionSyntax node)`.
- **`IReturnValueMethodPolicyHandler`** interface (`src/Core/Compiling/IReturnValueMethodPolicyHandler.cs`) — For policies returning a value. Currently disabled (the `LocalDeclarationStatementCompiler` is commented out in `CompilerModule.cs`).
- **Auto-registration** (`src/Core/IoC/CompilerModule.cs`) — Uses reflection to find and register all public, non-abstract classes in the `Microsoft.Azure.ApiManagement.PolicyToolkit.Compiling.Policy` namespace that implement `IMethodPolicyHandler`. No manual DI wiring needed for standard compilers.
- **`CompilerUtils`** (`src/Core/Compiling/CompilerUtils.cs`) — Static utility class with methods for parameter extraction (`ProcessParameter`, `TryExtractingConfig`), expression processing, and syntax normalization. Also defines `InitializerValue` for property name → value mapping.
- **`SyntaxExtensions`** (`src/Core/Compiling/SyntaxExtensions.cs`) — Extension methods for Roslyn syntax trees: attribute detection (`ContainsAttributeOfType<T>`), document class discovery (`GetDocumentAttributedClasses`), and document metadata extraction.
- **`GenericCompiler.HandleList`** (`src/Core/Compiling/Policy/GenericCompiler.cs`) — Utility for compiling string arrays into repeated child XML elements.
- **`CompilationErrors`** (`src/Core/Compiling/Diagnostics/CompilationErrors.cs`) — Static class with `DiagnosticDescriptor` fields for all compilation error types.
### Compiler Test Infrastructure
- **`CompilerTestInitialize`** (`test/Test.Core/CompilerTestInitialize.cs`) — Assembly-level MSTest setup. Creates Roslyn compilation with references to `System`, `System.Xml.Linq`, and the Authoring assembly. Provides the `CompileDocument()` extension method.
- **`CompilationResultAssertion`** (`test/Test.Core/Assertions/CompilationResultAssertion.cs`) — FluentAssertions extension providing `BeSuccessful()` and `DocumentEquivalentTo(string expectedXml)`.
- **`Usings.cs`** (`test/Test.Core/Usings.cs`) — Global usings: `FluentAssertions`, `Microsoft.VisualStudio.TestTools.UnitTesting`, assertion helpers, test extensions.
### Emulator Infrastructure
- **`IPolicyHandler`** interface (`src/Testing/Emulator/IPolicyHandler.cs`) — The handler interface. Properties: `string PolicyName { get; }`. Method: `object? Handle(GatewayContext context, object?[]? args)`.
- **`PolicyHandler<T>`** base classes (`src/Testing/Emulator/Policies/PolicyHandler.cs`) — Three generic variants: single config, optional config, and two-parameter. All include `CallbackSetup` for test mocking.
- **`SectionContextProxy<T>`** (`src/Testing/Emulator/SectionContextProxy.cs`) — Uses `System.Reflection.DispatchProxy` to dynamically route method calls to handlers. Discovers handlers via reflection on namespace + `[Section]` attribute.
- **`[Section]`** attribute (`src/Testing/Emulator/Policies/SectionAttribute.cs`) — Constructor takes `string scope` (use `nameof(IInboundContext)`, etc.). Multiple attributes can be stacked.
- **`ArgumentsExtensions`** (`src/Testing/Emulator/Policies/ArgumentsExtensions.cs`) — Static utility for safe argument extraction from `object?[]?`: `ExtractArgument<T>()` (required single arg), `ExtractOptionalArgument<T>()` (nullable), and `ExtractArguments<T1, T2>()` (two-param handlers).
- **`PolicyException`** (`src/Testing/Emulator/PolicyExeption.cs`) — Exception thrown when a handler fails. Carries `Policy`, `Section`, and `PolicyArgs` context. Note: filename has a typo (`Exeption`) — do not rename.
- **`GatewayContext`** (`src/Testing/GatewayContext.cs`) — Central mock object with section proxies, mock stores (CertificateStore, CacheStore, ResponseExampleStore, LoggerStore), and expression context.
- **`TestDocument`** (`src/Testing/TestDocument.cs`) — Orchestrates test execution across policy sections. Wraps `IDocument` and calls section methods through proxies.
- **`FinishSectionProcessingException`** — Thrown by handlers (e.g., MockResponse, ReturnResponse) to terminate section processing early.
### Emulator Test Infrastructure
- **`.AsTestDocument()`** extension — Creates `TestDocument` from `IDocument` for fluent test setup.
- **`SetupInbound()`/`SetupOutbound()`/etc.** — Returns `MockPoliciesProvider<TSection>` for mock configuration.
- **`Usings.cs`** (`test/Test.Testing/Usings.cs`) — Global usings for `FluentAssertions` and MSTest.
## Section Interfaces
Policies can be available in one or more pipeline sections:
| Section | Interface File | XML Section |
|---|---|---|
| Inbound | `src/Authoring/IInboundContext.cs` | `<inbound>` |
| Outbound | `src/Authoring/IOutboundContext.cs` | `<outbound>` |
| Backend | `src/Authoring/IBackendContext.cs` | `<backend>` |
| On-Error | `src/Authoring/IOnErrorContext.cs` | `<on-error>` |
| Fragment | `src/Authoring/IFragmentContext.cs` | N/A (reusable fragment) |
Note: `IFragmentContext` duplicates method signatures from other interfaces (see `//TODO` at top of file). Copy signatures verbatim when adding policies there.
## Emulator Reference Handler Selection Guide
When implementing a new emulator handler, choose the closest structural match:
| Policy Structure | Reference Handler | Reference Test |
|---|---|---|
| Single config, simple state change | `SetStatusHandler` | `SetStatusTests` |
| Two parameters (name + values) | `SetHeaderHandler` | `SetHeaderTests` |
| Config with callback hooks only (no-op) | `RateLimitHandler` | `RateLimitTests` |
| Optional config | `MockResponseHandler` | `MockResponseTests` |
| Validation + short-circuit | `CheckHeaderHandler` | `CheckHeaderTests` |
| Authentication + token | `AuthenticationManagedIdentityHandler` | `AuthenticationManagedIdentityHandlerTests` |
| Cache interaction | `CacheLookupValueHandler` | `CacheLookupValueTests` |
| Logging/store interaction | `LogToEventHubHandler` | `LogToEventHubTests` |
| No-config (no-arg method) | `BaseHandler` | `BaseTests` |
| Custom flow control / wrapper | `ReturnResponseHandler` | — |
| AzureOpenAi variant (inherits Llm) | `AzureOpenAiEmitTokenMetricHandler` | — |
## Common Pitfalls
| Pitfall | Rule |
|---------|------|
| Modifying `.csproj` files | Do **not** change `Compiling.csproj` or `Testing.csproj` unless explicitly required. Reformatting, reordering, or encoding changes (BOM, line endings) cause noisy diffs and will be rejected in review. |
| Missing `IFragmentContext` entry | Every method added to a section interface (`IInboundContext`, `IOutboundContext`, etc.) must also be added to `IFragmentContext.cs`. See the authoring skill for details. |
| Missing expression tests | Every property marked `[ExpressionAllowed]` in a config must have a corresponding expression test `[DataRow]`. See the testing skill section 3 for the pattern. |
## Build and Test Commands
```bash
# Build the entire solution
dotnet build
# Run all compiler tests
dotnet test --project test/Test.Core
# Run all emulator tests
dotnet test --project test/Test.Testing
# Run tests for a specific policy
dotnet test --filter "FullyQualifiedName~{PolicyName}Tests"
```
عرض على GitHub