Skip to content

Latest commit

 

History

History
369 lines (274 loc) · 12.3 KB

File metadata and controls

369 lines (274 loc) · 12.3 KB

Connector Code Generation

This document describes how to generate typed connector clients using the LogicAppsCompiler CLI tool.

Overview

The CodefulSdkGenerator tool generates typed C# clients from managed connector swagger definitions. The generated code provides:

  • Type-safe contracts - Input/output types with proper JSON serialization attributes
  • Typed client classes - Async methods for each connector action with XML documentation
  • Authentication handling - Built-in token acquisition for API Hub

Prerequisites

Tools Required

  1. ARMClient - For authenticated Azure Resource Manager API calls

    • Install via Chocolatey: choco install armclient

    • Install via WinGet: winget install projectkudu.ARMClient

    • The generator defaults to C:\ProgramData\chocolatey\bin\ARMClient.exe

    • If ARMClient is installed elsewhere (e.g., via WinGet), set the ARMCLIENT_PATH environment variable:

      # Find your ARMClient path
      (Get-Command armclient).Source
      # Set it persistently
      [System.Environment]::SetEnvironmentVariable("ARMCLIENT_PATH", (Get-Command armclient).Source, "User")
  2. Azure Subscription - Access to an Azure subscription with Logic Apps Standard

    • Required for fetching connector swagger definitions from ARM
  3. .NET 8 SDK - For building and running the generator

Azure Configuration

Set environment variables (or use defaults):

Variable Description Default
ARMCLIENT_PATH Path to ARMClient.exe C:\ProgramData\chocolatey\bin\ARMClient.exe
ARMCACHE_PATH Cache directory for ARM responses %TEMP%\armcache
AZURE_SUBSCRIPTION_ID Azure subscription ID (built-in default)
AZURE_RESOURCE_GROUP Resource group with Logic App (built-in default)
AZURE_LOGICAPP_SITE Logic App Standard site name (built-in default)
AZURE_LOCATION Azure region for managed APIs westus

Building the Generator

The generator lives in the BPM repository (internal to Microsoft). To build:

# Navigate to the BPM repository
cd <BPM-repo-root>

# Initialize the repo (first time only)
.\init.cmd

# Build the CLI tool
dotnet build .\src\tools\CodefulSdkGenerator\LogicAppsCompiler.Cli\LogicAppsCompiler.Cli.csproj -c Release

The compiled executable will be at:

src\tools\CodefulSdkGenerator\LogicAppsCompiler.Cli\bin\Release\net8.0\LogicAppsCompiler.exe

Generation Commands

Generate Connectors SDK (Recommended)

Generates typed async clients for calling connectors directly from Azure Functions:

# Generate all connectors
LogicAppsCompiler.exe <output-directory> unused --directClient

# Generate specific connectors only
LogicAppsCompiler.exe <output-directory> unused --directClient --connectors=office365,outlook,servicebus

# Example: Generate to this SDK repo's samples/generated folder
LogicAppsCompiler.exe "<path-to-Connectors-NET-SDK>/samples/generated" unused --directClient --connectors=office365

Output structure per connector:

  • {Connector}Extensions.cs - Combined types and client in one file

Generate Agent Managed Connectors

Generates SDK code for the Logic Apps agent pattern:

# Generate with connector filter
LogicAppsCompiler.exe <output-directory> unused --agentManagedConnectors --connectors=office365,servicebus,azureblob

# Generate all (with built-in skip list for problematic connectors)
LogicAppsCompiler.exe <output-directory> unused --agentManagedConnectors

Generate Managed Connectors (Legacy)

Generates code using the older managed connector pattern:

LogicAppsCompiler.exe <output-directory> unused --managedConnectors

Generated Code Structure

Connectors SDK Output

// Office365Extensions.cs - Auto-generated Connectors SDK
// Do not edit this file directly.

using System.Text.Json.Serialization;
// ... other usings

namespace Azure.Connectors.Sdk.Office365;

#region Types

/// <summary>
/// Response for calendar event operations.
/// </summary>
public class GraphCalendarEventClientReceive
{
    [JsonPropertyName("subject")]
    /// <summary>Event subject</summary>
    public string Subject { get; set; }

    // ... other properties
}

#endregion Types

#region Client

/// <summary>
/// Typed client for office365 connector.
/// </summary>
public class Office365Client : IDisposable
{
    private readonly string _connectionRuntimeUrl;
    private readonly HttpClient _httpClient;
    private readonly TokenCredential _credential;

    public Office365Client(string connectionRuntimeUrl, 
                           TokenCredential credential = null, 
                           HttpClient httpClient = null)
    {
        // ...
    }

    /// <summary>
    /// Send an email.
    /// </summary>
    public async Task SendEmailAsync(SendEmailInput input, 
                                     CancellationToken cancellationToken = default)
    {
        // ...
    }
}

#endregion Client

Cross-Repo Architecture

The connector SDK spans 4 repositories with a strict data flow:

┌──────────────────────────────────────┐
│  BPM (internal)                      │
│  CodefulSdkGenerator                 │
│  Parses swagger x-ms-dynamic-values  │
│  Emits [DynamicValues("opId")]       │
│  Includes discovery methods          │
└──────────┬───────────────────────────┘
           │ generates
           ▼
