How to call an API using time trigger Azure function - azure

I have to write an azure function using a time trigger that will hit an API every weekend and fetch the data from that API and store that data to my Azure SQL database.
So, I am not getting how to call an API from time trigger azure function to fetch data and how to store that data into my azure SQL database.

You can follow this link to get started Azure Function timer trigger.
You have to use HTTPClient to call Api.
static HttpClient client = new HttpClient();
// Update port # in the following line.
client.BaseAddress = new Uri("http://localhost:64195/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
Product product = null;
HttpResponseMessage response = await client.GetAsync(path);
if (response.IsSuccessStatusCode)
{
product = await response.Content.ReadAsAsync<Product>();
}
return product;
Note: If you have to call lots of API's/endpoints, you may get port exhaustion error. HttpClientFactory is recommended for that scenario.

Related

Azure Cosmos DB client throws "HttpRequestException: attempt was made to access a socket in a way forbidden by its access permissions" underneath

I use CosmosClient from SDK Microsoft.Azure.Cosmos 3.28.0 in ASP.NET Core 3.1 in Azure Durable Function. This client is getting and sending data from/to my cosmos instance (Core (SQL)) and it works fine but I see that it constantly throws exception in following http request for metadata
GET 169.254.169.254/metadata/instance
System.Net.Http.HttpRequestException: An attempt was made to access a socket in a way forbidden by its access permissions.
I use following configuration:
private static void RegisterCosmosDbClient(ContainerBuilder builder)
{
builder.Register(c => new SocketsHttpHandler()
{
PooledConnectionLifetime = TimeSpan.FromMinutes(10), // Customize this value based on desired DNS refresh timer
MaxConnectionsPerServer = 20, // Customize the maximum number of allowed connections
}).As<SocketsHttpHandler>().SingleInstance();
builder.Register(
x =>
{
var cosmosDbOptions = x.Resolve<CosmosDbOptions>();
var socketsHttpHandler = x.Resolve<SocketsHttpHandler>();
return new CosmosClient(cosmosDbOptions.ConnectionString, new CosmosClientOptions()
{
ConnectionMode = ConnectionMode.Direct,
PortReuseMode = PortReuseMode.PrivatePortPool,
IdleTcpConnectionTimeout = new TimeSpan(0, 23, 59, 59),
SerializerOptions = new CosmosSerializationOptions()
{
PropertyNamingPolicy = CosmosPropertyNamingPolicy.CamelCase
},
HttpClientFactory = () => new HttpClient(socketsHttpHandler, disposeHandler: false)
});
})
.AsSelf()
.SingleInstance();
}
I also tried approach with passing IHttpClientFactory from this blog but it didn't help.
It looks like there are no new sockets available in your environment therefore you are getting the socket forbidden error. Please review how to manage connection for Azure Cosmos DB clients and you should use a singleton Azure Cosmos DB client for the lifetime of your application to resolve the issue. In case if you still facing the issue leveraging the singleton object then please let me know so we can further review it.
That particular IP and path is for https://learn.microsoft.com/azure/virtual-machines/windows/instance-metadata-service?tabs=windows
The SDK is attempting to detect the Azure information. It could mean for Durable Functions, this information and endpoint is not available.
This does not affect SDK operations and should not block you from performing other actions on the CosmosClient instance.

How to recover Call Record information from MS Teams via Graph API

We have a stand alone process which needs to get call record details of completed calls via the Graph API.
We have obtained record IDs via the Azure Dashboard so that we can use them with the following endpoint
GET https://graph.microsoft.com/v1.0/communications/callRecords/{id}
as shown in
https://learn.microsoft.com/en-us/graph/api/callrecords-callrecord-get?view=graph-rest-1.0
The Azure App has been configured for access and has readAll permissions set.
The following code generates a token for access, but when actually trying to read back a call record specified by id, it always returns 404 Not found.
var scopes = new string[] { "https://graph.microsoft.com/.default" };
IConfidentialClientApplication app;
app = ConfidentialClientApplicationBuilder.Create(clientID)
.WithClientSecret(clientSecret)
.WithAuthority(new Uri(authority))
.Build();
var result = await app.AcquireTokenForClient(scopes).ExecuteAsync();
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
string id = "YYYYYYYY-F571-45D9-ABC6-XXXXXXXXXXXX"; // Real ID, but obfuscated for this example
HttpResponseMessage response = await httpClient.GetAsync(new Uri("https://graph.microsoft.com/v1.0/communications/callRecords/" + id));
Can anyone advise what I am missing.
Thanks

Calling a REST API using Azure function App

I want to call a REST API using Azure function App. REST API uses basic authentication and does not need any request parameters. The result of this API call need to be saved to ADLS gen2 blob storage. Below is the step 1 of the code where I am trying to call the REST API from function App. When I try to debug the code, response has 403 message. Any help is appreciated
string url = String.Format("my_rest_end_point_url");
HttpClient newClient = new HttpClient();
HttpRequestMessage newRequest = new HttpRequestMessage(HttpMethod.Get, url);
newRequest.Headers.Authorization =
new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "username", "pwd"))));
//Read Server Response
string responseMessage = null;
HttpResponseMessage response = await newClient.SendAsync(newRequest);
log.LogInformation("RESPONSE.", response.IsSuccessStatusCode.ToString());
return new OkObjectResult(responseMessage);

