From e01f8992375889e4edc26d5877ec31145458070e Mon Sep 17 00:00:00 2001 From: Dmitry Pushnitsa Date: Thu, 26 Nov 2020 15:43:32 +0200 Subject: [PATCH 1/8] 1.6.0 --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index cfdd929a..08a41a2c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -7,7 +7,7 @@ VirtoCommerce - 1.5.0 + 1.6.0 $(VersionSuffix)-$(BuildNumber) From 3a79425a8e98162356e138b407d979789d5cc198 Mon Sep 17 00:00:00 2001 From: Maksim Kopnov Date: Fri, 27 Nov 2020 11:05:48 +0700 Subject: [PATCH 2/8] Set up JDK 11 for sonarscanner in CI workflow --- .github/workflows/main.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4453c46f..73ca15ba 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -42,6 +42,11 @@ jobs: echo "PUBLISH_TO_DOCKER=false" >> $GITHUB_ENV echo "UPDATE_LATEST_TAG=false" >> $GITHUB_ENV + - name: Set up JDK 11 for dotnet-sonarscanner #Sonar stop accepting Java versions less than 11 + uses: actions/setup-java@v1 + with: + java-version: 1.11 + - uses: actions/checkout@v2 with: fetch-depth: 0 From 1bd781a927f72a945d3a9432eaff70c4fce45dff Mon Sep 17 00:00:00 2001 From: Dmitry Pushnitsa Date: Wed, 2 Dec 2020 12:51:11 +0200 Subject: [PATCH 3/8] Rework powered by filter --- .../Filters/CommonFilters.cs | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/VirtoCommerce.LiquidThemeEngine/Filters/CommonFilters.cs b/VirtoCommerce.LiquidThemeEngine/Filters/CommonFilters.cs index 00357801..c33f42d5 100644 --- a/VirtoCommerce.LiquidThemeEngine/Filters/CommonFilters.cs +++ b/VirtoCommerce.LiquidThemeEngine/Filters/CommonFilters.cs @@ -24,17 +24,7 @@ namespace VirtoCommerce.LiquidThemeEngine.Filters public static partial class CommonFilters { private static readonly string[] _poweredLinks = { - ".NET ecommerce platform by Virto", - "Shopping Cart by Virto", - ".NET Shopping Cart by Virto", - "ASP.NET Shopping Cart by Virto", - ".NET ecommerce by Virto", - ".NET ecommerce framework by Virto", - "ASP.NET ecommerce by Virto Commerce", - "ASP.NET ecommerce platform by Virto", - "ASP.NET ecommerce framework by Virto", - "Enterprise ecommerce by Virto", - "Enterprise ecommerce platform by Virto", + "B2B ecommerce platform by Virto Commerce", }; private static readonly JsonSerializerSettings _jsonSerializerSettings = new JsonSerializerSettings @@ -67,10 +57,9 @@ public static object ParseJson(string input) return result; } - public static string PoweredBy(string signature) + public static string PoweredBy() { - var hashCode = (uint)signature.GetHashCode(); - return _poweredLinks[hashCode % _poweredLinks.Length]; + return _poweredLinks.FirstOrDefault(); } public static string Render(TemplateContext context, string input) From 028866d272f8ba40a1a365b2fa2260d444f84057 Mon Sep 17 00:00:00 2001 From: Aleksandr Vishniakov Date: Thu, 10 Dec 2020 18:28:34 +0200 Subject: [PATCH 4/8] VDS-393: Use user groups from index (#47) * VDS-393: Use usergroups from index * Fix code smells * Check for groups field existance in index document --- .../Customer/Services/IDemoMemberService.cs | 10 + .../DemoCustomerSegmentsModuleModuleApi.cs | 2119 +++++++++++++++++ .../ServiceCollectionExtension.cs | 3 + .../Domain/Customer/DemoMemberService.cs | 67 +- VirtoCommerce.Storefront/Startup.cs | 4 +- 5 files changed, 2199 insertions(+), 4 deletions(-) create mode 100644 VirtoCommerce.Storefront.Model/Customer/Services/IDemoMemberService.cs create mode 100644 VirtoCommerce.Storefront/AutoRestClients/DemoCustomerSegmentsModuleModuleApi.cs diff --git a/VirtoCommerce.Storefront.Model/Customer/Services/IDemoMemberService.cs b/VirtoCommerce.Storefront.Model/Customer/Services/IDemoMemberService.cs new file mode 100644 index 00000000..b6b758a2 --- /dev/null +++ b/VirtoCommerce.Storefront.Model/Customer/Services/IDemoMemberService.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace VirtoCommerce.Storefront.Model.Customer.Services +{ + public interface IDemoMemberService + { + Task> GetMemberIndexByIdAsync(string memberId); + } +} diff --git a/VirtoCommerce.Storefront/AutoRestClients/DemoCustomerSegmentsModuleModuleApi.cs b/VirtoCommerce.Storefront/AutoRestClients/DemoCustomerSegmentsModuleModuleApi.cs new file mode 100644 index 00000000..da97a66b --- /dev/null +++ b/VirtoCommerce.Storefront/AutoRestClients/DemoCustomerSegmentsModuleModuleApi.cs @@ -0,0 +1,2119 @@ +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +namespace VirtoCommerce.Storefront.AutoRestClients.DemoCustomerSegmentsModuleModuleApi +{ + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Models; + using Newtonsoft.Json; + using System.Collections; + using System.Collections.Generic; + using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + + public partial class DemoCustomerSegmentsModuleModuleClient : ServiceClient, IDemoCustomerSegmentsModuleModuleClient + { + /// + /// The base URI of the service. + /// + public System.Uri BaseUri { get; set; } + + /// + /// Gets or sets json serialization settings. + /// + public JsonSerializerSettings SerializationSettings { get; private set; } + + /// + /// Gets or sets json deserialization settings. + /// + public JsonSerializerSettings DeserializationSettings { get; private set; } + + /// + /// Subscription credentials which uniquely identify client subscription. + /// + public ServiceClientCredentials Credentials { get; private set; } + + /// + /// Gets the IDemoCustomerSegmentOperations. + /// + public virtual IDemoCustomerSegmentOperations DemoCustomerSegment { get; private set; } + + /// + /// Gets the IDemoSearch. + /// + public virtual IDemoSearch DemoSearch { get; private set; } + + /// + /// Initializes a new instance of the DemoCustomerSegmentsModuleModuleClient class. + /// + /// + /// HttpClient to be used + /// + /// + /// True: will dispose the provided httpClient on calling DemoCustomerSegmentsModuleModuleClient.Dispose(). False: will not dispose provided httpClient + protected DemoCustomerSegmentsModuleModuleClient(HttpClient httpClient, bool disposeHttpClient) : base(httpClient, disposeHttpClient) + { + Initialize(); + } + + /// + /// Initializes a new instance of the DemoCustomerSegmentsModuleModuleClient class. + /// + /// + /// Optional. The delegating handlers to add to the http client pipeline. + /// + protected DemoCustomerSegmentsModuleModuleClient(params DelegatingHandler[] handlers) : base(handlers) + { + Initialize(); + } + + /// + /// Initializes a new instance of the DemoCustomerSegmentsModuleModuleClient class. + /// + /// + /// Optional. The http client handler used to handle http transport. + /// + /// + /// Optional. The delegating handlers to add to the http client pipeline. + /// + protected DemoCustomerSegmentsModuleModuleClient(HttpClientHandler rootHandler, params DelegatingHandler[] handlers) : base(rootHandler, handlers) + { + Initialize(); + } + + /// + /// Initializes a new instance of the DemoCustomerSegmentsModuleModuleClient class. + /// + /// + /// Optional. The base URI of the service. + /// + /// + /// Optional. The delegating handlers to add to the http client pipeline. + /// + /// + /// Thrown when a required parameter is null + /// + protected DemoCustomerSegmentsModuleModuleClient(System.Uri baseUri, params DelegatingHandler[] handlers) : this(handlers) + { + if (baseUri == null) + { + throw new System.ArgumentNullException("baseUri"); + } + BaseUri = baseUri; + } + + /// + /// Initializes a new instance of the DemoCustomerSegmentsModuleModuleClient class. + /// + /// + /// Optional. The base URI of the service. + /// + /// + /// Optional. The http client handler used to handle http transport. + /// + /// + /// Optional. The delegating handlers to add to the http client pipeline. + /// + /// + /// Thrown when a required parameter is null + /// + protected DemoCustomerSegmentsModuleModuleClient(System.Uri baseUri, HttpClientHandler rootHandler, params DelegatingHandler[] handlers) : this(rootHandler, handlers) + { + if (baseUri == null) + { + throw new System.ArgumentNullException("baseUri"); + } + BaseUri = baseUri; + } + + /// + /// Initializes a new instance of the DemoCustomerSegmentsModuleModuleClient class. + /// + /// + /// Required. Subscription credentials which uniquely identify client subscription. + /// + /// + /// Optional. The delegating handlers to add to the http client pipeline. + /// + /// + /// Thrown when a required parameter is null + /// + public DemoCustomerSegmentsModuleModuleClient(ServiceClientCredentials credentials, params DelegatingHandler[] handlers) : this(handlers) + { + if (credentials == null) + { + throw new System.ArgumentNullException("credentials"); + } + Credentials = credentials; + if (Credentials != null) + { + Credentials.InitializeServiceClient(this); + } + } + + /// + /// Initializes a new instance of the DemoCustomerSegmentsModuleModuleClient class. + /// + /// + /// Required. Subscription credentials which uniquely identify client subscription. + /// + /// + /// HttpClient to be used + /// + /// + /// True: will dispose the provided httpClient on calling DemoCustomerSegmentsModuleModuleClient.Dispose(). False: will not dispose provided httpClient + /// + /// Thrown when a required parameter is null + /// + public DemoCustomerSegmentsModuleModuleClient(ServiceClientCredentials credentials, HttpClient httpClient, bool disposeHttpClient) : this(httpClient, disposeHttpClient) + { + if (credentials == null) + { + throw new System.ArgumentNullException("credentials"); + } + Credentials = credentials; + if (Credentials != null) + { + Credentials.InitializeServiceClient(this); + } + } + + /// + /// Initializes a new instance of the DemoCustomerSegmentsModuleModuleClient class. + /// + /// + /// Required. Subscription credentials which uniquely identify client subscription. + /// + /// + /// Optional. The http client handler used to handle http transport. + /// + /// + /// Optional. The delegating handlers to add to the http client pipeline. + /// + /// + /// Thrown when a required parameter is null + /// + public DemoCustomerSegmentsModuleModuleClient(ServiceClientCredentials credentials, HttpClientHandler rootHandler, params DelegatingHandler[] handlers) : this(rootHandler, handlers) + { + if (credentials == null) + { + throw new System.ArgumentNullException("credentials"); + } + Credentials = credentials; + if (Credentials != null) + { + Credentials.InitializeServiceClient(this); + } + } + + /// + /// Initializes a new instance of the DemoCustomerSegmentsModuleModuleClient class. + /// + /// + /// Optional. The base URI of the service. + /// + /// + /// Required. Subscription credentials which uniquely identify client subscription. + /// + /// + /// Optional. The delegating handlers to add to the http client pipeline. + /// + /// + /// Thrown when a required parameter is null + /// + public DemoCustomerSegmentsModuleModuleClient(System.Uri baseUri, ServiceClientCredentials credentials, params DelegatingHandler[] handlers) : this(handlers) + { + if (baseUri == null) + { + throw new System.ArgumentNullException("baseUri"); + } + if (credentials == null) + { + throw new System.ArgumentNullException("credentials"); + } + BaseUri = baseUri; + Credentials = credentials; + if (Credentials != null) + { + Credentials.InitializeServiceClient(this); + } + } + + /// + /// Initializes a new instance of the DemoCustomerSegmentsModuleModuleClient class. + /// + /// + /// Optional. The base URI of the service. + /// + /// + /// Required. Subscription credentials which uniquely identify client subscription. + /// + /// + /// Optional. The http client handler used to handle http transport. + /// + /// + /// Optional. The delegating handlers to add to the http client pipeline. + /// + /// + /// Thrown when a required parameter is null + /// + public DemoCustomerSegmentsModuleModuleClient(System.Uri baseUri, ServiceClientCredentials credentials, HttpClientHandler rootHandler, params DelegatingHandler[] handlers) : this(rootHandler, handlers) + { + if (baseUri == null) + { + throw new System.ArgumentNullException("baseUri"); + } + if (credentials == null) + { + throw new System.ArgumentNullException("credentials"); + } + BaseUri = baseUri; + Credentials = credentials; + if (Credentials != null) + { + Credentials.InitializeServiceClient(this); + } + } + + /// + /// An optional partial-method to perform custom initialization. + /// + partial void CustomInitialize(); + /// + /// Initializes client properties. + /// + private void Initialize() + { + DemoCustomerSegment = new DemoCustomerSegmentOperations(this); + DemoSearch = new DemoSearch(this); + BaseUri = new System.Uri("http://localhost"); + SerializationSettings = new JsonSerializerSettings + { + Formatting = Newtonsoft.Json.Formatting.Indented, + DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat, + DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc, + NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore, + ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize, + ContractResolver = new ReadOnlyJsonContractResolver(), + Converters = new List + { + new Iso8601TimeSpanConverter() + } + }; + DeserializationSettings = new JsonSerializerSettings + { + DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat, + DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc, + NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore, + ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize, + ContractResolver = new ReadOnlyJsonContractResolver(), + Converters = new List + { + new Iso8601TimeSpanConverter() + } + }; + CustomInitialize(); + } + } +} +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +namespace VirtoCommerce.Storefront.AutoRestClients.DemoCustomerSegmentsModuleModuleApi +{ + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Models; + using Newtonsoft.Json; + using System.Collections; + using System.Collections.Generic; + using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + + /// + /// + public partial interface IDemoCustomerSegmentsModuleModuleClient : System.IDisposable + { + /// + /// The base URI of the service. + /// + System.Uri BaseUri { get; set; } + + /// + /// Gets or sets json serialization settings. + /// + JsonSerializerSettings SerializationSettings { get; } + + /// + /// Gets or sets json deserialization settings. + /// + JsonSerializerSettings DeserializationSettings { get; } + + /// + /// Subscription credentials which uniquely identify client + /// subscription. + /// + ServiceClientCredentials Credentials { get; } + + + /// + /// Gets the IDemoCustomerSegmentOperations. + /// + IDemoCustomerSegmentOperations DemoCustomerSegment { get; } + + /// + /// Gets the IDemoSearch. + /// + IDemoSearch DemoSearch { get; } + + } +} +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +namespace VirtoCommerce.Storefront.AutoRestClients.DemoCustomerSegmentsModuleModuleApi +{ + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Models; + using Newtonsoft.Json; + using System.Collections; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + + /// + /// DemoCustomerSegmentOperations operations. + /// + public partial class DemoCustomerSegmentOperations : IServiceOperations, IDemoCustomerSegmentOperations + { + /// + /// Initializes a new instance of the DemoCustomerSegmentOperations class. + /// + /// + /// Reference to the service client. + /// + /// + /// Thrown when a required parameter is null + /// + public DemoCustomerSegmentOperations(DemoCustomerSegmentsModuleModuleClient client) + { + if (client == null) + { + throw new System.ArgumentNullException("client"); + } + Client = client; + } + + /// + /// Gets a reference to the DemoCustomerSegmentsModuleModuleClient + /// + public DemoCustomerSegmentsModuleModuleClient Client { get; private set; } + + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task> GetNewCustomerSegmentWithHttpMessagesAsync(Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "GetNewCustomerSegment", tracingParameters); + } + // Construct URL + var _baseUrl = Client.BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "api/demo/customersegments/new").ToString(); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + // Set Credentials + if (Client.Credentials != null) + { + cancellationToken.ThrowIfCancellationRequested(); + await Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + } + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 200 && (int)_statusCode != 401 && (int)_statusCode != 403) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, Client.DeserializationSettings); + } + catch (JsonException ex) + { + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw new SerializationException("Unable to deserialize the response.", _responseContent, ex); + } + } + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + /// + /// Thrown when a required parameter is null + /// + /// + /// Thrown when a required parameter is null + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task> GetCustomerSegmentByIdWithHttpMessagesAsync(string id, Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + if (id == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "id"); + } + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("id", id); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "GetCustomerSegmentById", tracingParameters); + } + // Construct URL + var _baseUrl = Client.BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "api/demo/customersegments/{id}").ToString(); + _url = _url.Replace("{id}", System.Uri.EscapeDataString(id)); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + // Set Credentials + if (Client.Credentials != null) + { + cancellationToken.ThrowIfCancellationRequested(); + await Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + } + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 200 && (int)_statusCode != 401 && (int)_statusCode != 403) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, Client.DeserializationSettings); + } + catch (JsonException ex) + { + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw new SerializationException("Unable to deserialize the response.", _responseContent, ex); + } + } + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task>> SaveCustomerSegmentsWithHttpMessagesAsync(IList body = default(IList), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("body", body); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "SaveCustomerSegments", tracingParameters); + } + // Construct URL + var _baseUrl = Client.BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "api/demo/customersegments").ToString(); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("POST"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + if(body != null) + { + _requestContent = SafeJsonConvert.SerializeObject(body, Client.SerializationSettings); + _httpRequest.Content = new StringContent(_requestContent, System.Text.Encoding.UTF8); + _httpRequest.Content.Headers.ContentType =System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json-patch+json; charset=utf-8"); + } + // Set Credentials + if (Client.Credentials != null) + { + cancellationToken.ThrowIfCancellationRequested(); + await Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + } + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 200 && (int)_statusCode != 401 && (int)_statusCode != 403) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse>(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + _result.Body = SafeJsonConvert.DeserializeObject>(_responseContent, Client.DeserializationSettings); + } + catch (JsonException ex) + { + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw new SerializationException("Unable to deserialize the response.", _responseContent, ex); + } + } + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task DeleteCustomerSegmentsWithHttpMessagesAsync(IList ids = default(IList), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("ids", ids); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "DeleteCustomerSegments", tracingParameters); + } + // Construct URL + var _baseUrl = Client.BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "api/demo/customersegments").ToString(); + List _queryParameters = new List(); + if (ids != null) + { + _queryParameters.Add(string.Format("ids={0}", System.Uri.EscapeDataString(string.Join(",", ids)))); + } + if (_queryParameters.Count > 0) + { + _url += "?" + string.Join("&", _queryParameters); + } + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("DELETE"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + // Set Credentials + if (Client.Credentials != null) + { + cancellationToken.ThrowIfCancellationRequested(); + await Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + } + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 204 && (int)_statusCode != 401 && (int)_statusCode != 403) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task> SearchCustomerSegmentsWithHttpMessagesAsync(DemoCustomerSegmentSearchCriteria body = default(DemoCustomerSegmentSearchCriteria), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("body", body); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "SearchCustomerSegments", tracingParameters); + } + // Construct URL + var _baseUrl = Client.BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "api/demo/customersegments/search").ToString(); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("POST"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + if(body != null) + { + _requestContent = SafeJsonConvert.SerializeObject(body, Client.SerializationSettings); + _httpRequest.Content = new StringContent(_requestContent, System.Text.Encoding.UTF8); + _httpRequest.Content.Headers.ContentType =System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json-patch+json; charset=utf-8"); + } + // Set Credentials + if (Client.Credentials != null) + { + cancellationToken.ThrowIfCancellationRequested(); + await Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + } + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 200 && (int)_statusCode != 401 && (int)_statusCode != 403) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, Client.DeserializationSettings); + } + catch (JsonException ex) + { + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw new SerializationException("Unable to deserialize the response.", _responseContent, ex); + } + } + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + } +} +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +namespace VirtoCommerce.Storefront.AutoRestClients.DemoCustomerSegmentsModuleModuleApi +{ + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Models; + using Newtonsoft.Json; + using System.Collections; + using System.Collections.Generic; + using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + + /// + /// DemoCustomerSegmentOperations operations. + /// + public partial interface IDemoCustomerSegmentOperations + { + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + Task> GetNewCustomerSegmentWithHttpMessagesAsync(Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + /// + /// Thrown when a required parameter is null + /// + Task> GetCustomerSegmentByIdWithHttpMessagesAsync(string id, Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + Task>> SaveCustomerSegmentsWithHttpMessagesAsync(IList body = default(IList), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + Task DeleteCustomerSegmentsWithHttpMessagesAsync(IList ids = default(IList), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + Task> SearchCustomerSegmentsWithHttpMessagesAsync(DemoCustomerSegmentSearchCriteria body = default(DemoCustomerSegmentSearchCriteria), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + } +} +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +namespace VirtoCommerce.Storefront.AutoRestClients.DemoCustomerSegmentsModuleModuleApi +{ + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Models; + using Newtonsoft.Json; + using System.Collections; + using System.Collections.Generic; + using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + + /// + /// Extension methods for DemoCustomerSegmentOperations. + /// + public static partial class DemoCustomerSegmentOperationsExtensions + { + /// + /// The operations group for this extension method. + /// + public static DemoCustomerSegment GetNewCustomerSegment(this IDemoCustomerSegmentOperations operations) + { + return operations.GetNewCustomerSegmentAsync().GetAwaiter().GetResult(); + } + + /// + /// The operations group for this extension method. + /// + /// + /// The cancellation token. + /// + public static async Task GetNewCustomerSegmentAsync(this IDemoCustomerSegmentOperations operations, CancellationToken cancellationToken = default(CancellationToken)) + { + using (var _result = await operations.GetNewCustomerSegmentWithHttpMessagesAsync(null, cancellationToken).ConfigureAwait(false)) + { + return _result.Body; + } + } + + /// + /// The operations group for this extension method. + /// + /// + /// + public static DemoCustomerSegment GetCustomerSegmentById(this IDemoCustomerSegmentOperations operations, string id) + { + return operations.GetCustomerSegmentByIdAsync(id).GetAwaiter().GetResult(); + } + + /// + /// The operations group for this extension method. + /// + /// + /// + /// + /// The cancellation token. + /// + public static async Task GetCustomerSegmentByIdAsync(this IDemoCustomerSegmentOperations operations, string id, CancellationToken cancellationToken = default(CancellationToken)) + { + using (var _result = await operations.GetCustomerSegmentByIdWithHttpMessagesAsync(id, null, cancellationToken).ConfigureAwait(false)) + { + return _result.Body; + } + } + + /// + /// The operations group for this extension method. + /// + /// + /// + public static IList SaveCustomerSegments(this IDemoCustomerSegmentOperations operations, IList body = default(IList)) + { + return operations.SaveCustomerSegmentsAsync(body).GetAwaiter().GetResult(); + } + + /// + /// The operations group for this extension method. + /// + /// + /// + /// + /// The cancellation token. + /// + public static async Task> SaveCustomerSegmentsAsync(this IDemoCustomerSegmentOperations operations, IList body = default(IList), CancellationToken cancellationToken = default(CancellationToken)) + { + using (var _result = await operations.SaveCustomerSegmentsWithHttpMessagesAsync(body, null, cancellationToken).ConfigureAwait(false)) + { + return _result.Body; + } + } + + /// + /// The operations group for this extension method. + /// + /// + /// + public static void DeleteCustomerSegments(this IDemoCustomerSegmentOperations operations, IList ids = default(IList)) + { + operations.DeleteCustomerSegmentsAsync(ids).GetAwaiter().GetResult(); + } + + /// + /// The operations group for this extension method. + /// + /// + /// + /// + /// The cancellation token. + /// + public static async Task DeleteCustomerSegmentsAsync(this IDemoCustomerSegmentOperations operations, IList ids = default(IList), CancellationToken cancellationToken = default(CancellationToken)) + { + (await operations.DeleteCustomerSegmentsWithHttpMessagesAsync(ids, null, cancellationToken).ConfigureAwait(false)).Dispose(); + } + + /// + /// The operations group for this extension method. + /// + /// + /// + public static DemoCustomerSegmentSearchResult SearchCustomerSegments(this IDemoCustomerSegmentOperations operations, DemoCustomerSegmentSearchCriteria body = default(DemoCustomerSegmentSearchCriteria)) + { + return operations.SearchCustomerSegmentsAsync(body).GetAwaiter().GetResult(); + } + + /// + /// The operations group for this extension method. + /// + /// + /// + /// + /// The cancellation token. + /// + public static async Task SearchCustomerSegmentsAsync(this IDemoCustomerSegmentOperations operations, DemoCustomerSegmentSearchCriteria body = default(DemoCustomerSegmentSearchCriteria), CancellationToken cancellationToken = default(CancellationToken)) + { + using (var _result = await operations.SearchCustomerSegmentsWithHttpMessagesAsync(body, null, cancellationToken).ConfigureAwait(false)) + { + return _result.Body; + } + } + + } +} +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +namespace VirtoCommerce.Storefront.AutoRestClients.DemoCustomerSegmentsModuleModuleApi +{ + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Models; + using Newtonsoft.Json; + using System.Collections; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + + /// + /// DemoSearch operations. + /// + public partial class DemoSearch : IServiceOperations, IDemoSearch + { + /// + /// Initializes a new instance of the DemoSearch class. + /// + /// + /// Reference to the service client. + /// + /// + /// Thrown when a required parameter is null + /// + public DemoSearch(DemoCustomerSegmentsModuleModuleClient client) + { + if (client == null) + { + throw new System.ArgumentNullException("client"); + } + Client = client; + } + + /// + /// Gets a reference to the DemoCustomerSegmentsModuleModuleClient + /// + public DemoCustomerSegmentsModuleModuleClient Client { get; private set; } + + /// + /// + /// + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + /// + /// Thrown when a required parameter is null + /// + /// + /// Thrown when a required parameter is null + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task>> GetDocumentIndexAsyncWithHttpMessagesAsync(string documentType, string documentId, Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + if (documentType == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "documentType"); + } + if (documentId == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "documentId"); + } + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("documentType", documentType); + tracingParameters.Add("documentId", documentId); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "GetDocumentIndexAsync", tracingParameters); + } + // Construct URL + var _baseUrl = Client.BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "api/demo/search/index/{documentType}/{documentId}").ToString(); + _url = _url.Replace("{documentType}", System.Uri.EscapeDataString(documentType)); + _url = _url.Replace("{documentId}", System.Uri.EscapeDataString(documentId)); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + // Set Credentials + if (Client.Credentials != null) + { + cancellationToken.ThrowIfCancellationRequested(); + await Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + } + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 200 && (int)_statusCode != 401 && (int)_statusCode != 403) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse>(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + _result.Body = SafeJsonConvert.DeserializeObject>(_responseContent, Client.DeserializationSettings); + } + catch (JsonException ex) + { + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw new SerializationException("Unable to deserialize the response.", _responseContent, ex); + } + } + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + } +} +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +namespace VirtoCommerce.Storefront.AutoRestClients.DemoCustomerSegmentsModuleModuleApi +{ + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Models; + using Newtonsoft.Json; + using System.Collections; + using System.Collections.Generic; + using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + + /// + /// DemoSearch operations. + /// + public partial interface IDemoSearch + { + /// + /// + /// + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + /// + /// Thrown when a required parameter is null + /// + Task>> GetDocumentIndexAsyncWithHttpMessagesAsync(string documentType, string documentId, Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + } +} +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +namespace VirtoCommerce.Storefront.AutoRestClients.DemoCustomerSegmentsModuleModuleApi +{ + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Models; + using Newtonsoft.Json; + using System.Collections; + using System.Collections.Generic; + using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + + /// + /// Extension methods for DemoSearch. + /// + public static partial class DemoSearchExtensions + { + /// + /// The operations group for this extension method. + /// + /// + /// + /// + /// + public static IDictionary GetDocumentIndexAsync(this IDemoSearch operations, string documentType, string documentId) + { + return operations.GetDocumentIndexAsyncAsync(documentType, documentId).GetAwaiter().GetResult(); + } + + /// + /// The operations group for this extension method. + /// + /// + /// + /// + /// + /// + /// The cancellation token. + /// + public static async Task> GetDocumentIndexAsyncAsync(this IDemoSearch operations, string documentType, string documentId, CancellationToken cancellationToken = default(CancellationToken)) + { + using (var _result = await operations.GetDocumentIndexAsyncWithHttpMessagesAsync(documentType, documentId, null, cancellationToken).ConfigureAwait(false)) + { + return _result.Body; + } + } + + } +} +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +namespace VirtoCommerce.Storefront.AutoRestClients.DemoCustomerSegmentsModuleModuleApi.Models +{ + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Newtonsoft.Json; + using System.Collections; + using System.Collections.Generic; + using System.Linq; + using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + + public partial class IConditionTree + { + /// + /// Initializes a new instance of the IConditionTree class. + /// + public IConditionTree() + { + CustomInit(); + } + + /// + /// Initializes a new instance of the IConditionTree class. + /// + /// List of all available children for + /// current tree node (is used in expression designer) + public IConditionTree(string id = default(string), IList availableChildren = default(IList), IList children = default(IList)) + { + Id = id; + AvailableChildren = availableChildren; + Children = children; + CustomInit(); + } + + /// + /// An initialization method that performs custom operations like setting defaults + /// + partial void CustomInit(); + + /// + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; private set; } + + /// + /// Gets list of all available children for current tree node (is used + /// in expression designer) + /// + [JsonProperty(PropertyName = "availableChildren")] + public IList AvailableChildren { get; private set; } + + /// + /// + [JsonProperty(PropertyName = "children")] + public IList Children { get; private set; } + + } +} +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +namespace VirtoCommerce.Storefront.AutoRestClients.DemoCustomerSegmentsModuleModuleApi.Models +{ + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Newtonsoft.Json; + using System.Collections; + using System.Collections.Generic; + using System.Linq; + using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + + public partial class DemoCustomerSegmentTree + { + /// + /// Initializes a new instance of the DemoCustomerSegmentTree class. + /// + public DemoCustomerSegmentTree() + { + CustomInit(); + } + + /// + /// Initializes a new instance of the DemoCustomerSegmentTree class. + /// + public DemoCustomerSegmentTree(bool? all = default(bool?), bool? not = default(bool?), string id = default(string), IList availableChildren = default(IList), IList children = default(IList)) + { + All = all; + Not = not; + Id = id; + AvailableChildren = availableChildren; + Children = children; + CustomInit(); + } + + /// + /// An initialization method that performs custom operations like setting defaults + /// + partial void CustomInit(); + + /// + /// + [JsonProperty(PropertyName = "all")] + public bool? All { get; set; } + + /// + /// + [JsonProperty(PropertyName = "not")] + public bool? Not { get; set; } + + /// + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; private set; } + + /// + /// + [JsonProperty(PropertyName = "availableChildren")] + public IList AvailableChildren { get; set; } + + /// + /// + [JsonProperty(PropertyName = "children")] + public IList Children { get; set; } + + } +} +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +namespace VirtoCommerce.Storefront.AutoRestClients.DemoCustomerSegmentsModuleModuleApi.Models +{ + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Newtonsoft.Json; + using System.Collections; + using System.Collections.Generic; + using System.Linq; + using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + + public partial class DemoCustomerSegment + { + /// + /// Initializes a new instance of the DemoCustomerSegment class. + /// + public DemoCustomerSegment() + { + CustomInit(); + } + + /// + /// Initializes a new instance of the DemoCustomerSegment class. + /// + public DemoCustomerSegment(string name = default(string), string description = default(string), string userGroup = default(string), bool? isActive = default(bool?), System.DateTime? startDate = default(System.DateTime?), System.DateTime? endDate = default(System.DateTime?), IList storeIds = default(IList), DemoCustomerSegmentTree expressionTree = default(DemoCustomerSegmentTree), System.DateTime? createdDate = default(System.DateTime?), System.DateTime? modifiedDate = default(System.DateTime?), string createdBy = default(string), string modifiedBy = default(string), string id = default(string)) + { + Name = name; + Description = description; + UserGroup = userGroup; + IsActive = isActive; + StartDate = startDate; + EndDate = endDate; + StoreIds = storeIds; + ExpressionTree = expressionTree; + CreatedDate = createdDate; + ModifiedDate = modifiedDate; + CreatedBy = createdBy; + ModifiedBy = modifiedBy; + Id = id; + CustomInit(); + } + + /// + /// An initialization method that performs custom operations like setting defaults + /// + partial void CustomInit(); + + /// + /// + [JsonProperty(PropertyName = "name")] + public string Name { get; set; } + + /// + /// + [JsonProperty(PropertyName = "description")] + public string Description { get; set; } + + /// + /// + [JsonProperty(PropertyName = "userGroup")] + public string UserGroup { get; set; } + + /// + /// + [JsonProperty(PropertyName = "isActive")] + public bool? IsActive { get; set; } + + /// + /// + [JsonProperty(PropertyName = "startDate")] + public System.DateTime? StartDate { get; set; } + + /// + /// + [JsonProperty(PropertyName = "endDate")] + public System.DateTime? EndDate { get; set; } + + /// + /// + [JsonProperty(PropertyName = "storeIds")] + public IList StoreIds { get; set; } + + /// + /// + [JsonProperty(PropertyName = "expressionTree")] + public DemoCustomerSegmentTree ExpressionTree { get; set; } + + /// + /// + [JsonProperty(PropertyName = "createdDate")] + public System.DateTime? CreatedDate { get; set; } + + /// + /// + [JsonProperty(PropertyName = "modifiedDate")] + public System.DateTime? ModifiedDate { get; set; } + + /// + /// + [JsonProperty(PropertyName = "createdBy")] + public string CreatedBy { get; set; } + + /// + /// + [JsonProperty(PropertyName = "modifiedBy")] + public string ModifiedBy { get; set; } + + /// + /// + [JsonProperty(PropertyName = "id")] + public string Id { get; set; } + + } +} +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +namespace VirtoCommerce.Storefront.AutoRestClients.DemoCustomerSegmentsModuleModuleApi.Models +{ + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Newtonsoft.Json; + using System.Collections; + using System.Collections.Generic; + using System.Linq; + using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + + public partial class SortInfo + { + /// + /// Initializes a new instance of the SortInfo class. + /// + public SortInfo() + { + CustomInit(); + } + + /// + /// Initializes a new instance of the SortInfo class. + /// + /// Possible values include: 'Ascending', + /// 'Descending' + public SortInfo(string sortColumn = default(string), string sortDirection = default(string)) + { + SortColumn = sortColumn; + SortDirection = sortDirection; + CustomInit(); + } + + /// + /// An initialization method that performs custom operations like setting defaults + /// + partial void CustomInit(); + + /// + /// + [JsonProperty(PropertyName = "sortColumn")] + public string SortColumn { get; set; } + + /// + /// Gets or sets possible values include: 'Ascending', 'Descending' + /// + [JsonProperty(PropertyName = "sortDirection")] + public string SortDirection { get; set; } + + } +} +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +namespace VirtoCommerce.Storefront.AutoRestClients.DemoCustomerSegmentsModuleModuleApi.Models +{ + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Newtonsoft.Json; + using System.Collections; + using System.Collections.Generic; + using System.Linq; + using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + + public partial class DemoCustomerSegmentSearchCriteria + { + /// + /// Initializes a new instance of the DemoCustomerSegmentSearchCriteria + /// class. + /// + public DemoCustomerSegmentSearchCriteria() + { + CustomInit(); + } + + /// + /// Initializes a new instance of the DemoCustomerSegmentSearchCriteria + /// class. + /// + public DemoCustomerSegmentSearchCriteria(IList storeIds = default(IList), bool? isActive = default(bool?), string responseGroup = default(string), string objectType = default(string), IList objectTypes = default(IList), IList objectIds = default(IList), string keyword = default(string), string searchPhrase = default(string), string languageCode = default(string), string sort = default(string), IList sortInfos = default(IList), int? skip = default(int?), int? take = default(int?)) + { + StoreIds = storeIds; + IsActive = isActive; + ResponseGroup = responseGroup; + ObjectType = objectType; + ObjectTypes = objectTypes; + ObjectIds = objectIds; + Keyword = keyword; + SearchPhrase = searchPhrase; + LanguageCode = languageCode; + Sort = sort; + SortInfos = sortInfos; + Skip = skip; + Take = take; + CustomInit(); + } + + /// + /// An initialization method that performs custom operations like setting defaults + /// + partial void CustomInit(); + + /// + /// + [JsonProperty(PropertyName = "storeIds")] + public IList StoreIds { get; set; } + + /// + /// + [JsonProperty(PropertyName = "isActive")] + public bool? IsActive { get; set; } + + /// + /// + [JsonProperty(PropertyName = "responseGroup")] + public string ResponseGroup { get; set; } + + /// + /// + [JsonProperty(PropertyName = "objectType")] + public string ObjectType { get; set; } + + /// + /// + [JsonProperty(PropertyName = "objectTypes")] + public IList ObjectTypes { get; set; } + + /// + /// + [JsonProperty(PropertyName = "objectIds")] + public IList ObjectIds { get; set; } + + /// + /// + [JsonProperty(PropertyName = "keyword")] + public string Keyword { get; set; } + + /// + /// + [JsonProperty(PropertyName = "searchPhrase")] + public string SearchPhrase { get; set; } + + /// + /// + [JsonProperty(PropertyName = "languageCode")] + public string LanguageCode { get; set; } + + /// + /// + [JsonProperty(PropertyName = "sort")] + public string Sort { get; set; } + + /// + /// + [JsonProperty(PropertyName = "sortInfos")] + public IList SortInfos { get; private set; } + + /// + /// + [JsonProperty(PropertyName = "skip")] + public int? Skip { get; set; } + + /// + /// + [JsonProperty(PropertyName = "take")] + public int? Take { get; set; } + + } +} +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +namespace VirtoCommerce.Storefront.AutoRestClients.DemoCustomerSegmentsModuleModuleApi.Models +{ + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Newtonsoft.Json; + using System.Collections; + using System.Collections.Generic; + using System.Linq; + using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + + public partial class DemoCustomerSegmentSearchResult + { + /// + /// Initializes a new instance of the DemoCustomerSegmentSearchResult + /// class. + /// + public DemoCustomerSegmentSearchResult() + { + CustomInit(); + } + + /// + /// Initializes a new instance of the DemoCustomerSegmentSearchResult + /// class. + /// + public DemoCustomerSegmentSearchResult(int? totalCount = default(int?), IList results = default(IList)) + { + TotalCount = totalCount; + Results = results; + CustomInit(); + } + + /// + /// An initialization method that performs custom operations like setting defaults + /// + partial void CustomInit(); + + /// + /// + [JsonProperty(PropertyName = "totalCount")] + public int? TotalCount { get; set; } + + /// + /// + [JsonProperty(PropertyName = "results")] + public IList Results { get; set; } + + } +} diff --git a/VirtoCommerce.Storefront/DependencyInjection/ServiceCollectionExtension.cs b/VirtoCommerce.Storefront/DependencyInjection/ServiceCollectionExtension.cs index f42baafb..db167703 100644 --- a/VirtoCommerce.Storefront/DependencyInjection/ServiceCollectionExtension.cs +++ b/VirtoCommerce.Storefront/DependencyInjection/ServiceCollectionExtension.cs @@ -16,6 +16,7 @@ using VirtoCommerce.Storefront.AutoRestClients.ContentModuleApi; using VirtoCommerce.Storefront.AutoRestClients.CoreModuleApi; using VirtoCommerce.Storefront.AutoRestClients.CustomerModuleApi; +using VirtoCommerce.Storefront.AutoRestClients.DemoCustomerSegmentsModuleModuleApi; using VirtoCommerce.Storefront.AutoRestClients.DynamicAssociationsModuleModuleApi; using VirtoCommerce.Storefront.AutoRestClients.InventoryModuleApi; using VirtoCommerce.Storefront.AutoRestClients.MarketingModuleApi; @@ -120,6 +121,8 @@ public static void AddPlatformEndpoint(this IServiceCollection services, Action< services.AddSingleton(sp => new Notifications(sp.GetRequiredService())); services.AddAutoRestClient((credentials, httpClient, disposeHttpClient, baseUri) => new CustomerModuleClient(credentials, httpClient, disposeHttpClient) { BaseUri = baseUri }); services.AddSingleton(sp => new CustomerModule(sp.GetRequiredService())); + services.AddAutoRestClient((credentials, httpClient, disposeHttpClient, baseUri) => new DemoCustomerSegmentsModuleModuleClient(credentials, httpClient, disposeHttpClient) { BaseUri = baseUri }); + services.AddSingleton(sp => new DemoSearch(sp.GetRequiredService())); services.AddAutoRestClient((credentials, httpClient, disposeHttpClient, baseUri) => new OrdersModuleClient(credentials, httpClient, disposeHttpClient) { BaseUri = baseUri }); services.AddSingleton(sp => new OrderModule(sp.GetRequiredService())); services.AddSingleton(sp => new OrderModulePayments(sp.GetRequiredService())); diff --git a/VirtoCommerce.Storefront/Domain/Customer/DemoMemberService.cs b/VirtoCommerce.Storefront/Domain/Customer/DemoMemberService.cs index 36ac7bb1..5158af2a 100644 --- a/VirtoCommerce.Storefront/Domain/Customer/DemoMemberService.cs +++ b/VirtoCommerce.Storefront/Domain/Customer/DemoMemberService.cs @@ -1,21 +1,74 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; +using Microsoft.Extensions.Caching.Memory; using Microsoft.Rest; +using Newtonsoft.Json.Linq; using VirtoCommerce.Storefront.AutoRestClients.CustomerModuleApi; +using VirtoCommerce.Storefront.AutoRestClients.DemoCustomerSegmentsModuleModuleApi; using VirtoCommerce.Storefront.Infrastructure; using VirtoCommerce.Storefront.Model.Caching; +using VirtoCommerce.Storefront.Model.Common.Caching; +using VirtoCommerce.Storefront.Model.Customer; +using VirtoCommerce.Storefront.Model.Customer.Services; namespace VirtoCommerce.Storefront.Domain { - public class DemoMemberService : MemberService + public class DemoMemberService : MemberService, IDemoMemberService { private readonly ICustomerModule _customerApi; + private readonly IDemoSearch _demoSearchApi; + private readonly IStorefrontMemoryCache _memoryCache; + private readonly IApiChangesWatcher _apiChangesWatcher; private readonly string NO_CONTENT = "NoContent"; - public DemoMemberService(ICustomerModule customerApi, IStorefrontMemoryCache memoryCache, IApiChangesWatcher changesWatcher) - : base(customerApi, memoryCache, changesWatcher) + public DemoMemberService(ICustomerModule customerApi, IDemoSearch demoSearchApi, IStorefrontMemoryCache memoryCache, IApiChangesWatcher apiChangesWatcher) + : base(customerApi, memoryCache, apiChangesWatcher) { _customerApi = customerApi; + _demoSearchApi = demoSearchApi; + _memoryCache = memoryCache; + _apiChangesWatcher = apiChangesWatcher; + } + + public async Task> GetMemberIndexByIdAsync(string memberId) + { + ValidateParameters(memberId); + + var cacheKey = CacheKey.With(GetType(), "GetMemberIndexByIdAsync", memberId); + var result = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) => + { + var indexDto = await _demoSearchApi.GetDocumentIndexAsyncAsync(nameof(Member), memberId); + + cacheEntry.AddExpirationToken(CustomerCacheRegion.CreateChangeToken(memberId)); + cacheEntry.AddExpirationToken(_apiChangesWatcher.CreateChangeToken()); + return indexDto; + }); + return result; + } + + public override async Task GetContactByIdAsync(string contactId) + { + var result = await base.GetContactByIdAsync(contactId); + var indexDocument = await GetMemberIndexByIdAsync(contactId); + if (indexDocument != null) + { + indexDocument.TryGetValue("groups", out var groupsField); + // This conversion is required because returned IDictionary contains deserialized arrays as JArrays + string[] groups; + if (groupsField is JArray groupsArray) + { + groups = groupsArray.ToObject(); + } + else + { + groups = groupsField != null ? new[] { groupsField as string } : Array.Empty(); + } + + result.UserGroups = result.UserGroups.Concat(groups).Distinct().ToArray(); + } + return result; } public override async Task DeleteContactAsync(string contactId) @@ -39,5 +92,13 @@ public override async Task DeleteContactAsync(string contactId) //Invalidate cache CustomerCacheRegion.ExpireMember(contactId); } + + private static void ValidateParameters(string memberId) + { + if (memberId == null) + { + throw new ArgumentNullException(nameof(memberId)); + } + } } } diff --git a/VirtoCommerce.Storefront/Startup.cs b/VirtoCommerce.Storefront/Startup.cs index 2cfb568c..5abc0624 100644 --- a/VirtoCommerce.Storefront/Startup.cs +++ b/VirtoCommerce.Storefront/Startup.cs @@ -99,7 +99,9 @@ public void ConfigureServices(IServiceCollection services) services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(x => x.GetRequiredService()); + services.AddSingleton(x => x.GetRequiredService()); services.AddSingleton(); services.AddSingleton(x => x.GetRequiredService()); services.AddSingleton(x => x.GetRequiredService()); From 33e930a65e2f57148a0d66f8b940754892c2a21f Mon Sep 17 00:00:00 2001 From: Maksim Kopnov <44946644+mvktsk@users.noreply.github.com> Date: Fri, 11 Dec 2020 14:51:14 +0700 Subject: [PATCH 5/8] VP-6270: Add status badges (#45) * VP-6270: Add status badges * VP-6270: Update status badges * VP-6270: Update status badges --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 99c95d7c..12b6101a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,11 @@ -# [Virto Commerce Storefront Kit](https://virtocommerce.com) [![Share on Facebook](https://img.shields.io/badge/facebook--blue.svg?style=social&label=Share&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSIyNjYuODkzcHgiIGhlaWdodD0iMjY2Ljg5NXB4IiB2aWV3Qm94PSIwIDAgMjY2Ljg5MyAyNjYuODk1IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAyNjYuODkzIDI2Ni44OTUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGlkPSJCbHVlXzFfIiBmaWxsPSIjM0M1QTk5IiBkPSJNMjQ4LjA4MiwyNjIuMzA3YzcuODU0LDAsMTQuMjIzLTYuMzY5LDE0LjIyMy0xNC4yMjVWMTguODEyYzAtNy44NTctNi4zNjgtMTQuMjI0LTE0LjIyMy0xNC4yMjRIMTguODEyYy03Ljg1NywwLTE0LjIyNCw2LjM2Ny0xNC4yMjQsMTQuMjI0djIyOS4yN2MwLDcuODU1LDYuMzY2LDE0LjIyNSwxNC4yMjQsMTQuMjI1SDI0OC4wODJ6Ii8%2BPHBhdGggaWQ9ImYiIGZpbGw9IiNGRkZGRkYiIGQ9Ik0xODIuNDA5LDI2Mi4zMDd2LTk5LjgwM2gzMy40OTlsNS4wMTYtMzguODk1aC0zOC41MTVWOTguNzc3YzAtMTEuMjYxLDMuMTI3LTE4LjkzNSwxOS4yNzUtMTguOTM1bDIwLjU5Ni0wLjAwOVY0NS4wNDVjLTMuNTYyLTAuNDc0LTE1Ljc4OC0xLjUzMy0zMC4wMTItMS41MzNjLTI5LjY5NSwwLTUwLjAyNSwxOC4xMjYtNTAuMDI1LDUxLjQxM3YyOC42ODRoLTMzLjU4NXYzOC44OTVoMzMuNTg1djk5LjgwM0gxODIuNDA5eiIvPjwvc3ZnPg%3D%3D)](https://www.facebook.com/sharer.php?u=https://virtocommerce.com) [![Tweet](https://img.shields.io/twitter/url/https/virtocommerce.com.svg?style=social)](https://twitter.com/intent/tweet?text=%23VirtoCommerce%20puts%20the%20best%20of%20MS%20Azure%20Cloud%2C%20open%20source%20.Net%20code%20and%20agile%20development%20in%20a%20single%20enterprise%20%23ecommerce%20platform.) [![Latest release](https://img.shields.io/github/release/VirtoCommerce/vc-storefront.svg)](https://github.com/VirtoCommerce/vc-storefront/releases/latest) [![Total downloads](https://img.shields.io/github/downloads/VirtoCommerce/vc-storefront/total.svg?colorB=007ec6)](https://github.com/VirtoCommerce/vc-storefront/releases) [![License](https://img.shields.io/badge/license-VC%20OSL-blue.svg)](https://virtocommerce.com/open-source-license) +# [Virto Commerce Storefront Kit](https://virtocommerce.com) + +[![Share on Facebook](https://img.shields.io/badge/facebook--blue.svg?style=social&label=Share&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSIyNjYuODkzcHgiIGhlaWdodD0iMjY2Ljg5NXB4IiB2aWV3Qm94PSIwIDAgMjY2Ljg5MyAyNjYuODk1IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAyNjYuODkzIDI2Ni44OTUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGlkPSJCbHVlXzFfIiBmaWxsPSIjM0M1QTk5IiBkPSJNMjQ4LjA4MiwyNjIuMzA3YzcuODU0LDAsMTQuMjIzLTYuMzY5LDE0LjIyMy0xNC4yMjVWMTguODEyYzAtNy44NTctNi4zNjgtMTQuMjI0LTE0LjIyMy0xNC4yMjRIMTguODEyYy03Ljg1NywwLTE0LjIyNCw2LjM2Ny0xNC4yMjQsMTQuMjI0djIyOS4yN2MwLDcuODU1LDYuMzY2LDE0LjIyNSwxNC4yMjQsMTQuMjI1SDI0OC4wODJ6Ii8%2BPHBhdGggaWQ9ImYiIGZpbGw9IiNGRkZGRkYiIGQ9Ik0xODIuNDA5LDI2Mi4zMDd2LTk5LjgwM2gzMy40OTlsNS4wMTYtMzguODk1aC0zOC41MTVWOTguNzc3YzAtMTEuMjYxLDMuMTI3LTE4LjkzNSwxOS4yNzUtMTguOTM1bDIwLjU5Ni0wLjAwOVY0NS4wNDVjLTMuNTYyLTAuNDc0LTE1Ljc4OC0xLjUzMy0zMC4wMTItMS41MzNjLTI5LjY5NSwwLTUwLjAyNSwxOC4xMjYtNTAuMDI1LDUxLjQxM3YyOC42ODRoLTMzLjU4NXYzOC44OTVoMzMuNTg1djk5LjgwM0gxODIuNDA5eiIvPjwvc3ZnPg%3D%3D)](https://www.facebook.com/sharer.php?u=https://virtocommerce.com) [![Tweet](https://img.shields.io/twitter/url/https/virtocommerce.com.svg?style=social)](https://twitter.com/intent/tweet?text=%23VirtoCommerce%20puts%20the%20best%20of%20MS%20Azure%20Cloud%2C%20open%20source%20.Net%20code%20and%20agile%20development%20in%20a%20single%20enterprise%20%23ecommerce%20platform.) [![Latest release](https://img.shields.io/github/release/VirtoCommerce/vc-demo-storefront.svg)](https://github.com/VirtoCommerce/vc-demo-storefront/releases/latest) [![Total downloads](https://img.shields.io/github/downloads/VirtoCommerce/vc-demo-storefront/total.svg?colorB=007ec6)](https://github.com/VirtoCommerce/vc-demo-storefront/releases) [![License](https://img.shields.io/badge/license-VC%20OSL-blue.svg)](https://virtocommerce.com/open-source-license) > Precaution! Storefront version 5 and above is backward NON-compatible with VirtoCommerce platform v2! Use only with platform v3. -[![Build status](http://ci.virtocommerce.com/buildStatus/icon?job=vc-2-org/vc-storefront/master)](http://ci.virtocommerce.com/job/vc-2-org/job/vc-storefront/job/master/) [![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=VirtoCommerce_vc-storefront-core&branch=master&metric=alert_status)](https://sonarcloud.io/dashboard?id=VirtoCommerce_vc-storefront-core) [![Lines of code](https://sonarcloud.io/api/project_badges/measure?project=VirtoCommerce_vc-storefront-core&branch=master&metric=ncloc)](https://sonarcloud.io/api/project_badges/measure?project=VirtoCommerce_vc-storefront-core&branch=master&metric=ncloc)  +[![CI status](https://github.com/VirtoCommerce/vc-demo-storefront/workflows/Storefront%20CI/badge.svg?branch=dev)](https://github.com/VirtoCommerce/vc-demo-storefront/actions?query=workflow%3A"Storefront+CI") [![Deployment status](https://github.com/VirtoCommerce/vc-demo-storefront/workflows/VC%20image%20deployment/badge.svg?branch=dev)](https://github.com/VirtoCommerce/vc-demo-storefront/actions?query=workflow%3A"Module+deployment") [![Quality gate](https://sonarcloud.io/api/project_badges/measure?project=VirtoCommerce_vc-demo-storefront&metric=alert_status&branch=dev)](https://sonarcloud.io/dashboard?id=VirtoCommerce_vc-demo-storefront) [![Reliability rating](https://sonarcloud.io/api/project_badges/measure?project=VirtoCommerce_vc-demo-storefront&metric=reliability_rating&branch=dev)](https://sonarcloud.io/dashboard?id=VirtoCommerce_vc-demo-storefront) [![Security rating](https://sonarcloud.io/api/project_badges/measure?project=VirtoCommerce_vc-demo-storefront&metric=security_rating&branch=dev)](https://sonarcloud.io/dashboard?id=VirtoCommerce_vc-demo-storefront) [![Sqale rating](https://sonarcloud.io/api/project_badges/measure?project=VirtoCommerce_vc-demo-storefront&metric=sqale_rating&branch=dev)](https://sonarcloud.io/dashboard?id=VirtoCommerce_vc-demo-storefront) + [![Documentation](https://img.shields.io/badge/docs-read-brightgreen.svg)](https://virtocommerce.com/docs/latest/) [![Discourse topics](https://img.shields.io/discourse/topics?label=community&logo=community&server=http%3A%2F%2Fwww.virtocommerce.org)](https://www.virtocommerce.org) [![Contributors](https://img.shields.io/github/contributors/VirtoCommerce/vc-storefront.svg)](https://github.com/VirtoCommerce/vc-storefront/graphs/contributors) [![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FVirtoCommerce%2Fvc-storefront%2Fmaster%2Fazuredeploy.json) From bc7ffc4b1109471058976d1dd73636d500b0ed5c Mon Sep 17 00:00:00 2001 From: Maksim Kopnov <44946644+mvktsk@users.noreply.github.com> Date: Thu, 17 Dec 2020 09:09:28 +0700 Subject: [PATCH 6/8] VDS-404: Remove unused workflows (#48) --- .github/workflows/delivery.yml | 151 ---------------------------- .github/workflows/release-alpha.yml | 107 -------------------- 2 files changed, 258 deletions(-) delete mode 100644 .github/workflows/delivery.yml delete mode 100644 .github/workflows/release-alpha.yml diff --git a/.github/workflows/delivery.yml b/.github/workflows/delivery.yml deleted file mode 100644 index 43da5703..00000000 --- a/.github/workflows/delivery.yml +++ /dev/null @@ -1,151 +0,0 @@ -name: Deploy - -# Controls when the action will run. Triggers the workflow on push or pull request -# events but only for the master branch -on: - push: - tags: - - ver.* - - pull_request: - types: [labeled] - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - deploy: - name: Deploy - # The type of runner that the job will run on - runs-on: ubuntu-latest - if: ${{ github.event_name != 'pull_request' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deployment pending') }} - env: - DOCKER_USERNAME: ${{secrets.DOCKER_USERNAME}} - DOCKER_TOKEN: ${{secrets.DOCKER_TOKEN}} - steps: - - uses: actions/checkout@v2 - - - name: Get Image Tag - uses: VirtoCommerce/vc-github-actions/get-image-tag@v2 - id: image - - - name: Setup Kustomize - uses: imranismail/setup-kustomize@v1 - with: - kustomize-version: "3.1.0" - - - name: Start deployment - uses: bobheadxi/deployments@master - id: deployment - with: - step: start - token: ${{ secrets.GITHUB_TOKEN }} - env: Development - no_override: false - - - name: Commit environment change - shell: pwsh - run: | - cd ${{ github.workspace }} - git clone https://github.com/VirtoCommerce/vc-deploy-apps.git - cd vc-deploy-apps/webstore-app/overlays/dev - - $REPOSITORY = "docker.pkg.github.com/$('${{ github.repository }}'.ToLower())" - kustomize edit set image virtocommerce/storefront=$REPOSITORY/storefront:${{ steps.image.outputs.tag }} - - git config user.email "github.actions@virtoway.com" - git config user.name "GitHub Actions" - - git add . - git commit -m "Update the platform image version to $($version)" - - $remoteRepo="https://${{ github.actor }}:${{ secrets.REPO_TOKEN }}@github.com/VirtoCommerce/vc-deploy-apps.git" - - git push $remoteRepo - - - name: Wait for environment is up - shell: pwsh - env: - ARGOCD_SERVER: cd.govirto.com - ARGOCD_AUTH_TOKEN: ${{ secrets.ARGOCD_TOKEN }} - timeout-minutes: 5 - run: | - cd ${{ github.workspace }} - - $latestVersion = (Invoke-WebRequest -Uri "https://api.github.com/repos/argoproj/argo-cd/releases/latest" | ConvertFrom-Json).tag_name - Invoke-WebRequest -Uri "https://github.com/argoproj/argo-cd/releases/download/$($latestVersion)/argocd-linux-amd64" -OutFile argocd - chmod +x argocd - ./argocd app sync webstore-dev-app --grpc-web --async - - do { - Start-Sleep -s 15 - - $statusBage = (Invoke-WebRequest -Uri "https://cd.govirto.com/api/badge?name=webstore-dev-app").Content - - $syncedAndHealthy = $statusBage.Contains('>Healthy<') -and $statusBage.Contains('>Synced<') - - if (-not $syncedAndHealthy) { - Write-Host "Sync pending..." - } - } - while (-not $syncedAndHealthy) - - - name: BUILD_STATE::successful - if: success() - run: echo "::set-env name=BUILD_STATE::successful" - - - name: BUILD_STATE::failed - if: failure() - run: echo "::set-env name=BUILD_STATE::failed" - - - name: Update GitHub deployment status - uses: bobheadxi/deployments@master - if: always() - with: - step: finish - token: ${{ secrets.GITHUB_TOKEN }} - status: ${{ job.status }} - deployment_id: ${{ steps.deployment.outputs.deployment_id }} - - - name: Parse Jira Keys from All Commits - id: jira_keys - if: always() - uses: HighwayThree/jira-extract-issue-keys@master - with: - is-pull-request: ${{ github.event_name == 'pull_request' }} - parse-all-commits: ${{ github.event_name == 'push' }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Push Deployment Info to Jira - if: ${{ env.CLOUD_INSTANCE_BASE_URL != 0 && env.CLIENT_ID != 0 && env.CLIENT_SECRET != 0 && steps.jira_keys.outputs.jira-keys != '' && always() }} - id: push_deployment_info_to_jira - uses: HighwayThree/jira-upload-deployment-info@master - env: - CLOUD_INSTANCE_BASE_URL: ${{secrets.CLOUD_INSTANCE_BASE_URL}} - CLIENT_ID: ${{secrets.CLIENT_ID}} - CLIENT_SECRET: ${{secrets.CLIENT_SECRET}} - with: - cloud-instance-base-url: '${{ secrets.CLOUD_INSTANCE_BASE_URL }}' - client-id: '${{ secrets.CLIENT_ID }}' - client-secret: '${{ secrets.CLIENT_SECRET }}' - deployment-sequence-number: '${{ github.run_id }}' - update-sequence-number: '${{ github.run_id }}' - issue-keys: "${{ steps.jira_keys.outputs.jira-keys }}" - display-name: "http://platform-platform.dev.govirto.com/f" - url: "http://platform-platform.dev.govirto.com/" - description: "Deployment to the Development environment" - last-updated: '${{github.event.head_commit.timestamp}}' - state: "${{ env.BUILD_STATE }}" - pipeline-id: '${{ github.repository }} ${{ github.workflow }}' - pipeline-display-name: 'Workflow: ${{ github.workflow }} (#${{ github.run_number }})' - pipeline-url: '${{github.event.repository.html_url}}/actions/runs/${{github.run_id}}' - environment-id: 'development' - environment-display-name: 'Dev' - environment-type: 'development' - - - name: Remove Deployment Pending Label - uses: buildsville/add-remove-label@v1 - if: ${{ always() && github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deployment pending') }} - with: - token: ${{secrets.GITHUB_TOKEN}} - label: 'deployment pending' - type: remove \ No newline at end of file diff --git a/.github/workflows/release-alpha.yml b/.github/workflows/release-alpha.yml deleted file mode 100644 index c8a09757..00000000 --- a/.github/workflows/release-alpha.yml +++ /dev/null @@ -1,107 +0,0 @@ -# v1 -name: Release alpha - -on: - workflow_dispatch: - -jobs: - ci: - runs-on: ubuntu-latest - env: - SONAR_TOKEN: ${{secrets.SONAR_TOKEN}} - GITHUB_TOKEN: ${{ secrets.REPO_TOKEN }} - NUGET_KEY: ${{ secrets.NUGET_KEY }} - BLOB_SAS: ${{ secrets.BLOB_TOKEN }} - - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - name: Install VirtoCommerce.GlobalTool - run: dotnet tool install --global VirtoCommerce.GlobalTool - - - name: Install dotnet-sonarscanner - run: dotnet tool install --global dotnet-sonarscanner - -# - name: Get changelog -# id: changelog -# uses: VirtoCommerce/vc-github-actions/changelog-generator@master - - name: Get Image Version - uses: VirtoCommerce/vc-github-actions/get-image-version@master - id: image - - - name: Add version suffix - uses: VirtoCommerce/vc-github-actions/add-version-suffix@master - - - name: SonarCloud Begin - uses: VirtoCommerce/vc-github-actions/sonar-scanner-begin@master - - - name: Build - run: vc-build Compile - - - name: Unit Tests - run: vc-build Test -TestsFilter "Category=Unit|Category=CI" -skip - - - name: SonarCloud End - uses: VirtoCommerce/vc-github-actions/sonar-scanner-end@master - - - name: Packaging - run: vc-build Compress -skip Clean+Restore+Compile+Test - - - name: Build Docker Image -# if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/dev' }} - id: dockerBuild - uses: VirtoCommerce/vc-github-actions/build-docker-image@master - with: - imageName: "demo-storefront" - tag: ${{ steps.image.outputs.taggedVersion }} - dockerFiles: "https://raw.githubusercontent.com/VirtoCommerce/vc-docker/master/linux/storefront/Dockerfile" - - - name: Docker Login -# if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/dev' }} - uses: azure/docker-login@v1 - with: - login-server: docker.pkg.github.com - username: $GITHUB_ACTOR - password: ${{ secrets.GITHUB_TOKEN }} - - - - name: Publish Docker Image -# if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/dev' }} - uses: VirtoCommerce/vc-github-actions/publish-docker-image@master - with: - image: ${{ steps.dockerBuild.outputs.imageName }} - tag: ${{ steps.image.outputs.taggedVersion }} - docker_user: ${{ secrets.DOCKER_USERNAME }} - docker_token: ${{ secrets.DOCKER_TOKEN }} - docker_hub: 'false' - update_latest: 'false' - -# - name: Publish Nuget -# uses: VirtoCommerce/vc-github-actions/publish-nuget@master - -# - name: Publish to Blob -# if: ${{ github.ref == 'refs/heads/dev' }} -# id: blobRelease -# uses: VirtoCommerce/vc-github-actions/publish-blob-release@master -# with: -# blobSAS: ${{ secrets.BLOB_TOKEN }} - -# - name: Publish Github Release -# if: ${{ github.ref == 'refs/heads/master' }} -# with: -# changelog: ${{ steps.changelog.outputs.changelog }} -# uses: VirtoCommerce/vc-github-actions/publish-github-release@master - -# - name: Setup Git Credentials -# if: ${{ github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/master'}} -# uses: VirtoCommerce/vc-github-actions/setup-git-credentials-github@master -# with: -# githubToken: ${{ secrets.REPO_TOKEN }} - -# - name: Publish Manifest -# if: ${{ github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/master'}} -# uses: VirtoCommerce/vc-github-actions/publish-manifest@master -# with: -# packageUrl: ${{ steps.blobRelease.outputs.packageUrl }} From f13cfa1879c145d20f6494f23f746fda8e399853 Mon Sep 17 00:00:00 2001 From: Maksim Kopnov <44946644+mvktsk@users.noreply.github.com> Date: Thu, 17 Dec 2020 17:32:33 +0700 Subject: [PATCH 7/8] VDS-422: Add setup-dotnet step (#49) * VDS-422: Add setup-dotnet step * VDS-422: Add setup-dotnet step name * VDS-422: Change workflow version --- .github/workflows/main.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 73ca15ba..545a5852 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,4 +1,4 @@ -# v1.1.1.vc-demo-storefront +# v1.1.2.vc-demo-storefront name: Storefront CI # Controls when the action will run. Triggers the workflow on push or pull request @@ -47,6 +47,11 @@ jobs: with: java-version: 1.11 + - name: Set up .net Core 3.1.x for vc-build #GitHib Actions migrates to .net Core 5.x. To vc-build work properly need to manually install .net Core 3.1.x + uses: actions/setup-dotnet@v1 + with: + dotnet-version: '3.1.x' + - uses: actions/checkout@v2 with: fetch-depth: 0 From a14f84976970163c3d8015c8d873161324654113 Mon Sep 17 00:00:00 2001 From: Ilya Litvinenko Date: Fri, 18 Dec 2020 09:05:21 +0200 Subject: [PATCH 8/8] VDS-408: Add filter for removing leading symbols from string (#50) --- .../Filters/StringFilters.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/VirtoCommerce.LiquidThemeEngine/Filters/StringFilters.cs b/VirtoCommerce.LiquidThemeEngine/Filters/StringFilters.cs index de28383f..81a57d6a 100644 --- a/VirtoCommerce.LiquidThemeEngine/Filters/StringFilters.cs +++ b/VirtoCommerce.LiquidThemeEngine/Filters/StringFilters.cs @@ -109,6 +109,22 @@ public static string Strip(string input) return input.Trim(); } + /// + /// Remove leading symbols from a string. + /// + /// + /// + /// + public static string StripStart(string input, string symbols) + { + if (string.IsNullOrEmpty(input)) + { + return input; + } + + return input.TrimStart(symbols.ToCharArray()); + } + public static string Format(object input, string format) { if (input == null)