Skip to content

Commit d686eab

Browse files
authored
Merge pull request #4 from xxyziggy/master
Support Linux deployment
2 parents 43e1bea + 2def637 commit d686eab

29 files changed

+239
-284
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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 project to Azure Function App - datasource-functions-linux-net9
5+
6+
on:
7+
push:
8+
branches:
9+
- master
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: '9.0' # set this to the dotnet version to use
15+
16+
jobs:
17+
build-and-deploy:
18+
runs-on: ubuntu-latest
19+
20+
steps:
21+
- name: 'Checkout GitHub Action'
22+
uses: actions/checkout@v4
23+
24+
- name: Setup DotNet ${{ env.DOTNET_VERSION }} Environment
25+
uses: actions/setup-dotnet@v1
26+
with:
27+
dotnet-version: ${{ env.DOTNET_VERSION }}
28+
29+
- name: 'Resolve Project Dependencies Using Dotnet'
30+
shell: bash
31+
run: |
32+
pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}'
33+
dotnet build --configuration Release --output ./output
34+
popd
35+
36+
- name: 'Run Azure Functions Action'
37+
uses: Azure/functions-action@v1
38+
id: fa
39+
with:
40+
app-name: 'datasource-functions-linux-net9'
41+
slot-name: 'Production'
42+
package: '${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}/output'
43+
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_E623F929BAB146A5BEEB08ACBF7B3541 }}
44+
sku: 'flexconsumption'
45+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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 project to Azure Function App - datasource-functions-linux
5+
6+
on:
7+
push:
8+
branches:
9+
- master
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: ubuntu-latest
19+
20+
steps:
21+
- name: 'Checkout GitHub Action'
22+
uses: actions/checkout@v4
23+
24+
- name: Setup DotNet ${{ env.DOTNET_VERSION }} Environment
25+
uses: actions/setup-dotnet@v1
26+
with:
27+
dotnet-version: ${{ env.DOTNET_VERSION }}
28+
29+
- name: 'Resolve Project Dependencies Using Dotnet'
30+
shell: bash
31+
run: |
32+
pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}'
33+
dotnet build --configuration Release --output ./output
34+
popd
35+
36+
- name: 'Run Azure Functions Action'
37+
uses: Azure/functions-action@v1
38+
id: fa
39+
with:
40+
app-name: 'datasource-functions-linux'
41+
slot-name: 'Production'
42+
package: '${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}/output'
43+
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_919E07FAD6B34819868BF5757E7C6396 }}
44+
sku: 'flexconsumption'
45+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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 - datasource-functions-windows
5+
6+
on:
7+
push:
8+
branches:
9+
- master
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+
steps:
20+
- name: 'Checkout GitHub Action'
21+
uses: actions/checkout@v4
22+
23+
- name: Setup DotNet ${{ env.DOTNET_VERSION }} Environment
24+
uses: actions/setup-dotnet@v1
25+
with:
26+
dotnet-version: ${{ env.DOTNET_VERSION }}
27+
28+
- name: 'Resolve Project Dependencies Using Dotnet'
29+
shell: pwsh
30+
run: |
31+
pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}'
32+
dotnet build --configuration Release --output ./output
33+
popd
34+
35+
- name: 'Run Azure Functions Action'
36+
uses: Azure/functions-action@v1
37+
id: fa
38+
with:
39+
app-name: 'datasource-functions-windows'
40+
slot-name: 'Production'
41+
package: '${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}/output'
42+
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_C16424E797DD45EBB2AF8083A6FB7B68 }}

