Skip to content
Open
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
9 changes: 5 additions & 4 deletions EdiApi.Client/EdiApi.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Vostok.ClusterClient.Core" Version="0.1.59" />
<PackageReference Include="Vostok.ClusterClient.Singular" Version="0.1.30" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="Vostok.ClusterClient.Core" Version="0.1.60" />
<PackageReference Include="Vostok.ClusterClient.Singular" Version="0.1.32" />
<PackageReference Include="Vostok.ClusterClient.Tracing" Version="0.1.9" />
<PackageReference Include="Vostok.ClusterClient.Transport" Version="0.1.40" />
<PackageReference Include="Vostok.ClusterClient.Transport" Version="0.1.41" />
<PackageReference Update="Nerdbank.GitVersioning" Version="3.8.118" />
</ItemGroup>

</Project>
230 changes: 204 additions & 26 deletions EdiApi.Client/Http/BaseEdiApiHttpClient.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Net;
using System.Text;
using System.Threading.Tasks;

using SkbKontur.EdiApi.Client.Types.Boxes;
using SkbKontur.EdiApi.Client.Types.Logistics;
Expand All @@ -24,28 +25,58 @@ protected BaseEdiApiHttpClient(
string apiClientId, Uri baseUri, IEdiApiTypesSerializer serializer,
int timeoutInMilliseconds, IWebProxy? proxy = null)
{
if (string.IsNullOrEmpty(apiClientId))
throw new ArgumentNullException(nameof(apiClientId));

this.apiClientId = apiClientId;
Serializer = serializer;
clusterClient = ClusterClientFactory.Get(baseUri, timeoutInMilliseconds, proxy);
clusterClient = ClusterClientFactory.Get(baseUri, TimeSpan.FromMilliseconds(timeoutInMilliseconds), proxy);
}

protected BaseEdiApiHttpClient(
string apiClientId, string environment, IEdiApiTypesSerializer serializer,
int timeoutInMilliseconds, IWebProxy? proxy = null, ITracer? tracer = null)
{
if (string.IsNullOrEmpty(apiClientId))
throw new ArgumentException(nameof(apiClientId));

this.apiClientId = apiClientId;
Serializer = serializer;
clusterClient = ClusterClientFactory.Get(environment, timeoutInMilliseconds, proxy, tracer : tracer);
clusterClient = ClusterClientFactory.Get(environment, TimeSpan.FromMilliseconds(timeoutInMilliseconds), proxy, tracer : tracer);
}

protected BaseEdiApiHttpClient(Uri baseUri,
IEdiApiTypesSerializer? serializer = null,
TimeSpan? timeout = null,
IWebProxy? proxy = null)
{
Serializer = serializer ?? new JsonEdiApiTypesSerializer();
clusterClient = ClusterClientFactory.Get(baseUri, timeout ?? DefaultTimeout, proxy);
}

protected BaseEdiApiHttpClient(string environment,
IEdiApiTypesSerializer? serializer = null,
TimeSpan? timeout = null,
IWebProxy? proxy = null,
ITracer? tracer = null)
{
Serializer = serializer ?? new JsonEdiApiTypesSerializer();
clusterClient = ClusterClientFactory.Get(environment, timeout ?? DefaultTimeout, proxy, tracer : tracer);
}

[Obsolete("Use new OpenId Connect authentication scheme")]
public string Authenticate(string portalSid) =>
DoAuthenticate(new AuthCredentials {PortalSid = portalSid});

[Obsolete("Use new OpenId Connect authentication scheme")]
public string Authenticate(string login, string password) =>
DoAuthenticate(new AuthCredentials {Login = login, Password = password});

