Skip to content

Commit

Permalink
Added POS factory for HTTP
Browse files Browse the repository at this point in the history
  • Loading branch information
TSchmiedlechner committed Apr 30, 2020
1 parent d1fefa3 commit 08c75bf
Show file tree
Hide file tree
Showing 13 changed files with 369 additions and 6 deletions.
6 changes: 0 additions & 6 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PackageReference Include="Nerdbank.GitVersioning">
<Version>3.0.50</Version>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
</Project>
21 changes: 21 additions & 0 deletions fiskaltrust.Middleware.Interface.sln
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "fiskaltrust.Middleware.Inte
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "fiskaltrust.Middleware.Interface.Tests", "test\fiskaltrust.ifPOS.Tests\fiskaltrust.Middleware.Interface.Tests.csproj", "{B4ECE1C6-E1F3-4F54-98B8-B588D9DB52D9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "fiskaltrust.Middleware.Interface.Http", "src\fiskaltrust.Middleware.Interface.Http\fiskaltrust.Middleware.Interface.Http.csproj", "{191B6405-4ACC-4200-87C9-72D9DBE59776}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "fiskaltrust.Middleware.Interface.Soap", "src\fiskaltrust.Middleware.Interface.Soap\fiskaltrust.Middleware.Interface.Soap.csproj", "{B461D451-1794-4088-8208-62F10604B60A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "fiskaltrust.Middleware.Interface.Grpc", "src\fiskaltrust.Middleware.Interface.Grpc\fiskaltrust.Middleware.Interface.Grpc.csproj", "{0D9AB222-DCBF-4037-9210-A08BBE80859B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -32,13 +38,28 @@ Global
{B4ECE1C6-E1F3-4F54-98B8-B588D9DB52D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B4ECE1C6-E1F3-4F54-98B8-B588D9DB52D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B4ECE1C6-E1F3-4F54-98B8-B588D9DB52D9}.Release|Any CPU.Build.0 = Release|Any CPU
{191B6405-4ACC-4200-87C9-72D9DBE59776}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{191B6405-4ACC-4200-87C9-72D9DBE59776}.Debug|Any CPU.Build.0 = Debug|Any CPU
{191B6405-4ACC-4200-87C9-72D9DBE59776}.Release|Any CPU.ActiveCfg = Release|Any CPU
{191B6405-4ACC-4200-87C9-72D9DBE59776}.Release|Any CPU.Build.0 = Release|Any CPU
{B461D451-1794-4088-8208-62F10604B60A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B461D451-1794-4088-8208-62F10604B60A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B461D451-1794-4088-8208-62F10604B60A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B461D451-1794-4088-8208-62F10604B60A}.Release|Any CPU.Build.0 = Release|Any CPU
{0D9AB222-DCBF-4037-9210-A08BBE80859B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0D9AB222-DCBF-4037-9210-A08BBE80859B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0D9AB222-DCBF-4037-9210-A08BBE80859B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0D9AB222-DCBF-4037-9210-A08BBE80859B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{ED0862F3-D1A0-4246-A22D-937F471647CE} = {18766606-E68D-44CC-B89A-5807F901D943}
{B4ECE1C6-E1F3-4F54-98B8-B588D9DB52D9} = {4A4977D1-0B9A-44F9-B4A3-3D08FBB58D14}
{191B6405-4ACC-4200-87C9-72D9DBE59776} = {18766606-E68D-44CC-B89A-5807F901D943}
{B461D451-1794-4088-8208-62F10604B60A} = {18766606-E68D-44CC-B89A-5807F901D943}
{0D9AB222-DCBF-4037-9210-A08BBE80859B} = {18766606-E68D-44CC-B89A-5807F901D943}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3CAE7E81-C6A5-44FA-8E98-F9207561129F}
Expand Down
8 changes: 8 additions & 0 deletions src/fiskaltrust.Middleware.Interface.Grpc/Class1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System;

namespace fiskaltrust.Middleware.Interface.Grpc
{
public class Class1
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.IO;
using System.Xml.Serialization;

namespace fiskaltrust.Middleware.Interface.Http.Helpers
{
internal static class XmlSerializationHelpers
{
public static string Serialize(object inputObject)
{
using (var writer = new StringWriter())
{
new XmlSerializer(inputObject.GetType()).Serialize(writer, inputObject);
return writer.ToString();
}
}
}
}
223 changes: 223 additions & 0 deletions src/fiskaltrust.Middleware.Interface.Http/HttpPos.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
using fiskaltrust.ifPOS.v1;
using fiskaltrust.Middleware.Interface.Http.Helpers;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace fiskaltrust.Middleware.Interface.Http
{
public class HttpPos : IPOS
{
private readonly string _url;
private readonly HttpPosOptions _options;

private delegate string AsyncEchoCaller(string message);
private delegate ifPOS.v0.ReceiptResponse AsyncSignCaller(ifPOS.v0.ReceiptRequest request);
private delegate Stream AsyncJournalCaller(long ftJournalType, long from, long to);

public HttpPos(HttpPosOptions options)
{
_url = options.Url.Replace("rest://", "http://").Replace("xml://", "http://");
_options = options;
}

IAsyncResult ifPOS.v0.IPOS.BeginEcho(string message, AsyncCallback callback, object state)
{
var d = new AsyncEchoCaller((this as ifPOS.v0.IPOS).Echo);
return d.BeginInvoke(message, callback, d);
}

string ifPOS.v0.IPOS.EndEcho(IAsyncResult result)
{
var d = (AsyncEchoCaller)result.AsyncState;
return d.EndInvoke(result);
}

string ifPOS.v0.IPOS.Echo(string message)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(_url);

var jsonstring = JsonConvert.SerializeObject(message);
var jsonContent = new StringContent(jsonstring, Encoding.UTF8, "application/json");

using (var response = client.PostAsync("v0/Echo", jsonContent).Result)
{
response.EnsureSuccessStatusCode();
var reponse = response.Content.ReadAsStringAsync().Result;
return JsonConvert.DeserializeObject<string>(reponse);
}
}
}

async Task<EchoResponse> IPOS.EchoAsync(EchoRequest message)
{
if (_options.CommunicationType == HttpCommunicationType.Json)
{
return await JsonEchoAsync(message);
}
else
{
return await XmlEchoAsync(message);
}
}

private async Task<EchoResponse> XmlEchoAsync(EchoRequest message)
{
var xmlString = XmlSerializationHelpers.Serialize(message);
var xmlContent = new StringContent(xmlString, Encoding.UTF8, "application/xml");

using (var client = new HttpClient())
{
client.BaseAddress = new Uri(_url);

using (var response = await client.PostAsync("v1/Echo", xmlContent))
{
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();

var xml = XElement.Parse(content);
string jsonText = JsonConvert.SerializeXNode(xml);
return JsonConvert.DeserializeObject<EchoResponse>(jsonText);
}
}
}

private async Task<EchoResponse> JsonEchoAsync(EchoRequest message)
{
var jsonstring = JsonConvert.SerializeObject(message);
var jsonContent = new StringContent(jsonstring, Encoding.UTF8, "application/json");

using (var client = new HttpClient())
{
client.BaseAddress = new Uri(_url);

using (var response = await client.PostAsync("v1/Echo", jsonContent))
{
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<EchoResponse>(content.ToString());
}
}
}


IAsyncResult ifPOS.v0.IPOS.BeginSign(ifPOS.v0.ReceiptRequest data, AsyncCallback callback, object state)
{
var d = new AsyncSignCaller((this as ifPOS.v0.IPOS).Sign);
return d.BeginInvoke(data, callback, d);
}

ifPOS.v0.ReceiptResponse ifPOS.v0.IPOS.EndSign(IAsyncResult result)
{
var d = (AsyncSignCaller)result.AsyncState;
return d.EndInvoke(result);
}

ifPOS.v0.ReceiptResponse ifPOS.v0.IPOS.Sign(ifPOS.v0.ReceiptRequest data)
{
if (_options.CommunicationType == HttpCommunicationType.Json)
{
return JsonSignAsync<ifPOS.v0.ReceiptRequest, ifPOS.v0.ReceiptResponse>(data, "v0/sign").Result;
}
else
{
return XmlSignAsync<ifPOS.v0.ReceiptRequest, ifPOS.v0.ReceiptResponse>(data, "v0/sign").Result;
}
}

async Task<ReceiptResponse> IPOS.SignAsync(ReceiptRequest request)
{
if (_options.CommunicationType == HttpCommunicationType.Json)
{
return await JsonSignAsync<ReceiptRequest, ReceiptResponse>(request, "v1/sign");
}
else
{
return await XmlSignAsync<ReceiptRequest, ReceiptResponse>(request, "v1/sign");
}
}

private async Task<TResponse> JsonSignAsync<TRequest, TResponse>(TRequest request, string endpoint)
{
var jsonstring = JsonConvert.SerializeObject(request);
var jsonContent = new StringContent(jsonstring, Encoding.UTF8, "application/json");

using (var client = new HttpClient())
{
client.BaseAddress = new Uri(_url);

using (var response = await client.PostAsync(Path.Combine(_url, endpoint), jsonContent))
{
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();

return JsonConvert.DeserializeObject<TResponse>(content);
}
}
}

private async Task<TResponse> XmlSignAsync<TRequest, TResponse>(TRequest request, string endpoint)
{
var xmlString = XmlSerializationHelpers.Serialize(request);
var xmlContent = new StringContent(xmlString, Encoding.UTF8, "application/xml");

using (var client = new HttpClient())
{
client.BaseAddress = new Uri(_url);

using (var response = await client.PostAsync(endpoint, xmlContent))
{
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
var xml = XElement.Parse(content);
string jsonText = JsonConvert.SerializeXNode(xml);

return JsonConvert.DeserializeObject<TResponse>(jsonText);
}
}
}


IAsyncResult ifPOS.v0.IPOS.BeginJournal(long ftJournalType, long from, long to, AsyncCallback callback, object state)
{
var d = new AsyncJournalCaller((this as ifPOS.v0.IPOS).Journal);
return d.BeginInvoke(ftJournalType, from, to, callback, d);
}

Stream ifPOS.v0.IPOS.EndJournal(IAsyncResult result)
{
var d = (AsyncJournalCaller)result.AsyncState;
return d.EndInvoke(result);
}

Stream ifPOS.v0.IPOS.Journal(long ftJournalType, long from, long to)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(_url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

using (var response = client.GetAsync($"v0/journal?type={ftJournalType}&from={from}&to={to}").Result)
{
response.EnsureSuccessStatusCode();
var stream = response.Content.ReadAsStreamAsync().Result;
return stream;
}
}
}

IAsyncEnumerable<JournalResponse> IPOS.JournalAsync(JournalRequest request)
{
throw new NotSupportedException("Async streaming is not supported in HTTP. Please call the non-async Journal method.");
}
}
}
18 changes: 18 additions & 0 deletions src/fiskaltrust.Middleware.Interface.Http/HttpPosFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using fiskaltrust.ifPOS.v1;
using System;

