0
votes

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.ValueTask1.get_Result() at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask1.get_Result() at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask1 creationTask) at System.Threading.Tasks.ValueTask1.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(Task1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts) at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteAsyncInternal[T](RESTCommand1 cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token) --- End of inner exception stack trace --- at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteAsyncInternal[T](RESTCommand1 cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token) at Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.ListBlobsSegmentedAsync(String prefix, Boolean useFlatBlobListing, BlobListingDetails blobListingDetails, Nullable1 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 ?

1
For debugging purpose you could consider logging your hostname/port so you now the settings are correct.Preben Huybrechts
I actually did that, sorry, I should have specified. But the settings are exactly the same ones as in my local.settings.json file.MarleneHE
do you have some firewall / IP restriction in place on your cosmosdb?silent
Not that I know of. How can I verify that ?MarleneHE
Sorry, I checked and no, there is no IP restriction. This is very confusing.MarleneHE

1 Answers

0
votes

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: