Skip to content

Commit b8484b0

Browse files
author
Dmitry Kozlov
committed
Merge branch 'release/1.0.4-upgrade-to-net-8-isolated' into master
2 parents 9549425 + 018fc48 commit b8484b0

26 files changed

+429
-378
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action
2+
# More GitHub Actions for Azure: https://github.com/Azure/actions
3+
4+
name: Build and deploy dotnet core app to Azure Function App - data-source-functions
5+
6+
on:
7+
push:
8+
branches:
9+
- develop
10+
workflow_dispatch:
11+
12+
env:
13+
AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root
14+
DOTNET_VERSION: '8.0.x' # set this to the dotnet version to use
15+
16+
jobs:
17+
build-and-deploy:
18+
runs-on: windows-latest
19+
permissions:
20+
id-token: write #This is required for requesting the JWT
21+
22+
steps:
23+
- name: 'Checkout GitHub Action'
24+
uses: actions/checkout@v4
25+
26+
- name: Setup DotNet ${{ env.DOTNET_VERSION }} Environment
27+
uses: actions/setup-dotnet@v1
28+
with:
29+
dotnet-version: ${{ env.DOTNET_VERSION }}
30+
31+
- name: 'Resolve Project Dependencies Using Dotnet'
32+
shell: pwsh
33+
run: |
34+
pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}'
35+
dotnet build --configuration Release --output ./output
36+
popd
37+
38+
- name: Login to Azure
39+
uses: azure/login@v2
40+
with:
41+
client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_F1F0122F19484BB2858796558B0D19C9 }}
42+
tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_2C4D4BECD44F46F5B6E6CA8ABD485841 }}
43+
subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_29B57699ACA7440BB8E138E8DA7FB705 }}
44+
45+
- name: 'Run Azure Functions Action'
46+
uses: Azure/functions-action@v1
47+
id: fa
48+
with:
49+
app-name: 'data-source-functions'
50+
slot-name: 'Production'
51+
package: '${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}/output'
52+

FunctionApp/DebugRequestHandler.cs

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace Plumsail.DataSource
8+
{
9+
class DebugRequestHandler : DelegatingHandler
10+
{
11+
public DebugRequestHandler(HttpMessageHandler? innerHandler = null)
12+
{
13+
InnerHandler = innerHandler ?? new HttpClientHandler();
14+
}
15+
16+
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
17+
{
18+
Console.WriteLine("");
19+
Console.WriteLine(string.Format("Request: {0} {1}", request.Method, request.RequestUri));
20+
Console.WriteLine("Request headers:");
21+
foreach (var header in request.Headers)
22+
{
23+
Console.WriteLine(string.Format("{0}: {1}", header.Key, string.Join(',', header.Value)));
24+
}
25+
if (request.Content is not null)
26+
{
27+
Console.WriteLine("");
28+
Console.WriteLine("Request body:");
29+
var body = await request.Content.ReadAsStringAsync();
30+
Console.WriteLine(body);
31+
}
32+
33+
return await base.SendAsync(request, cancellationToken);
34+
}
35+
}
36+
}

FunctionApp/DebugResponseHandler.cs

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace Plumsail.DataSource
8+
{
9+
class DebugResponseHandler : DelegatingHandler
10+
{
11+
public DebugResponseHandler(HttpMessageHandler? innerHandler = null)
12+
{
13+
InnerHandler = innerHandler ?? new HttpClientHandler();
14+
}
15+
16+
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
17+
{
18+
var response = await base.SendAsync(request, cancellationToken);
19+
20+
Console.WriteLine("");
21+
Console.WriteLine("Response headers:");
22+
foreach (var header in response.Headers)
23+
{
24+
Console.WriteLine(string.Format("{0}: {1}", header.Key, string.Join(',', header.Value)));
25+
}
26+
if (response.Content is not null)
27+
{
28+
Console.WriteLine("");
29+
Console.WriteLine("Response body:");
30+
var body = await response.Content.ReadAsStringAsync();
31+
Console.WriteLine(body);
32+
}
33+
34+
return response;
35+
}
36+
}
37+
}

FunctionApp/Dynamics365/BusinessCentral/Authorize.cs

+13-20
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,34 @@
1-
using System;
2-
using System.IO;
3-
using System.Threading.Tasks;
1+
using Microsoft.AspNetCore.Http;
2+
using Microsoft.AspNetCore.Http.Extensions;
43
using Microsoft.AspNetCore.Mvc;
4+
using Microsoft.Azure.Functions.Worker;
55
using Microsoft.Azure.WebJobs;
6-
using Microsoft.Azure.WebJobs.Extensions.Http;
7-
using Microsoft.AspNetCore.Http;
86
using Microsoft.Extensions.Logging;
9-
using Newtonsoft.Json;
10-
using Microsoft.Graph;
11-
using Microsoft.Identity.Client;
12-
using System.Net.Http.Headers;
13-
using Microsoft.Graph.Auth;
14-
using System.Linq;
15-
using System.Collections.Generic;
167
using Microsoft.Extensions.Options;
8+
using Microsoft.Identity.Client;
179
using Plumsail.DataSource.Dynamics365.BusinessCentral.Settings;
18-
using System.Text;
19-
using Microsoft.AspNetCore.Http.Extensions;
10+
using System.Linq;
2011
using System.Net;
12+
using System.Text;
13+
using System.Threading.Tasks;
2114

2215
namespace Plumsail.DataSource.Dynamics365.BusinessCentral
2316
{
2417
public class Authorize
2518
{
2619
private readonly AzureApp _settings;
20+
private readonly ILogger<Authorize> _logger;
2721

28-
public Authorize(IOptions<AppSettings> settings)
22+
public Authorize(IOptions<AppSettings> settings, ILogger<Authorize> logger)
2923
{
3024
_settings = settings.Value.AzureApp;
25+
_logger = logger;
3126
}
3227

33-
[FunctionName("D365-BC-Authorize")]
34-
public async Task<IActionResult> Run(
35-
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
36-
ILogger log)
28+
[Function("D365-BC-Authorize")]
29+
public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req)
3730
{
38-
var scopes = new string[] { "https://graph.microsoft.com/.default", "offline_access" };
31+
var scopes = new string[] { "https://api.businesscentral.dynamics.com/.default", "offline_access" };
3932

4033
if (req.Method == "POST" && req.Form.ContainsKey("code"))
4134
{
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,48 @@
1-
using System;
2-
using System.IO;
3-
using System.Threading.Tasks;
1+
using Microsoft.AspNetCore.Http;
42
using Microsoft.AspNetCore.Mvc;
3+
using Microsoft.Azure.Functions.Worker;
54
using Microsoft.Azure.WebJobs;
6-
using Microsoft.Azure.WebJobs.Extensions.Http;
7-
using Microsoft.AspNetCore.Http;
85
using Microsoft.Extensions.Logging;
9-
using Newtonsoft.Json;
10-
using Microsoft.Graph;
11-
using Microsoft.Identity.Client;
12-
using System.Net.Http.Headers;
13-
using Microsoft.Graph.Auth;
14-
using System.Linq;
15-
using System.Collections.Generic;
166
using Microsoft.Extensions.Options;
7+
using Microsoft.Graph;
8+
using Microsoft.Graph.Beta;
9+
using Microsoft.Graph.Beta.Models;
1710
using Plumsail.DataSource.Dynamics365.BusinessCentral.Settings;
18-
using System.Text;
19-
using Microsoft.AspNetCore.Http.Extensions;
20-
using System.Net;
11+
using Plumsail.DataSource.Dynamics365.CRM;
12+
using System.Collections.Generic;
13+
using System.Text.Json.Nodes;
14+
using System.Threading.Tasks;
2115

2216
namespace Plumsail.DataSource.Dynamics365.BusinessCentral
2317
{
2418
public class Customers
2519
{
2620
private readonly Settings.Customers _settings;
27-
private readonly GraphServiceClientProvider _graphProvider;
21+
private readonly HttpClientProvider _httpClientProvider;
22+
private readonly ILogger<Customers> _logger;
2823

29-
public Customers(IOptions<AppSettings> settings, GraphServiceClientProvider graphProvider)
24+
public Customers(IOptions<AppSettings> settings, HttpClientProvider httpClientProvider, ILogger<Customers> logger)
3025
{
3126
_settings = settings.Value.Customers;
32-
_graphProvider = graphProvider;
27+
_httpClientProvider = httpClientProvider;
28+
_logger = logger;
3329
}
3430

35-
[FunctionName("D365-BC-Customers")]
36-
public async Task<IActionResult> Run(
37-
[HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
38-
ILogger log)
31+
[Function("D365-BC-Customers")]
32+
public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req)
3933
{
40-
log.LogInformation("Dynamics365-BusinessCentral-Customers is requested.");
34+
_logger.LogInformation("Dynamics365-BusinessCentral-Customers is requested.");
4135

42-
var graph = await _graphProvider.Create();
43-
var company = await graph.GetCompanyAsync(_settings.Company);
44-
if (company == null)
36+
var client = _httpClientProvider.Create();
37+
var companyId = await client.GetCompanyIdAsync(_settings.Company);
38+
if (companyId == null)
4539
{
4640
return new NotFoundResult();
4741
}
4842

49-
var customersPage = await graph.Financials.Companies[company.Id].Customers.Request().GetAsync();
50-
var customers = new List<Customer>(customersPage);
51-
while (customersPage.NextPageRequest != null)
52-
{
53-
customersPage = await customersPage.NextPageRequest.GetAsync();
54-
customers.AddRange(customersPage);
55-
}
56-
57-
return new OkObjectResult(customers);
43+
var customersJson = await client.GetStringAsync($"companies({companyId})/customers");
44+
var customers = JsonValue.Parse(customersJson);
45+
return new OkObjectResult(customers?["value"]);
5846
}
5947
}
6048
}

FunctionApp/Dynamics365/BusinessCentral/GraphServiceClientExtensions.cs

-18
This file was deleted.

FunctionApp/Dynamics365/BusinessCentral/GraphServiceClientProvider.cs

-44
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System.Text.Json.Nodes;
2+
3+
namespace Plumsail.DataSource.Dynamics365.BusinessCentral
4+
{
5+
internal static class HttpClientExtensions
6+
{
7+
internal static async System.Threading.Tasks.Task<string> GetCompanyIdAsync(this HttpClient client, string companyName)
8+
{
9+
var companiesJson = await client.GetStringAsync("companies?$select=id,name");
10+
var contacts = JsonValue.Parse(companiesJson)["value"].AsArray();
11+
12+
return contacts.FirstOrDefault(c => c["name"]?.GetValue<string>() == companyName)?["id"]?.GetValue<string>();
13+
}
14+
}
15+
}

0 commit comments

Comments
 (0)