namespace fiskaltrust.Middleware.Interface.Http
{
public class HttpPosFactory : IPOSFactory
{
public IPOS CreatePosAsync(POSOptions options)
{
if (!(options is HttpPosOptions httpOptions))
{
throw new ArgumentException($"Parameter {nameof(options)} must be of type {nameof(HttpPosOptions)}.");
}

return new HttpPos(httpOptions);
}
}
}
15 changes: 15 additions & 0 deletions src/fiskaltrust.Middleware.Interface.Http/HttpPosOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using fiskaltrust.ifPOS.v1;

namespace fiskaltrust.Middleware.Interface.Http
{
public class HttpPosOptions : POSOptions
{
public HttpCommunicationType CommunicationType { get; set; }
}

public enum HttpCommunicationType
{
Json,
Xml
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net461;netstandard2.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="fiskaltrust.interface" Version="1.3.0-rc1" />
<PackageReference Include="Newtonsoft.Json" Version="6.0.8" />
</ItemGroup>

<PropertyGroup>
<PackageId>fiskaltrust.Middleware.Interface.Http</PackageId>
<Authors>fiskaltrust</Authors>
<Company>fiskaltrust</Company>
<PackageLicenseUrl>https://github.com/fiskaltrust/middleware-interface-dotnet/LICENSE</PackageLicenseUrl>
<PackageProjectUrl>https://github.com/fiskaltrust/middleware-interface-dotnet</PackageProjectUrl>
<PackageIconUrl>https://portal.fiskaltrust.at/Content/favicons/favicon-64x64.png</PackageIconUrl>
<Description>An optional helper implementation to simplify the usage of the fiskaltrust Middleware interface via HTTP.</Description>
<Copyright>Copyright 2020</Copyright>
<PackageTags>fiskaltrust interface</PackageTags>
<AssemblyCompany>fiskaltrust</AssemblyCompany>
<AssemblyProduct>fiskaltrust.Middleware.Interface.Http</AssemblyProduct>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\fiskaltrust.ifPOS\fiskaltrust.Middleware.Interface.csproj" />
</ItemGroup>

</Project>
8 changes: 8 additions & 0 deletions src/fiskaltrust.Middleware.Interface.Soap/Class1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System;

namespace fiskaltrust.Middleware.Interface.Soap
{
public class Class1
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

</Project>
Loading

0 comments on commit 08c75bf

Please sign in to comment.