简体   繁体   中英

I can connect my local Azure function to my CosmosDB database, but when I publish the code on Azure, it cannot connect anymore

I have developed a blob-triggered function app that then saves data to a CosmosDB database using the Gremlin API and the Gremlin.Net driver.

I have created a CosmosDB database on my Azure account, and then read the connection parameters from local.settings.json when I run my function locally. This works perfectly fine, and my function manages to store data on the database hosted on Azure. Here's my code for connecting to my database:

        var hostName = Environment.GetEnvironmentVariable($"CosmosDBHostname");

        var portNumber = Int32.Parse(Environment.GetEnvironmentVariable($"CosmosDBPort"));

        var enableSsl = Boolean.Parse(Environment.GetEnvironmentVariable($"CosmosDBEnableSSL"));

        string containerLink = Environment.GetEnvironmentVariable($"CosmosDBContainerLink");

        string password = Environment.GetEnvironmentVariable($"CosmosDBPassword");

        var gremlinServer = new GremlinServer(hostName, portNumber, enableSsl,
            username: containerLink,
            password: password);

        var gremlinClient = new GremlinClient(gremlinServer, new GraphSON2Reader(), new GraphSON2Writer(),
            GremlinClient.GraphSON2MimeType);

I then created a Function App on the same ResourceGroup as the database on my Azure account, and publish my code to this Function App, and copied the parameters of my local.settings.json file to the Azure settings of my function app. But when I do that, my function is not able to connect to the database anymore.

I get the following exception when my function runs and tries to connect to the database:

Error while processing files: Microsoft.WindowsAzure.Storage.StorageException: An attempt was made to access a socket in a way forbidden by its access permissions ---> System.Net.Http.HttpRequestException: An attempt was made to access a socket in a way forbidden by its access permissions ---> System.Net.Sockets.SocketException: An attempt was made to access a socket in a way forbidden by its access permissions at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken) --- End of inner exception stack trace --- at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask 1.get_Result() at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask 1.get_Result() at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask 1.get_Result() at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask 1 creationTask) at System.Threading.Tasks.ValueTask 1.get_Result() at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task 1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts) at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteAsyncInternal[T](RESTCommand 1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts) at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteAsyncInternal[T](RESTCommand 1 cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token) --- End of inner exception stack trace --- at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteAsyncInternal[T](RESTCommand 1 cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token) at Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.ListBlobsSegmentedAsync(String prefix, Boolean useFlatBlobListing, BlobListingDetails blobListingDetails, Nullable 1 maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken)

Is there any explanation as to why my function can connect to my database from my local development environment, using local.settings.json, but not when it is published, using the Azure settings?

The error is coming from Azure Storage ( Microsoft.WindowsAzure.Storage.StorageException ), not from your Gremlin client, based on the stack trace you provided:

Error while processing files: Microsoft.WindowsAzure.Storage.StorageException: An attempt was made to access a socket in a way forbidden by its access permissions 

Functions use an Azure Storage account which is also part of the settings. Locally it usually uses the Storage Emulator.

Double check that configuration and check which Storage account is using, and if that Storage account (if it exists) has any Firewall / VPN restrictions.

EDIT: The stack trace also shows that the issue seems related to the access of the file:

Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.ListBlobsSegmentedAsync

This could also be related to the number of connections you are opening, if this is happen sporadically or after X amount of time running (if you restart the Function App it works temporarily).

I see that your code is creating a GremlinServer instance, if you are doing that on every Function execution, that might lead to connection issues.

See:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM