Add project files.

This commit is contained in:
2021-05-05 21:00:33 +01:00
commit 13c79a8da4
349 changed files with 158726 additions and 0 deletions
@@ -0,0 +1,431 @@
using Sarand.BusinessMgr.Net.Standard.Base.Data;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Data;
using Sarand.Net.Standard.Base.Net;
using Sarand.Net.Standard.Base.Tasks;
using Sarand.Net.Standard.Base.Utils;
using Sarand.Net.Standard.Base.Xml;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Sarand.BusinessMgr.Net.Standard.Base.WebService
{
//=======================================================================
// Business Web Service Client
// Make requests to BusinessMgr Web Service hosted by Windows Service application.
//-----------------------------------------------------------------------
// Threading:
// Ref. https://blog.xamarin.com/getting-started-with-async-await/
//=======================================================================
public class SbmWebServiceClient
{
//-------------------------------------------------------------------
// Definitions.
public class RequestData : SacsTaskData
{
/// <summary>
/// Web Service Request data.
/// <para>Cancellation token can optionally be supplied if available higher up the chain.</para>
/// </summary>
public RequestData(SbmWebServiceInstanceDefinition instanceDefinition, CancellationToken? cancellationToken = null) :
base(cancellationToken)
{
InstanceDefinition = instanceDefinition;
}
public SbmWebServiceInstanceDefinition InstanceDefinition { get; }
public String Data { get; set; } = "";
}
//-------------------------------------------------------------------
// Data members.
//-------------------------------------------------------------------
// Construction.
public SbmWebServiceClient()
{
}
//-------------------------------------------------------------------
// Properties.
//-------------------------------------------------------------------
// I s A l i v e
//-------------------------------------------------------------------
public async Task<bool> RequestIsAlive(SbmWebServiceInstanceDefinition instanceDefinition)
{
String fn = GetType().Name + ".IsAlive";
try
{
RequestData requestData = new RequestData(instanceDefinition);
SbmWebServiceResponse serviceResponse = await DoWebServiceRequest(requestData);
if (serviceResponse.ResponseData.EqualsCI(SbmWebServiceDfn.IsAliveResponse))
return true;
}
catch (Exception exc) { SaLogger.Warn(fn + " " + exc.GetLogMessage()); }
return false;
}
//-------------------------------------------------------------------
// I t e m C o u n t R e q u e s t
//-------------------------------------------------------------------
public class ItemCountResponseData : SbmWebServiceResponse
{
public ItemCountResponseData(SbmWebServiceResponse serviceResponse) : base(serviceResponse) { }
public long ItemCount { get; set; }
}
public async Task<ItemCountResponseData> RequestItemCount(SbmWebServiceRequest.Config configRequest, Dictionary<String, String> filters, SacsTaskData taskData)
{
String fn = GetType().Name + ".GetItemCount";
if (SacsSystem.DebugMode && configRequest.RequestType != SbmWebServiceRequest.RequestType.Count) Debugger.Break();
// Service Request.
SbmWebServiceRequest serviceRequestData = new SbmWebServiceRequest(configRequest);
serviceRequestData.Filters.AddRange(filters);
// Configure Web Service and make Request.
RequestData requestData = new RequestData(configRequest.Context.InstanceDefinition, taskData.CancellationToken) { Debug = taskData.Debug };
requestData.Data = serviceRequestData.GenerateRequestData();
SbmWebServiceResponse serviceResponse = await DoWebServiceRequest(requestData);
ItemCountResponseData responseData = new ItemCountResponseData(serviceResponse);
bool itemCountFound = false;
// Interpret response.
if (serviceResponse.ResponseElement != null && !taskData.IsCancellationRequested)
{
foreach (XElement responseChildElement in serviceResponse.ResponseElement.Elements())
{
if (responseChildElement.Name.LocalName.EqualsCI(SbmWebServiceDfn.ElementName.Data))
{
foreach (XElement dataElement in responseChildElement.Elements())
{
if (dataElement.Name.LocalName.EqualsCI(SbmWebServiceDfn.ElementName.Count))
{
itemCountFound = true;
responseData.ItemCount = StringUtil.ToLong(dataElement.Value);
break;
}
if (taskData.IsCancellationRequested) break;
}
}
if (itemCountFound || taskData.IsCancellationRequested) break;
}
}
if (!itemCountFound) responseData.ErrorStateMessage = "Incomplete item count";
if (taskData.IsCancellationRequested) responseData.TaskCancelled = true;
return responseData;
}
//-------------------------------------------------------------------
// Q u e r y L i s t R e q u e s t
//-------------------------------------------------------------------
public class QueryListResponseData : SbmWebServiceResponse
{
public QueryListResponseData(SbmWebServiceResponse serviceResponse) : base(serviceResponse) { }
public List<SbmWebServiceItemData> Items { get; } = new List<SbmWebServiceItemData>();
public int Count { get; set; }
public int Total { get; set; }
public uint PageNo { get; set; }
public ushort PageLength { get; set; }
}
public async Task<QueryListResponseData> RequestQueryList(SbmWebServiceRequest.Config configRequest, Dictionary<String, String> filters, List<string> columns, List<String> sortColumns, SacsTaskData taskData)
{
String fn = GetType().Name + ".GetItemList";
if (SacsSystem.DebugMode && configRequest.RequestType != SbmWebServiceRequest.RequestType.QueryList) Debugger.Break();
// Service Request.
SbmWebServiceRequest serviceRequestData = new SbmWebServiceRequest(configRequest);
serviceRequestData.Filters.AddRange(filters);
serviceRequestData.Columns.AddRange(columns);
if (sortColumns != null) serviceRequestData.SortColumns.AddRange(sortColumns);
// Configure Web Service and make Request.
RequestData requestData = new RequestData(configRequest.Context.InstanceDefinition, taskData.CancellationToken) { Debug = taskData.Debug };
requestData.Data = serviceRequestData.GenerateRequestData();
SbmWebServiceResponse serviceResponse = await DoWebServiceRequest(requestData);
QueryListResponseData responseData = new QueryListResponseData(serviceResponse);
//if (SacsSystem.DebugMode && responseData.ResponseElement != null) SaLogger.Debug(fn + " Response:\n\n" + responseData.ResponseElement.FormatXml() + "\n");
// Interpret response.
if (serviceResponse.ResponseElement != null && !taskData.IsCancellationRequested)
{
foreach (XElement responseChildElement in serviceResponse.ResponseElement.Elements())
{
if (responseChildElement.Name.LocalName.EqualsCI(SbmWebServiceDfn.ElementName.Data))
{
foreach (XElement dataElement in responseChildElement.Elements())
{
if (dataElement.Name.LocalName.EqualsCI(SbmWebServiceDfn.ElementName.List))
{
// Paging info.
// <List Count="8" Total="196527" PageNo="1" PageLength="8">
responseData.Count = StringUtil.ToInt(dataElement.GetAttributeValue(SbmWebServiceDfn.AttributeName.Count));
responseData.Total = StringUtil.ToInt(dataElement.GetAttributeValue(SbmWebServiceDfn.AttributeName.Total));
responseData.PageNo = (uint)StringUtil.ToInt(dataElement.GetAttributeValue(SbmWebServiceDfn.AttributeName.PageNo));
responseData.PageLength = (ushort)StringUtil.ToInt(dataElement.GetAttributeValue(SbmWebServiceDfn.AttributeName.PageLength));
// Extract items.
foreach (XElement listElement in dataElement.Elements())
{
taskData.ThrowIfCancellationRequested();
if (listElement.Name.LocalName.EqualsCI(SbmWebServiceDfn.ElementName.Item))
{
SbmWebServiceItemData itemData = new SbmWebServiceItemData("");
List<String> fields = SacsCsvHandler.ParseCsvRecord(listElement.Value);
for (int fieldIdx = 0; fieldIdx < fields.Count && fieldIdx < columns.Count; fieldIdx++)
{
String column = columns[fieldIdx];
String field = fields[fieldIdx];
itemData.AddValue(column, field);
}
responseData.Items.Add(itemData);
}
if (taskData.IsCancellationRequested) break;
}
}
if (taskData.IsCancellationRequested) break;
}
}
if (taskData.IsCancellationRequested) break;
}
}
if (taskData.IsCancellationRequested) responseData.TaskCancelled = true;
return responseData;
}
//-------------------------------------------------------------------
// I t e m L i s t R e q u e s t
//-------------------------------------------------------------------
public class ItemListResponseData : SbmWebServiceResponse
{
public ItemListResponseData(SbmWebServiceResponse serviceResponse) : base(serviceResponse) { }
public List<SbmWebServiceItemData> Items { get; } = new List<SbmWebServiceItemData>();
public int Count { get; set; }
public int Total { get; set; }
public uint PageNo { get; set; }
public ushort PageLength { get; set; }
}
public async Task<ItemListResponseData> RequestItemList(SbmWebServiceRequest.Config configRequest, Dictionary<String, String> filters, List<String> sortColumns, SacsTaskData taskData)
{
String fn = GetType().Name + ".GetItemList";
if (SacsSystem.DebugMode && configRequest.RequestType != SbmWebServiceRequest.RequestType.ItemList) Debugger.Break();
// Service Request.
SbmWebServiceRequest serviceRequestData = new SbmWebServiceRequest(configRequest);
serviceRequestData.Filters.AddRange(filters);
if (sortColumns != null) serviceRequestData.SortColumns.AddRange(sortColumns);
// Configure Web Service and make Request.
RequestData requestData = new RequestData(configRequest.Context.InstanceDefinition, taskData.CancellationToken) { Debug = taskData.Debug };
requestData.Data = serviceRequestData.GenerateRequestData();
SbmWebServiceResponse serviceResponse = await DoWebServiceRequest(requestData);
ItemListResponseData responseData = new ItemListResponseData(serviceResponse);
//if (SacsSystem.DebugMode && responseData.ResponseElement != null) SaLogger.Debug(fn + " Response:\n\n" + responseData.ResponseElement.FormatXml() + "\n");
// Interpret response.
if (serviceResponse.ResponseElement != null && !taskData.IsCancellationRequested)
{
foreach (XElement responseChildElement in serviceResponse.ResponseElement.Elements())
{
if (responseChildElement.Name.LocalName.EqualsCI(SbmWebServiceDfn.ElementName.Data))
{
foreach (XElement dataElement in responseChildElement.Elements())
{
if (dataElement.Name.LocalName.EqualsCI(SbmWebServiceDfn.ElementName.List))
{
// Paging info.
// <List Count="8" Total="196527" PageNo="1" PageLength="8">
responseData.Count = StringUtil.ToInt(dataElement.GetAttributeValue(SbmWebServiceDfn.AttributeName.Count));
responseData.Total = StringUtil.ToInt(dataElement.GetAttributeValue(SbmWebServiceDfn.AttributeName.Total));
responseData.PageNo = (uint)StringUtil.ToInt(dataElement.GetAttributeValue(SbmWebServiceDfn.AttributeName.PageNo));
responseData.PageLength = (ushort)StringUtil.ToInt(dataElement.GetAttributeValue(SbmWebServiceDfn.AttributeName.PageLength));
// Extract items.
foreach (XElement listElement in dataElement.Elements())
{
taskData.ThrowIfCancellationRequested();
if (listElement.Name.LocalName.EqualsCI(SbmWebServiceDfn.ElementName.Item))
responseData.Items.Add(ExtractItemData(listElement, taskData));
if (taskData.IsCancellationRequested) break;
}
}
if (taskData.IsCancellationRequested) break;
}
}
if (taskData.IsCancellationRequested) break;
}
}
if (taskData.IsCancellationRequested) responseData.TaskCancelled = true;
return responseData;
}
//-------------------------------------------------------------------
// I t e m D a t a R e q u e s t
//-------------------------------------------------------------------
public class ItemDataResponseData : SbmWebServiceResponse
{
public ItemDataResponseData(SbmWebServiceResponse serviceResponse) : base(serviceResponse) { }
public XElement DataElement => (ResponseElement?.GetFirstChildElement(SbmWebServiceDfn.ElementName.Data) ?? null);
public XElement ItemElement => (DataElement?.GetFirstChildElement(SbmWebServiceDfn.ElementName.Item) ?? null);
public SbmWebServiceItemData Item { get; set; }
}
public async Task<ItemDataResponseData> RequestItemData(SbmWebServiceRequest.Config configRequest, Dictionary<String, String> filters, SacsTaskData taskData)
{
String fn = GetType().Name + ".GetItemData";
if (SacsSystem.DebugMode && configRequest.RequestType != SbmWebServiceRequest.RequestType.Item) Debugger.Break();
// Service Request.
SbmWebServiceRequest serviceRequestData = new SbmWebServiceRequest(configRequest);
serviceRequestData.Filters.AddRange(filters);
// Configure Web Service and make Request.
RequestData requestData = new RequestData(configRequest.Context.InstanceDefinition, taskData.CancellationToken) { Debug = taskData.Debug };
requestData.Data = serviceRequestData.GenerateRequestData();
SbmWebServiceResponse serviceResponse = await DoWebServiceRequest(requestData);
ItemDataResponseData responseData = new ItemDataResponseData(serviceResponse);
//if (SacsSystem.DebugMode && responseData.ResponseElement != null) SaLogger.Debug("Response:\n\n" + responseData.ResponseElement.FormatXml()+"\n");
// Extract item properties.
if (serviceResponse.ResponseElement != null && !taskData.IsCancellationRequested)
{
foreach (XElement responseChildElement in serviceResponse.ResponseElement.Elements())
{
requestData.ThrowIfCancellationRequested();
if (responseChildElement.Name.LocalName.EqualsCI(SbmWebServiceDfn.ElementName.Data))
{
foreach (XElement dataElement in responseChildElement.Elements())
{
requestData.ThrowIfCancellationRequested();
if (dataElement.Name.LocalName.EqualsCI(SbmWebServiceDfn.ElementName.Item))
responseData.Item = ExtractItemData(dataElement, taskData);
if (taskData.IsCancellationRequested) break;
}
}
if (taskData.IsCancellationRequested) break;
}
}
if (taskData.IsCancellationRequested) responseData.TaskCancelled = true;
return responseData;
}
//-------------------------------------------------------------------
// E x t r a c t I t e m
//-------------------------------------------------------------------
private SbmWebServiceItemData ExtractItemData(XElement itemElement, SacsTaskData taskData)
{
SbmWebServiceItemData itemData = new SbmWebServiceItemData(itemElement.GetAttributeValue(SbmWebServiceDfn.AttributeName.ItemType));
foreach (XElement itemDataElement in itemElement.Elements())
{
if (!itemDataElement.HasElements)
{
// No child elements - treat as item property.
itemData.AddValue(itemDataElement.Name.LocalName, itemDataElement.Value);
}
else if (itemDataElement.Name.LocalName.Length > 4 && itemDataElement.Name.LocalName.EndsWithCI("List"))
{
// Data elements has children and is a list of child items.
String childItemType = itemDataElement.Name.LocalName;
if (!itemData.ChildItems.ContainsKey(childItemType))
itemData.ChildItems[childItemType] = new List<SbmWebServiceItemData>();
foreach (XElement childItemElement in itemDataElement.Elements())
{
itemData.ChildItems[childItemType].Add(ExtractItemData(childItemElement, taskData));
if (taskData.IsCancellationRequested) break;
}
}
if (taskData.IsCancellationRequested) break;
}
return itemData;
}
//-------------------------------------------------------------------
// S t o r e I t e m R e q u e s t
//-------------------------------------------------------------------
public class StoreItemResponseData : SbmWebServiceResponse
{
public StoreItemResponseData(SbmWebServiceResponse serviceResponse) : base(serviceResponse) { }
public XElement DataElement => (ResponseElement?.GetFirstChildElement("Item") ?? null);
}
public async Task<StoreItemResponseData> StoreItem(SbmWebServiceRequest.Config configRequest, XElement itemElement, SacsTaskData taskData)
{
String fn = GetType().Name + ".StoreItem";
if (SacsSystem.DebugMode && configRequest.RequestType != SbmWebServiceRequest.RequestType.Store) Debugger.Break();
// Service Request.
SbmWebServiceRequest serviceRequestData = new SbmWebServiceRequest(configRequest);
serviceRequestData.ItemElement = itemElement;
// Configure Web Service and make Request.
RequestData requestData = new RequestData(configRequest.Context.InstanceDefinition, taskData.CancellationToken) { Debug = taskData.Debug };
requestData.Data = serviceRequestData.GenerateRequestData();
SbmWebServiceResponse serviceResponse = await DoWebServiceRequest(requestData);
// Return result.
return new StoreItemResponseData(serviceResponse);
}
//-------------------------------------------------------------------
// W e b S e r v i c e R e q u e s t
//-------------------------------------------------------------------
/// <summary>
/// Execute the web service request.
/// <para>Request data is encrypted and response data is decrypted automatically.</para>
/// </summary>
public async Task<SbmWebServiceResponse> DoWebServiceRequest(RequestData requestData)
{
String fn = GetType().Name + ".DoWebServiceRequest";
SbmWebServiceResponse serviceResponse = null;
// Throw canceled exception if task has been cancelled - invoke at regular intervals.
requestData.ThrowIfCancellationRequested();
// Log request.
//if (SacsSystem.DebugMode) SaLogger.Debug(fn + " Request URL:" + requestData.InstanceDefinition.URL);
if (requestData.Debug)
{
if (requestData.Data.Length < 512)
SaLogger.Debug(fn + " Request:\n\t" + requestData.Data);
else SaLogger.Debug(fn + " Request length:" + requestData.Data.Length);
}
// Configure the request.
SacsHttpRequestData httpRequestData = new SacsHttpRequestData(requestData.CancellationToken)
{
Url = requestData.InstanceDefinition.URL,
TimeoutSecs = 1,
PostData = SbmWindowsServiceCrypter.EncryptRequestData(requestData.Data)
};
// Make the request.
DateTime started = DateTime.Now;
requestData.InstanceDefinition.LastRequestAt = started;
SacsHttpResponseData httpResponseData = await SacsHttpClient.DoRequest(httpRequestData);
// Construct the response.
SbmWebServiceResponse.Config serviceResponseConfig = new SbmWebServiceResponse.Config()
{
RequestStarted = started,
RequestCompleted = DateTime.Now,
HttpResponseData = httpResponseData
};
serviceResponse = new SbmWebServiceResponse(serviceResponseConfig);
// Note if request was successful.
if (httpResponseData.Success)
requestData.InstanceDefinition.LastSuccessfulRequestAt = serviceResponseConfig.RequestCompleted;
// Log response.
if (requestData.Debug)
{
if (serviceResponse.ResponseData.Length < 1024)
SaLogger.Debug(fn + " Response: " + serviceResponse.ResponseData);
else SaLogger.Debug(fn + " Response size: " + serviceResponse.ResponseData.Length);
}
return serviceResponse;
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,78 @@
using System;
namespace Sarand.BusinessMgr.Net.Standard.Base.WebService
{
//=======================================================================
public static class SbmWebServiceDfn
{
//-------------------------------------------------------------------
// Web Service XML element names.
public class ElementNameData
{
// Common.
public String Data { get; } = "Data";
public String List { get; } = "List";
public String Item { get; } = "Item";
public String Filter { get; } = "Filter";
public String Property { get; } = "Property";
public String Columns { get; } = "Columns";
public String SortColumns { get; } = "SortColumns";
public String SortColumn { get; } = "SortColumn";
// Request.
public String Config { get; } = "Config";
public String Context { get; } = "Context";
public String Site { get; } = "Site";
public String Host { get; } = "Host";
public String User { get; } = "User";
public String Email { get; } = "Email";
public String AffiliateIdOrganisation { get; } = "AffiliateIdOrganisation";
public String Debug { get; } = "Debug";
// Response.
public String SbmResponse { get; } = "SbmResponse";
public String Status { get; } = "Status";
public String Messages { get; } = "Messages";
public String Message { get; } = "Message";
public String Count { get; } = "Count";
// Item.
public String Id { get; } = "Id";
public String Code { get; } = "Code";
public String Notes { get; } = "Notes";
public String Flags { get; } = "Flags";
public String CreatedOn { get; } = "CreatedOn";
public String UpdatedOn { get; } = "UpdatedOn";
}
public static ElementNameData ElementName { get; } = new ElementNameData();
//-------------------------------------------------------------------
// Web Service XML attribute names.
public class AttributeNameData
{
// Common.
public String ItemType { get; } = "ItemType";
public String Name { get; } = "Name";
public String Value { get; } = "Value";
public String Code { get; } = "Code";
public String Debug { get; } = "Debug";
// Messages.
public String Context { get; } = "Context";
public String Level { get; } = "Level";
// Item list.
public String Total { get; } = "Total";
public String Count { get; } = "Count";
public String PageNo { get; } = "PageNo";
public String PageLength { get; } = "PageLength";
}
public static AttributeNameData AttributeName { get; } = new AttributeNameData();
//-------------------------------------------------------------------
// Properties.
public static String IsAliveResponse { get; } = "Hello";
public static String StatusSuccess { get; } = "OK";
public static String StatusFatal { get; } = "Fatal";
public static String StatusError { get; } = "Error";
public static String StatusWarning { get; } = "Warning";
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,34 @@
using Sarand.Net.Standard.Base.Utils;
using System;
namespace Sarand.BusinessMgr.Net.Standard.Base.WebService
{
//=======================================================================
public class SbmWebServiceInstanceDefinition
{
//-------------------------------------------------------------------
// Definitions.
//-------------------------------------------------------------------
// Data members.
//-------------------------------------------------------------------
// Construction.
public SbmWebServiceInstanceDefinition(String caption, String url)
{
Caption = caption;
URL = url;
}
//-------------------------------------------------------------------
// Properties.
public String Caption { get; }
public String URL { get; }
public DateTime LastRequestAt { get; set; }
public DateTime LastSuccessfulRequestAt { get; set; }
public bool Valid { get { return (!StringUtil.IsEmpty(URL)); } }
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,129 @@
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
namespace Sarand.BusinessMgr.Net.Standard.Base.WebService
{
//=======================================================================
public class SbmWebServiceItemData
{
//-------------------------------------------------------------------
// Data members.
private readonly Dictionary<String, String> values = new Dictionary<String, String>();
//-------------------------------------------------------------------
// Construction.
public SbmWebServiceItemData(String itemType)
{
ItemType = itemType;
}
// Copy construction.
public SbmWebServiceItemData(SbmWebServiceItemData itemData)
{
values.AddRange(itemData.values);
}
//-------------------------------------------------------------------
// Properties.
public String ItemType { get; }
/// <summary>
/// Child items.
/// <para>Dictionary key identifies type of item.</para>
/// </summary>
public Dictionary<String, List<SbmWebServiceItemData>> ChildItems { get; } = new Dictionary<string, List<SbmWebServiceItemData>>();
//-------------------------------------------------------------------
// Population.
public void AddValue(String name, String value)
{
values[name] = value;
}
//-------------------------------------------------------------------
// Value exists.
public bool HasValue<T>(T name)
{
return HasValue(name.ToString());
}
public bool HasValue(string name)
{
return values.ContainsKey(name);
}
//-------------------------------------------------------------------
// String value.
public String GetValue<T>(T name)
{
return GetValue(name.ToString());
}
public String GetValue(string name)
{
return values.GetValue(name, "");
}
//-------------------------------------------------------------------
// SysId value.
public SysId GetIdValue<T>(T name)
{
return GetIdValue(name.ToString());
}
public SysId GetIdValue(string name)
{
return new SysId(StringUtil.ToInt(GetValue(name)));
}
//-------------------------------------------------------------------
// Bool value.
public bool GetBoolValue<T>(T name)
{
return GetBoolValue(name.ToString());
}
public bool GetBoolValue(string name)
{
return StringUtil.ToBool(GetValue(name));
}
// Int value.
public int GetIntValue<T>(T name)
{
return GetIntValue(name.ToString());
}
public int GetIntValue(string name)
{
return StringUtil.ToInt(GetValue(name));
}
// Decimal value.
public decimal GetDecimalValue<T>(T name)
{
return GetDecimalValue(name.ToString());
}
public decimal GetDecimalValue(string name)
{
return StringUtil.ToDecimal(GetValue(name));
}
//-------------------------------------------------------------------
// Date value.
public DateTime GetDateValue<T>(T name)
{
return GetDateValue(name.ToString());
}
public DateTime GetDateValue(string name)
{
return DateUtil.ParseXmlDate(GetValue(name));
}
// DateTime value.
public DateTime GetDateTimeValue<T>(T name)
{
return GetDateTimeValue(name.ToString());
}
public DateTime GetDateTimeValue(string name)
{
return DateUtil.ParseXmlDateTime(GetValue(name));
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,45 @@
using Sarand.Net.Standard.Base.Core;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Sarand.BusinessMgr.Net.Standard.Base.WebService
{
//=======================================================================
public class SbmWebServiceMessage
{
//-------------------------------------------------------------------
// Construction.
public SbmWebServiceMessage(String context, String code, String message, SaMessageLevel level = SaMessageLevel.Info)
{
Level = level;
Context = context;
Code = code;
Message = message;
}
//-------------------------------------------------------------------
// Properties.
public SaMessageLevel Level { get; }
public string Context { get; }
public string Code { get; }
public string Message { get; }
//-------------------------------------------------------------------
}
//=======================================================================
public static class SbmWebServiceMessageList
{
public static bool HasMessagesOfLevel(this IEnumerable<SbmWebServiceMessage> messages, SaMessageLevel level)
{
return messages.Any(msg => msg.Level == level);
}
public static List<SbmWebServiceMessage> GetMessagesOfLevel(this IEnumerable<SbmWebServiceMessage> messages, SaMessageLevel level)
{
return messages.Where(msg => msg.Level == level).ToList();
}
}
//=======================================================================
}
@@ -0,0 +1,244 @@
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Utils;
using Sarand.Net.Standard.Base.Xml;
using System;
using System.Collections.Generic;
using System.Xml.Linq;
namespace Sarand.BusinessMgr.Net.Standard.Base.WebService
{
//=======================================================================
public class SbmWebServiceRequest
{
//-------------------------------------------------------------------
// Definitions.
public enum RequestType
{
Unknown,
IsAlive,
/// <summary>Item count</summary>
Count,
/// <summary>Query list - specific columns, compressed (csv etc) response data</summary>
QueryList,
/// <summary>Item list - full xml for each item with optional associated items.</summary>
ItemList,
/// <summary>Single Item with optional associated items.</summary>
Item,
/// <summary>Validate item properties without update.</summary>
Validate,
/// <summary>Validate properties and store (insert/update) item.</summary>
Store,
/// <summary>Delete item.</summary>
Delete,
/// <summary>List - as per Query List</summary>
[Obsolete("Deprecated. Use QueryList instead.", true)]
List,
/// <summary>Single Item with optional associated items.</summary>
[Obsolete("Deprecated. Use Item instead.", true)]
Data,
}
public enum DataType
{
Unknown,
// Security.
UserProfile,
// Reference data.
CodeType,
Code,
// Accounts.
Affiliate,
Address,
Association,
SysParam,
SystemAccount,
SystemUser,
SystemAccountUser,
// Assets.
Asset,
AssetCategory,
AssetProcess,
VehicleClass,
Vehicle,
VehicleEvent,
VehicleFeature,
// Commodity.
Commodity,
CommodityCustomer,
CommoditySupplier,
Container,
ContainerItem,
PortfolioItem,
// Price.
Price,
PriceSet,
// Stock.
Location,
Movement,
// Transaction.
Transaction,
Requirement,
Constituent,
// Process.
ItemProcess,
Process,
// Data.
ItemBatch,
ItemLink,
// Reference Data.
Currency,
Language,
Region,
TaxCode,
UnitMeasure,
}
//-------------------------------------------------------------------
/// <summary>
/// Sort column identified by column name with ascending flag.
/// </summary>
public class SortColumnData
{
public SortColumnData(String columnName, bool ascending)
{
ColumnName = columnName;
Ascending = ascending;
}
public String ColumnName { get; }
public bool Ascending { get; }
}
//-------------------------------------------------------------------
// Configuration.
public class Config
{
public bool SoapEnvelope { get; set; }
public String SoapPrefix { get; set; }
public DataType DataType { get; set; }
public RequestType RequestType { get; set; }
public class ContextProperties
{
public SbmWebServiceInstanceDefinition InstanceDefinition { get; set; }
public String User { get; set; }
public String Email { get; set; }
public SysId AffiliateIdOrganisation { get; set; }
public bool Commit { get; set; }
public bool Debug { get; set; }
}
public ContextProperties Context { get; } = new ContextProperties();
}
//-------------------------------------------------------------------
// Data members.
private readonly Config config;
//-------------------------------------------------------------------
// Construction.
public SbmWebServiceRequest(Config config)
{
this.config = config;
}
//-------------------------------------------------------------------
// Properties.
public Dictionary<String, String> Filters { get; } = new Dictionary<String, String>();
public List<String> Columns { get; } = new List<String>();
public List<String> SortColumns { get; } = new List<String>();
public XElement ItemElement { get; set; }
//-------------------------------------------------------------------
// D a t a G e n e r a t i o n
//-------------------------------------------------------------------
public String GetRequestName()
{
if (config.RequestType == RequestType.IsAlive) return "";
String requestName = "";
if (config.DataType > 0)
requestName += config.DataType.ToString();
if (config.RequestType > 0)
requestName += config.RequestType.ToString();
return requestName + "Request";
}
public String GenerateRequestData(bool formatted = false)
{
if (config.RequestType == RequestType.IsAlive) return "";
// Request document.
XDocument requestDoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));
// Request root.
XElement requestElement = null;
if (config.SoapEnvelope)
{
XElement envelopeElement = null;
XElement headerElement = null;
XElement bodyElement = null;
if (!StringUtil.IsEmpty(config.SoapPrefix))
{
XNamespace soapNamespace = SacsSoapUtils.GetSoapNamespace(SoapNamespaceType.Soap_1_1);
envelopeElement = requestDoc.AppendElement(soapNamespace, SacsSoapUtils.GetElementName(SoapElementType.Envelope));
envelopeElement.SetAttributeValue(XNamespace.Xmlns + config.SoapPrefix, soapNamespace);
headerElement = envelopeElement.AppendElement(soapNamespace, SacsSoapUtils.GetElementName(SoapElementType.Header));
bodyElement = envelopeElement.AppendElement(soapNamespace, SacsSoapUtils.GetElementName(SoapElementType.Body));
}
else
{
// No namespace.
envelopeElement = requestDoc.AppendElement(SacsSoapUtils.GetElementName(SoapElementType.Envelope));
headerElement = envelopeElement.AppendElement(SacsSoapUtils.GetElementName(SoapElementType.Header));
bodyElement = envelopeElement.AppendElement(SacsSoapUtils.GetElementName(SoapElementType.Body));
}
requestElement = bodyElement.AppendElement(GetRequestName());
}
else
{
// Otherwise add the request directly to the document.
requestElement = requestDoc.AppendElement(GetRequestName());
}
// Config.
XElement configElement = requestElement.AppendElement("Config");
// Context.
XElement contextElement = configElement.AppendElement("Context");
if (!StringUtil.IsEmpty(config.Context.User)) contextElement.AppendElement("User", config.Context.User);
if (!StringUtil.IsEmpty(config.Context.Email)) contextElement.AppendElement("Email", config.Context.Email);
if (SysId.IsValid(config.Context.AffiliateIdOrganisation)) contextElement.AppendElement("AffiliateIdOrganisation", SysId.ToString(config.Context.AffiliateIdOrganisation));
if (config.Context.Commit) contextElement.AppendElement("Commit", "1");
if (config.Context.Debug) contextElement.AppendElement("Debug", "1");
// Filter.
if (Filters.Count > 0)
{
XElement filterElement = configElement.AppendElement("Filter");
foreach (String name in Filters.Keys)
filterElement.AppendElement(name, Filters[name]);
}
// Columns.
if (Columns.Count > 0)
{
XElement columnsElement = configElement.AppendElement("Columns", Columns.Concat(",", "", ""));
}
// Sort columns.
if (SortColumns.Count > 0)
{
XElement sortColumnsElement = configElement.AppendElement("SortColumns", SortColumns.Concat(",", "", ""));
}
// Item.
if (ItemElement != null)
{
XElement dataElement = requestElement.AppendElement("Data");
dataElement.AppendElement(ItemElement);
}
if (formatted)
return requestDoc.FormatXml();
return requestDoc.GetXml();
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,126 @@
using Sarand.BusinessMgr.Net.Standard.Base.Data;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Net;
using Sarand.Net.Standard.Base.Utils;
using Sarand.Net.Standard.Base.Xml;
using System;
using System.Collections.Generic;
using System.Xml.Linq;
namespace Sarand.BusinessMgr.Net.Standard.Base.WebService
{
//=======================================================================
public class SbmWebServiceResponse
{
//-------------------------------------------------------------------
// Definitions.
//-------------------------------------------------------------------
// Configuration.
public class Config
{
public DateTime RequestStarted { get; set; } = DateTime.Now;
public DateTime RequestCompleted { get; set; }
public SacsHttpResponseData HttpResponseData { get; set; }
}
//-------------------------------------------------------------------
// Data members.
protected readonly Config config;
//-------------------------------------------------------------------
// Construction.
public SbmWebServiceResponse(Config config)
{
this.config = config;
ResponseData = SbmWindowsServiceCrypter.DecryptResponseData(config.HttpResponseData.Data);
try
{
// Identify the response element in the xml data.
ResponseDoc = XDocument.Parse(ResponseData, LoadOptions.None);
XElement rootElement = ResponseDoc.Root;
if (rootElement.Name.LocalName.EndsWithCI("Response"))
ResponseElement = rootElement;
else if (rootElement.Name.LocalName.EqualsCI(SacsSoapUtils.GetElementName(SoapElementType.Envelope)))
{
SoapEnvelope = true;
SoapPrefix = rootElement.GetNamespacePrefix();
foreach (XElement soapElement in rootElement.Elements())
{
if (soapElement.Name.LocalName.EqualsCI(SacsSoapUtils.GetElementName(SoapElementType.Body)))
{
foreach (XElement bodyElement in soapElement.Elements())
{
if (bodyElement.Name.LocalName.EndsWithCI("Response"))
{
ResponseElement = bodyElement;
}
}
}
}
}
if (ResponseElement != null)
{
// Extract status code.
XElement statusElement = ResponseElement.GetFirstChildElement(SbmWebServiceDfn.ElementName.Status);
if (statusElement != null)
{
StatusCode = statusElement.GetAttributeValue(SbmWebServiceDfn.AttributeName.Code);
// Extract messages.
XElement messagesElement = statusElement.GetFirstChildElement(SbmWebServiceDfn.ElementName.Messages);
if (messagesElement != null)
{
foreach (XElement messageElement in messagesElement.GetChildElements(SbmWebServiceDfn.ElementName.Message))
{
String context = messageElement.GetAttributeValue(SbmWebServiceDfn.AttributeName.Context);
String code = messageElement.GetAttributeValue(SbmWebServiceDfn.AttributeName.Code);
SaMessageLevel level = SacsSystem.GetMessageLevelFromCode(messageElement.GetAttributeValue(SbmWebServiceDfn.AttributeName.Level));
SbmWebServiceMessage message = new SbmWebServiceMessage(context, code, messageElement.Value, level);
Messages.Add(message);
}
}
}
}
}
catch (Exception) { }
}
public SbmWebServiceResponse(SbmWebServiceResponse serviceResponse)
{
// Copied from another service reponse - don't re-intrepert properties.
this.config = serviceResponse.config;
// Structure.
SoapEnvelope = serviceResponse.SoapEnvelope;
SoapPrefix = serviceResponse.SoapPrefix;
// Response.
ResponseData = serviceResponse.ResponseData;
ResponseDoc = serviceResponse.ResponseDoc;
ResponseElement = serviceResponse.ResponseElement;
// Status.
StatusCode = serviceResponse.StatusCode;
Messages = serviceResponse.Messages;
}
//-------------------------------------------------------------------
// Properties.
public DateTime RequestStarted { get { return config.RequestStarted; } }
public DateTime RequestCompleted { get { return config.RequestCompleted; } }
public SacsHttpResponseData HttpResponseData { get { return config.HttpResponseData; } }
// Structure.
public bool SoapEnvelope { get; }
public String SoapPrefix { get; } = "";
// Response.
public String ResponseData { get; }
public XDocument ResponseDoc { get; }
public XElement ResponseElement { get; }
// Status.
public bool TaskCancelled { get; set; }
public String StatusCode { get; } = "";
public List<SbmWebServiceMessage> Messages { get; } = new List<SbmWebServiceMessage>();
public String ErrorStateMessage { get; set; }
//-------------------------------------------------------------------
}
//=======================================================================
}