How dispose connections to services such as Azure Storage

My function stores data up Azure Data Lakta Storage Gen 1.
But I got bug An error occurred while sending the request.
When I investigated,I knowed that my connection in azure function overcome 8k then it's broken.
Here is my code(Append to file Azure DataLakeStorage Gen 1)
//This for authorizing azure data lake storage gen 1
await InitADLInfo(adlsAccountName);
DataLakeStoreFileSystemManagementClient _adlsFileSystemClient;
//Here is my code to append data lake storage gen 1
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(buffer)))
{
await _adlsFileSystemClient.FileSystem.AppendAsync(_adlsAccountName, path, stream);
}
How to dispose that when every append ends.
I try to dispose
_adlsFileSystemClient.Dispose();
But it didn't dispose anything.My connection will up.
I read this
https://www.troyhunt.com/breaking-azure-functions-with-too-many-connections/1
and I have made connection down.Just use DO NOT create a new client with every function invocation.
Example Code :
// Create a single, static HttpClient
private static HttpClient httpClient = new HttpClient();
public static async Task Run(string input)
{
var response = await httpClient.GetAsync("http://example.com");
// Rest of function
}

How to speed up calls to microsoft graph endpoints?

We make calls to the groups and users endpoints for Microsoft Graph and they are taking 200+ ms to complete. The web application making the calls is hosted as an App Service in Azure (South Central US). For some users we need to make multiple calls per user request and it is slowing down our application significantly. I have reviewed the best practices and known issues with MS Graph and have found no resolution. Is caching the only way to speed this up?
Documentation we have reviewed:
https://learn.microsoft.com/en-us/graph/best-practices-concept
https://learn.microsoft.com/en-us/graph/known-issues
The endpoints we are seeing this delay with are:
https://graph.microsoft.com/v1.0/groups
https://graph.microsoft.com/v1.0/users
We have seen the same delay with both HttpClient REST calls and the SDK. We get the same delay if we make a call for a single user or all users.
Code using HttpClient that takes 200+ ms within an Azure data center:
var accessToken = await GetBearerAccessToken();
var url = "https://graph.microsoft.com/v1.0/users/" + id;
using (var client = new HttpClient())
{
using (var request = new HttpRequestMessage(HttpMethod.Get, url))
{
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
using (var response = await client.SendAsync(request))
{
if (response.StatusCode == HttpStatusCode.OK)
{
var json = await response.Content.ReadAsStringAsync();
result = JsonConvert.DeserializeObject<Salesperson>(json);
}
}
}
}

Resources