Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/integrationtests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,8 @@ jobs:
CLIENT_SECRET: ${{ secrets.AUTH0_TEST_CLIENT_SECRET }}
run: |
dotnet test --filter TestCollectionName='authenticated'
- name: Run Integration Tests for Example Application
working-directory: TransformerBeeClient/ExampleAspNetCoreApplication.Test
run: |
dotnet build --no-restore
dotnet test
24 changes: 17 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,38 +15,47 @@ Ask info@hochfrequenz.de or ping @JoschaMetze on GitHub to get one.
You can check if your account is working by logging [into our stage environment](https://transformerstage.utilibee.io/app/).

### Using the client
![Nuget Package](https://badgen.net/nuget/v/TransformerBeeClient)
Install it from nuget [TransformerBeeClient](https://www.nuget.org/packages/TransformerBeeClient):

Install it from nuget [TransformerBeeClient](https://www.nuget.org/packages/TransformerBeeClient) ![Nuget Package](https://badgen.net/nuget/v/TransformerBeeClient):

```bash
dotnet add package TransformerBeeClient
```

### Authentication

You need to provide something that implements `ITransformerBeeAuthenticator` to the `TransformerBeeClient`.

#### No Authentication
If you're hosting transformer.bee in the same network and there is no authentication, you can use the `NoAuthenticator`.

If you're hosting transformer.bee in the same network or your localhost and there is no authentication, you can use the `NoAuthenticator`.

```csharp
using TransformerBeeClient;
var myAuthenticator = new NoAuthenticationProvider();
```

#### OAuth2 Client and Secret
If, which is more likely, Hochfrequenz provided you with a client ID and secret, you can use the `ClientIdClientSecretAuthenticator` class like this:
If, which is more likely, Hochfrequenz provided you with a client Id and secret, you can use the `ClientIdClientSecretAuthenticator` class like this:

```csharp
using TransformerBeeClient;
var myAuthenticator = new ClientIdClientSecretAuthenticationProvider("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET");
```

...todo
```csharp
### Use with ASP.NET Core
This library is thought to be primarily used in ASP.NET Core applications.
That's why it assumes that you have an `IHttpClientFactory` available in your dependency injection container.
See the [`ExampleAspNetCoreApplication/Program.cs`](TransformerBeeClient/ExampleAspNetCoreApplication/Program.cs) for a minimal working example.

```
### Use without ASP.NET Core
If you're not using ASP.NET Core, you can still use this library but setting up th `IHttpClientFactory` comes with a bit of boilerplate.
See the [`MweWithoutAspNetTest.cs`](TransformerBeeClient/TransformerBeeClient.IntegrationTest/MweWithoutAspNetTest.cs) for a minimal working example.

## Development

### Integration Tests

To run the integration test login to your docker to access the transformer.bee image.

```bash
Expand All @@ -56,6 +65,7 @@ docker login ghcr.io -u YOUR_GITHUB_USERNAME
then paste your PAT similarly to described in the [integration test CI pipeline](.github/workflows/integrationtests.yml)

### Release (CI/CD)

To release a new version of this library, [create a new release](https://github.com/Hochfrequenz/transformer.bee_client.net/releases/new) in GitHub.
Make sure its tag starts with `v` and the version number, e.g. `v1.2.3`.
Tags without a release wont trigger the release workflow; This enforces that you have to write a changelog before releasing.
Expand Down
4 changes: 4 additions & 0 deletions TransformerBeeClient/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ TransformerBeeClient.IntegrationTest/obj
TransformerBeeClient.IntegrationTest/bin
TransformerBeeClient.UnitTest/obj
TransformerBeeClient.UnitTest/bin
ExampleAspNetCoreApplication/obj
ExampleAspNetCoreApplication/bin
ExampleAspNetCoreApplication.Test/obj
ExampleAspNetCoreApplication.Test/bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Net;
using System.Text.Json;
using System.Text.Json.Serialization;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc.Testing;
using TransformerBeeClient.Model;

namespace ExampleAspNetCoreApplication.Test;

public class ApplicationTest : IClassFixture<WebApplicationFactory<Program>>
{
protected readonly WebApplicationFactory<Program> Factory;

public ApplicationTest(WebApplicationFactory<Program> factory)
{
Factory = factory;
}

[Fact]
public async Task Test_That_Setup_Works_As_Designed()
{
var client = Factory.CreateDefaultClient();
var response = await client.GetAsync("/talkToTransformerBee");
response.StatusCode.Should().Be(HttpStatusCode.OK);
var content = await response.Content.ReadAsStringAsync();
var bo4e = JsonSerializer.Deserialize<BOneyComb>(content, new JsonSerializerOptions { Converters = { new JsonStringEnumConverter() } });
bo4e.Should().NotBeNull();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0"/>
<PackageReference Include="xunit" Version="2.4.2"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\ExampleAspNetCoreApplication\ExampleAspNetCoreApplication.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
global using Xunit;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"shadowCopy": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<PreserveCompilationContext>true</PreserveCompilationContext>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\TransformerBeeClient\TransformerBeeClient.csproj"/>
</ItemGroup>
</Project>
29 changes: 29 additions & 0 deletions TransformerBeeClient/ExampleAspNetCoreApplication/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using EDILibrary;
using TransformerBeeClient;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpClient();

builder.Services.AddTransient<ITransformerBeeAuthenticator, NoAuthenticator>(); // Or you could use ClientIdClientSecretAuthenticator
builder.Services.AddHttpClient("TransformerBee", client =>
{
client.BaseAddress = new Uri("http://localhost:5021/"); // or https://transformerstage.utilibee.io
});
builder.Services.AddTransient<ICanConvertToBo4e, TransformerBeeRestClient>();
builder.Services.AddTransient<ICanConvertToEdifact, TransformerBeeRestClient>();

var app = builder.Build();

app.MapGet("/", () => "I ❤ BO4E");
app.MapGet("/talkToTransformerBee", async (ICanConvertToBo4e transformerBeeRestClient) =>
{
var bo4e = await transformerBeeRestClient.ConvertToBo4e(
"UNA:+,? 'UNB+UNOC:3+9912345789012:500+9909876543210:500+230703:1059+ASDFHGJ'UNH+11223344556678+UTILMD:D:11A:UN:S1.1'BGM+E01+918273746512345678901'DTM+137:202306300558?+00:303'NAD+MS+9912345789012::293'NAD+MR+9909876543210::293'IDE+24+918273746512345678901'IMD++Z36+Z13'DTM+92:202212312300?+00:303'STS+7++E01'LOC+Z16+78889918283'LOC+Z17+DE0000111122223333444455556667778'RFF+Z13:55001'SEQ+Z01'CCI+Z30++Z07'CCI+Z19++11X0-0000-0116-J'CCI+++Z15'CCI+++Z88'CAV+Z74:::Z09'CAV+Z73:::Z11'SEQ+Z12'QTY+Z16:0:P1'SEQ+Z03'CCI+++E13'CAV+Z30:::788811123'SEQ+Z75'CCI+Z61++ZG1'NAD+Z09+++Schaefer:Ulrike:::Frau:Z01'NAD+Z04+++Schaefer:Ulrike:::Frau:Z01+Flughafenstrasse::64+Vilseck++92247+DE'NAD+DP++++Flughafenstrasse::64+Vilseck++92247+DE'NAD+Z05+++Schaefer:Ulrike:::Frau:Z01+Flughafenstrasse::64+Vilseck++92247+DE'UNT+31+11223344556678'UNZ+1+ASDFHGJ'",
EdifactFormatVersion.FV2310);
return bo4e.Single().Transaktionen.Single();
});
app.Run();

public partial class Program
{
} // required for integration testing; If you miss this the test will complain, that it cannot find a 'testhost.deps.json'
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:26369",
"sslPort": 44341
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5137",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7030;http://localhost:5137",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using EDILibrary;
using Xunit;

namespace TransformerBeeClient.IntegrationTest;

/// <summary>
/// A minimal working example on how to use this library without ASP.NET
/// </summary>
public class MweWithoutAspNetTest
{
/// <summary>
/// in asp.net applications, there's a service collection that is used to create the http client factory for you
/// </summary>
internal class MyHttpClientFactory : IHttpClientFactory
{
public HttpClient CreateClient(string name)
{
return new HttpClient
{
BaseAddress = new Uri("http://localhost:5021")
};
}
}

[Fact]
public async Task Test_Transformer_Bee_Communication()
{
IHttpClientFactory myFactory = new MyHttpClientFactory();
ITransformerBeeAuthenticator myAuthenticator = new NoAuthenticator(); // or use ClientIdClientSecretAuthenticator
var client = new TransformerBeeRestClient(myFactory, myAuthenticator);
await client.ConvertToBo4e("UNA:+,? 'UNB+UNOC:3+9912345789012:500+9909876543210:500+230703:1059+ASDFHGJ'UNH+11223344556678+UTILMD:D:11A:UN:S1.1'BGM+E01+918273746512345678901'DTM+137:202306300558?+00:303'NAD+MS+9912345789012::293'NAD+MR+9909876543210::293'IDE+24+918273746512345678901'IMD++Z36+Z13'DTM+92:202212312300?+00:303'STS+7++E01'LOC+Z16+78889918283'LOC+Z17+DE0000111122223333444455556667778'RFF+Z13:55001'SEQ+Z01'CCI+Z30++Z07'CCI+Z19++11X0-0000-0116-J'CCI+++Z15'CCI+++Z88'CAV+Z74:::Z09'CAV+Z73:::Z11'SEQ+Z12'QTY+Z16:0:P1'SEQ+Z03'CCI+++E13'CAV+Z30:::788811123'SEQ+Z75'CCI+Z61++ZG1'NAD+Z09+++Schaefer:Ulrike:::Frau:Z01'NAD+Z04+++Schaefer:Ulrike:::Frau:Z01+Flughafenstrasse::64+Vilseck++92247+DE'NAD+DP++++Flughafenstrasse::64+Vilseck++92247+DE'NAD+Z05+++Schaefer:Ulrike:::Frau:Z01+Flughafenstrasse::64+Vilseck++92247+DE'UNT+31+11223344556678'UNZ+1+ASDFHGJ'", EdifactFormatVersion.FV2310);
}
}
12 changes: 12 additions & 0 deletions TransformerBeeClient/TransformerBeeClient.sln
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TransformerBeeClient.UnitTe
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TransformerBeeClient.IntegrationTest", "TransformerBeeClient.IntegrationTest\TransformerBeeClient.IntegrationTest.csproj", "{77598126-7BB0-4C07-BF06-331033E0DE78}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExampleAspNetCoreApplication", "ExampleAspNetCoreApplication\ExampleAspNetCoreApplication.csproj", "{E6F6E532-9758-46C0-AC04-42CC054613C7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExampleAspNetCoreApplication.Test", "ExampleAspNetCoreApplication.Test\ExampleAspNetCoreApplication.Test.csproj", "{39992205-201D-445B-A58D-BB098F5EFC1D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -24,5 +28,13 @@ Global
{77598126-7BB0-4C07-BF06-331033E0DE78}.Debug|Any CPU.Build.0 = Debug|Any CPU
{77598126-7BB0-4C07-BF06-331033E0DE78}.Release|Any CPU.ActiveCfg = Release|Any CPU
{77598126-7BB0-4C07-BF06-331033E0DE78}.Release|Any CPU.Build.0 = Release|Any CPU
{E6F6E532-9758-46C0-AC04-42CC054613C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E6F6E532-9758-46C0-AC04-42CC054613C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E6F6E532-9758-46C0-AC04-42CC054613C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E6F6E532-9758-46C0-AC04-42CC054613C7}.Release|Any CPU.Build.0 = Release|Any CPU
{39992205-201D-445B-A58D-BB098F5EFC1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{39992205-201D-445B-A58D-BB098F5EFC1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{39992205-201D-445B-A58D-BB098F5EFC1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{39992205-201D-445B-A58D-BB098F5EFC1D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
16 changes: 4 additions & 12 deletions TransformerBeeClient/TransformerBeeClient.sln.DotSettings.user
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=1c8bdc71_002Dfc3e_002D44fe_002D9812_002D1b49b4ba3413/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="All tests from Solution" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;

<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=4fa21289_002Debff_002D4c5a_002D8d89_002D3c311da32c05/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from Solution #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
&lt;Solution /&gt;&#xD;
&lt;/SessionState&gt;</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=4fa21289_002Debff_002D4c5a_002D8d89_002D3c311da32c05/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="All tests from Solution #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
&lt;Solution /&gt;&#xD;
&lt;/SessionState&gt;</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=591857ee_002D832a_002D4abe_002D964d_002Db61be9cce36e/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="BOneyComb_Can_Be_Converted_To_Edifact" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
&lt;TestAncestor&gt;&#xD;
&lt;TestId&gt;xUnit::77598126-7BB0-4C07-BF06-331033E0DE78::net8.0::TransformerBeeClient.IntegrationTest.Bo4eToEdifactTests.BOneyComb_Can_Be_Converted_To_Edifact&lt;/TestId&gt;&#xD;
&lt;/TestAncestor&gt;&#xD;
&lt;/SessionState&gt;</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=de4efd69_002D9f4a_002D4e00_002D83fa_002Ddaa381865bd8/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="ConnectionTest" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
&lt;Solution /&gt;&#xD;
&lt;/SessionState&gt;</s:String></wpf:ResourceDictionary>

</wpf:ResourceDictionary>
6 changes: 4 additions & 2 deletions TransformerBeeClient/TransformerBeeClient/RestClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,13 @@ public async Task<List<Marktnachricht>> ConvertToBo4e(string edifact, EdifactFor
var httpResponse = await _httpClient.PostAsync(convertUrl, new StringContent(requestJson, Encoding.UTF8, "application/json"));
if (!httpResponse.IsSuccessStatusCode)
{
var errorContent = await httpResponse.Content.ReadAsStringAsync();
if (httpResponse.StatusCode == HttpStatusCode.Unauthorized && !_authenticator.UseAuthentication())
{
throw new AuthenticationException($"Did you correctly set up the {nameof(ITransformerBeeAuthenticator)}?");
}

throw new HttpRequestException($"Could not convert {edifact} to BO4E. Status code: {httpResponse.StatusCode}");
throw new HttpRequestException($"Could not convert {edifact} to BO4E. Status code: {httpResponse.StatusCode} / {errorContent}");
}

var responseContent = await httpResponse.Content.ReadAsStringAsync();
Expand Down Expand Up @@ -149,12 +150,13 @@ public async Task<string> ConvertToEdifact(BOneyComb boneyComb, EdifactFormatVer
var httpResponse = await _httpClient.PostAsync(convertUrl, new StringContent(requestJson, Encoding.UTF8, "application/json"));
if (!httpResponse.IsSuccessStatusCode)
{
var errorContent = await httpResponse.Content.ReadAsStringAsync();
if (httpResponse.StatusCode == HttpStatusCode.Unauthorized && !_authenticator.UseAuthentication())
{
throw new AuthenticationException($"Did you correctly set up the {nameof(ITransformerBeeAuthenticator)}?");
}

throw new HttpRequestException($"Could not convert to EDIFACT; Status code: {httpResponse.StatusCode}");
throw new HttpRequestException($"Could not convert to EDIFACT; Status code: {httpResponse.StatusCode} / {errorContent}");
}

var responseContent = await httpResponse.Content.ReadAsStringAsync();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TargetFrameworks>net8.0;net6.0;net7.0</TargetFrameworks>
<RepositoryUrl>https://github.com/Hochfrequenz/transformer.bee_client.net</RepositoryUrl>
<License>MIT</License>
</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
Expand Down