LogicAppUnit / TestingFramework

Unit testing framework for Azure Logic Apps (Standard)
MIT License
23 stars 11 forks source link

connection.json file has @appsetting, which is not recognized #9

Closed raunaknarooka closed 12 months ago

raunaknarooka commented 1 year ago

I have the following connection.json file which has a managed api connection

{ "managedApiConnections": {

    "products-evgt-apiConnection": {
        "api": {
          "id": "/subscriptions/@appsetting('WORKFLOWS_SUBSCRIPTION_ID')/providers/Microsoft.Web/locations/westeurope/managedApis/azureeventgrid"
        },
        "kind": "V2",
        "authentication": {
          "type": "ManagedServiceIdentity"
        },
        "connection": {
          "id": "/subscriptions/@appsetting('WORKFLOWS_SUBSCRIPTION_ID')/resourceGroups/@appsetting('WORKFLOWS_RESOURCE_GROUP_NAME')/providers/Microsoft.Web/connections/int0313-iver-products-evgt-apiConnection"
        },
        "connectionProperties": {
          "authentication": {
            "audience": "https://management.core.windows.net/",
            "type": "ManagedServiceIdentity"
          }
        },
        "connectionRuntimeUrl": "@appsetting('EVENTGRID_CONNECTION_RUNTIMEURL')"
      }
},

As i understand, the testing framework looks at all built in and managed connections and replaces them with a localhost url. When i use the appsetting in the connectionRuntimeurl of the eventgrid api connection, it tells its an invalid url. I get the following error: Error Message: Initialization method INT0313.Iver.Products.Tests.Products.Products.TestInitialize threw exception. System.UriFormatException: Invalid URI: The format of the URI could not be determined.. Stack Trace: at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind, UriCreationOptions& creationOptions) at System.Uri..ctor(String uriString) at LogicAppUnit.InternalHelper.ConnectionHelper.<>c.b__3_0(JProperty connection) at System.Collections.Generic.List1.ForEach(Action1 action) at LogicAppUnit.InternalHelper.ConnectionHelper.ReplaceManagedApiConnectionUrlsWithMockServer() at LogicAppUnit.WorkflowTestBase.Initialize(String logicAppBasePath, String workflowName, String localSettingsFilename) at LogicAppUnit.WorkflowTestBase.Initialize(String logicAppBasePath, String workflowName) at INT0313.Iver.Products.Tests.Products.Products.TestInitialize() in C:\Users\PSRAUNAR\OneDrive - Peab\Dokument\INT0313.Iver.Products\INT0313.Iver.Products.Tests\Products\Products.cs:line 21

And the output stops here: Standard Output Messages:


when i put a valid dummy url in connectionruntimeurl it works. But this is not what i want. The connections are deployed in the azure devops pipeline and i need this to be an app setting.

mark-abrams commented 1 year ago

Hi @raunaknarooka, thanks for logging this issue.

The framework is replacing the connectionRuntimeUrl value with a URL that points to the mock HTTP server. It does this by replacing the host name in the URL with the mock server's host name. But this assumes that the value of connectionRuntimeUrl is a valid URL in the first place. In your case it is not because you are referencing an app setting so that you can deploy the same connection file across multiple environments.

I can think of a few ways to fix this:

  1. if the value of connectionRuntimeUrl is @appsetting('<setting name>') then get the value of the referenced app setting, then replace the host name with the mock server's host name.
  2. if the value of connectionRuntimeUrl is more complex, for example something like https://@appsetting('CONN_HOSTNAME').common.logic-uksouth.azure-apihub.net/apim/outlook/@appsetting('CONN_SOMETHING_ELSE')/ then things get a little more complex to handle because you potentially need to find each instance of the app settings and hope that replacing with the app setting value gives you a valid URL.

Do all of your values of connectionRuntimeUrl fall into the first category?

raunaknarooka commented 1 year ago

Hi Mark, thanks for reaching out. The connectionRuntimeurl is different for every logic app. It looks somewhat like: https://.10.common.logic-westeurope.azure-apihub.net/apim/azureeventgrid/. I construct this in the bicep file, like this:

 {
          name: 'EVENTGRID_CONNECTION_RUNTIMEURL'
          value: reference(azureEventGridConnection.id, azureEventGridConnection.apiVersion, 'full').properties.connectionRuntimeUrl
        }

The azureEventGridConnection is created using the following bicep resource:

resource azureEventGridConnection 'Microsoft.Web/connections@2016-06-01' = {
  name: eventGridConnectionName
  location: location
  kind: 'V2'
  properties: {
    displayName: eventGridConnectionName
    statuses: [
      {
        status: 'Ready'
      }
    ]
    parameterValueSet: {
      name: 'managedIdentityAuth'
      values: {}
    }
    customParameterValues: {}
    api: {
      name: 'azureeventgrid' 

      id: '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Web/locations/westeurope/managedApis/azureeventgrid'
      type: 'Microsoft.Web/locations/managedApis'
    }

  }
}
mark-abrams commented 1 year ago

Hi @raunaknarooka , I've had a think about this and I propose the following change when handling connection runtime URLs for managed connectors:

  1. If the value of the connection runtime URL does not include @appsettings then validate that the value is a URL and replace the host name with the mock HTTP server name. This is essentially what the framework does at the moment, but I've added (i) explicit validation of the runtime URL and (ii) a check for any @appsettings.
  2. If the value of the connection runtime URL does include @appsettings then replace the app settings values with those from local.settings.json. Then validate that the value is a URL and replace the host name with the mock HTTP server name.

Point 2 covers your scenario and will fix your issue.

mark-abrams commented 1 year ago

Hi @raunaknarooka , I've completed this change, please download package version 1.4.0 from Nuget: https://www.nuget.org/packages/LogicAppUnit/1.4.0.

Please let me know if this fixes your issue.