private string DoAuthenticate(AuthCredentials authCredentials)
{
if (IsOpenIdConnectEnabled())
throw new InvalidOperationException("The client is configured with the new OpenId Connect authentication method that is incompatible with the legacy '/V1/Authenticate' endpoint");

var request = BuildPostRequest("V1/Authenticate", authCredentials);

var result = clusterClient.Send(request);
Expand All @@ -56,93 +87,167 @@ private string DoAuthenticate(AuthCredentials authCredentials)

public PartiesInfo GetAccessiblePartiesInfo(string authToken)
{
var request = BuildGetRequest("V1/Parties/GetAccessiblePartiesInfo", authToken : authToken);
var request = BuildGetAccessiblePartiesInfoRequest(authToken);

var result = clusterClient.Send(request);
EnsureSuccessResult(result);

return Serializer.Deserialize<PartiesInfo>(result.Response.Content.ToString());
return DeserializeResponse<PartiesInfo>(result);
}

public async Task<PartiesInfo> GetAccessiblePartiesInfoAsync(string authToken)
{
var request = BuildGetAccessiblePartiesInfoRequest(authToken);

var result = await clusterClient.SendAsync(request).ConfigureAwait(false);
EnsureSuccessResult(result);

return DeserializeResponse<PartiesInfo>(result);
}

public PartyInfo GetPartyInfo(string authToken, string partyId)
{
var request = BuildGetRequest("V1/Parties/GetPartyInfo", authToken : authToken)
.WithAdditionalQueryParameter("partyId", partyId);
var request = BuildGetPartyInfoRequest(authToken, partyId);

var result = clusterClient.Send(request);
EnsureSuccessResult(result);

return Serializer.Deserialize<PartyInfo>(result.Response.Content.ToString());
return DeserializeResponse<PartyInfo>(result);
}

public async Task<PartyInfo> GetPartyInfoAsync(string authToken, string partyId)
{
var request = BuildGetPartyInfoRequest(authToken, partyId);

var result = await clusterClient.SendAsync(request).ConfigureAwait(false);
EnsureSuccessResult(result);

return DeserializeResponse<PartyInfo>(result);
}

public PartyInfo GetPartyInfoByGln(string authToken, string partyGln)
{
var request = BuildGetRequest("V1/Parties/GetPartyInfoByGln", authToken : authToken)
.WithAdditionalQueryParameter("partyGln", partyGln);
var request = BuildGetPartyInfoByGlnRequest(authToken, partyGln);

var result = clusterClient.Send(request);
EnsureSuccessResult(result);

return Serializer.Deserialize<PartyInfo>(result.Response.Content.ToString());
return DeserializeResponse<PartyInfo>(result);
}

public async Task<PartyInfo> GetPartyInfoByGlnAsync(string authToken, string partyGln)
{
var request = BuildGetPartyInfoByGlnRequest(authToken, partyGln);

var result = await clusterClient.SendAsync(request).ConfigureAwait(false);
EnsureSuccessResult(result);

return DeserializeResponse<PartyInfo>(result);
}

public PartyInfo GetPartyInfoByDepartmentGln(string authToken, string departmentGln)
{
var request = BuildGetRequest("V1/Parties/GetPartyInfoByDepartmentGln", authToken : authToken)
.WithAdditionalQueryParameter("departmentGln", departmentGln);
var request = BuildGetPartyInfoByDepartmentGlnRequest(authToken, departmentGln);

var result = clusterClient.Send(request);
EnsureSuccessResult(result);

return Serializer.Deserialize<PartyInfo>(result.Response.Content.ToString());
return DeserializeResponse<PartyInfo>(result);
}

public async Task<PartyInfo> GetPartyInfoByDepartmentGlnAsync(string authToken, string departmentGln)
{
var request = BuildGetPartyInfoByDepartmentGlnRequest(authToken, departmentGln);

var result = await clusterClient.SendAsync(request).ConfigureAwait(false);
EnsureSuccessResult(result);

return DeserializeResponse<PartyInfo>(result);
}

public BoxesInfo GetBoxesInfo(string authToken)
{
var request = BuildGetRequest("V1/Boxes/GetBoxesInfo", authToken : authToken);
var request = BuildGetBoxesInfoRequest(authToken);

var result = clusterClient.Send(request);
EnsureSuccessResult(result);

return Serializer.Deserialize<BoxesInfo>(result.Response.Content.ToString());
return DeserializeResponse<BoxesInfo>(result);
}

public async Task<BoxesInfo> GetBoxesInfoAsync(string authToken)
{
var request = BuildGetBoxesInfoRequest(authToken);

var result = await clusterClient.SendAsync(request).ConfigureAwait(false);
EnsureSuccessResult(result);

return DeserializeResponse<BoxesInfo>(result);
}

public BoxInfo GetMainApiBox(string authToken, string partyId)
{
var request = BuildGetRequest("V1/Boxes/GetMainApiBox", authToken : authToken)
.WithAdditionalQueryParameter("partyId", partyId);
var request = BuildGetMainApiBoxRequest(authToken, partyId);

var result = clusterClient.Send(request);
EnsureSuccessResult(result);

return Serializer.Deserialize<BoxInfo>(result.Response.Content.ToString());
return DeserializeResponse<BoxInfo>(result);
}

public async Task<BoxInfo> GetMainApiBoxAsync(string authToken, string partyId)
{
var request = BuildGetMainApiBoxRequest(authToken, partyId);

var result = await clusterClient.SendAsync(request).ConfigureAwait(false);
EnsureSuccessResult(result);

return DeserializeResponse<BoxInfo>(result);
}

public OrganizationCatalogueInfo GetOrganizationCatalogueInfo(string authToken, string partyId)
{
var request = BuildGetRequest("V1/Organizations/GetOrganizationCatalogueInfo", authToken : authToken)
.WithAdditionalQueryParameter("partyId", partyId);
var request = BuildGetOrganizationCatalogueInfoRequest(authToken, partyId);

var result = clusterClient.Send(request);
EnsureSuccessResult(result);

return Serializer.Deserialize<OrganizationCatalogueInfo>(result.Response.Content.ToString());
return DeserializeResponse<OrganizationCatalogueInfo>(result);
}

public async Task<OrganizationCatalogueInfo> GetOrganizationCatalogueInfoAsync(string authToken, string partyId)
{
var request = BuildGetOrganizationCatalogueInfoRequest(authToken, partyId);

var result = await clusterClient.SendAsync(request).ConfigureAwait(false);
EnsureSuccessResult(result);

return DeserializeResponse<OrganizationCatalogueInfo>(result);
}

public TransportationDocumentIdentifier GetTransportationDocumentIdentifier(string authToken, string partyId)
{
var request = BuildGetRequest("V1/Logistics/GetTransportationDocumentIdentifier", authToken : authToken)
.WithAdditionalQueryParameter("partyId", partyId);
var request = BuildGetTransportationDocumentIdentifierRequest(authToken, partyId);

var result = clusterClient.Send(request);
EnsureSuccessResult(result);

return Serializer.Deserialize<TransportationDocumentIdentifier>(result.Response.Content.ToString());
return DeserializeResponse<TransportationDocumentIdentifier>(result);
}

public async Task<TransportationDocumentIdentifier> GetTransportationDocumentIdentifierAsync(string authToken, string partyId)
{
var request = BuildGetTransportationDocumentIdentifierRequest(authToken, partyId);

var result = await clusterClient.SendAsync(request).ConfigureAwait(false);
EnsureSuccessResult(result);

return DeserializeResponse<TransportationDocumentIdentifier>(result);
}

protected IEdiApiTypesSerializer Serializer { get; }

protected const int DefaultTimeout = 30 * 1000;
protected const int DefaultTimeoutMs = 30_000;

protected virtual Request BuildPostRequest(string relativeUrl, AuthCredentials? authCredentials = null, string? authToken = null)
=> BuildPostRequest(relativeUrl, authCredentials, authToken, Array.Empty<byte>());
Expand Down Expand Up @@ -190,7 +295,78 @@ protected virtual void EnsureSuccessResult(ClusterResult result)
}
}

