You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Today, a bad Databricks warehouse ID, Blob container name, Azure Maps subscription key, Tableau PAT, Snowflake account, Log Analytics workspace ID, MCP endpoint, or OpenAPI base URL is only discovered when an agent actually invokes the tool at chat time. Admins and workspace owners have to save, run a chat, read a failure, and guess. A pre-save Test Connection turns that into an immediate, actionable message in the modal — the same experience SQL and Cosmos actions already have.
Proposed Behavior
Follow the existing SQL/Cosmos pattern.
Backend
New shared module application/single_app/functions_action_connection_tests.py with one tester per action type. Routes stay thin.
Eight dedicated routes on the bpap blueprint, matching the existing /api/plugins/test-sql-connection naming:
POST /api/plugins/test-openapi-connection
POST /api/plugins/test-azure-maps-connection
POST /api/plugins/test-blob-storage-connection
POST /api/plugins/test-databricks-connection
POST /api/plugins/test-log-analytics-connection
POST /api/plugins/test-mcp-connection
POST /api/plugins/test-snowflake-connection
POST /api/plugins/test-tableau-connection
A shared _prepare_action_test_manifest(...) helper in route_backend_plugins.py that reuses the existing _load_existing_plugin_for_test, _resolve_action_identity_context, ui_trigger_word re-hydration, hydrate_action_identity_reference, _resolve_secret_value_for_plugin_test, and PluginHealthChecker.validate_plugin_manifest flow, so masked secrets and reusable identities keep working on edit.
What each test verifies (full verification: authenticate, then one lightweight read)
Type
Verification
OpenAPI
Parse the stored spec, report operation count, then authenticated GET to the base URL
Azure Maps
GET {endpoint}/map/tile for tile 0/0/0 of microsoft.base.road with the subscription key
Blob Storage
get_container_properties() then list one blob under the configured prefix
Databricks
GET /api/2.0/sql/warehouses/{warehouse_id}; report warehouse name and state
Test Connection button plus a result alert in each of the eight Step 3 config sections in templates/_plugin_modal.html.
One shared JS runner in static/js/plugin_modal_stepper.js so loading/success/error UX is identical across all eight.
Log Analytics currently has no dedicated Step 3 section (it uses the generic endpoint/auth form, with Workspace ID and Cloud rendered dynamically in Step 4 → Advanced → Additional Fields). Give it a dedicated Step 3 section with Workspace ID, Cloud, Authority Host / Endpoint Override, endpoint, and its own auth block, so the Test Connection button sits next to the config it validates.
Acceptance Criteria
All eight action types show a working Test Connection button in the action modal, for personal, group, and admin/global scopes
Each test authenticates and performs one lightweight read against the configured resource, and reports a specific, actionable message
Auth failures, not-found resources, and transport errors are distinguishable in the returned message
Existing actions can be tested in edit mode without re-entering masked (ui_trigger_word) secrets, and reusable workspace identities are hydrated before the test runs
No credential value is ever echoed back to the browser; all exception text is sanitized
The MCP test route enforces the same stdio scope restriction and outbound destination policy as /api/plugins/mcp/discover, so it does not become a weaker SSRF path
Missing optional packages (snowflake-connector-python, tableauserverclient, azure-monitor-query) return a clear message rather than a 500
Log Analytics gets a dedicated Step 3 section, and existing log_analytics actions keep their manifest shape, including query_history and any other stored additionalFields keys
Every new route carries @swagger_route(security=get_auth_security()) plus @login_required and @user_required
Functional tests cover route registration and decorators, secret redaction, and Log Analytics config round-tripping
Playwright UI tests cover the button and mocked success/failure alerts for all eight types
docs/explanation/features/ACTION_TEST_CONNECTION.md added and config.pyVERSION bumped
Notes
The existing /api/plugins/test-sql-connection and /api/plugins/test-cosmos-connection routes are left untouched.
Testers reuse the existing plugin classes and factories (OpenApiPluginFactory, BlobStoragePlugin, DatabricksPluginFactory, LogAnalyticsPlugin, McpPluginFactory, SnowflakePluginFactory, TableauPluginFactory) rather than reimplementing clients.
No files under deployers/ change, so deployers/version.txt is not bumped.
Suggested size: L (backend module, eight routes, template and JS changes, plus functional and UI test coverage).
Summary
Only the SQL and Cosmos action types expose a Test Connection button in the action (plugin) modal. Add the same capability to eight more action types:
openapi,azure_maps_openlayers,blob_storage,databricks,log_analytics,mcp,snowflake,tableau.User Value
Today, a bad Databricks warehouse ID, Blob container name, Azure Maps subscription key, Tableau PAT, Snowflake account, Log Analytics workspace ID, MCP endpoint, or OpenAPI base URL is only discovered when an agent actually invokes the tool at chat time. Admins and workspace owners have to save, run a chat, read a failure, and guess. A pre-save Test Connection turns that into an immediate, actionable message in the modal — the same experience SQL and Cosmos actions already have.
Proposed Behavior
Follow the existing SQL/Cosmos pattern.
Backend
application/single_app/functions_action_connection_tests.pywith one tester per action type. Routes stay thin.bpapblueprint, matching the existing/api/plugins/test-sql-connectionnaming:POST /api/plugins/test-openapi-connectionPOST /api/plugins/test-azure-maps-connectionPOST /api/plugins/test-blob-storage-connectionPOST /api/plugins/test-databricks-connectionPOST /api/plugins/test-log-analytics-connectionPOST /api/plugins/test-mcp-connectionPOST /api/plugins/test-snowflake-connectionPOST /api/plugins/test-tableau-connection_prepare_action_test_manifest(...)helper inroute_backend_plugins.pythat reuses the existing_load_existing_plugin_for_test,_resolve_action_identity_context,ui_trigger_wordre-hydration,hydrate_action_identity_reference,_resolve_secret_value_for_plugin_test, andPluginHealthChecker.validate_plugin_manifestflow, so masked secrets and reusable identities keep working on edit.What each test verifies (full verification: authenticate, then one lightweight read)
GETto the base URLGET {endpoint}/map/tilefor tile0/0/0ofmicrosoft.base.roadwith the subscription keyget_container_properties()then list one blob under the configured prefixGET /api/2.0/sql/warehouses/{warehouse_id}; report warehouse name and stateLogsQueryClient.query_workspace(workspace_id, "print 1", ...)McpPluginFactory.probe_server_from_config; report transport, auth method, tool countSELECT CURRENT_VERSION(), closeFrontend
templates/_plugin_modal.html.static/js/plugin_modal_stepper.jsso loading/success/error UX is identical across all eight.Acceptance Criteria
ui_trigger_word) secrets, and reusable workspace identities are hydrated before the test runs/api/plugins/mcp/discover, so it does not become a weaker SSRF pathsnowflake-connector-python,tableauserverclient,azure-monitor-query) return a clear message rather than a 500log_analyticsactions keep their manifest shape, includingquery_historyand any other storedadditionalFieldskeys@swagger_route(security=get_auth_security())plus@login_requiredand@user_requireddocs/explanation/features/ACTION_TEST_CONNECTION.mdadded andconfig.pyVERSIONbumpedNotes
/api/plugins/test-sql-connectionand/api/plugins/test-cosmos-connectionroutes are left untouched.OpenApiPluginFactory,BlobStoragePlugin,DatabricksPluginFactory,LogAnalyticsPlugin,McpPluginFactory,SnowflakePluginFactory,TableauPluginFactory) rather than reimplementing clients.deployers/change, sodeployers/version.txtis not bumped.