TS - Bus objects updated + Service classes and forms added

This commit is contained in:
Thomas Savine
2020-03-23 09:12:33 +00:00
parent 114aa49535
commit 7edbd07575
55 changed files with 8312 additions and 372 deletions
@@ -0,0 +1,432 @@
using Sarand.Core.App;
using Sarand.Core.Base;
using Sarand.Core.Data;
using Sarand.Core.Net;
using Sarand.Core.Tasks;
using Sarand.Core.Xml;
using Sarand.PatientMgr.Core.Data;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Sarand.PatientMgr.Core.WebService
{
//=======================================================================
// Patient Web Service Client
// Make requests to PatientMgr Web Service hosted by Windows Service application.
//-----------------------------------------------------------------------
// Threading:
// Ref. https://blog.xamarin.com/getting-started-with-async-await/
//=======================================================================
public class SpmWebServiceClient
{
//-------------------------------------------------------------------
// 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 (SpmWebServiceInstanceDefinition instanceDefinition, CancellationToken? cancellationToken = null) :
base(cancellationToken)
{
InstanceDefinition = instanceDefinition;
}
public SpmWebServiceInstanceDefinition InstanceDefinition { get; }
public String Data { get; set; } = "";
}
//-------------------------------------------------------------------
// Data members.
//-------------------------------------------------------------------
// Construction.
public SpmWebServiceClient ()
{
}
//-------------------------------------------------------------------
// Properties.
//-------------------------------------------------------------------
// I s A l i v e
//-------------------------------------------------------------------
public async Task<bool> RequestIsAlive (SpmWebServiceInstanceDefinition instanceDefinition)
{
String fn = GetType().Name + ".IsAlive";
try
{
RequestData requestData = new RequestData(instanceDefinition);
SpmWebServiceResponse serviceResponse = await DoWebServiceRequest(requestData);
if (serviceResponse.ResponseData.EqualsCI(SpmWebServiceDfn.IsAliveResponse))
return true;
}
catch (Exception exc) { Logger.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 : SpmWebServiceResponse
{
public ItemCountResponseData (SpmWebServiceResponse serviceResponse) : base(serviceResponse) { }
public long ItemCount { get; set; }
}
public async Task<ItemCountResponseData> RequestItemCount (SpmWebServiceRequest.Config configRequest, Dictionary<String, String> filters, SacsTaskData taskData)
{
String fn = GetType().Name + ".GetItemCount";
if (SacsSystem.DebugMode && configRequest.RequestType != SpmWebServiceRequest.RequestType.Count) Debugger.Break();
// Service Request.
SpmWebServiceRequest serviceRequestData = new SpmWebServiceRequest(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();
SpmWebServiceResponse 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(SpmWebServiceDfn.ElementName.Data))
{
foreach (XElement dataElement in responseChildElement.Elements())
{
if (dataElement.Name.LocalName.EqualsCI(SpmWebServiceDfn.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 : SpmWebServiceResponse
{
public QueryListResponseData (SpmWebServiceResponse serviceResponse) : base(serviceResponse) { }
public List<SpmWebServiceItemData> Items { get; } = new List<SpmWebServiceItemData>();
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 (SpmWebServiceRequest.Config configRequest, Dictionary<String, String> filters, List<string> columns, List<String> sortColumns, SacsTaskData taskData)
{
String fn = GetType().Name + ".GetItemList";
if (SacsSystem.DebugMode && configRequest.RequestType != SpmWebServiceRequest.RequestType.QueryList) Debugger.Break();
// Service Request.
SpmWebServiceRequest serviceRequestData = new SpmWebServiceRequest(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();
SpmWebServiceResponse serviceResponse = await DoWebServiceRequest(requestData);
QueryListResponseData responseData = new QueryListResponseData(serviceResponse);
//if (SacsSystem.DebugMode && responseData.ResponseElement != null) Logger.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(SpmWebServiceDfn.ElementName.Data))
{
foreach (XElement dataElement in responseChildElement.Elements())
{
if (dataElement.Name.LocalName.EqualsCI(SpmWebServiceDfn.ElementName.List))
{
// Paging info.
// <List Count="8" Total="196527" PageNo="1" PageLength="8">
responseData.Count = StringUtil.ToInt(dataElement.GetAttributeValue(SpmWebServiceDfn.AttributeName.Count));
responseData.Total = StringUtil.ToInt(dataElement.GetAttributeValue(SpmWebServiceDfn.AttributeName.Total));
responseData.PageNo = (uint)StringUtil.ToInt(dataElement.GetAttributeValue(SpmWebServiceDfn.AttributeName.PageNo));
responseData.PageLength = (ushort)StringUtil.ToInt(dataElement.GetAttributeValue(SpmWebServiceDfn.AttributeName.PageLength));
// Extract items.
foreach (XElement listElement in dataElement.Elements())
{
taskData.ThrowIfCancellationRequested();
if (listElement.Name.LocalName.EqualsCI(SpmWebServiceDfn.ElementName.Item))
{
SpmWebServiceItemData itemData = new SpmWebServiceItemData("");
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 : SpmWebServiceResponse
{
public ItemListResponseData (SpmWebServiceResponse serviceResponse) : base(serviceResponse) { }
public List<SpmWebServiceItemData> Items { get; } = new List<SpmWebServiceItemData>();
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 (SpmWebServiceRequest.Config configRequest, Dictionary<String, String> filters, List<String> sortColumns, SacsTaskData taskData)
{
String fn = GetType().Name + ".GetItemList";
if (SacsSystem.DebugMode && configRequest.RequestType != SpmWebServiceRequest.RequestType.ItemList) Debugger.Break();
// Service Request.
SpmWebServiceRequest serviceRequestData = new SpmWebServiceRequest(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();
SpmWebServiceResponse serviceResponse = await DoWebServiceRequest(requestData);
ItemListResponseData responseData = new ItemListResponseData(serviceResponse);
//if (SacsSystem.DebugMode && responseData.ResponseElement != null) Logger.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(SpmWebServiceDfn.ElementName.Data))
{
foreach (XElement dataElement in responseChildElement.Elements())
{
if (dataElement.Name.LocalName.EqualsCI(SpmWebServiceDfn.ElementName.List))
{
// Paging info.
// <List Count="8" Total="196527" PageNo="1" PageLength="8">
responseData.Count = StringUtil.ToInt(dataElement.GetAttributeValue(SpmWebServiceDfn.AttributeName.Count));
responseData.Total = StringUtil.ToInt(dataElement.GetAttributeValue(SpmWebServiceDfn.AttributeName.Total));
responseData.PageNo = (uint)StringUtil.ToInt(dataElement.GetAttributeValue(SpmWebServiceDfn.AttributeName.PageNo));
responseData.PageLength = (ushort)StringUtil.ToInt(dataElement.GetAttributeValue(SpmWebServiceDfn.AttributeName.PageLength));
// Extract items.
foreach (XElement listElement in dataElement.Elements())
{
taskData.ThrowIfCancellationRequested();
if (listElement.Name.LocalName.EqualsCI(SpmWebServiceDfn.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 : SpmWebServiceResponse
{
public ItemDataResponseData (SpmWebServiceResponse serviceResponse) : base(serviceResponse) { }
public XElement DataElement => (ResponseElement?.GetFirstChildElement(SpmWebServiceDfn.ElementName.Data) ?? null);
public XElement ItemElement => (DataElement?.GetFirstChildElement(SpmWebServiceDfn.ElementName.Item) ?? null);
public SpmWebServiceItemData Item { get; set; }
}
public async Task<ItemDataResponseData> RequestItemData (SpmWebServiceRequest.Config configRequest, Dictionary<String, String> filters, SacsTaskData taskData)
{
String fn = GetType().Name + ".GetItemData";
if (SacsSystem.DebugMode && configRequest.RequestType != SpmWebServiceRequest.RequestType.Item) Debugger.Break();
// Service Request.
SpmWebServiceRequest serviceRequestData = new SpmWebServiceRequest(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();
SpmWebServiceResponse serviceResponse = await DoWebServiceRequest(requestData);
ItemDataResponseData responseData = new ItemDataResponseData(serviceResponse);
//if (SacsSystem.DebugMode && responseData.ResponseElement != null) Logger.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(SpmWebServiceDfn.ElementName.Data))
{
foreach (XElement dataElement in responseChildElement.Elements())
{
requestData.ThrowIfCancellationRequested();
if (dataElement.Name.LocalName.EqualsCI(SpmWebServiceDfn.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 SpmWebServiceItemData ExtractItemData (XElement itemElement, SacsTaskData taskData)
{
SpmWebServiceItemData itemData = new SpmWebServiceItemData(itemElement.GetAttributeValue(SpmWebServiceDfn.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<SpmWebServiceItemData>();
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 : SpmWebServiceResponse
{
public StoreItemResponseData (SpmWebServiceResponse serviceResponse) : base(serviceResponse) { }
public XElement DataElement => (ResponseElement?.GetFirstChildElement("Item") ?? null);
}
public async Task<StoreItemResponseData> StoreItem (SpmWebServiceRequest.Config configRequest, XElement itemElement, SacsTaskData taskData)
{
String fn = GetType().Name + ".StoreItem";
if (SacsSystem.DebugMode && configRequest.RequestType != SpmWebServiceRequest.RequestType.Store) Debugger.Break();
// Service Request.
SpmWebServiceRequest serviceRequestData = new SpmWebServiceRequest(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();
SpmWebServiceResponse 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<SpmWebServiceResponse> DoWebServiceRequest (RequestData requestData)
{
String fn = GetType().Name + ".DoWebServiceRequest";
SpmWebServiceResponse serviceResponse = null;
// Throw canceled exception if task has been cancelled - invoke at regular intervals.
requestData.ThrowIfCancellationRequested();
// Log request.
if (SacsSystem.DebugMode) Logger.Debug(fn + " Request URL:" + requestData.InstanceDefinition.URL);
if (requestData.Debug)
{
if (requestData.Data.Length < 512)
Logger.Debug(fn + " Request:\n\t" + requestData.Data);
else Logger.Debug(fn + " Request length:" + requestData.Data.Length);
}
// Configure the request.
SacsHttpRequestData httpRequestData = new SacsHttpRequestData(requestData.CancellationToken)
{
Url = requestData.InstanceDefinition.URL,
TimeoutSecs = 1,
PostData = SpmWindowsServiceCrypter.EncryptRequestData(requestData.Data)
};
// Make the request.
DateTime started = DateTime.Now;
requestData.InstanceDefinition.LastRequestAt = started;
SacsHttpResponseData httpResponseData = await SacsHttpClient.DoRequest(httpRequestData);
// Construct the response.
SpmWebServiceResponse.Config serviceResponseConfig = new SpmWebServiceResponse.Config()
{
RequestStarted = started,
RequestCompleted = DateTime.Now,
HttpResponseData = httpResponseData
};
serviceResponse = new SpmWebServiceResponse(serviceResponseConfig);
// Note if request was successful.
if (httpResponseData.Success)
requestData.InstanceDefinition.LastSuccessfulRequestAt = serviceResponseConfig.RequestCompleted;
// Log response.
if (requestData.Debug)
{
if (serviceResponse.ResponseData.Length < 1024)
Logger.Debug(fn + " Response: " + serviceResponse.ResponseData);
else Logger.Debug(fn + " Response size: " + serviceResponse.ResponseData.Length);
}
return serviceResponse;
}
//-------------------------------------------------------------------
}
//=======================================================================
}