Skip to content

Conversation

nturinski
Copy link
Member

Summary

This PR enhances the Azurite integration by dynamically generating complete connection strings using workspace settings instead of returning partial URLs.

Changes

  • Complete connection string generation: Now generates full Azure Storage connection strings with all endpoints (blob, queue, table) instead of just blob URLs
  • Dynamic configuration: Uses Azurite workspace settings for flexible host/port configuration:
    • azurite.blobHost, azurite.queueHost, azurite.tableHost (defaults to 127.0.0.1)
    • azurite.blobPort, azurite.queuePort, azurite.tablePort (defaults to 10000, 10001, 10002)
  • Protocol support: Automatically detects HTTP/HTTPS based on certificate settings
  • Emulator detection: Added improved logic to detect when a connection string is for an emulator

Connection String Format

The generated connection string follows the standard Azure Storage format:

DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;

References

Testing

  • Generates proper connection strings with default Azurite settings
  • Respects custom workspace configuration
  • Handles both HTTP and HTTPS protocols
  • Maintains backward compatibility

…e settings

- Generate complete connection strings with all endpoints (blob, queue, table)
- Use Azurite workspace settings for dynamic host/port configuration
- Support both HTTP and HTTPS protocols based on certificate settings
- Add emulator detection functionality for improved connection handling

Fixes #3876
@nturinski nturinski requested a review from a team as a code owner August 13, 2025 23:12
- Update validateStorageConnectionPreDebug to handle tuple return type
- Adapt validatePreDebug to work with new getLocalSettingsConnectionString signature
- Maintain compatibility with emulator detection functionality
alexweininger
alexweininger previously approved these changes Aug 14, 2025
Copy link
Member Author

@nturinski nturinski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes improve Azurite integration by generating complete connection strings dynamically. However, there are some logic issues with emulator detection that need to be addressed, particularly around environment variable handling and false positive detection.

export async function getLocalSettingsConnectionString(context: IActionContext, connectionKey: ConnectionKey, projectPath: string): Promise<string | undefined> {
export async function getLocalSettingsConnectionString(context: IActionContext, connectionKey: ConnectionKey, projectPath: string): Promise<[string | undefined, boolean]> {
// func cli uses environment variable if it's defined on the machine, so no need to prompt
if (process.env[connectionKey]) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: process.env[connectionKey] is treated as an emulator connection on line 25, but environment variables are typically production connection strings, not emulator connections. This will cause incorrect emulator detection for production deployments that use environment variables.

The return value should be [process.env[connectionKey], false] to indicate it's not an emulator connection.



Review generated with Copilot

// check for azurite settings and build the connection string if it's an emulator
connectionString = getLocalSettingsEmulatorConnectionString();
}
const isEmulator = isConnectionStringEmulator(connectionString);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Missing null check for connectionString before calling isConnectionStringEmulator() on line 35. If settings.Values[connectionKey] is undefined, this could cause issues in the emulator detection logic.

The isConnectionStringEmulator function handles undefined values, but the logic flow should be clarified to ensure connectionString is validated before the emulator check.



Review generated with Copilot

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If isConnectionStringEmulator can handle undefined, why are you flagging this issue?

const tablePort = getWorkspaceSetting('tablePort', undefined, 'azurite') || '10002';

const protocol = getTransferProtocol();
return `DefaultEndpointsProtocol=${protocol};AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=${protocol}://${blobHost}:${blobPort}/devstoreaccount1;QueueEndpoint=${protocol}://${queueHost}:${queuePort}/devstoreaccount1;TableEndpoint=${protocol}://${tableHost}:${tablePort}/devstoreaccount1;`;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hard-coded account key Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw== should be extracted to a constant for maintainability. This is the standard Azurite development account key, but having it as a magic string makes it harder to maintain.

Consider adding it to constants.ts as azuriteAccountKey or similar.



Review generated with Copilot

return !!connectionString &&
(connectionString.includes(blobHost) ||
connectionString.includes(queueHost) ||
connectionString.includes(tableHost) ||
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The emulator detection logic on lines 54-59 could produce false positives. Checking for 'localhost' as a blanket condition might match legitimate production connection strings that happen to contain "localhost" in metadata or descriptions.

Consider making the localhost check more specific, such as checking for localhost in endpoint URLs rather than anywhere in the connection string.



Review generated with Copilot

const azureWebJobsStorage: string | undefined = await getLocalSettingsConnectionString(context, ConnectionKey.Storage, projectPath);
if (azureWebJobsStorage && azureWebJobsStorage.toLowerCase() === localStorageEmulatorConnectionString.toLowerCase()) {
const [azureWebJobsStorage, isEmulator] = await getLocalSettingsConnectionString(context, ConnectionKey.Storage, projectPath);
if (azureWebJobsStorage && isEmulator) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The destructuring assignment here correctly handles the new tuple return type from getLocalSettingsConnectionString(). The isEmulator boolean provides better semantic clarity than string comparison.



Review generated with Copilot

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need to tell me that I am doing things correctly. Please don't do that.

@nturinski nturinski enabled auto-merge (squash) August 14, 2025 22:10
@nturinski nturinski merged commit 6df1d8e into main Aug 14, 2025
2 checks passed
@nturinski nturinski deleted the feature/azurite-dynamic-connection-string branch August 14, 2025 22:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pass Azurite configuration settings to function host

2 participants