┌──────────────────────────────────────┐
│  Azure/Connectors-NET-SDK            │
│  (this repo, GitHub)                 │
│                                      │
│  src/.../DynamicValuesAttribute.cs   │  ← hand-written attribute definition
│  samples/generated/*Extensions.cs    │  ← generator output (DO NOT hand-edit)
│  src/.../Generated/                  │  ← packaged into NuGet
└──────────┬───────────┬───────────────┘
           │           │
   NuGet   │           │ NuGet
           ▼           ▼
┌────────────────┐  ┌──────────────────────────┐
│  Azure/         │  │  Azure/                  │
│  azure-         │  │  azure-connector-sdk-    │
│  connector-     │  │  samples                 │
│  sdk-lsp        │  │  (GitHub)                │
│  (GitHub)       │  │                          │
│  Roslyn reads   │  │  E2E test target         │
│  [DynamicValues]│  │  DirectConnector uses    │
│  from SDK .dll  │  │  generated client        │
│  Hover handler  │  │  SharePoint connection   │
│  fetches values │  │                          │
│  from API Hub   │  │                          │
└─────────────────┘  └──────────────────────────┘

Key Rules

  1. Generated content is read-only — files in samples/generated/ and src/.../Generated/ are produced by the BPM CodefulSdkGenerator. Never hand-edit generated files.
  2. Fix bugs in the generator, not in generated output — if generated code has issues (typos, wrong annotations, missing methods), fix the CodefulSdkGenerator in the BPM repo, then regenerate. This ensures fixes survive regeneration and benefit all generation targets (Connectors SDK, Codeful Workflow SDK, etc.).
  3. DynamicValuesAttribute is hand-written — defined in src/.../DynamicValuesAttribute.cs. The generator emits references to it; the LSP reads it via Roslyn reflection.
  4. Merge order — SDK (attribute) → BPM (generator) → LSP and POC (consumers). The SDK must define the attribute before the generator can reference it, and the generator must produce the annotations before consumers can use them.
  5. Regeneration — after generator changes in BPM, re-run the generator and commit the output to this repo. See Generation Commands above.
  6. Swagger text sanitization — the generator's SanitizeSwaggerText() method corrects known typos from swagger definitions before they flow into XML documentation. Add new corrections there rather than patching generated files.

Repository Links

Repo URL Role
BPM (CodefulSdkGenerator) Internal (Microsoft Azure DevOps) Generator source
Connector SDK (this repo) https://github.com/Azure/Connectors-NET-SDK Attribute + generated output
Connector SDK LSP https://github.com/Azure/Connectors-NET-LSP Design-time IntelliSense consumer
Connector SDK Samples https://github.com/Azure/Connectors-NET-Samples E2E validation target

Integration with SDK

The generated code depends on the runtime SDK for:

  • ConnectorClientBase / TokenCredential - Authentication via Azure.Core
  • ConnectorHttpClient - HTTP operations with retry
  • ConnectorJsonSerializer - JSON serialization helpers

Install the SDK NuGet package in your project:

<PackageReference Include="Azure.Connectors.Sdk" Version="1.0.0" />

Regeneration Schedule

Generated connectors should be regenerated periodically to incorporate:

  • New connector operations
  • Updated parameter schemas
  • Bug fixes in swagger definitions

Recommended schedule:

  • Monthly regeneration for active development
  • Quarterly regeneration for stable projects
  • Immediate regeneration when new connector features are needed

Automation

CI/CD Integration

Example GitHub Actions workflow for scheduled regeneration:

name: Regenerate Connector SDKs

on:
  schedule:
    - cron: '0 0 1 * *'  # First day of each month
  workflow_dispatch:  # Allow manual trigger

jobs:
  regenerate:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '8.0.x'
      
      - name: Install ARMClient
        run: choco install armclient -y
      
      - name: Login to Azure
        run: armclient login
      
      - name: Build Generator
        run: |
          dotnet build src/tools/CodefulSdkGenerator/LogicAppsCompiler.Cli -c Release
      
      - name: Generate Connectors
        env:
          AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
          AZURE_RESOURCE_GROUP: ${{ secrets.AZURE_RESOURCE_GROUP }}
        run: |
          ./LogicAppsCompiler.exe ./generated unused --directClient --connectors=office365,servicebus
      
      - name: Create PR
        uses: peter-evans/create-pull-request@v5
        with:
          title: 'chore: Regenerate connector SDKs'
          body: 'Monthly connector SDK regeneration'
          branch: chore/regenerate-connectors

Troubleshooting

Common Issues

ARMClient not authenticated:

Run: armclient login

Connector not found:

  • Verify connector name is correct (use lowercase, no spaces)
  • Check if connector is available in the specified Azure region

Schema parsing errors:

  • Some connectors have malformed swagger definitions
  • The generator includes built-in patches for known issues
  • Problematic connectors are in the skip list

Cache Management

ARM responses are cached to improve regeneration speed:

# Clear cache to force fresh API calls
Remove-Item -Path "$env:TEMP\armcache" -Recurse -Force

Available Connectors

To see the list of available connectors:

# Login to ARM
armclient login

# List managed APIs in a region
armclient GET "https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Web/locations/westus/managedApis?api-version=2016-06-01"

Common connectors:

  • office365 - Office 365 Outlook
  • outlook - Outlook.com
  • servicebus - Azure Service Bus
  • azureblob - Azure Blob Storage
  • azuretables - Azure Table Storage
  • azurequeues - Azure Queue Storage
  • teams - Microsoft Teams
  • keyvault - Azure Key Vault
  • sql - SQL Server
  • cosmosdb - Azure Cosmos DB