protected TResult DeserializeResponse<TResult>(ClusterResult result)
where TResult : class
{
return Serializer.Deserialize<TResult>(result.Response.Content.ToString());
}

private bool IsOpenIdConnectEnabled() => string.IsNullOrEmpty(apiClientId);

private Request BuildGetAccessiblePartiesInfoRequest(string authToken)
{
return BuildGetRequest("V1/Parties/GetAccessiblePartiesInfo", authToken : authToken);
}

private Request BuildGetPartyInfoRequest(string authToken, string partyId)
{
return BuildGetRequest("V1/Parties/GetPartyInfo", authToken : authToken)
.WithAdditionalQueryParameter("partyId", partyId);
}

private Request BuildGetPartyInfoByGlnRequest(string authToken, string partyGln)
{
return BuildGetRequest("V1/Parties/GetPartyInfoByGln", authToken : authToken)
.WithAdditionalQueryParameter("partyGln", partyGln);
}

private Request BuildGetPartyInfoByDepartmentGlnRequest(string authToken, string departmentGln)
{
return BuildGetRequest("V1/Parties/GetPartyInfoByDepartmentGln", authToken : authToken)
.WithAdditionalQueryParameter("departmentGln", departmentGln);
}

private Request BuildGetBoxesInfoRequest(string authToken)
{
return BuildGetRequest("V1/Boxes/GetBoxesInfo", authToken : authToken);
}

private Request BuildGetMainApiBoxRequest(string authToken, string partyId)
{
return BuildGetRequest("V1/Boxes/GetMainApiBox", authToken : authToken)
.WithAdditionalQueryParameter("partyId", partyId);
}

private Request BuildGetOrganizationCatalogueInfoRequest(string authToken, string partyId)
{
return BuildGetRequest("V1/Organizations/GetOrganizationCatalogueInfo", authToken : authToken)
.WithAdditionalQueryParameter("partyId", partyId);
}

private Request BuildGetTransportationDocumentIdentifierRequest(string authToken, string partyId)
{
return BuildGetRequest("V1/Logistics/GetTransportationDocumentIdentifier", authToken : authToken)
.WithAdditionalQueryParameter("partyId", partyId);
}

private string BuildAuthorizationHeader(AuthCredentials? authCredentials, string? authToken)
{
if (IsOpenIdConnectEnabled())
{
if (string.IsNullOrEmpty(authToken))
throw new ArgumentNullException(nameof(authToken), "AuthToken should not be empty when using the new OpenId Connect authentication scheme.");
return BuildBearerAuthorizationHeader(authToken!);
}

return BuildKonturEdiAuthorizationHeader(authCredentials, authToken);
}

private static string BuildBearerAuthorizationHeader(string authToken)
{
return $"Bearer {authToken}";
}

private string BuildKonturEdiAuthorizationHeader(AuthCredentials? authCredentials, string? authToken)
{
var stringBuilder = new StringBuilder();
stringBuilder.Append("KonturEdiAuth ");
Expand All @@ -211,8 +387,10 @@ private string BuildAuthorizationHeader(AuthCredentials? authCredentials, string
return stringBuilder.ToString();
}

private static readonly TimeSpan DefaultTimeout = TimeSpan.FromMilliseconds(DefaultTimeoutMs);

protected readonly IClusterClient clusterClient;

private readonly string apiClientId;
private readonly string? apiClientId;
}
}
Loading
Loading