FunctionApp/DebugRequestHandler.cs

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
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
1+
namespace Plumsail.DataSource
82
{
93
class DebugRequestHandler : DelegatingHandler
104
{

FunctionApp/DebugResponseHandler.cs

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
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
1+
namespace Plumsail.DataSource
82
{
93
class DebugResponseHandler : DelegatingHandler
104
{

FunctionApp/Dynamics365/BusinessCentral/Authorize.cs

+3-12
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,19 @@
22
using Microsoft.AspNetCore.Http.Extensions;
33
using Microsoft.AspNetCore.Mvc;
44
using Microsoft.Azure.Functions.Worker;
5-
using Microsoft.Azure.WebJobs;
65
using Microsoft.Extensions.Logging;
76
using Microsoft.Extensions.Options;
87
using Microsoft.Identity.Client;
98
using Plumsail.DataSource.Dynamics365.BusinessCentral.Settings;
10-
using System.Linq;
119
using System.Net;
1210
using System.Text;
13-
using System.Threading.Tasks;
1411

1512
namespace Plumsail.DataSource.Dynamics365.BusinessCentral
1613
{
17-
public class Authorize
14+
public class Authorize(IOptions<AppSettings> settings, ILogger<Authorize> logger)
1815
{
19-
private readonly AzureApp _settings;
20-
private readonly ILogger<Authorize> _logger;
21-
22-
public Authorize(IOptions<AppSettings> settings, ILogger<Authorize> logger)
23-
{
24-
_settings = settings.Value.AzureApp;
25-
_logger = logger;
26-
}
16+
private readonly AzureApp _settings = settings.Value.AzureApp;
17+
private readonly ILogger<Authorize> _logger = logger;
2718

2819
[Function("D365-BC-Authorize")]
2920
public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "bc/authorize")] HttpRequest req)

FunctionApp/Dynamics365/BusinessCentral/Customers.cs

+8-22
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,28 @@
1-
using Grpc.Core;
21
using Microsoft.AspNetCore.Http;
32
using Microsoft.AspNetCore.Mvc;
43
using Microsoft.Azure.Functions.Worker;
5-
using Microsoft.Azure.WebJobs;
64
using Microsoft.Extensions.Logging;
75
using Microsoft.Extensions.Options;
8-
using Microsoft.Graph;
9-
using Microsoft.Graph.Beta;
10-
using Microsoft.Graph.Beta.Models;
116
using Plumsail.DataSource.Dynamics365.BusinessCentral.Settings;
12-
using Plumsail.DataSource.Dynamics365.CRM;
13-
using System.Collections.Generic;
147
using System.Text.Json.Nodes;
15-
using System.Threading.Tasks;
168

179
namespace Plumsail.DataSource.Dynamics365.BusinessCentral
1810
{
19-
public class Customers
11+
public class Customers(
12+
IOptions<AppSettings> settings,
13+
HttpClientProvider httpClientProvider,
14+
ILogger<Customers> logger)
2015
{
21-
private readonly Settings.Customers _settings;
22-
private readonly HttpClientProvider _httpClientProvider;
23-
private readonly ILogger<Customers> _logger;
24-
25-
public Customers(IOptions<AppSettings> settings, HttpClientProvider httpClientProvider, ILogger<Customers> logger)
26-
{
27-
_settings = settings.Value.Customers;
28-
_httpClientProvider = httpClientProvider;
29-
_logger = logger;
30-
}
16+
private readonly Settings.Customers _settings = settings.Value.Customers;
3117

3218
[Function("D365-BC-Customers")]
3319
public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", Route = "bc/customers/{id?}")] HttpRequest req, Guid? id)
3420
{
35-
_logger.LogInformation("D365-BC-Customers is requested.");
21+
logger.LogInformation("D365-BC-Customers is requested.");
3622

3723
try
3824
{
39-
var client = _httpClientProvider.Create();
25+
var client = httpClientProvider.Create();
4026
var companyId = await client.GetCompanyIdAsync(_settings.Company);
4127
if (companyId == null)
4228
{
@@ -71,7 +57,7 @@ public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "
7157
}
7258
catch (HttpRequestException ex)
7359
{
74-
_logger.LogError(ex, "An error has occured while processing D365-BC-Customers request.");
60+
logger.LogError(ex, "An error has occured while processing D365-BC-Customers request.");
7561
return new StatusCodeResult(ex.StatusCode.HasValue ? (int)ex.StatusCode.Value : StatusCodes.Status500InternalServerError);
7662
}
7763
}

FunctionApp/Dynamics365/BusinessCentral/HttpClientProvider.cs

+9-29
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,13 @@
1-
using Azure.Core;
2-
using Azure.Identity;
3-
using Microsoft.Extensions.Options;
4-
using Microsoft.Graph.Beta;
1+
using Microsoft.Extensions.Options;
52
using Microsoft.Identity.Client;
6-
using Microsoft.Kiota.Abstractions.Authentication;
73
using Plumsail.DataSource.Dynamics365.BusinessCentral.Settings;
8-
using Plumsail.DataSource.Dynamics365.CRM;
9-
using System;
10-
using System.Net.Http;
114
using System.Net.Http.Headers;
12-
using System.Threading;
13-
using System.Threading.Tasks;
145

156
namespace Plumsail.DataSource.Dynamics365.BusinessCentral
167
{
17-
public class HttpClientProvider
8+
public class HttpClientProvider(IOptions<AppSettings> settings)
189
{
19-
private readonly AzureApp _azureAppSettings;
20-
21-
public HttpClientProvider(IOptions<AppSettings> settings)
22-
{
23-
_azureAppSettings = settings.Value.AzureApp;
24-
}
10+
private readonly AzureApp _azureAppSettings = settings.Value.AzureApp;
2511

2612
public HttpClient Create()
2713
{
@@ -38,27 +24,21 @@ public HttpClient Create()
3824
}
3925
}
4026

41-
class OAuthMessageHandler : DelegatingHandler
27+
class OAuthMessageHandler(AzureApp azureAppSettings, HttpMessageHandler? innerHandler = null)
28+
: DelegatingHandler(innerHandler ?? new HttpClientHandler())
4229
{
43-
private readonly AzureApp _azureAppSettings;
44-
45-
public OAuthMessageHandler(AzureApp azureAppSettings, HttpMessageHandler? innerHandler = null) : base(innerHandler ?? new HttpClientHandler())
46-
{
47-
_azureAppSettings = azureAppSettings;
48-
}
49-
5030
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
5131
{
52-
var app = ConfidentialClientApplicationBuilder.Create(_azureAppSettings.ClientId)
53-
.WithClientSecret(_azureAppSettings.ClientSecret)
54-
.WithTenantId(_azureAppSettings.Tenant)
32+
var app = ConfidentialClientApplicationBuilder.Create(azureAppSettings.ClientId)
33+
.WithClientSecret(azureAppSettings.ClientSecret)
34+
.WithTenantId(azureAppSettings.Tenant)
5535
.Build();
5636

5737
var cache = new TokenCacheHelper(AzureApp.CacheFileDir);
5838
cache.EnableSerialization(app.UserTokenCache);
5939

6040
var account = await app.GetAccountAsync(cache.GetAccountIdentifier());
61-
var result = await app.AcquireTokenSilent(["https://api.businesscentral.dynamics.com/.default"], account).ExecuteAsync();
41+
var result = await app.AcquireTokenSilent(["https://api.businesscentral.dynamics.com/.default"], account).ExecuteAsync(cancellationToken);
6242
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
6343
return await base.SendAsync(request, cancellationToken);
6444
}

FunctionApp/Dynamics365/BusinessCentral/Items.cs

+5-20
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,26 @@
1-
using Grpc.Core;
21
using Microsoft.AspNetCore.Http;
32
using Microsoft.AspNetCore.Mvc;
43
using Microsoft.Azure.Functions.Worker;
5-
using Microsoft.Azure.WebJobs;
64
using Microsoft.Extensions.Logging;
75
using Microsoft.Extensions.Options;
8-
using Microsoft.Graph;
9-
using Microsoft.Graph.Beta.Models;
106
using Plumsail.DataSource.Dynamics365.BusinessCentral.Settings;
11-
using System.Collections.Generic;
127
using System.Text.Json.Nodes;
13-
using System.Threading.Tasks;
148

159
namespace Plumsail.DataSource.Dynamics365.BusinessCentral
1610
{
17-
public class Items
11+
public class Items(IOptions<AppSettings> settings, HttpClientProvider httpClientProvider, ILogger<Items> logger)
1812
{
19-
private readonly Settings.Items _settings;
20-
private readonly HttpClientProvider _httpClientProvider;
21-
private readonly ILogger<Items> _logger;
22-
23-
public Items(IOptions<AppSettings> settings, HttpClientProvider httpClientProvider, ILogger<Items> logger)
24-
{
25-
_settings = settings.Value.Items;
26-
_httpClientProvider = httpClientProvider;
27-
_logger = logger;
28-
}
13+
private readonly Settings.Items _settings = settings.Value.Items;
2914

3015
[Function("D365-BC-Items")]
3116
public async Task<IActionResult> Run(
3217
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "bc/items/{id?}")] HttpRequest req, Guid? id)
3318
{
34-
_logger.LogInformation("D365-BC-Items is requested.");
19+
logger.LogInformation("D365-BC-Items is requested.");
3520

3621
try
3722
{
38-
var client = _httpClientProvider.Create();
23+
var client = httpClientProvider.Create();
3924
var companyId = await client.GetCompanyIdAsync(_settings.Company);
4025
if (companyId == null)
4126
{
@@ -70,7 +55,7 @@ public async Task<IActionResult> Run(
7055
}
7156
catch (HttpRequestException ex)
7257
{
73-
_logger.LogError(ex, "An error has occured while processing D365-BC-Items request.");
58+
logger.LogError(ex, "An error has occured while processing D365-BC-Items request.");
7459
return new StatusCodeResult(ex.StatusCode.HasValue ? (int)ex.StatusCode.Value : StatusCodes.Status500InternalServerError);
7560
}
7661
}

FunctionApp/Dynamics365/BusinessCentral/Settings/AppSettings.cs

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Text;
4-
5-
namespace Plumsail.DataSource.Dynamics365.BusinessCentral.Settings
1+
namespace Plumsail.DataSource.Dynamics365.BusinessCentral.Settings
62
{
73
public class AppSettings
84
{

FunctionApp/Dynamics365/BusinessCentral/Settings/AzureApp.cs

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Text;
4-
5-
namespace Plumsail.DataSource.Dynamics365.BusinessCentral.Settings
1+
namespace Plumsail.DataSource.Dynamics365.BusinessCentral.Settings
62
{
73
public class AzureApp
84
{
9-
public const string CacheFileDir = @"%HOME%\data\Dynamics365.BusinessCentral";
5+
public static readonly string CacheFileDir = Path.Combine(Environment.GetEnvironmentVariable("HOME"), "data", "Dynamics365.BusinessCentral");
106
public string ClientId { get; set; }
117
public string ClientSecret { get; set; }
128
public string Tenant { get; set; }

0 commit comments

Comments
 (0)