Initial Commit
This commit is contained in:
125
TomcatServer/PlutoServer.MSL/Authentication_Impl.cs
Normal file
125
TomcatServer/PlutoServer.MSL/Authentication_Impl.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
namespace Pluto.Api {
|
||||
using System;
|
||||
using RemObjects.SDK;
|
||||
using RemObjects.SDK.Types;
|
||||
using RemObjects.SDK.Server;
|
||||
using RemObjects.SDK.Server.ClassFactories;
|
||||
using PlutoServer.MSL;
|
||||
using System.Collections.Generic;
|
||||
using PlutoServer.MSL.Connectors;
|
||||
|
||||
|
||||
[RemObjects.SDK.Server.ClassFactories.StandardClassFactory()]
|
||||
[RemObjects.SDK.Server.Service(Name = "Authentication", InvokerClass = typeof(Authentication_Invoker), ActivatorClass = typeof(Authentication_Activator))]
|
||||
public class Authentication : RemObjects.SDK.Server.Service, IAuthentication {
|
||||
|
||||
private System.ComponentModel.Container components = null;
|
||||
public Authentication() :
|
||||
base() {
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent() {
|
||||
|
||||
}
|
||||
|
||||
protected override void Dispose(bool aDisposing) {
|
||||
if(aDisposing) {
|
||||
if((this.components != null)) {
|
||||
this.components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(aDisposing);
|
||||
}
|
||||
|
||||
public virtual UserInfo1 Login1(string apiKey, PracticeInfo1 practiceInfo, string userId, string password)
|
||||
{
|
||||
if(ProductType.IsKeyLytec(apiKey))
|
||||
{
|
||||
UserInfo1 info = LytecConnector.AuthenticateUserLogin(apiKey, userId, password);
|
||||
if (info == null)
|
||||
MSLSpecific.Logger.Error("Lytec Authentication Failed for User:{0} into Practice:{1}", userId, practiceInfo.Name);
|
||||
return info;
|
||||
}
|
||||
else if (ProductType.IsKeyMedisoft(apiKey))
|
||||
{
|
||||
UserInfo1 info = MedisoftConnector.AuthenticateUserLogin(apiKey, userId, password);
|
||||
if (info == null)
|
||||
MSLSpecific.Logger.Error("Medisoft Authentication Failed for User:{0} into Practice:{1}", userId, practiceInfo.Name);
|
||||
return info;
|
||||
}
|
||||
|
||||
MSLSpecific.Logger.Error("Invalid Product");
|
||||
return null;
|
||||
}
|
||||
|
||||
#region IAuthentication Members
|
||||
|
||||
public PracticeInfo1[] GetPracticeList1(string apiKey)
|
||||
{
|
||||
MSLSpecific.Logger.Error("GetPracticeList1 is not implemented, shouldn't never be called");
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual bool CreatePin1(string apiKey, PracticeInfo1 practiceInfo, string userId, string fourdigitpin)
|
||||
{
|
||||
if (ProductType.IsKeyLytec(apiKey))
|
||||
{
|
||||
return LytecConnector.CreatePin(apiKey, userId, fourdigitpin);
|
||||
}
|
||||
else if (ProductType.IsKeyMedisoft(apiKey))
|
||||
{
|
||||
return MedisoftConnector.CreatePin(apiKey, userId, fourdigitpin);
|
||||
}
|
||||
|
||||
MSLSpecific.Logger.Error("Invalid Product");
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual UserInfo1 ValidatePin1(string apiKey, PracticeInfo1 practiceInfo, string userId, string pin)
|
||||
{
|
||||
if (ProductType.IsKeyLytec(apiKey))
|
||||
{
|
||||
return LytecConnector.AuthenticateUserPIN(apiKey, userId, pin);
|
||||
}
|
||||
else if (ProductType.IsKeyMedisoft(apiKey))
|
||||
{
|
||||
return MedisoftConnector.AuthenticateUserPIN(apiKey, userId, pin);
|
||||
}
|
||||
|
||||
MSLSpecific.Logger.Error("Invalid Product");
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual bool PinIsSet1(string apiKey, PracticeInfo1 practiceInfo, string userId)
|
||||
{
|
||||
if (ProductType.IsKeyLytec(apiKey))
|
||||
{
|
||||
return LytecConnector.PinIsSet(apiKey, userId);
|
||||
}
|
||||
else if (ProductType.IsKeyMedisoft(apiKey))
|
||||
{
|
||||
return MedisoftConnector.PinIsSet(apiKey, userId);
|
||||
}
|
||||
|
||||
MSLSpecific.Logger.Error("Invalid Product");
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual string GetAPIVersion()
|
||||
{
|
||||
Version LocalVersion = Yaulw.Assembly.AssemblyW.GetAssemblyVersion(Yaulw.Assembly.AssemblyW.AssemblyST.Entry);
|
||||
return LocalVersion.ToString();
|
||||
}
|
||||
|
||||
public virtual bool IsAPIOutOfDate()
|
||||
{
|
||||
bool bRetVal = AutoUpdate.IsLocalServiceVersionOutOfDate();
|
||||
if (bRetVal)
|
||||
MSLSpecific.Logger.Info("Local Service is out of Date");
|
||||
return bRetVal;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
316
TomcatServer/PlutoServer.MSL/AutoUpdate.cs
Normal file
316
TomcatServer/PlutoServer.MSL/AutoUpdate.cs
Normal file
@@ -0,0 +1,316 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Yaulw.File;
|
||||
using System.IO;
|
||||
using Yaulw.Thread;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace PlutoServer.MSL
|
||||
{
|
||||
internal static class AutoUpdate
|
||||
{
|
||||
#region Private Statics
|
||||
|
||||
/// <summary>
|
||||
/// Check every 2.5 hours
|
||||
/// </summary>
|
||||
private const int AUTO_CHECK_INTERVAL_IN_MINUTES = 150;
|
||||
|
||||
/// <summary>
|
||||
/// Keep track when last update occured
|
||||
/// </summary>
|
||||
private static ISReadWrite s_ISReadWrite = new ISReadWrite("update");
|
||||
|
||||
/// <summary>
|
||||
/// Auto-Update Thread
|
||||
/// </summary>
|
||||
private static SingleThreadTimer timer = null;
|
||||
|
||||
/// <summary>
|
||||
/// Online Version of the Service
|
||||
/// </summary>
|
||||
private static Version OnlineVersion = null;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the LocalFileNameNPath for SetupMini File (TEMP FOLDER)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static string MiniSetupFileNameNPath
|
||||
{
|
||||
get
|
||||
{
|
||||
string LocalFileNameNPath = Yaulw.Tools.PathNaming.PathEndsWithSlash(Path.GetTempPath()) + "SetupMini.exe";
|
||||
return LocalFileNameNPath;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Construction
|
||||
|
||||
static AutoUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region internal Methods
|
||||
|
||||
/// <summary>
|
||||
/// Try to update the Service, if needed
|
||||
/// </summary>
|
||||
internal static void TryToUpdateIfNeeded(int nDelay, bool bCheckDTStamp)
|
||||
{
|
||||
// Default Auto Update with 15 sec delay
|
||||
if (nDelay < 0)
|
||||
nDelay = 15;
|
||||
|
||||
PlutoService.AppLogInfo(String.Format("TryToUpdateIfNeeded called at {0} with delay {1} and CheckDT {2}", DateTime.Now.ToLongTimeString(), nDelay.ToString(), bCheckDTStamp));
|
||||
if (bCheckDTStamp)
|
||||
{
|
||||
DateTime dtLastUpdated = GetLastUpdated();
|
||||
TimeSpan ts = DateTime.Now - dtLastUpdated;
|
||||
if (ts.TotalDays >= 1.0)
|
||||
{
|
||||
PlutoService.AppLogInfo(String.Format("LaunchUpdateThread called with Delay {0}", nDelay));
|
||||
LaunchUpdateThread(nDelay);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PlutoService.AppLogInfo(String.Format("LaunchUpdateThread called with Delay {0}", nDelay));
|
||||
LaunchUpdateThread(nDelay);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Main Entry Point - Service Calls into here upon Start-Up
|
||||
/// </summary>
|
||||
internal static void StartAutoTimer_ServiceStarted()
|
||||
{
|
||||
// Important Sanity Clean-up, this way we know that the service
|
||||
// always downloads the latest setup and runs the latest setup
|
||||
if (File.Exists(MiniSetupFileNameNPath))
|
||||
File.Delete(MiniSetupFileNameNPath);
|
||||
|
||||
// Right at Service Startup Check if we have tried to update
|
||||
// within the last day, if we have not, try to update.
|
||||
// NOTE: Don't do this if we just got installed for the very first time
|
||||
// the service seems to hang when doing that during the install of
|
||||
// lytec/medisoft. (not known what the root cause is), but let's
|
||||
// just avoid it alltogether. (We could potentially add a timeout here
|
||||
// and just check way way later), not sure what the best course of action
|
||||
// is at this point.
|
||||
DateTime dt = Yaulw.Registry.RegKey.GetKey<DateTime>(Yaulw.Registry.HKEYRoot.LocalMachine, PlutoService.LOCAL_MACHINE_SUBKEY, PlutoService.LOCAL_MACHINE_INITIALSETUPDT, DateTime.MinValue);
|
||||
TimeSpan ts = DateTime.Now - dt;
|
||||
|
||||
// If the ts is < 10 Minutes we must have just gotten installed, hence, we shouldn't
|
||||
// try to update the service and just let it start (let the autoUpdate Handler below or Diagnose Mobile handle the initial updating).
|
||||
if (ts.TotalMinutes > 10)
|
||||
TryToUpdateIfNeeded(0, false);
|
||||
|
||||
// Additionally, we want to start a Timer Thread,
|
||||
// that Randomly checks for new updates, once every few hours, but only
|
||||
// in specific circumstances will it actually perform the update. ( check every 2.5 hours )
|
||||
timer = new SingleThreadTimer(AutoUpdateHandler, (uint)TimeSpan.FromMinutes(AUTO_CHECK_INTERVAL_IN_MINUTES).TotalMilliseconds, true);
|
||||
// * for debugging *:
|
||||
//SingleThreadTimer timer = new SingleThreadTimer(STElapsedEventHandler, (uint)TimeSpan.FromSeconds(30).TotalMilliseconds, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Main Entry Point - Service Calls into here upon Stop
|
||||
/// </summary>
|
||||
internal static void StopAutoTimer_ServiceStopped()
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.Stop();
|
||||
timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetch the Latest Version that is Online
|
||||
/// </summary>
|
||||
/// <returns>valid version object or null if error occured</returns>
|
||||
internal static Version FetchOnlineVerion()
|
||||
{
|
||||
string fetchVersion = Yaulw.Net.WCHelper.ScreenScrapeFromURL(Configuration.CHECK_VERSION_URL);
|
||||
if (!String.IsNullOrEmpty(fetchVersion))
|
||||
{
|
||||
fetchVersion = fetchVersion.Replace("\n", "");
|
||||
fetchVersion = fetchVersion.Replace("\r", "");
|
||||
fetchVersion = fetchVersion.Trim();
|
||||
|
||||
try
|
||||
{
|
||||
Version version = new Version(fetchVersion);
|
||||
return version;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
PlutoService.AppLogError(String.Format("The url:{0} to check the Mobile version could not be parsed: {1}", Configuration.CHECK_VERSION_URL, e.Message));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PlutoService.AppLogError(String.Format("The url:{0} to check the Mobile version could not be accessed", Configuration.CHECK_VERSION_URL));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Quick Check to see if the Local Service is out of date
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal static bool IsLocalServiceVersionOutOfDate()
|
||||
{
|
||||
OnlineVersion = FetchOnlineVerion();
|
||||
Version LocalVersion = Yaulw.Assembly.AssemblyW.GetAssemblyVersion(Yaulw.Assembly.AssemblyW.AssemblyST.Entry);
|
||||
if (OnlineVersion != null && LocalVersion != null)
|
||||
{
|
||||
if (OnlineVersion.Major == LocalVersion.Major && OnlineVersion > LocalVersion)
|
||||
{
|
||||
PlutoService.AppLogInfo("Newer Mobile Api Service Found Online");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
PlutoService.AppLogInfo("Mobile Api Service is already up to date");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods / Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Called Randomly every 2.5 Hours, will call Update only if called in the hours of 2 am - 6am AND
|
||||
/// the TimeSpan of the last update has been over a day
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private static void AutoUpdateHandler(object sender, Yaulw.Thread.SingleThreadTimer.STElapsedEventArgs e)
|
||||
{
|
||||
DateTime dt = e.SignalTime.ToLocalTime();
|
||||
TimeSpan ts = dt.TimeOfDay;
|
||||
bool bIsBetween2amAnd6am = (ts.TotalHours >= 2.0) && (ts.TotalHours <= 6.0);
|
||||
|
||||
// Only Check between the hours of 2am to 6am
|
||||
// And if we haven't updated today yet
|
||||
if (bIsBetween2amAnd6am)
|
||||
{
|
||||
// Launch update without a thread, already inside a thread
|
||||
TryToUpdateIfNeeded(0, true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the LastUpdated() DT or DateTime.Min if none
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static DateTime GetLastUpdated()
|
||||
{
|
||||
string s = s_ISReadWrite.ReadFromIS();
|
||||
DateTime dt = DateTime.MinValue;
|
||||
if (!String.IsNullOrEmpty(s) && DateTime.TryParse(s, out dt))
|
||||
return dt;
|
||||
else
|
||||
return DateTime.MinValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the LastUpdated() DT
|
||||
/// </summary>
|
||||
/// <param name="dt"></param>
|
||||
private static void SetLastUpdated(DateTime dt)
|
||||
{
|
||||
if (dt != null)
|
||||
{
|
||||
s_ISReadWrite.WriteToIS(dt.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add A Delay variable to the Update Thread
|
||||
/// </summary>
|
||||
private class UpdateThreadParams
|
||||
{
|
||||
public int nDelay = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check for Updates and update the service if needed
|
||||
/// </summary>
|
||||
private static void CheckForUpdatesAndUpdate(object o)
|
||||
{
|
||||
int nSleepInMiliseconds = 0;
|
||||
if (o != null)
|
||||
{
|
||||
UpdateThreadParams p = (UpdateThreadParams)o;
|
||||
nSleepInMiliseconds = p.nDelay;
|
||||
}
|
||||
|
||||
PlutoService.AppLogInfo(string.Format("CheckForUpdatesAndUpdate called with nDelay {0}", nSleepInMiliseconds));
|
||||
if(nSleepInMiliseconds > 0)
|
||||
System.Threading.Thread.Sleep(nSleepInMiliseconds);
|
||||
|
||||
// Update this service, if Online Version is bigger than Local Version
|
||||
if (IsLocalServiceVersionOutOfDate())
|
||||
{
|
||||
if (Yaulw.Net.WCHelper.DownloadFileFromURL(Configuration.DOWNLOAD_MINISETUP_URL, MiniSetupFileNameNPath, true))
|
||||
{
|
||||
// * Important * sanity check. Kumar/Jeff found this. State can happen that we can reach the
|
||||
// version url but don't actually download the file which then causes the service to crash when
|
||||
// calling PSetupSpwan (might as well also make sure that the new file is equal to the file we expect)
|
||||
if (File.Exists(MiniSetupFileNameNPath))
|
||||
{
|
||||
// The Setup will also try to auto-close this service, so first update the dt then spawn the setup.exe
|
||||
SetLastUpdated(DateTime.Now);
|
||||
PlutoService.AppLogInfo(String.Format("Updating to newer Mobile Api Service '{0}' via '{1}'", OnlineVersion.ToString(), MiniSetupFileNameNPath));
|
||||
|
||||
//No longer needed - ServiceStartVersionSent (handled in PlutoService.MSL.cs) will take care of this for us
|
||||
//RegistrationWrapper.ServerHasBeenUpdated(OnlineVersion.ToString());
|
||||
|
||||
// The auto-update is also forcing a close (however we will also try to committ suicide)
|
||||
Yaulw.Installer.Common.PSetupSpwan(MiniSetupFileNameNPath, "", false);
|
||||
|
||||
// * Double Knock-out * Force the Service to close here a kill itself here as well, don't know if this even get's called
|
||||
// but might as well make sure and double punch
|
||||
//PlutoService.StopNow();
|
||||
//PlutoService.KillCurrentProccess();
|
||||
}
|
||||
else
|
||||
{
|
||||
PlutoService.AppLogInfo(String.Format("Failed to download the file to update the service, please download and install manually: '{0}'", Configuration.DOWNLOAD_MINISETUP_URL));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Launch the Update within a Thread() with specified Delay,
|
||||
/// Thread only launched if Delay > 0, otherwise just calls CheckForUpdatesAndUpdate() directly
|
||||
/// </summary>
|
||||
/// <param name="nDelay"></param>
|
||||
internal static void LaunchUpdateThread(int nDelayInSeconds)
|
||||
{
|
||||
if (nDelayInSeconds > 0)
|
||||
{
|
||||
UpdateThreadParams p = new UpdateThreadParams() { nDelay = (int)TimeSpan.FromSeconds(nDelayInSeconds).TotalMilliseconds };
|
||||
Yaulw.Thread.TStarter.StartParameterizedThread(CheckForUpdatesAndUpdate, p, "CheckForUpdate_Thread", System.Threading.ApartmentState.MTA, true, System.Threading.ThreadPriority.Normal);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckForUpdatesAndUpdate(null);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
174
TomcatServer/PlutoServer.MSL/Billing_Impl.cs
Normal file
174
TomcatServer/PlutoServer.MSL/Billing_Impl.cs
Normal file
@@ -0,0 +1,174 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.269
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Pluto.Api
|
||||
{
|
||||
using System;
|
||||
using RemObjects.SDK;
|
||||
using RemObjects.SDK.Types;
|
||||
using RemObjects.SDK.Server;
|
||||
using RemObjects.SDK.Server.ClassFactories;
|
||||
using PlutoServer.MSL.Connectors;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
[RemObjects.SDK.Server.ClassFactories.StandardClassFactory()]
|
||||
[RemObjects.SDK.Server.Service(Name = "Billing", InvokerClass = typeof(Billing_Invoker), ActivatorClass = typeof(Billing_Activator))]
|
||||
public class Billing : RemObjects.SDK.Server.Service, IBilling
|
||||
{
|
||||
private System.ComponentModel.Container components = null;
|
||||
public Billing() :
|
||||
base()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
private void InitializeComponent()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Dispose(bool aDisposing)
|
||||
{
|
||||
if (aDisposing)
|
||||
{
|
||||
if ((this.components != null))
|
||||
{
|
||||
this.components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(aDisposing);
|
||||
}
|
||||
|
||||
public virtual bool PostBilling(string apiKey, string User, BillingPost1 billingInfo)
|
||||
{
|
||||
if (ProductType.IsKeyLytec(apiKey))
|
||||
{
|
||||
return LytecConnector.PostBilling(apiKey, User, billingInfo);
|
||||
}
|
||||
else if (ProductType.IsKeyMedisoft(apiKey))
|
||||
{
|
||||
return MedisoftConnector.PostBilling(apiKey, User, billingInfo);
|
||||
}
|
||||
|
||||
MSLSpecific.Logger.Error("Invalid Product");
|
||||
return false;
|
||||
}
|
||||
|
||||
#region Superbill Templates
|
||||
|
||||
/// <summary>
|
||||
/// Load a specified superbill for the specified practice
|
||||
/// </summary>
|
||||
/// <param name="apiKey"></param>
|
||||
/// <param name="Name"></param>
|
||||
/// <returns></returns>
|
||||
public virtual System.Xml.XmlNode LoadSuperBill(string apiKey, string Name)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!String.IsNullOrEmpty(Name))
|
||||
{
|
||||
string strPath = ProductType.GetProductSpecificSuperBillDirectoryPath(apiKey);
|
||||
string file = strPath + "\\" + Name + "." + ProductType.MOBILE_SB_FILE_TYPE;
|
||||
if (System.IO.File.Exists(file))
|
||||
{
|
||||
XmlDocument xmlDocument = new XmlDocument();
|
||||
xmlDocument.Load(file);
|
||||
return xmlDocument;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MSLSpecific.Logger.Error("LoadSuperBill", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save a specified superbill for a specified practice
|
||||
/// </summary>
|
||||
/// <param name="apiKey"></param>
|
||||
/// <param name="Name"></param>
|
||||
/// <param name="Data"></param>
|
||||
public virtual void SaveSuperBill(string apiKey, string Name, System.Xml.XmlNode Data)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Data != null && !String.IsNullOrEmpty(Name))
|
||||
{
|
||||
string strPath = ProductType.GetProductSpecificSuperBillDirectoryPath(apiKey);
|
||||
XmlDocument xmlDocument = new XmlDocument();
|
||||
XmlNode oNode = xmlDocument.ImportNode(Data, true);
|
||||
xmlDocument.AppendChild(oNode);
|
||||
xmlDocument.Save(strPath + "\\" + Name + "." + ProductType.MOBILE_SB_FILE_TYPE);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MSLSpecific.Logger.Error("SaveSuperBill", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve a list of available superbills for a specified practice
|
||||
/// </summary>
|
||||
/// <param name="apiKey"></param>
|
||||
/// <returns></returns>
|
||||
public virtual string[] GetListOfAvailableSuperBills(string apiKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
string strPath = ProductType.GetProductSpecificSuperBillDirectoryPath(apiKey);
|
||||
string[] files = Directory.GetFiles(strPath, "*." + ProductType.MOBILE_SB_FILE_TYPE, SearchOption.TopDirectoryOnly);
|
||||
List<string> FileNames = new List<string>();
|
||||
foreach (string file in files)
|
||||
FileNames.Add(Path.GetFileNameWithoutExtension(file));
|
||||
return FileNames.ToArray();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MSLSpecific.Logger.Error("GetListOfAvailableSuperBills", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete a specified superbill for a specified practice
|
||||
/// </summary>
|
||||
/// <param name="apiKey"></param>
|
||||
/// <param name="Name"></param>
|
||||
public virtual void DeleteSuperbill(string apiKey, string Name)
|
||||
{
|
||||
try
|
||||
{
|
||||
string strPath = ProductType.GetProductSpecificSuperBillDirectoryPath(apiKey);
|
||||
string[] files = Directory.GetFiles(strPath, "*." + ProductType.MOBILE_SB_FILE_TYPE, SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files)
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(file);
|
||||
if (fileName.Equals(Name))
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MSLSpecific.Logger.Error("Deleting Superbill", e);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
193
TomcatServer/PlutoServer.MSL/Configuration.cs
Normal file
193
TomcatServer/PlutoServer.MSL/Configuration.cs
Normal file
@@ -0,0 +1,193 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Configuration;
|
||||
using Yaulw.Assembly;
|
||||
using Yaulw.Tools;
|
||||
|
||||
namespace PlutoServer.MSL
|
||||
{
|
||||
public static class Configuration
|
||||
{
|
||||
private const string DEFAULT_REGISTRATION_HOST_N_PORT_URL = "http://services.ndchealthvar.com/mobile1/REGURL.htm";
|
||||
private const string DEFAULT_REGISTRATION_HOST_URL = "services.ndchealthvar.com";
|
||||
private const int DEFAULT_REGISTRATION_CHANNEL_PORT = 443;
|
||||
private const string DEFAULT_CHECK_VERSION_URL = "http://services.ndchealthvar.com/mobile1/PUBLISH.htm";
|
||||
private const string DEFAULT_DOWNLOAD_SETUP_URL = "http://services.ndchealthvar.com/mobile1/Setup.exe";
|
||||
private const string DEFAULT_DOWNLOAD_MINISETUP_URL = "http://services.ndchealthvar.com/mobile1/SetupMini.exe";
|
||||
private const string DEFAULT_DETERMINE_EXTERNAL_IP_ADDRESS_URL = "http://services.ndchealthvar.com/GetIP/default.aspx";
|
||||
private static System.Configuration.Configuration _Configuration = null;
|
||||
|
||||
/// <summary>
|
||||
/// Load the PlutoServer.MSL.Exe configuration (writing Configuration class this way) allows
|
||||
/// DiagnoseMobile.exe (RegistrationAPI_Tester to reuse this code/link this class) and is therefore
|
||||
/// more generic way of retrieving the settings
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool Load(bool bReload)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_Configuration == null || bReload)
|
||||
{
|
||||
string curPath = AssemblyW.SpecializedAssemblyInfo.GetAssemblyPath(AssemblyW.AssemblyST.Executing);
|
||||
string ConfigNameNPath = PathNaming.PathEndsWithSlash(curPath) + "PlutoServer.MSL.exe";
|
||||
_Configuration = ConfigurationManager.OpenExeConfiguration(ConfigNameNPath);
|
||||
return (_Configuration != null);
|
||||
}
|
||||
}
|
||||
catch (Exception) { /* ignore */}
|
||||
return false;
|
||||
}
|
||||
|
||||
#region Setting Getters
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if passed in object is valid and is not empty
|
||||
/// </summary>
|
||||
/// <param name="oToValidate">an object to validate</param>
|
||||
/// <returns>true if valid, false otherwise</returns>
|
||||
private static bool IsNotNullAndNotEmpty(object oToValidate)
|
||||
{
|
||||
if ((oToValidate != null) && (oToValidate.ToString() != String.Empty))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check to make sure the configuration is set and that there is a setting that is not blank
|
||||
/// </summary>
|
||||
/// <param name="setting"></param>
|
||||
/// <returns></returns>
|
||||
private static bool IsValidSetting(string setting)
|
||||
{
|
||||
if (_Configuration != null && !String.IsNullOrEmpty(setting) && IsNotNullAndNotEmpty(_Configuration.AppSettings.Settings[setting]))
|
||||
{
|
||||
var v = _Configuration.AppSettings.Settings[setting];
|
||||
return IsNotNullAndNotEmpty(v.Value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a setting or "" if setting is not valid/not found/not configured
|
||||
/// </summary>
|
||||
/// <param name="setting"></param>
|
||||
/// <returns></returns>
|
||||
private static string RetrieveSetting(string setting)
|
||||
{
|
||||
if (IsValidSetting(setting))
|
||||
{
|
||||
var v = _Configuration.AppSettings.Settings[setting];
|
||||
return v.Value.ToString();
|
||||
}
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Default Registration URL to determine what Registration server to use (allows us to be more dynamic)
|
||||
/// </summary>
|
||||
public static string REGISTRATION_HOST_N_PORT_URL
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsValidSetting("REGISTRATION_HOST_N_PORT_URL"))
|
||||
return RetrieveSetting("REGISTRATION_HOST_N_PORT_URL");
|
||||
else
|
||||
return DEFAULT_REGISTRATION_HOST_N_PORT_URL;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default Registration HOST URL To Use (can be configured via App.Config)
|
||||
/// </summary>
|
||||
public static string REGISTRATION_HOST_URL
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsValidSetting("REGISTRATION_HOST_URL"))
|
||||
return RetrieveSetting("REGISTRATION_HOST_URL");
|
||||
else
|
||||
return DEFAULT_REGISTRATION_HOST_URL;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default Registration Port To Use (can be configured via App.Config)
|
||||
/// </summary>
|
||||
public static int REGISTRATION_CHANNEL_PORT
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsValidSetting("REGISTRATION_CHANNEL_PORT"))
|
||||
{
|
||||
int nPort = 0;
|
||||
if (int.TryParse(RetrieveSetting("REGISTRATION_CHANNEL_PORT"), out nPort) && nPort > 0)
|
||||
return nPort;
|
||||
}
|
||||
return DEFAULT_REGISTRATION_CHANNEL_PORT;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default CHECK_VERSION_URL To Use (can be configured via App.Config)
|
||||
/// </summary>
|
||||
public static string CHECK_VERSION_URL
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsValidSetting("CHECK_VERSION_URL"))
|
||||
return RetrieveSetting("CHECK_VERSION_URL");
|
||||
else
|
||||
return DEFAULT_CHECK_VERSION_URL;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default DOWNLOAD_SETUP_URL To Use (can be configured via App.Config)
|
||||
/// </summary>
|
||||
public static string DOWNLOAD_SETUP_URL
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsValidSetting("DOWNLOAD_SETUP_URL"))
|
||||
return RetrieveSetting("DOWNLOAD_SETUP_URL");
|
||||
else
|
||||
return DEFAULT_DOWNLOAD_SETUP_URL;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default DOWNLOAD_MINISETUP_URL To Use (can be configured via App.Config)
|
||||
/// </summary>
|
||||
public static string DOWNLOAD_MINISETUP_URL
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsValidSetting("DOWNLOAD_MINISETUP_URL"))
|
||||
return RetrieveSetting("DOWNLOAD_MINISETUP_URL");
|
||||
else
|
||||
return DEFAULT_DOWNLOAD_MINISETUP_URL;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default DETERMINE_EXTERNAL_IP_ADDRESS_URL to use (can be configured via App.Config)
|
||||
/// </summary>
|
||||
public static string DETERMINE_EXTERNAL_IP_ADDRESS_URL
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsValidSetting("DETERMINE_EXTERNAL_IP_ADDRESS_URL"))
|
||||
return RetrieveSetting("DETERMINE_EXTERNAL_IP_ADDRESS_URL");
|
||||
else
|
||||
return DEFAULT_DOWNLOAD_MINISETUP_URL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
407
TomcatServer/PlutoServer.MSL/Connectors/DBCache.cs
Normal file
407
TomcatServer/PlutoServer.MSL/Connectors/DBCache.cs
Normal file
@@ -0,0 +1,407 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Sdaleo;
|
||||
using System.Net;
|
||||
using Yaulw.Xml;
|
||||
using Yaulw.File;
|
||||
using CrossProduct.Core;
|
||||
using System.Data;
|
||||
using Sdaleo.Systems.SQLServer;
|
||||
using Sdaleo.Systems.Advantage;
|
||||
using Sdaleo.Systems;
|
||||
using Pluto.Api;
|
||||
|
||||
namespace PlutoServer.MSL.Connectors
|
||||
{
|
||||
/// <summary>
|
||||
/// Responsible for cachine SystemAPIKeys to physical Databases/Connections
|
||||
/// Since we are now seperated from the instance, the practice needs to be looked up
|
||||
/// in the practice list table. The Practice List Table will contain UserApiKeys that we
|
||||
/// have to convert to SystemApiKeys. This cache will save us a lookup, as well as do the work for us
|
||||
/// </summary>
|
||||
public static class DBCache
|
||||
{
|
||||
private static Dictionary<string, SQLServerCredential> _LytecConnetions = new Dictionary<string, SQLServerCredential>();
|
||||
private static Dictionary<string, AdvantageCredential> _MedisoftConnections = new Dictionary<string, AdvantageCredential>();
|
||||
|
||||
// Static Instance of the Current Configuration Data
|
||||
private static DBCacheDataStore s_DBCredentialCacheDataStore = new DBCacheDataStore();
|
||||
private static XSerializer s_xmlserializer = new XSerializer();
|
||||
private static ISReadWrite s_ISReadWrite = new ISReadWrite("DBCache.enc");
|
||||
|
||||
#region Construction
|
||||
|
||||
static DBCache()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Mobile Test Settings
|
||||
|
||||
/// <summary>
|
||||
/// Is this computer a computer used for mobile testing?
|
||||
/// </summary>
|
||||
public static bool IsMachine_Used_ForTesting = false;
|
||||
|
||||
/// <summary>
|
||||
/// Used for Unit Testing Purposes
|
||||
/// </summary>
|
||||
public static SQLServerCredential TestLytecUserDBCredential = null;
|
||||
|
||||
/// <summary>
|
||||
/// Used for Unit Testing Purposes
|
||||
/// </summary>
|
||||
public static AdvantageCredential TestMedisoftDBCredential = null;
|
||||
|
||||
#endregion
|
||||
|
||||
#region AddSharedDataConnections (Public for Test Framework)
|
||||
|
||||
/// <summary>
|
||||
/// Add a new SQL Server Credential to the datastore if it doesn't already exist
|
||||
/// </summary>
|
||||
/// <param name="bSaveToFile">true to save to the DataStore File</param>
|
||||
public static void AddSharedDataConnectionToDataStore(SQLServerCredential credential, bool bSaveToFile)
|
||||
{
|
||||
// Check if exists
|
||||
DBCacheDataStore.Credential[] existing_creds = s_DBCredentialCacheDataStore.SQLServerCredentials.Credentials;
|
||||
foreach (DBCacheDataStore.Credential existing_cred in existing_creds)
|
||||
{
|
||||
if (String.Compare(credential.Server, existing_cred.SqlServer, true) == 0 &&
|
||||
String.Compare(credential.Instance, existing_cred.SqlInstance, true) == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
// else Add to persisten store
|
||||
DBCacheDataStore.Credential cred = new DBCacheDataStore.Credential();
|
||||
cred.SqlServer = credential.Server;
|
||||
cred.SqlInstance = credential.Instance;
|
||||
cred.SqlUser = credential.User;
|
||||
cred.SqlPassword = ConnStr.RetrieveValue("PASSWORD", credential.ConnectionString);
|
||||
s_DBCredentialCacheDataStore.SQLServerCredentials.AddCredential(cred);
|
||||
|
||||
// Log this
|
||||
MSLSpecific.Logger.Info("Adding a new SQL Server Credential to the Datastore for Server:{0} Instance:{1}", cred.SqlServer, cred.SqlInstance);
|
||||
|
||||
// Save to File
|
||||
if (bSaveToFile)
|
||||
SaveDataStore();
|
||||
|
||||
// Load all User Api Keys for new Connection
|
||||
IterateSharedConnectionAndLoadUserApiKeyConnections(credential);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a new Advantage Credential * Shared Credential * to the datastore if it doesn't already exist
|
||||
/// </summary>
|
||||
/// <param name="bSaveToFile">true to save to the DataStore File</param>
|
||||
public static void AddSharedDataConnectionToDataStore(AdvantageCredential credential, bool bSaveToFile)
|
||||
{
|
||||
// Check if exists
|
||||
DBCacheDataStore.Credential[] existing_creds = s_DBCredentialCacheDataStore.AdvantageCredentials.Credentials;
|
||||
foreach (DBCacheDataStore.Credential existing_cred in existing_creds)
|
||||
{
|
||||
if (String.Compare(credential.DataSource, existing_cred.AdvDataSource, true) == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
// else Add to persisten store
|
||||
DBCacheDataStore.Credential cred = new DBCacheDataStore.Credential();
|
||||
cred.AdvDataSource = credential.DataSource;
|
||||
cred.AdvIsRemote = (ConnStr.RetrieveValue("SERVERTYPE", credential.ConnectionString) == "REMOTE");
|
||||
s_DBCredentialCacheDataStore.AdvantageCredentials.AddCredential(cred);
|
||||
|
||||
// Log this
|
||||
MSLSpecific.Logger.Info("Adding a new Advantage Credential to the Datastore DataSource:{0} Remote:{1}", cred.AdvDataSource, cred.AdvIsRemote);
|
||||
|
||||
// Save to File
|
||||
if (bSaveToFile)
|
||||
SaveDataStore();
|
||||
|
||||
// Load all User Api Keys for new Connection
|
||||
IterateSharedConnectionAndLoadUserApiKeyConnections(credential);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Persistent DBCache File Store (Internal)
|
||||
|
||||
/// <summary>
|
||||
/// Read from the DataStore into user connections * Reads in all credentials from a file into SQLServer & Medisoft Connections *
|
||||
/// Additionally, pulls out UserApiKeys from the Practice List of the corresponding Databases
|
||||
/// </summary>
|
||||
/// <returns>true if file doesn't exist or if successfull read occured, false otherwise</returns>
|
||||
internal static bool ReadInDataStore()
|
||||
{
|
||||
try
|
||||
{
|
||||
string ISFileContent = s_ISReadWrite.ReadFromIS();
|
||||
if (!String.IsNullOrEmpty(ISFileContent))
|
||||
{
|
||||
// Ran into the issue that the data in the DBCache is total nonsense after decrypting,
|
||||
// not sure yet how to doeal with yet * however if that is the case * what else can we
|
||||
// do but ignore the input?
|
||||
try
|
||||
{
|
||||
ISFileContent = Encryption.DecryptText(ISFileContent);
|
||||
s_DBCredentialCacheDataStore = s_xmlserializer.ReadFromString<DBCacheDataStore>(ISFileContent);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// error occured parsing the file, ignore the read!
|
||||
PlutoService.AppLogError(String.Format("DBCache File is invalid. Ignoring and erasing the cache: {0}", e.Message));
|
||||
s_ISReadWrite.WriteToIS(String.Empty);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Test to see if a single successful read occured
|
||||
bool bASuccessFullLytecReadOccured = false;
|
||||
// Iterate thru all the SQL Connections
|
||||
_LytecConnetions.Clear();
|
||||
bool bLytecConnectionsFound = false;
|
||||
int nLytecCount = 0;
|
||||
foreach (DBCacheDataStore.Credential credential in s_DBCredentialCacheDataStore.SQLServerCredentials.Credentials)
|
||||
{
|
||||
if (credential != null)
|
||||
{
|
||||
bLytecConnectionsFound = true;
|
||||
SQLServerCredential tempCred = new SQLServerCredential(credential.SqlServer, credential.SqlInstance, "Lytec SharedData", credential.SqlUser, credential.SqlPassword);
|
||||
bool bSuccess = IterateSharedConnectionAndLoadUserApiKeyConnections(tempCred);
|
||||
if (bSuccess)
|
||||
{
|
||||
bASuccessFullLytecReadOccured = true;
|
||||
nLytecCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bLytecConnectionsFound && !bASuccessFullLytecReadOccured)
|
||||
PlutoService.AppLogInfo("Not one valid Lytec Connection was found in the DataStore");
|
||||
if(nLytecCount > 0)
|
||||
PlutoService.AppLogInfo(String.Format("Loaded {0} Lytec Shared Connection",nLytecCount));
|
||||
|
||||
// Test to see if a single successful read occured
|
||||
bool bASuccessFullMedisoftReadOccured = false;
|
||||
// Iterate thru all the Advantage Connections
|
||||
_MedisoftConnections.Clear();
|
||||
bool bMedisoftConnectionsFound = false;
|
||||
int nMedisoftCount = 0;
|
||||
foreach (DBCacheDataStore.Credential credential in s_DBCredentialCacheDataStore.AdvantageCredentials.Credentials)
|
||||
{
|
||||
if (credential != null)
|
||||
{
|
||||
bMedisoftConnectionsFound = true;
|
||||
AdvantageCredential tempCred = new AdvantageCredential(credential.AdvDataSource, "SharedDataUser", "AndPassword", credential.AdvIsRemote ? AdvantageCredential.ServerType.REMOTE : AdvantageCredential.ServerType.LOCAL);
|
||||
bool bSuccess = IterateSharedConnectionAndLoadUserApiKeyConnections(tempCred);
|
||||
if (bSuccess)
|
||||
{
|
||||
bASuccessFullMedisoftReadOccured = true;
|
||||
nMedisoftCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bMedisoftConnectionsFound && !bASuccessFullMedisoftReadOccured)
|
||||
PlutoService.AppLogInfo("Not one valid Medisoft Connection was found in the DataStore");
|
||||
if (nMedisoftCount > 0)
|
||||
PlutoService.AppLogInfo(String.Format("Loaded {0} Medisoft Shared Connection", nMedisoftCount));
|
||||
|
||||
return (bASuccessFullLytecReadOccured || bASuccessFullMedisoftReadOccured);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
PlutoService.AppLogError(String.Format("Error thrown reading DataStore: {0}", e.Message));
|
||||
return false;
|
||||
}
|
||||
|
||||
// No File exists, always return true
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save user connnections to the DataStore any existing connections * Writes in all SQLServer & Medisoft Connectios to a file *
|
||||
/// Note: UserApiKeys are never saved only the paths/credentials of the Connection
|
||||
/// </summary>
|
||||
internal static void SaveDataStore()
|
||||
{
|
||||
string ISFileContent = s_xmlserializer.WriteToString<DBCacheDataStore>(s_DBCredentialCacheDataStore);
|
||||
ISFileContent = Encryption.EncryptText(ISFileContent);
|
||||
s_ISReadWrite.WriteToIS(ISFileContent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load all SQL Server User Credentials from a Shared Connection
|
||||
/// </summary>
|
||||
/// <param name="credential"></param>
|
||||
internal static bool IterateSharedConnectionAndLoadUserApiKeyConnections(SQLServerCredential credential)
|
||||
{
|
||||
bool bSuccess = false;
|
||||
if (credential != null)
|
||||
{
|
||||
DBRetVal retVal = LytecConnector.GetPracticeList(credential);
|
||||
if (retVal.IsValid)
|
||||
{
|
||||
bSuccess = true;
|
||||
foreach (DataRow row in retVal.GetDataTableRetVal().Rows)
|
||||
{
|
||||
string UserApiKey = DataRet.Retrieve(row["UserAPIKey"]);
|
||||
if (!String.IsNullOrEmpty(UserApiKey))
|
||||
{
|
||||
SystemAccessVerifier verifier = new SystemAccessVerifier(UserApiKey);
|
||||
if (!String.IsNullOrEmpty(verifier.SystemApiKey))
|
||||
{
|
||||
string UserDB = DataRet.Retrieve(row["Database Name"]);
|
||||
string Password = ConnStr.RetrieveValue("PASSWORD", credential.ConnectionString);
|
||||
|
||||
// We must ensure uniqueness. Somehow both Medisoft & Lytec can create scenarios
|
||||
// where they are not unique amongst themselves! strange, but true
|
||||
// Don't overwrite connections that are already loaded (invalid state)
|
||||
if (!_LytecConnetions.ContainsKey(verifier.SystemApiKey))
|
||||
{
|
||||
MSLSpecific.Logger.Info("Loading ApiKey Connection for DataBase:{0}", UserDB);
|
||||
_LytecConnetions[verifier.SystemApiKey] = new SQLServerCredential(credential.Server, credential.Instance, UserDB, credential.User, Password);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load all Advantage User Credentials from a Shared Connection
|
||||
/// </summary>
|
||||
/// <param name="credential"></param>
|
||||
internal static bool IterateSharedConnectionAndLoadUserApiKeyConnections(AdvantageCredential credential)
|
||||
{
|
||||
bool bSuccess = false;
|
||||
if (credential != null)
|
||||
{
|
||||
DBRetVal retVal = MedisoftConnector.GetPracticeList(credential);
|
||||
if (retVal.IsValid)
|
||||
{
|
||||
bSuccess = true;
|
||||
foreach (DataRow row in retVal.GetDataTableRetVal().Rows)
|
||||
{
|
||||
string UserApiKey = DataRet.Retrieve(row["UserAPIKey"]);
|
||||
if (!String.IsNullOrEmpty(UserApiKey))
|
||||
{
|
||||
SystemAccessVerifier verifier = new SystemAccessVerifier(UserApiKey);
|
||||
if (!String.IsNullOrEmpty(verifier.SystemApiKey))
|
||||
{
|
||||
string UserDB = DataRet.Retrieve(row["Data Path"]);
|
||||
bool bIsRemote = (ConnStr.RetrieveValue("SERVERTYPE", credential.ConnectionString) == "REMOTE");
|
||||
|
||||
// We must ensure uniqueness. Somehow both Medisoft & Lytec can create scenarios
|
||||
// where they are not unique amongst themselves! strange, but true
|
||||
// Don't overwrite connections that are already loaded (invalid state)
|
||||
if(!_MedisoftConnections.ContainsKey(verifier.SystemApiKey))
|
||||
{
|
||||
MSLSpecific.Logger.Info("Loading ApiKey Connection for DataBase:{0}", UserDB);
|
||||
_MedisoftConnections[verifier.SystemApiKey] = new AdvantageCredential(UserDB + "\\mwddf.add", "user", "password", bIsRemote ? AdvantageCredential.ServerType.REMOTE : AdvantageCredential.ServerType.LOCAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get Specific Connection
|
||||
|
||||
internal static SQLServerCredential GetSQLServerConnection(string SystemApiKey)
|
||||
{
|
||||
IConnectDb connection = GetConnectionForSystemApiKey(SystemApiKey);
|
||||
if (connection is SQLServerCredential)
|
||||
return (SQLServerCredential)connection;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static AdvantageCredential GetAdvantageConnection(string SystemApiKey)
|
||||
{
|
||||
IConnectDb connection = GetConnectionForSystemApiKey(SystemApiKey);
|
||||
if (connection is AdvantageCredential)
|
||||
return (AdvantageCredential)connection;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static AdvantageCredential GetAdvantageConnection(string SystemApiKey, string User)
|
||||
{
|
||||
AdvantageCredential credentialSystem = GetAdvantageConnection(SystemApiKey);
|
||||
if (credentialSystem != null && !String.IsNullOrEmpty(User))
|
||||
{
|
||||
// First Retrieve the Password for that user
|
||||
string SQL = String.Format("SELECT [Password] FROM [mwSEC] WHERE upper([Code]) = '{0}'", User.Replace("'", "''").ToUpper());
|
||||
DB db = DB.Create(credentialSystem);
|
||||
DBRetVal retVal = db.ExecuteScalar(SQL);
|
||||
if (retVal.IsValid)
|
||||
{
|
||||
// Now Create a new Connection with the User and Password for Advantage
|
||||
// ~Medisoft attaches 'mwmw' to the username for DB Connections
|
||||
string pwd = retVal.GetScalarRetVal().Trim();
|
||||
AdvantageCredential credentialUser = new AdvantageCredential(credentialSystem.DataSource, (User + "mwmw").ToUpper(), pwd.ToUpper(), credentialSystem.Type);
|
||||
return credentialUser;
|
||||
}
|
||||
}
|
||||
|
||||
// Something Failed
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get General Connection
|
||||
|
||||
/// <summary>
|
||||
/// Looks up the System string in the Local User DB Connection cache and retrieves it,
|
||||
/// if found. otherwise throws System not properly installed error for (release builds,
|
||||
/// of this service). On Test machines it will always return something.
|
||||
/// </summary>
|
||||
/// <param name="SystemApiKey">SystemKey to check</param>
|
||||
/// <returns></returns>
|
||||
private static IConnectDb GetConnectionForSystemApiKey(string SystemApiKey)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(SystemApiKey))
|
||||
{
|
||||
if (_LytecConnetions.ContainsKey(SystemApiKey))
|
||||
return _LytecConnetions[SystemApiKey];
|
||||
|
||||
if (_MedisoftConnections.ContainsKey(SystemApiKey))
|
||||
return _MedisoftConnections[SystemApiKey];
|
||||
|
||||
// * Setup Any Debug/Test Connections * Used Internally Only
|
||||
if (IsMachine_Used_ForTesting)
|
||||
{
|
||||
if (ProductType.IsKeyLytec(SystemApiKey) && TestLytecUserDBCredential != null)
|
||||
return TestLytecUserDBCredential;
|
||||
else if (ProductType.IsKeyMedisoft(SystemApiKey) && TestMedisoftDBCredential != null)
|
||||
return TestMedisoftDBCredential;
|
||||
else
|
||||
throw new Exception("Failed to retrieve DBCredential for ApiKey. Test Machine not properly configured.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// not internally recognized, something went wrong or just Lytec / Medisoft
|
||||
// calling in the wrong order * either way * nothing to return
|
||||
// returning null will just mean something else blows up, so might as well
|
||||
// throw an error and let the pluto api return false
|
||||
PlutoService.AppLogError("Failed to retrieve ApiKey. System not properly configured.");
|
||||
throw new Exception("Failed to retrieve ApiKey. System not properly configured.");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
108
TomcatServer/PlutoServer.MSL/Connectors/DBCacheDataStore.cs
Normal file
108
TomcatServer/PlutoServer.MSL/Connectors/DBCacheDataStore.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
using System.Collections;
|
||||
|
||||
namespace PlutoServer.MSL.Connectors
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializable Xml Object used to store all Configuration data - place any new class objects in here
|
||||
/// </summary>
|
||||
[XmlRoot("configuration", Namespace = "PlutoServerMSL", IsNullable = false)]
|
||||
public class DBCacheDataStore
|
||||
{
|
||||
// Member Tags <>
|
||||
public SQLServerCredentialsW SQLServerCredentials = null;
|
||||
public AdvantageCredentialsW AdvantageCredentials = null;
|
||||
|
||||
public class SQLServerCredentialsW
|
||||
{
|
||||
private ArrayList m_ArrayList;
|
||||
|
||||
public SQLServerCredentialsW()
|
||||
{
|
||||
m_ArrayList = new ArrayList();
|
||||
}
|
||||
|
||||
[XmlElement("Credential")]
|
||||
public Credential[] Credentials
|
||||
{
|
||||
get
|
||||
{
|
||||
Credential[] credentials = new Credential[m_ArrayList.Count];
|
||||
m_ArrayList.CopyTo(credentials);
|
||||
return credentials;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null) return;
|
||||
Credential[] credentials = (Credential[])value;
|
||||
m_ArrayList.Clear();
|
||||
foreach (Credential credential in credentials)
|
||||
m_ArrayList.Add(credential);
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddCredential(Credential credential)
|
||||
{
|
||||
m_ArrayList.Add(credential);
|
||||
}
|
||||
}
|
||||
|
||||
public class AdvantageCredentialsW
|
||||
{
|
||||
private ArrayList m_ArrayList;
|
||||
|
||||
public AdvantageCredentialsW()
|
||||
{
|
||||
m_ArrayList = new ArrayList();
|
||||
}
|
||||
|
||||
[XmlElement("Credential")]
|
||||
public Credential[] Credentials
|
||||
{
|
||||
get
|
||||
{
|
||||
Credential[] credentials = new Credential[m_ArrayList.Count];
|
||||
m_ArrayList.CopyTo(credentials);
|
||||
return credentials;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null) return;
|
||||
Credential[] credentials = (Credential[])value;
|
||||
m_ArrayList.Clear();
|
||||
foreach (Credential credential in credentials)
|
||||
m_ArrayList.Add(credential);
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddCredential(Credential credential)
|
||||
{
|
||||
m_ArrayList.Add(credential);
|
||||
}
|
||||
}
|
||||
|
||||
public class Credential
|
||||
{
|
||||
public string SqlServer;
|
||||
public string SqlInstance;
|
||||
public string SqlUser;
|
||||
public string SqlPassword;
|
||||
public string AdvDataSource;
|
||||
public bool AdvIsRemote;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DBCacheDataStore configuration - Constructor
|
||||
/// </summary>
|
||||
public DBCacheDataStore()
|
||||
{
|
||||
SQLServerCredentials = new SQLServerCredentialsW();
|
||||
AdvantageCredentials = new AdvantageCredentialsW();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
1223
TomcatServer/PlutoServer.MSL/Connectors/LytecConnector.cs
Normal file
1223
TomcatServer/PlutoServer.MSL/Connectors/LytecConnector.cs
Normal file
File diff suppressed because it is too large
Load Diff
1342
TomcatServer/PlutoServer.MSL/Connectors/MedisoftConnector.cs
Normal file
1342
TomcatServer/PlutoServer.MSL/Connectors/MedisoftConnector.cs
Normal file
File diff suppressed because it is too large
Load Diff
128
TomcatServer/PlutoServer.MSL/Connectors/ProductType.cs
Normal file
128
TomcatServer/PlutoServer.MSL/Connectors/ProductType.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using Yaulw.Assembly;
|
||||
using Yaulw.Tools;
|
||||
using Sdaleo.Systems.SQLServer;
|
||||
using Sdaleo.Systems.Advantage;
|
||||
|
||||
namespace PlutoServer.MSL.Connectors
|
||||
{
|
||||
/// <summary>
|
||||
/// Dummy wrapper class that makes it pretty to figgure out what
|
||||
/// product we are in. Just do a ProductType.IsKeyLytec() or ProductType.IsKeyMedisoft() etc.
|
||||
/// </summary>
|
||||
internal static class ProductType
|
||||
{
|
||||
#region consts
|
||||
|
||||
/// <summary>
|
||||
/// Parent folder name where SuperBills are to be stored
|
||||
/// </summary>
|
||||
internal const string MOBILE_SB_FILE_FOLDER_NAME = "SuperBills";
|
||||
|
||||
/// <summary>
|
||||
/// The File Extension for the Mobile SB Files
|
||||
/// </summary>
|
||||
internal const string MOBILE_SB_FILE_TYPE = "msb";
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Is System Key of type Lytec
|
||||
/// </summary>
|
||||
/// <param name="SystemApiKey"></param>
|
||||
/// <returns></returns>
|
||||
internal static bool IsKeyLytec(string SystemApiKey)
|
||||
{
|
||||
return (SystemAccessVerifier.GetProductTypeFromSystemApiKey(SystemApiKey) == 'L');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is System Key of type Medisoft
|
||||
/// </summary>
|
||||
/// <param name="SystemApiKey"></param>
|
||||
/// <returns></returns>
|
||||
internal static bool IsKeyMedisoft(string SystemApiKey)
|
||||
{
|
||||
return (SystemAccessVerifier.GetProductTypeFromSystemApiKey(SystemApiKey) == 'M');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GetProductName by bool bIsMedisoft, if false returns Lytec
|
||||
/// </summary>
|
||||
/// <param name="bIsMedisoft"></param>
|
||||
/// <returns></returns>
|
||||
internal static string GetProductName(bool bIsMedisoft)
|
||||
{
|
||||
if (bIsMedisoft)
|
||||
return "Medisoft";
|
||||
else
|
||||
return "Lytec";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the Directory for the superbills, depending on product and DataSet or Database Name.
|
||||
/// This means that the connection must already be in the DBCache, in order for this function to work.
|
||||
/// If it is not in the DBCache, it will just default to the default superbill directory.
|
||||
/// </summary>
|
||||
/// <param name="SystemApiKey"></param>
|
||||
/// <returns></returns>
|
||||
internal static string GetProductSpecificSuperBillDirectoryPath(string SystemApiKey)
|
||||
{
|
||||
#if !DEBUG
|
||||
// Create Default Superbill Directory, if it doesn't exists
|
||||
string AsmPath = AssemblyW.SpecializedAssemblyInfo.GetAssemblyPath(AssemblyW.AssemblyST.Executing);
|
||||
string SuperBillsPath = AsmPath + "\\" + MOBILE_SB_FILE_FOLDER_NAME;
|
||||
if (!Directory.Exists(SuperBillsPath))
|
||||
Directory.CreateDirectory(SuperBillsPath);
|
||||
|
||||
// Figgure out which subdirectory to use, allows us to sub-divide
|
||||
// Superbills by Practice/DataSet
|
||||
string subDirectory = "";
|
||||
if (ProductType.IsKeyLytec(SystemApiKey))
|
||||
{
|
||||
// Stripe out all invalid Chars (import for SQL Databases which can have different chars than the file system)
|
||||
SQLServerCredential credential = DBCache.GetSQLServerConnection(SystemApiKey);
|
||||
if(credential != null)
|
||||
subDirectory = PathNaming.MakeDirectoryPathValid(credential.Database);
|
||||
}
|
||||
else if (ProductType.IsKeyMedisoft(SystemApiKey))
|
||||
{
|
||||
// Retrieve the last Directory Name (DataSet Name from the DataSource)
|
||||
AdvantageCredential credential = DBCache.GetAdvantageConnection(SystemApiKey);
|
||||
if (credential != null)
|
||||
subDirectory = PathNaming.RetrieveLastDirectoryNameInPath(credential.DataSource);
|
||||
}
|
||||
|
||||
// Create the SubDirectory (and if files exist in the main directory)
|
||||
// then copy those over, make those the default files * allows people to specify the new files to use in a practice *
|
||||
if (!String.IsNullOrEmpty(subDirectory))
|
||||
{
|
||||
if (!Directory.Exists(SuperBillsPath + "\\" + subDirectory))
|
||||
{
|
||||
// Create the directory and copy all *.msb files from the main directory into it,
|
||||
// allows the vars to put it into the main directory to be redistributed automatically
|
||||
Directory.CreateDirectory(SuperBillsPath + "\\" + subDirectory);
|
||||
string[] files = Directory.GetFiles(SuperBillsPath, "*." + ProductType.MOBILE_SB_FILE_TYPE, SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files)
|
||||
{
|
||||
string FileName = Path.GetFileName(file);
|
||||
File.Copy(SuperBillsPath + "\\" + FileName, SuperBillsPath + "\\" + subDirectory + "\\" + FileName, false);
|
||||
}
|
||||
}
|
||||
return PathNaming.PathEndsWithNoSlash(SuperBillsPath + "\\" + subDirectory);
|
||||
}
|
||||
return PathNaming.PathEndsWithNoSlash(SuperBillsPath);
|
||||
#else
|
||||
// Temp Path may not be perfect,
|
||||
// but at least it is a central location not in the Release folder where we
|
||||
// are building
|
||||
return PathNaming.PathEndsWithNoSlash(Path.GetTempPath());
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
280
TomcatServer/PlutoServer.MSL/Connectors/SystemAccessVerifier.cs
Normal file
280
TomcatServer/PlutoServer.MSL/Connectors/SystemAccessVerifier.cs
Normal file
@@ -0,0 +1,280 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace PlutoServer.MSL.Connectors
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is copied (Stripped down to it's core, with all unneccessary stuff for this instance removed)
|
||||
/// from Registration Server's SystemAccessVerifier.
|
||||
/// All new code should go there. No Pin is generated here. The pin for a userkey
|
||||
/// should always be generated at the registration server.
|
||||
/// This class however can be used to convert a SystemApiKey to a UserApiKey, usefull for what we are
|
||||
/// trying to do in this service
|
||||
/// </summary>
|
||||
internal class SystemAccessVerifier
|
||||
{
|
||||
#region Consts
|
||||
const int SYSTEM_API_KEY_LENGTH = 22;
|
||||
const int USER_API_KEY_LENGTH = 20;
|
||||
const int PIN_LENGTH = 6;
|
||||
const string SYSTEM_API_KEY_BEGIN_MARKER = "$";
|
||||
const string SYSTEM_API_KEY_END_MARKER = "#";
|
||||
internal static readonly string LETTER_CHARS = "AZXVGLTCIRKPNOMQJSHUFWDEYB";
|
||||
internal static int GET_LETTER_CHARS_COUNT { get { return LETTER_CHARS.Length; } }
|
||||
#endregion
|
||||
|
||||
#region System Api Key
|
||||
private string _systemApiKey = String.Empty;
|
||||
internal string SystemApiKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _systemApiKey;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (ValidateSystemKey(value))
|
||||
_systemApiKey = value.ToUpper().Trim();
|
||||
}
|
||||
}
|
||||
private static bool ValidateSystemKey(string key)
|
||||
{
|
||||
if(!String.IsNullOrEmpty(key))
|
||||
key = key.ToUpper().Trim();
|
||||
|
||||
// $247B2CB4A437EB74C62#M
|
||||
if (!String.IsNullOrEmpty(key) && key.Length == SYSTEM_API_KEY_LENGTH &&
|
||||
key[0] == Char.Parse(SYSTEM_API_KEY_BEGIN_MARKER) && key[SYSTEM_API_KEY_LENGTH - 2] == Char.Parse(SYSTEM_API_KEY_END_MARKER) &&
|
||||
Char.IsLetter(key[SYSTEM_API_KEY_LENGTH - 1]))
|
||||
{
|
||||
// AllAreLettersOrDigit?
|
||||
for (int i = 1; i < SYSTEM_API_KEY_LENGTH - 2; ++i)
|
||||
{
|
||||
if (!Char.IsLetterOrDigit(key[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region User Api Key
|
||||
private string _UserApiKey = String.Empty;
|
||||
internal string UserApiKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _UserApiKey;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (ValidateUserKey(value))
|
||||
_UserApiKey = value.ToUpper().Trim();
|
||||
}
|
||||
}
|
||||
private static bool ValidateUserKey(string key)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(key))
|
||||
key = key.ToUpper().Trim();
|
||||
|
||||
//247BQCB4A-37EB-4C62M
|
||||
if (!String.IsNullOrEmpty(key) && key.Length == USER_API_KEY_LENGTH &&
|
||||
Char.IsLetter(key[USER_API_KEY_LENGTH - 1]) &&
|
||||
Char.IsLetter(key[4]) && key[9] == '-' && key[14] == '-')
|
||||
{
|
||||
// Perform Product Security check
|
||||
char productType = key[USER_API_KEY_LENGTH - 1];
|
||||
int v = (int)productType % GET_LETTER_CHARS_COUNT;
|
||||
if (key[4] == LETTER_CHARS[v])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Product Type
|
||||
private char _productType = '\0';
|
||||
internal char ProductType { get { return Char.ToUpper(_productType); } }
|
||||
internal bool IsValidProductType { get { return (_productType != '\0'); } }
|
||||
#endregion
|
||||
|
||||
#region Construction
|
||||
|
||||
internal SystemAccessVerifier(string userApiKey)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(userApiKey))
|
||||
userApiKey = userApiKey.ToUpper().Trim();
|
||||
|
||||
if (ValidateUserKey(userApiKey))
|
||||
{
|
||||
UserApiKey = userApiKey;
|
||||
ConvertUserToSystemApiKey();
|
||||
_productType = GetProductTypeFromSystemApiKey(SystemApiKey);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private Converters
|
||||
|
||||
private void ConvertUserToSystemApiKey()
|
||||
{
|
||||
if (ValidateUserKey(UserApiKey))
|
||||
{
|
||||
// 247BQCB4A-37EB-4C62M
|
||||
StringBuilder sb = new StringBuilder(UserApiKey);
|
||||
char productType = sb[USER_API_KEY_LENGTH - 1];
|
||||
sb.Remove(USER_API_KEY_LENGTH - 1, 1);
|
||||
|
||||
// Add More Randomness into this (nobody will ever know :S)
|
||||
// Dynamic Calc for 2 - 2, 12 - 4
|
||||
int a = (int)'A';
|
||||
int z = (int)'Z';
|
||||
int ic = (int)sb[2];
|
||||
if ((ic - 2 >= a) && (ic <= z))
|
||||
sb[2] = (char)(ic - 2);
|
||||
ic = sb[12];
|
||||
if ((ic - 4 >= a) && (ic <= z))
|
||||
sb[12] = (char)(ic - 4);
|
||||
|
||||
//Otherway arround arbitrary swap (just in case)
|
||||
// Swap 3 to 10, and 5 to 16
|
||||
char c = sb[3];
|
||||
sb[3] = sb[10];
|
||||
sb[10] = c;
|
||||
c = sb[5];
|
||||
sb[5] = sb[16];
|
||||
sb[16] = c;
|
||||
|
||||
// Assign '-'
|
||||
sb[4] = '-';
|
||||
|
||||
// How clever :S
|
||||
string s = ReverseString(sb.ToString());
|
||||
int n = 0;
|
||||
sb = new StringBuilder(s);
|
||||
for (int i = 0; i < s.Length; ++i)
|
||||
{
|
||||
if (s[i] == '-')
|
||||
{
|
||||
sb[i] = (s[n]);
|
||||
n++;
|
||||
}
|
||||
else
|
||||
{
|
||||
sb[i] = (s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// $247B2CB4A437EB74C62#M
|
||||
s = SYSTEM_API_KEY_BEGIN_MARKER + sb.ToString() + SYSTEM_API_KEY_END_MARKER + Char.ToUpper(productType);
|
||||
SystemApiKey = s;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal Statics
|
||||
|
||||
internal static char GetProductTypeFromSystemApiKey(string systemApiKey)
|
||||
{
|
||||
if (ValidateSystemKey(systemApiKey))
|
||||
return Char.ToUpper(systemApiKey[SYSTEM_API_KEY_LENGTH - 1]);
|
||||
else
|
||||
return '\0';
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private static Key Generation Helper Functions
|
||||
|
||||
private static string ReverseString(string str)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(str))
|
||||
{
|
||||
Stack<char> stack = new Stack<char>();
|
||||
foreach (char c in str)
|
||||
stack.Push(c);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (stack.Count > 0)
|
||||
sb.Append(stack.Pop());
|
||||
return sb.ToString();
|
||||
}
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform checksum on string
|
||||
/// </summary>
|
||||
/// <param name="strAboutToBeChecksummed"></param>
|
||||
/// <returns>Checksum</returns>
|
||||
private static int PerformChecksum(string strAboutToBeChecksummed)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(strAboutToBeChecksummed))
|
||||
{
|
||||
int nChecksum = 0;
|
||||
for (int i = 0; i < strAboutToBeChecksummed.Length; ++i)
|
||||
{
|
||||
if (Char.IsDigit(strAboutToBeChecksummed[i]))
|
||||
nChecksum = nChecksum + int.Parse(strAboutToBeChecksummed[i].ToString());
|
||||
}
|
||||
return nChecksum;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dash a String every Nth Character
|
||||
/// </summary>
|
||||
/// <returns>a dashed string</returns>
|
||||
private static string MakeIntoDashSeperatedString(string strAboutToBeDashed, int DashEveryNthCharacter)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(strAboutToBeDashed))
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < strAboutToBeDashed.Length; i++)
|
||||
{
|
||||
if ((i != 0) && ((i % DashEveryNthCharacter) == 0))
|
||||
sb.Append("-");
|
||||
sb.Append(strAboutToBeDashed[i]);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Undash a String
|
||||
/// </summary>
|
||||
/// <returns>a string without dashes</returns>
|
||||
private static string MakeIntoDashUnseperatedString(string strAboutToBeUndashed)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(strAboutToBeUndashed))
|
||||
return strAboutToBeUndashed.Replace("-", "");
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the passed in string contains only digits
|
||||
/// </summary>
|
||||
/// <param name="strToCheckForDigits">string to check for digits for</param>
|
||||
/// <returns>true, if all digits are numbers</returns>
|
||||
private static bool ContainsOnlyDigits(string strToCheckForDigits)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(strToCheckForDigits))
|
||||
{
|
||||
for (int i = 0; i < strToCheckForDigits.Length; ++i)
|
||||
{
|
||||
if (!Char.IsDigit(strToCheckForDigits[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
10
TomcatServer/PlutoServer.MSL/Constants.cs
Normal file
10
TomcatServer/PlutoServer.MSL/Constants.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace PlutoServer.MSL {
|
||||
public static class SessionKeys {
|
||||
public static readonly string AuthToken = "AUTH_TOKEN";
|
||||
}
|
||||
}
|
||||
100
TomcatServer/PlutoServer.MSL/DEBUGGING_ONLY.cs
Normal file
100
TomcatServer/PlutoServer.MSL/DEBUGGING_ONLY.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Pluto.Api;
|
||||
using Sdaleo.Systems.SQLServer;
|
||||
using Sdaleo;
|
||||
using PlutoServer.MSL.Connectors;
|
||||
using Sdaleo.Systems.Advantage;
|
||||
using RegistrationAPI;
|
||||
using Pluto.Registration;
|
||||
|
||||
namespace PlutoServer.MSL
|
||||
{
|
||||
/// <summary>
|
||||
/// Only used for Debugging / Testing
|
||||
/// </summary>
|
||||
internal static class DEBUGGING_ONLY
|
||||
{
|
||||
#region Debug Step Credentials (For Testing)
|
||||
|
||||
const string LYTEC_KEY = "$616866C0D12EC1641A5#L";
|
||||
const string MEDISOFT_KEY = "$616866C0D12EC1641A5#M";
|
||||
|
||||
/// <summary>
|
||||
/// Advantage User Test Credential
|
||||
/// </summary>
|
||||
internal static AdvantageCredential AdvantageTestCredential = new AdvantageCredential(@"\\10.97.156.4\Medidata\Tutor\mwddf.add", "user", "password", AdvantageCredential.ServerType.REMOTE);
|
||||
|
||||
/// <summary>
|
||||
/// Advantage Shared Test Credential
|
||||
/// </summary>
|
||||
internal static AdvantageCredential AdvantageTestSharedCredential = new AdvantageCredential(@"\\10.97.156.4\Medidata\SharedData.add", "SharedDataUser", "AndPassword", AdvantageCredential.ServerType.REMOTE);
|
||||
|
||||
/// <summary>
|
||||
/// SQLServer User Test Credential
|
||||
/// </summary>
|
||||
internal static SQLServerCredential SQLServerTestCredential = new SQLServerCredential("10.97.156.22", "LytecMD", "Lytec Tutorial", "sa", "Clinical$1");
|
||||
|
||||
/// <summary>
|
||||
/// SQLServer Shared Test Credential
|
||||
/// </summary>
|
||||
internal static SQLServerCredential SQLServerTestSharedCredential = new SQLServerCredential("10.97.156.22", "LytecMD", "Lytec SharedData", "sa", "Clinical$1");
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Called in Debug Mode to allow us to step into specific things and
|
||||
/// easier test them straight thru the service, called before OnStart(),
|
||||
/// makes it easier to directly test Medisoft/Lytec Connectors
|
||||
/// </summary>
|
||||
internal static void DEBUGSTEP_INTO()
|
||||
{
|
||||
MSLSpecific.Setup_Test_Logger();
|
||||
DBCache.IsMachine_Used_ForTesting = true;
|
||||
DBCache.TestMedisoftDBCredential = AdvantageTestCredential;
|
||||
DBCache.TestLytecUserDBCredential = SQLServerTestCredential;
|
||||
|
||||
//Could you please run the script for IP address thing for orgs with key 2A66B402F-4041-E491M and E2G4Y3777-4F3E-BFEDL
|
||||
//SystemAccessVerifier v = new SystemAccessVerifier("CC67BA96B-4E85-57BBM");
|
||||
//SystemAccessVerifier v = new SystemAccessVerifier("930CY6704-42FE-1D1FL");
|
||||
//SystemAccessVerifier v = new SystemAccessVerifier("2A66B402F-4041-E491M"); // "$194E114069F204446A2#M"
|
||||
SystemAccessVerifier v = new SystemAccessVerifier("E2G4Y3777-4F3E-BFEDL"); // "$DE3BDE3F4E777F34E2E#L"
|
||||
|
||||
//string pin = RegistrationAPI.API.RetrieveUserApiKeyPin("CC67BA96B-4E85-57BBM");
|
||||
string apikey = v.SystemApiKey;
|
||||
|
||||
Pluto.Registration.Host host = RegistrationAPI.API.GetApiMobile(v.SystemApiKey);
|
||||
string ip = host.host;
|
||||
int port = host.port;
|
||||
bool bTest = RegistrationAPI.API.IsApiMobileReachable(v.SystemApiKey);
|
||||
|
||||
//RegistrationAPI.API.SetNetworkSettings("172.19.73.26", 443);
|
||||
RegistrationAPI.API.SetNetworkSettings("ppsmobile.mckesson.com", 443);
|
||||
//RegistrationAPI.API.SetNetworkSettings("services.ndchealthvar.com", 443);
|
||||
string strApiKey;
|
||||
string strPin;
|
||||
bool bSuccess = RegistrationAPI.API.RegisterNewServerPractice(new Guid("7c18db98-3c34-4382-963c-1175f0d20f44"), "Happy Valley Medical Clinic (Mck)", "10.24.52.25", "", 1945, "Medisoft", out strApiKey, out strPin);
|
||||
|
||||
//SuperBillLoadingSavingDebugStep();
|
||||
}
|
||||
|
||||
private static void SuperBillLoadingSavingDebugStep()
|
||||
{
|
||||
//string path = Path.GetTempPath();
|
||||
//string str = "<Name>Default</Name><Sections><SuperbillSection><Title>Office Visit (New)</Title><BgColor><Red>0</Red><Green>0</Green><Blue>0</Blue></BgColor><Sequence>1</Sequence><Row>0</Row><Column>0</Column><Fields><SuperbillField><FieldType>Diagnosis</FieldType><Sequence>1</Sequence><Code>99201</Code><DisplayText>Problem focused</DisplayText><Modifiers /><Units>0</Units></SuperbillField><SuperbillField><FieldType>Diagnosis</FieldType><Sequence>2</Sequence><Code>99202</Code><DisplayText>Expanded problem focused</DisplayText><Modifiers /><Units>0</Units></SuperbillField><SuperbillField><FieldType>Diagnosis</FieldType><Sequence>3</Sequence><Code>99203</Code><DisplayText>Detailed</DisplayText><Modifiers /><Units>0</Units></SuperbillField><SuperbillField><FieldType>Diagnosis</FieldType><Sequence>4</Sequence><Code>99204</Code><DisplayText>Comprehensive</DisplayText><Modifiers /><Units>0</Units></SuperbillField><SuperbillField><FieldType>Diagnosis</FieldType><Sequence>5</Sequence><Code>99205</Code><DisplayText>Comprehensive (new patient)</DisplayText><Modifiers /><Units>0</Units></SuperbillField><SuperbillField><FieldType>Diagnosis</FieldType><Sequence>6</Sequence><Code>-25</Code><DisplayText>Significant, separate service</DisplayText><Modifiers /><Units>0</Units></SuperbillField></Fields></SuperbillSection><SuperbillSection><Title>Office Visit (Est)</Title><BgColor><Red>0</Red><Green>0</Green><Blue>0</Blue></BgColor><Sequence>2</Sequence><Row>1</Row><Column>0</Column><Fields><SuperbillField><FieldType>Diagnosis</FieldType><Sequence>1</Sequence><Code>99211</Code><DisplayText>Minimal</DisplayText><Modifiers /><Units>0</Units></SuperbillField><SuperbillField><FieldType>Diagnosis</FieldType><Sequence>2</Sequence><Code>99212</Code><DisplayText>Expanded problem focused</DisplayText><Modifiers /><Units>0</Units></SuperbillField><SuperbillField><FieldType>Diagnosis</FieldType><Sequence>3</Sequence><Code>99213</Code><DisplayText>Detailed</DisplayText><Modifiers /><Units>0</Units></SuperbillField><SuperbillField><FieldType>Diagnosis</FieldType><Sequence>4</Sequence><Code>99214</Code><DisplayText>Comprehensive</DisplayText><Modifiers /><Units>0</Units></SuperbillField><SuperbillField><FieldType>Diagnosis</FieldType><Sequence>5</Sequence><Code>99215</Code><DisplayText>Comprehensive (new patient)</DisplayText><Modifiers /><Units>0</Units></SuperbillField><SuperbillField><FieldType>Diagnosis</FieldType><Sequence>6</Sequence><Code>-25</Code><DisplayText>Significant, separate service</DisplayText><Modifiers /><Units>0</Units></SuperbillField></Fields></SuperbillSection><SuperbillSection><Title>Discharge Instructions</Title><BgColor><Red>0</Red><Green>0</Green><Blue>0</Blue></BgColor><Sequence>3</Sequence><Row>2</Row><Column>0</Column><Fields><SuperbillField><FieldType>Diagnosis</FieldType><Sequence>1</Sequence><Code /><DisplayText>Comeback in 2 weeks</DisplayText><Modifiers /><Units>0</Units></SuperbillField><SuperbillField><FieldType>Diagnosis</FieldType><Sequence>1</Sequence><Code /><DisplayText>Comeback in 4 weeks</DisplayText><Modifiers /><Units>0</Units></SuperbillField><SuperbillField><FieldType>Diagnosis</FieldType><Sequence>1</Sequence><Code /><DisplayText>Comeback in 6 weeks</DisplayText><Modifiers /><Units>0</Units></SuperbillField><SuperbillField><FieldType>Diagnosis</FieldType><Sequence>1</Sequence><Code /><DisplayText>Comeback in 8 weeks</DisplayText><Modifiers /><Units>0</Units></SuperbillField><SuperbillField><FieldType>Diagnosis</FieldType><Sequence>1</Sequence><Code /><DisplayText>Comeback in 6 months</DisplayText><Modifiers /><Units>0</Units></SuperbillField></Fields></SuperbillSection><SuperbillSection><Title>Skin procedures</Title><BgColor><Red>0</Red><Green>0</Green><Blue>0</Blue></BgColor><Sequence>4</Sequence><Row>3</Row><Column>0</Column><Fields /></SuperbillSection><SuperbillSection><Title>Other services</Title><BgColor><Red>0</Red><Green>0</Green><Blue>0</Blue></BgColor><Sequence>5</Sequence><Row>4</Row><Column>0</Column><Fields /></SuperbillSection></Sections>";
|
||||
//string strPath = ProductType.GetProductSpecificSuperBillDirectoryPath("");
|
||||
//XmlDocument xmlDocument = new XmlDocument();
|
||||
//XmlNode Data = xmlDocument.CreateNode(XmlNodeType.Element, "SuperBillTemplate", "SuperBillTemplate");
|
||||
//Data.InnerXml = str;
|
||||
//XmlNode oNode = xmlDocument.ImportNode(Data, true);
|
||||
//xmlDocument.AppendChild(oNode);
|
||||
//xmlDocument.Save(strPath + "\\" + "Default" + ".msb");
|
||||
//xmlDocument.Load(strPath + "\\" + "Default" + ".msb");
|
||||
//XmlNode oNode2 = (XmlNode) xmlDocument;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
31
TomcatServer/PlutoServer.MSL/Installer.Designer.cs
generated
Normal file
31
TomcatServer/PlutoServer.MSL/Installer.Designer.cs
generated
Normal file
@@ -0,0 +1,31 @@
|
||||
namespace PlutoServer.MSL {
|
||||
partial class Installer {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing) {
|
||||
if(disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
components = new System.ComponentModel.Container();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
34
TomcatServer/PlutoServer.MSL/Installer.cs
Normal file
34
TomcatServer/PlutoServer.MSL/Installer.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Configuration.Install;
|
||||
using System.Linq;
|
||||
using System.ServiceProcess;
|
||||
|
||||
namespace PlutoServer.MSL {
|
||||
[RunInstaller(true)]
|
||||
public partial class Installer : System.Configuration.Install.Installer {
|
||||
public Installer() {
|
||||
InitializeComponent();
|
||||
|
||||
ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller();
|
||||
ServiceInstaller serviceInstaller = new ServiceInstaller();
|
||||
|
||||
//# Service Account Information
|
||||
serviceProcessInstaller.Account = ServiceAccount.LocalSystem;
|
||||
serviceProcessInstaller.Username = null;
|
||||
serviceProcessInstaller.Password = null;
|
||||
|
||||
//# Service Information
|
||||
serviceInstaller.ServiceName = "PlutoServer.MSL";
|
||||
serviceInstaller.DisplayName = "McKesson MSL Mobile Api Server";
|
||||
serviceInstaller.Description = "Manages data updates and retrieval for McKesson's PPS Mobile App from MSL";
|
||||
serviceInstaller.StartType = ServiceStartMode.Automatic;
|
||||
|
||||
// # Done
|
||||
this.Installers.Add(serviceProcessInstaller);
|
||||
this.Installers.Add(serviceInstaller);
|
||||
}
|
||||
}
|
||||
}
|
||||
727
TomcatServer/PlutoServer.MSL/MSLSpecific_Impl.cs
Normal file
727
TomcatServer/PlutoServer.MSL/MSLSpecific_Impl.cs
Normal file
@@ -0,0 +1,727 @@
|
||||
|
||||
|
||||
namespace Pluto.Api
|
||||
{
|
||||
using System;
|
||||
using RemObjects.SDK;
|
||||
using RemObjects.SDK.Types;
|
||||
using RemObjects.SDK.Server;
|
||||
using RemObjects.SDK.Server.ClassFactories;
|
||||
using PlutoServer.MSL.Connectors;
|
||||
using Yaulw.File;
|
||||
using Sdaleo;
|
||||
using Sdaleo.Systems.SQLServer;
|
||||
using Sdaleo.Systems.Advantage;
|
||||
using Sdaleo.Systems;
|
||||
using System.Net;
|
||||
using PlutoServer.MSL;
|
||||
using Yaulw.Assembly;
|
||||
using Yaulw.Tools;
|
||||
|
||||
[RemObjects.SDK.Server.ClassFactories.StandardClassFactory()]
|
||||
[RemObjects.SDK.Server.Service(Name = "MSLSpecific", InvokerClass = typeof(MSLSpecific_Invoker), ActivatorClass = typeof(MSLSpecific_Activator))]
|
||||
public class MSLSpecific : RemObjects.SDK.Server.Service, IMSLSpecific
|
||||
{
|
||||
private System.ComponentModel.Container components = null;
|
||||
public MSLSpecific() :
|
||||
base()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Dispose(bool aDisposing)
|
||||
{
|
||||
if (aDisposing)
|
||||
{
|
||||
if ((this.components != null))
|
||||
{
|
||||
this.components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(aDisposing);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Keep track of the Host GUID
|
||||
/// </summary>
|
||||
private static ISReadWrite s_ISReadWrite = new ISReadWrite("host");
|
||||
|
||||
#region Logger Functions (public one is for Test Framework)
|
||||
|
||||
/// <summary>
|
||||
/// For Logging to a File
|
||||
/// </summary>
|
||||
internal static Logging Logger = null;
|
||||
|
||||
/// <summary>
|
||||
/// Test Log File and Path
|
||||
/// </summary>
|
||||
internal static string TestLogFileNameNPath = String.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Setup the Logger Object, should be done only once at when the application starts
|
||||
/// </summary>
|
||||
internal static void Setup_Logger()
|
||||
{
|
||||
if (Logger == null)
|
||||
{
|
||||
// Is Setup_Test_Logger() Called?
|
||||
bool bIsTestLogFileSet = !String.IsNullOrEmpty(TestLogFileNameNPath);
|
||||
|
||||
// Default Log File Settings
|
||||
const int LOG_FILE_FILE_SIZE_IN_MB = 4;
|
||||
const int LOG_FILE_NUM_OF_BACKUPS = 2;
|
||||
const string FILE_EXTENSION_LOG_DEFAULT = "log";
|
||||
|
||||
// Default Log File Name N Path Settings
|
||||
string LogFileNameNPath = String.Empty;
|
||||
if (!bIsTestLogFileSet)
|
||||
{
|
||||
string Path = AssemblyW.SpecializedAssemblyInfo.GetAssemblyPath(AssemblyW.AssemblyST.Entry);
|
||||
LogFileNameNPath = PathNaming.PathEndsWithSlash(Path) + AssemblyW.GetAssemblyName(AssemblyW.AssemblyST.Entry) + "." + FILE_EXTENSION_LOG_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allow Unit test framework to set the log file path
|
||||
LogFileNameNPath = TestLogFileNameNPath;
|
||||
}
|
||||
|
||||
// Log Config
|
||||
Logging_Configuration config = new Logging_Configuration();
|
||||
config.LogFileNameNPath = LogFileNameNPath;
|
||||
config.maxFileSizeInMB = LOG_FILE_FILE_SIZE_IN_MB;
|
||||
config.numOfBackupLogFiles = LOG_FILE_NUM_OF_BACKUPS;
|
||||
config.Log4NetDetailPatternLayout = "%date{dd MMM HH:mm:ss,fff} %level - %message%newline";
|
||||
config.LogCallingFunction = false;
|
||||
config.LogCallingType = false;
|
||||
if (PlutoService.IsOnMcKessonNetwork || bIsTestLogFileSet)
|
||||
config.Detail = Logging_Detail.DEBUG;
|
||||
else
|
||||
config.Detail = Logging_Detail.INFO;
|
||||
config.UseExclusiveFileLock = false;
|
||||
|
||||
// Now just create the Logger
|
||||
if (!bIsTestLogFileSet)
|
||||
Logger = Logging.AddGlobalLoggerConfiguration(AssemblyW.GetAssemblyName(AssemblyW.AssemblyST.Entry), config);
|
||||
else
|
||||
Logger = Logging.AddGlobalLoggerConfiguration("Pluto.MSL.Test", config);
|
||||
|
||||
// Make a Debug Message show, if we are on McKesson
|
||||
if (PlutoService.IsOnMcKessonNetwork)
|
||||
Logger.Info("**** NOTE **** This is a McKesson Networked Machine. DEBUG Messages will only show when service is run from a McKesson Networked Machine.");
|
||||
else
|
||||
Logger.Info("**** NOTE **** This is a Regularly Networked Machine. Only INFO and ERROR Messages will show when service in this Environment.");
|
||||
Logger.Info("Logger Started at:{0} with Service Version {1}", DateTime.Now.ToString(), AssemblyW.GetAssemblyVersion(AssemblyW.AssemblyST.Entry));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setup the Test Logger Object, should be done by the Unit test framework to put the file in c:\\
|
||||
/// </summary>
|
||||
public static void Setup_Test_Logger()
|
||||
{
|
||||
TestLogFileNameNPath = @"C:\\Pluto.MSL.Test.log";
|
||||
Setup_Logger();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal Static Helper Functions
|
||||
|
||||
// Wipes all information known to use, both on the registration server as well as here
|
||||
// and starts over. logs the information to the user. System is auto-fixing itelf.
|
||||
// performing an internal re-install. The user may not like it, but that is just what
|
||||
// happend, we are in a bad state ERROR IT * BOLDLY in the Error log*
|
||||
internal static void MAJOR_ERROR_INTEGRITY_EVENT_OCCURED_ENTER_REINSTALL_STATE()
|
||||
{
|
||||
Logger.Fatal("******** FATAL ******** State occured. Service integrity invalid. All UserApiKeys will get deregistered as well as all hostGuid keys");
|
||||
Logger.Fatal("******** FATAL ******** Someone must have tried to tamper with the system (registry / files) loosing vital information needed to continue.");
|
||||
Logger.Fatal("******** FATAL ******** Service is attempting to auto-fix itself. All users must re-open Mobile->Help about and obtain a new user api key.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the UserApiKey for a given Practice
|
||||
/// </summary>
|
||||
/// <param name="bIsMedisoft"></param>
|
||||
/// <param name="credential"></param>
|
||||
/// <param name="DataSetOrDataBaseName"></param>
|
||||
/// <returns></returns>
|
||||
internal static string GetUserApiKeyForPractice(bool bIsMedisoft, IConnectDb credential, string DataSetOrDataBaseName, out bool bErrorOccured)
|
||||
{
|
||||
string UserApiKey = "";
|
||||
bErrorOccured = true;
|
||||
if (!String.IsNullOrEmpty(DataSetOrDataBaseName) && credential != null)
|
||||
{
|
||||
if (bIsMedisoft)
|
||||
{
|
||||
string retVal = MedisoftConnector.GetUserApiKeyForPractice((AdvantageCredential)credential, DataSetOrDataBaseName, out bErrorOccured);
|
||||
if (!String.IsNullOrEmpty(retVal))
|
||||
UserApiKey = retVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
string retVal = LytecConnector.GetUserApiKeyForPractice((SQLServerCredential)credential, DataSetOrDataBaseName, out bErrorOccured);
|
||||
if (!String.IsNullOrEmpty(retVal))
|
||||
UserApiKey = retVal;
|
||||
}
|
||||
}
|
||||
return UserApiKey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the UserApiKey for a given Practice
|
||||
/// </summary>
|
||||
/// <param name="bIsMedisoft"></param>
|
||||
/// <param name="credential"></param>
|
||||
/// <param name="DataSetOrDataBaseName"></param>
|
||||
/// <returns></returns>
|
||||
internal static bool SetUserApiKeyForPractice(bool bIsMedisoft, IConnectDb credential, string DataSetOrDataBaseName, string UserApiKey)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(DataSetOrDataBaseName) && credential != null)
|
||||
{
|
||||
if (bIsMedisoft)
|
||||
{
|
||||
bool bSuccess = MedisoftConnector.SetUserApiKeyForPractice((AdvantageCredential)credential, DataSetOrDataBaseName, UserApiKey);
|
||||
if(!bSuccess)
|
||||
Logger.Error("Error setting UserApiKey for DataSetorDataBaseName {0}", DataSetOrDataBaseName);
|
||||
return bSuccess;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool bSuccess = LytecConnector.SetUserApiKeyForPractice((SQLServerCredential)credential, DataSetOrDataBaseName, UserApiKey);
|
||||
if (!bSuccess)
|
||||
Logger.Error("Error setting UserApiKey for DataSetorDataBaseName {0}", DataSetOrDataBaseName);
|
||||
return bSuccess;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the Host Guid for this instance,k if not exists,
|
||||
/// create one. Host Guid is stored in isolated storage * why not *
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal static Guid GetHostGUID()
|
||||
{
|
||||
string s = s_ISReadWrite.ReadFromIS();
|
||||
if (String.IsNullOrEmpty(s))
|
||||
{
|
||||
Guid g = Guid.NewGuid();
|
||||
Logger.Debug("Creating new Host GUID {0}", g.ToString());
|
||||
s_ISReadWrite.WriteToIS(g.ToString());
|
||||
return g;
|
||||
}
|
||||
return new Guid(s);
|
||||
|
||||
// New Untested Code * Still needs some hashing out *
|
||||
//string s = s_ISReadWrite.ReadFromIS();
|
||||
//Guid g = Guid.NewGuid();
|
||||
//if (String.IsNullOrEmpty(s))
|
||||
//{
|
||||
// // Store bck HostGuid in registry to make sure this value is never lost
|
||||
// Yaulw.Registry.RegKey.SetKey<string>(Yaulw.Registry.HKEYRoot.LocalMachine, PlutoService.LOCAL_MACHINE_SUBKEY, PlutoService.LOCAL_MACHINE_HOSTGUID, g.ToString());
|
||||
// Logger.Debug("Creating new Host GUID {0}", g.ToString());
|
||||
// s_ISReadWrite.WriteToIS(g.ToString());
|
||||
// return g;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// // Read registry and retrieve backup guid first * if empty set it, Upgrade service issues * feature added in 1.0.2.3
|
||||
// string bckGuid = Yaulw.Registry.RegKey.GetKey<string>(Yaulw.Registry.HKEYRoot.LocalMachine, PlutoService.LOCAL_MACHINE_SUBKEY, PlutoService.LOCAL_MACHINE_HOSTGUID, String.Empty);
|
||||
// if (String.IsNullOrEmpty(bckGuid.ToString()))
|
||||
// {
|
||||
// Yaulw.Registry.RegKey.SetKey<string>(Yaulw.Registry.HKEYRoot.LocalMachine, PlutoService.LOCAL_MACHINE_SUBKEY, PlutoService.LOCAL_MACHINE_HOSTGUID, g.ToString());
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // if not empty compare them (they should always be equal if not, we are kind of in mayor trouble)
|
||||
// // we will pick the guid that is stored in online, that is our only choice, doubtful that both got
|
||||
// // stored online (*that state is a major error state and would require wiping the host guid, and wiping
|
||||
// // all hostkeys online and all userapikeys online. Even maybe the DBCacheFile. basically an internal re-install
|
||||
// if (String.Compare(s, bckGuid, true) != 0)
|
||||
// {
|
||||
// // chech which guid is online, pick that one first
|
||||
|
||||
|
||||
|
||||
// // else Mayor event occured
|
||||
// MAJOR_ERROR_INTEGRITY_EVENT_OCCURED_ENTER_REINSTALL_STATE();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//return new Guid(s);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Quick check to see if the connection is a Medisoft / Advantage DB Connection
|
||||
/// </summary>
|
||||
/// <param name="ConnectionString"></param>
|
||||
/// <returns></returns>
|
||||
internal static bool ConnectionContainsAdvServerType(string ConnectionString)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(ConnectionString))
|
||||
return (ConnStr.ContainsKey("Advantage Server Type", ConnectionString) || ConnStr.ContainsKey("ServerType", ConnectionString));
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private DBCache Related Helper Functions
|
||||
|
||||
/// <summary>
|
||||
/// Shared Database Connection needs to be added
|
||||
/// </summary>
|
||||
/// <param name="SharedConnectionDataSource">Connection String of the Shared DB to be added to Cache</param>
|
||||
/// <param name="bTryToConnect">Will try to connect to the DB, if set to true</param>
|
||||
/// <param name="bCanConnect">if bTryToConnect is true, it will try to connect and assign out this value</param>
|
||||
/// <returns>true if it needed to be added and, if TryToConnect is set, and communication is working, false otherwise</returns>
|
||||
private bool AddConnectionIfNotAlreadyThere(string SharedConnectionDataSource, bool bTryToConnect)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(SharedConnectionDataSource))
|
||||
{
|
||||
IConnectDb credential = ConvertSharedDataSourceToProperCredential(SharedConnectionDataSource);
|
||||
if (credential != null)
|
||||
{
|
||||
// Is Connection of Type Medisoft
|
||||
if (ConnectionContainsAdvServerType(SharedConnectionDataSource))
|
||||
{
|
||||
DBCache.AddSharedDataConnectionToDataStore((AdvantageCredential)credential, true);
|
||||
|
||||
// Test the Connection = see if error occurs calling practice list
|
||||
if (bTryToConnect)
|
||||
{
|
||||
bool bConnect = MedisoftConnector.GetPracticeList((AdvantageCredential)credential).IsValid;
|
||||
return bConnect;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else // Or Lytec
|
||||
{
|
||||
DBCache.AddSharedDataConnectionToDataStore((SQLServerCredential)credential, true);
|
||||
|
||||
// Test the Connection = see if error occurs calling practice list
|
||||
if (bTryToConnect)
|
||||
{
|
||||
bool bConnect = LytecConnector.GetPracticeList((SQLServerCredential)credential).IsValid;
|
||||
return bConnect;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a passed in SharedConnection (from Medisoft/Lytec) into a proper IConnectDb credential
|
||||
/// we can use to pass arround
|
||||
/// </summary>
|
||||
/// <param name="SharedConnectionDataSource"></param>
|
||||
/// <returns></returns>
|
||||
private IConnectDb ConvertSharedDataSourceToProperCredential(string SharedConnectionDataSource)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(SharedConnectionDataSource))
|
||||
{
|
||||
// Is Connection of Type Medisoft
|
||||
if (ConnectionContainsAdvServerType(SharedConnectionDataSource))
|
||||
{
|
||||
string Type = ConnStr.RetrieveValue("Advantage Server Type", SharedConnectionDataSource);
|
||||
if (String.IsNullOrEmpty(Type))
|
||||
Type = ConnStr.RetrieveValue("ServerType", SharedConnectionDataSource);
|
||||
|
||||
bool bIsRemote = Type.ToUpper().Contains("REMOTE");
|
||||
AdvantageCredential credential = new AdvantageCredential(Yaulw.Net.IPHostHelper.GetDataSource(SharedConnectionDataSource), "SharedDataUser", "AndPassword", bIsRemote ? AdvantageCredential.ServerType.REMOTE : AdvantageCredential.ServerType.LOCAL);
|
||||
return credential;
|
||||
}
|
||||
else // Or Lytec
|
||||
{
|
||||
string Server;
|
||||
string Instance;
|
||||
if (SQLServerUtilities.SplitServerOrServerNInstance(Yaulw.Net.IPHostHelper.GetDataSource(SharedConnectionDataSource), out Server, out Instance))
|
||||
{
|
||||
string UserID = ConnStr.RetrieveValue("User ID", SharedConnectionDataSource);
|
||||
string Password = ConnStr.RetrieveValue("Password", SharedConnectionDataSource);
|
||||
SQLServerCredential credential = new SQLServerCredential(Server, Instance, "Lytec SharedData", UserID, Password);
|
||||
return credential;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reload the UserCredentials for a given SharedCredentials in the Cache
|
||||
/// </summary>
|
||||
/// <param name="SharedCredential"></param>
|
||||
/// <param name="bIsMedisoft"></param>
|
||||
private void ReloadUserDBConnectionForSharedCredential(IConnectDb SharedCredential, bool bIsMedisoft)
|
||||
{
|
||||
if (bIsMedisoft)
|
||||
DBCache.IterateSharedConnectionAndLoadUserApiKeyConnections((AdvantageCredential)SharedCredential);
|
||||
else
|
||||
DBCache.IterateSharedConnectionAndLoadUserApiKeyConnections((SQLServerCredential)SharedCredential);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IMSLMobileConnect
|
||||
|
||||
/// <summary>
|
||||
/// Common Tasks to do for all of our MSLSpecific Calls
|
||||
/// </summary>
|
||||
/// <param name="SharedConnectionDataSource">Medisoft/Lytec SharedDataConnection</param>
|
||||
/// <param name="bAddSharedConnection">if true, add the connection to our DataStore</param>
|
||||
/// <param name="bTryToConnect">if true, trying to connect to the db to test</param>
|
||||
/// <param name="bIsMedisoft">out is Medisoft</param>
|
||||
/// <param name="Credential">out Credential</param>
|
||||
/// <returns>return true when everything is ok, false otherwise</returns>
|
||||
private bool CommonThingsToDoUponEveryMSLCall(string SharedConnectionDataSource, bool bAddSharedConnection, bool bTryToConnect, out bool bIsMedisoft, out IConnectDb Credential)
|
||||
{
|
||||
bIsMedisoft = false;
|
||||
Credential = null;
|
||||
if(!String.IsNullOrEmpty(SharedConnectionDataSource))
|
||||
{
|
||||
// Is Lytec or Medisoft?
|
||||
bIsMedisoft = ConnectionContainsAdvServerType(SharedConnectionDataSource);
|
||||
Credential = ConvertSharedDataSourceToProperCredential(SharedConnectionDataSource);
|
||||
if (Credential != null)
|
||||
{
|
||||
// Local Host name and IP
|
||||
if(bIsMedisoft)
|
||||
Logger.Info("Determined DataSource to be Medisoft");
|
||||
else
|
||||
Logger.Info("Determined DataSource to be Lytec");
|
||||
Logger.Info("Determined Host:{0} with Host Guid:'{1}'", Dns.GetHostName(), GetHostGUID());
|
||||
|
||||
// Should we add the connection?
|
||||
if (bAddSharedConnection)
|
||||
{
|
||||
// will always return true, unless bTryToConnect is true and it will try to connect and fail
|
||||
bool bConnect = AddConnectionIfNotAlreadyThere(SharedConnectionDataSource, bTryToConnect);
|
||||
if (bTryToConnect && bConnect)
|
||||
Logger.Debug("Successfully connected to SharedDataSource: {0}", SharedConnectionDataSource);
|
||||
else if(bTryToConnect && !bConnect)
|
||||
Logger.Error("Failed to Connect to passed in DataSource");
|
||||
|
||||
// Ensure that all UserApiKeys are unique - running into issues
|
||||
// with Lytec and Medisoft somehow
|
||||
if (bConnect)
|
||||
{
|
||||
if (bIsMedisoft)
|
||||
MedisoftConnector.CleanUpDuplicateUserApiKeyExists((AdvantageCredential)Credential);
|
||||
else
|
||||
LytecConnector.CleanUpDuplicateUserApiKeyExists((SQLServerCredential)Credential);
|
||||
}
|
||||
return bConnect;
|
||||
}
|
||||
}
|
||||
}
|
||||
Logger.Debug("Something is wrong with this DataSource {0},", SharedConnectionDataSource);
|
||||
Logger.Error("Failed to Retrieve the information needed to continue");
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mobile About Dialog got called by Lytec/Medisoft. Here we do the main work of registering everything
|
||||
/// </summary>
|
||||
/// <param name="SharedConnectionDataSource"></param>
|
||||
/// <param name="RegisteredName"></param>
|
||||
/// <param name="PracticeName"></param>
|
||||
/// <returns></returns>
|
||||
public virtual ApiKeyNPin MobileAboutDialogCalled(string SharedConnectionDataSource, string RegisteredName, string PracticeName, string DataBaseNameOrDataSetName)
|
||||
{
|
||||
Logger.Debug("called with SharedDataSource: {0}, RegisteredName: {1}, PracticeName: {2}, DataSetOrDBName: {3}", SharedConnectionDataSource, RegisteredName, PracticeName, DataBaseNameOrDataSetName);
|
||||
ApiKeyNPin apikey = new ApiKeyNPin();
|
||||
try
|
||||
{
|
||||
// Perform this for all MSL Entry Calls * for Sanity *
|
||||
bool bIsMedisoft = false;
|
||||
IConnectDb Credential = null;
|
||||
bool bIsValid = CommonThingsToDoUponEveryMSLCall(SharedConnectionDataSource, true, false, out bIsMedisoft, out Credential);
|
||||
if (!bIsValid)
|
||||
return apikey;
|
||||
|
||||
// Try To Fetch the UserApikey
|
||||
bool bErrorOccured = true;
|
||||
string UserApiKey = GetUserApiKeyForPractice(bIsMedisoft, Credential, DataBaseNameOrDataSetName, out bErrorOccured);
|
||||
if (bErrorOccured)
|
||||
{
|
||||
Logger.Error("Database Error Occured fetching UserApiKey - Mobile About Dialog cannot continue for DataSetorDataBaseName {0}", DataBaseNameOrDataSetName);
|
||||
return apikey;
|
||||
}
|
||||
|
||||
// To Do: UserApiKey could not match with the current host, if that ever happens,
|
||||
// we should ideally re-register and not retrieve the PIN, because now the systems are out of sync
|
||||
// (TBD)
|
||||
|
||||
// If there is no UserApiKey already in the System,
|
||||
// it means we must register this practice as * new *
|
||||
if (String.IsNullOrEmpty(UserApiKey))
|
||||
{
|
||||
string strApiKey;
|
||||
string strPin;
|
||||
bool bSuccess = RegistrationWrapper.RegisterNewPractice(PracticeName, bIsMedisoft, out strApiKey, out strPin);
|
||||
if (bSuccess)
|
||||
{
|
||||
Logger.Debug("Retrieved new UserApiKey {0} and Pin {1}", strApiKey, strPin);
|
||||
|
||||
// Set the Service State
|
||||
PlutoService.state = RegistrationWrapper.HostGUIDstate.exists;
|
||||
|
||||
// Save the UserApiKey in the DB (if successful save, then continue to reload user DB Connections)
|
||||
// and only then assign out the api key! ~if it didn't save in the db it shouldn't show on the dialog
|
||||
if (SetUserApiKeyForPractice(bIsMedisoft, Credential, DataBaseNameOrDataSetName, strApiKey))
|
||||
{
|
||||
apikey.UserApiKey = strApiKey;
|
||||
apikey.UserPin = strPin;
|
||||
|
||||
// Reload the UserDB Cache
|
||||
ReloadUserDBConnectionForSharedCredential(Credential, bIsMedisoft);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Error("Database Error Occured saving UserApiKey - Mobile About Dialog cannot continue");
|
||||
}
|
||||
return apikey;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Practice already registered! So just retrieve the pin for the UserApikey and we are done
|
||||
string Pin = RegistrationWrapper.RetrievePinForUserApiKey(UserApiKey);
|
||||
if (!String.IsNullOrEmpty(Pin))
|
||||
{
|
||||
apikey.UserApiKey = UserApiKey;
|
||||
apikey.UserPin = Pin;
|
||||
Logger.Debug("MobileAboutDialogCalled() Retrieving Pin:{0} for UserApiKey:{1}", Pin, UserApiKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Error("Failed to retrieve Pin - Mobile About Dialog cannot continue");
|
||||
}
|
||||
return apikey;
|
||||
}
|
||||
}
|
||||
catch (Exception e) { Logger.Error("MobileAboutDialogCalled() Error", e); }
|
||||
return apikey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called upon every lytec/medisoft launch. Currently doesn't do very much. (It was kind of
|
||||
/// intended for Registration Purposes).
|
||||
/// </summary>
|
||||
/// <param name="SharedConnectionDataSource"></param>
|
||||
/// <param name="RegisteredName"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool ProductSetupCompleted(string SharedConnectionDataSource, string RegisteredName)
|
||||
{
|
||||
Logger.Debug("called with SharedDataSource: {0}, RegisteredName: {1}", SharedConnectionDataSource, RegisteredName);
|
||||
try
|
||||
{
|
||||
// Perform this for all MSL Entry Calls * for Sanity *
|
||||
bool bIsMedisoft = false;
|
||||
IConnectDb Credential = null;
|
||||
CommonThingsToDoUponEveryMSLCall(SharedConnectionDataSource, true, true, out bIsMedisoft, out Credential);
|
||||
|
||||
// Always return true, Medisoft/Lytec Checking that it can connect to this service expects
|
||||
// a true back, if it doesn't it will hinder the CheckConnectivity Test at step 1,
|
||||
// not allowing the real step 2 and step 3 to continue
|
||||
return true;
|
||||
}
|
||||
catch (Exception e) { Logger.Error("ProductSetupCompleted() Error", e); }
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Practice Name Change Occured
|
||||
/// </summary>
|
||||
/// <param name="SharedConnectionDataSource"></param>
|
||||
/// <param name="NewPracticeName"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool PracticeNameChangeOccured(string SharedConnectionDataSource, string NewPracticeName, string DataBaseNameOrDataSetName)
|
||||
{
|
||||
Logger.Debug("called with SharedDataSource: {0}, NewPracticeName: {1}, DataSetOrDBName: {2}", SharedConnectionDataSource, NewPracticeName, DataBaseNameOrDataSetName);
|
||||
try
|
||||
{
|
||||
// Perform this for all MSL Entry Calls * for Sanity *
|
||||
bool bIsMedisoft = false;
|
||||
IConnectDb Credential = null;
|
||||
bool bIsValid = CommonThingsToDoUponEveryMSLCall(SharedConnectionDataSource, true, false, out bIsMedisoft, out Credential);
|
||||
if (!bIsValid)
|
||||
return false;
|
||||
|
||||
// Try To Fetch the UserApikey
|
||||
bool bErrorOccured = true;
|
||||
string UserApiKey = GetUserApiKeyForPractice(bIsMedisoft, Credential, DataBaseNameOrDataSetName, out bErrorOccured);
|
||||
if (bErrorOccured)
|
||||
{
|
||||
Logger.Error("Database Error Occured fetching UserApiKey - PracticeNameChangeOccured cannot continue for DataSetorDataBaseName {0}", DataBaseNameOrDataSetName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(UserApiKey))
|
||||
{
|
||||
// Auto-Retrieve the Pin
|
||||
string Pin = RegistrationWrapper.RetrievePinForUserApiKey(UserApiKey);
|
||||
if (!String.IsNullOrEmpty(Pin))
|
||||
{
|
||||
Logger.Debug("Retrieved UserApiKey:{0} Pin:{1} for Practice:{2}", UserApiKey, Pin, NewPracticeName);
|
||||
|
||||
// Update the Practice Name
|
||||
bool bSuccess = RegistrationWrapper.UpdatePracticeName(UserApiKey, Pin, NewPracticeName);
|
||||
return bSuccess;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Error("Failed to retrieve Pin - PracticeNameChangeOccured cannot continue");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch (Exception e) { Logger.Error("PracticeNameChangeOccured() Error", e); }
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check to see if the external IP can be accessed by the McKesson's Mobile Gateway
|
||||
/// </summary>
|
||||
/// <param name="SharedConnectionDataSource"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool IsServerReachableFromTheInternet(string SharedConnectionDataSource)
|
||||
{
|
||||
Logger.Debug("called with SharedDataSource: {0}", SharedConnectionDataSource);
|
||||
try
|
||||
{
|
||||
// Perform this for all MSL Entry Calls * for Sanity *
|
||||
bool bIsMedisoft = false;
|
||||
IConnectDb Credential = null;
|
||||
bool bIsValid = CommonThingsToDoUponEveryMSLCall(SharedConnectionDataSource, true, false, out bIsMedisoft, out Credential);
|
||||
if (!bIsValid)
|
||||
return false;
|
||||
|
||||
// Check to see if this server is reachable from the internet
|
||||
bool bIsReachable = RegistrationWrapper.IsServerReachable();
|
||||
return bIsReachable;
|
||||
}
|
||||
catch (Exception e) { Logger.Error("IsServerReachableFromTheInternet() Error", e); }
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the Service if needed
|
||||
/// </summary>
|
||||
public virtual void UpdateServiceIfNeeded()
|
||||
{
|
||||
PlutoService.AppLogInfo("UpdateServiceIfNeeded() called - Will try to Update the Service, if new Service was found online");
|
||||
|
||||
// Callback from MSLConnect, to try to update the service,
|
||||
// we only need a little delay here, let this call return as quickly as possible
|
||||
AutoUpdate.TryToUpdateIfNeeded(5, false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Pluto AddOns
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the Host GUID for this machine
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual string GetHostSpecGUID()
|
||||
{
|
||||
return GetHostGUID().ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the External Port Set
|
||||
/// </summary>
|
||||
/// <returns>a valid port or -1 for none</returns>
|
||||
public virtual int GetExternalPort()
|
||||
{
|
||||
if (PlutoService.IsExtIPandExtPortSet)
|
||||
return (int) PlutoService.ExternalPort;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set and reload the External CHannel on a different port
|
||||
/// </summary>
|
||||
/// <param name="Port"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool SetExternalPort(int Port)
|
||||
{
|
||||
// never tested (coded), but never tested
|
||||
// must test ReloadExtIPandPortConfiguration() at some point,
|
||||
// won't get called by Diagnose mobile at this time
|
||||
return PlutoService.ReloadExtIPandPortConfiguration(Port);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the latest external IP
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual string GetExternalIP()
|
||||
{
|
||||
if (PlutoService.IsExtIPandExtPortSet)
|
||||
return PlutoService.ExternalIP.ToString();
|
||||
else
|
||||
return IPAddress.None.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the latest Internal IP
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual string GetLocalIP()
|
||||
{
|
||||
return PlutoService.InternalIP.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Pluto Dev AddOns (To Do)
|
||||
|
||||
/// <summary>
|
||||
/// Go thru all the Shared Database Connections and auto-generate a
|
||||
/// user api key for all practices * good for testing and debugging *
|
||||
/// this means lytec/medisoft is not needed to create the userapikeys
|
||||
/// </summary>
|
||||
public virtual void GenerateApiKeysForPracticesInLoadedSharedCredentials()
|
||||
{
|
||||
// TO DO:
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a custom Shared Database Credential Medisoft or Lytec to the system
|
||||
/// *good for testing and debugging*
|
||||
/// </summary>
|
||||
/// <param name="credential"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool AddSharedCredential(ApiKeyNCredential credential)
|
||||
{
|
||||
// TO DO:
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve all currently loaded credentials good for support,
|
||||
/// dev, qa, etc to see what is going on
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual ApiKeyNCredential[] GetLoadedCredentials()
|
||||
{
|
||||
// TO DO:
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
35
TomcatServer/PlutoServer.MSL/Medication_Impl.cs
Normal file
35
TomcatServer/PlutoServer.MSL/Medication_Impl.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
namespace Pluto.Api {
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using RemObjects.SDK;
|
||||
using RemObjects.SDK.Types;
|
||||
using RemObjects.SDK.Server;
|
||||
using RemObjects.SDK.Server.ClassFactories;
|
||||
using PlutoServer.MSL;
|
||||
|
||||
[RemObjects.SDK.Server.ClassFactories.StandardClassFactory()]
|
||||
[RemObjects.SDK.Server.Service(Name = "Medication", InvokerClass = typeof(Medication_Invoker), ActivatorClass = typeof(Medication_Activator))]
|
||||
public class Medication : RemObjects.SDK.Server.Service, IMedication {
|
||||
private System.ComponentModel.Container components = null;
|
||||
public Medication() :
|
||||
base() {
|
||||
this.InitializeComponent();
|
||||
}
|
||||
private void InitializeComponent() {
|
||||
}
|
||||
protected override void Dispose(bool aDisposing) {
|
||||
if(aDisposing) {
|
||||
if((this.components != null)) {
|
||||
this.components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(aDisposing);
|
||||
}
|
||||
public virtual MedicationInfo1[] Search(string apiKey, string searchString)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
TomcatServer/PlutoServer.MSL/PUBLISH.htm
Normal file
1
TomcatServer/PlutoServer.MSL/PUBLISH.htm
Normal file
@@ -0,0 +1 @@
|
||||
1.0.3.8
|
||||
96
TomcatServer/PlutoServer.MSL/Patient_Impl.cs
Normal file
96
TomcatServer/PlutoServer.MSL/Patient_Impl.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
namespace Pluto.Api {
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using RemObjects.SDK;
|
||||
using RemObjects.SDK.Types;
|
||||
using RemObjects.SDK.Server;
|
||||
using RemObjects.SDK.Server.ClassFactories;
|
||||
using PlutoServer.MSL;
|
||||
using PlutoServer.MSL.Connectors;
|
||||
|
||||
[RemObjects.SDK.Server.ClassFactories.StandardClassFactory()]
|
||||
[RemObjects.SDK.Server.Service(Name = "Patient", InvokerClass = typeof(Patient_Invoker), ActivatorClass = typeof(Patient_Activator))]
|
||||
public class Patient : RemObjects.SDK.Server.Service, IPatient {
|
||||
private System.ComponentModel.Container components = null;
|
||||
public Patient() :
|
||||
base() {
|
||||
this.InitializeComponent();
|
||||
}
|
||||
private void InitializeComponent() {
|
||||
}
|
||||
protected override void Dispose(bool aDisposing) {
|
||||
if(aDisposing) {
|
||||
if((this.components != null)) {
|
||||
this.components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(aDisposing);
|
||||
}
|
||||
|
||||
#region IPatient Members
|
||||
|
||||
public virtual PrescribedMedicationInfo1[] GetMedications(string apiKey, int chartId)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual AllergyInfo1[] GetAllergies(string apiKey, int chartId)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual ProblemInfo1[] GetProblems(string apiKey, int chartId)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual ChartInfo1 GetChart(string apiKey, int patientId, int chartId)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual VitalSignInfo1[] GetVitalSigns(string apiKey, int patientId, int chartId)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual void AddNote(string apiKey, int patientId, int chartId, PatientNoteInfo1 patientNote)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public virtual PatientNoteInfo1[] GetNotes(string apiKey, int patientId, int chartId)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual ProcedureInfo1[] GetProcedures(string apiKey, int chartId)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual PatientDetail1 GetPatientDetail(string apiKey, string chartId)
|
||||
{
|
||||
if (ProductType.IsKeyLytec(apiKey))
|
||||
{
|
||||
return LytecConnector.GetPatientDetail(apiKey, null, chartId, true);
|
||||
}
|
||||
else if (ProductType.IsKeyMedisoft(apiKey))
|
||||
{
|
||||
return MedisoftConnector.GetPatientDetail(apiKey, null, chartId, true);
|
||||
}
|
||||
|
||||
MSLSpecific.Logger.Error("Invalid Product");
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual string CreatePatient(string apiKey, PatientInfo1 basicPatientInfo)
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
222
TomcatServer/PlutoServer.MSL/PlutoServer.MSL.csproj
Normal file
222
TomcatServer/PlutoServer.MSL/PlutoServer.MSL.csproj
Normal file
@@ -0,0 +1,222 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{36D78B93-9ECC-4BF1-852F-10E18B0EB41C}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>PlutoServer.MSL</RootNamespace>
|
||||
<AssemblyName>PlutoServer.MSL</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\Target\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\Target\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="log4net">
|
||||
<HintPath>Components\log4net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RemObjects.InternetPack, Version=7.0.63.1055, Culture=neutral, PublicKeyToken=3df3cad1b7aa5098, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Components\RemObjects.InternetPack.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="RemObjects.SDK, Version=7.0.63.1055, Culture=neutral, PublicKeyToken=3df3cad1b7aa5098, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Components\RemObjects.SDK.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="RemObjects.SDK.Server, Version=7.0.63.1055, Culture=neutral, PublicKeyToken=3df3cad1b7aa5098, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Components\RemObjects.SDK.Server.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="RemObjects.SDK.ZLib, Version=7.0.63.1055, Culture=neutral, PublicKeyToken=3df3cad1b7aa5098, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Components\RemObjects.SDK.ZLib.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Sdaleo, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\3rdParty\Sdaleo\Sdaleo.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.configuration" />
|
||||
<Reference Include="System.Configuration.Install" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Yaulw">
|
||||
<HintPath>..\..\3rdParty\Sdaleo\Yaulw.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\PlutoServer\PlutoApi_Events.cs">
|
||||
<Link>PlutoApi_Events.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\PlutoServer\PlutoApi_Intf.cs">
|
||||
<Link>PlutoApi_Intf.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\PlutoServer\PlutoApi_Invk.cs">
|
||||
<Link>PlutoApi_Invk.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Authentication_Impl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="AutoUpdate.cs" />
|
||||
<Compile Include="Billing_Impl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Configuration.cs" />
|
||||
<Compile Include="Connectors\DBCache.cs" />
|
||||
<Compile Include="Connectors\DBCacheDataStore.cs" />
|
||||
<Compile Include="Connectors\ProductType.cs" />
|
||||
<Compile Include="Connectors\LytecConnector.cs" />
|
||||
<Compile Include="Connectors\MedisoftConnector.cs" />
|
||||
<Compile Include="Constants.cs" />
|
||||
<Compile Include="DEBUGGING_ONLY.cs" />
|
||||
<Compile Include="Installer.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Installer.Designer.cs">
|
||||
<DependentUpon>Installer.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Medication_Impl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MSLSpecific_Impl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Patient_Impl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="PlutoService.MSL.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="PlutoService.MSL.Designer.cs">
|
||||
<DependentUpon>PlutoService.MSL.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Practice_Impl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Provider_Impl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="RegistrationWrapper.cs" />
|
||||
<Compile Include="Schedule_Impl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Connectors\SystemAccessVerifier.cs" />
|
||||
<Compile Include="Terminology_Impl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="PlutoService.MSL.resx">
|
||||
<DependentUpon>PlutoService.MSL.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\licenses.licx" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Windows Installer 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CrossProduct.Core\CrossProduct.Core.csproj">
|
||||
<Project>{D6CC42F0-0F08-457F-84D1-44D0D25715F6}</Project>
|
||||
<Name>CrossProduct.Core</Name>
|
||||
<Private>True</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\RegistrationAPI\RegistrationAPI.csproj">
|
||||
<Project>{D8974253-F538-4AA6-B567-48B7CD574888}</Project>
|
||||
<Name>RegistrationAPI</Name>
|
||||
<Private>True</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\TCMPortMapper\TCMPortMapper.csproj">
|
||||
<Project>{7D79CD16-563E-470E-8042-58863719544A}</Project>
|
||||
<Name>TCMPortMapper</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="PUBLISH.htm">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
6
TomcatServer/PlutoServer.MSL/PlutoServer.MSL.csproj.user
Normal file
6
TomcatServer/PlutoServer.MSL/PlutoServer.MSL.csproj.user
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectView>ShowAllFiles</ProjectView>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
102
TomcatServer/PlutoServer.MSL/PlutoService.MSL.Designer.cs
generated
Normal file
102
TomcatServer/PlutoServer.MSL/PlutoService.MSL.Designer.cs
generated
Normal file
@@ -0,0 +1,102 @@
|
||||
using System.Configuration;
|
||||
using System;
|
||||
namespace PlutoServer.MSL {
|
||||
partial class PlutoService {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing) {
|
||||
if(disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the Internal Port to use for the internal Channel
|
||||
/// </summary>
|
||||
/// <param name="Port">Port To use</param>
|
||||
private void SetInternalPort(int Port)
|
||||
{
|
||||
if (Port > 0 && this.MSLTcpServerChannelInternal.Port != Port)
|
||||
{
|
||||
this.MSLTcpServerChannelInternal.Port = Port;
|
||||
this.MSLTcpServerChannelInternal.TcpServer.Port = Port;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the External Port to use for the external Channel
|
||||
/// </summary>
|
||||
/// <param name="Port">Port To use</param>
|
||||
private void SetExternalPort(int Port)
|
||||
{
|
||||
if (Port > 0 && this.MSLTcpServerChannelExternal.Port != Port)
|
||||
{
|
||||
this.MSLTcpServerChannelExternal.Port = Port;
|
||||
this.MSLTcpServerChannelExternal.TcpServer.Port = Port;
|
||||
}
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.MSLBinMessage = new RemObjects.SDK.BinMessage();
|
||||
this.MSLTcpServerChannelInternal = new RemObjects.SDK.Server.IpTcpServerChannel(this.components);
|
||||
this.MSLTcpServerChannelExternal = new RemObjects.SDK.Server.IpTcpServerChannel(this.components);
|
||||
this.aesEncryptionEnvelope = new RemObjects.SDK.AesEncryptionEnvelope();
|
||||
((System.ComponentModel.ISupportInitialize)(this.MSLTcpServerChannelInternal)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.MSLTcpServerChannelExternal)).BeginInit();
|
||||
//
|
||||
// MSLBinMessage
|
||||
//
|
||||
this.MSLBinMessage.ContentType = "application/octet-stream";
|
||||
this.MSLBinMessage.Envelopes.Add(new RemObjects.SDK.MessageEnvelopeItem(this.aesEncryptionEnvelope));
|
||||
this.MSLBinMessage.SerializerInstance = null;
|
||||
//
|
||||
// MSLTcpServerChannelInternal
|
||||
//
|
||||
this.MSLTcpServerChannelInternal.Dispatchers.Add(new RemObjects.SDK.Server.MessageDispatcher("bin", this.MSLBinMessage));
|
||||
this.MSLTcpServerChannelInternal.Port = 1945;
|
||||
//
|
||||
//
|
||||
//
|
||||
this.MSLTcpServerChannelInternal.TcpServer.Port = 1945;
|
||||
//
|
||||
// MSLTcpServerChannelExternal
|
||||
//
|
||||
this.MSLTcpServerChannelExternal.Dispatchers.Add(new RemObjects.SDK.Server.MessageDispatcher("bin", this.MSLBinMessage));
|
||||
this.MSLTcpServerChannelExternal.Port = 0;
|
||||
//
|
||||
// aesEncryptionEnvelope
|
||||
//
|
||||
this.aesEncryptionEnvelope.EnvelopeMarker = "AES";
|
||||
this.aesEncryptionEnvelope.Password = "KxHWkkE5PAp4tuTzmPKQF7RUyylMk7VOV8zfYln2w6NZJMOvT3yrXofIJWxJYRSQwAkm8DysTG9k7";
|
||||
//
|
||||
// PlutoService
|
||||
//
|
||||
this.ServiceName = "PlutoServer.MSL";
|
||||
((System.ComponentModel.ISupportInitialize)(this.MSLTcpServerChannelInternal)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.MSLTcpServerChannelExternal)).EndInit();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private RemObjects.SDK.BinMessage MSLBinMessage;
|
||||
private RemObjects.SDK.Server.IpTcpServerChannel MSLTcpServerChannelInternal;
|
||||
private RemObjects.SDK.Server.IpTcpServerChannel MSLTcpServerChannelExternal;
|
||||
private RemObjects.SDK.AesEncryptionEnvelope aesEncryptionEnvelope;
|
||||
}
|
||||
}
|
||||
1150
TomcatServer/PlutoServer.MSL/PlutoService.MSL.cs
Normal file
1150
TomcatServer/PlutoServer.MSL/PlutoService.MSL.cs
Normal file
File diff suppressed because it is too large
Load Diff
135
TomcatServer/PlutoServer.MSL/PlutoService.MSL.resx
Normal file
135
TomcatServer/PlutoServer.MSL/PlutoService.MSL.resx
Normal file
@@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="MSLBinMessage.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 54</value>
|
||||
</metadata>
|
||||
<metadata name="MSLTcpServerChannelInternal.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 91</value>
|
||||
</metadata>
|
||||
<metadata name="MSLTcpServerChannelExternal.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>229, 55</value>
|
||||
</metadata>
|
||||
<metadata name="aesEncryptionEnvelope.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>218, 91</value>
|
||||
</metadata>
|
||||
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
||||
105
TomcatServer/PlutoServer.MSL/Practice_Impl.cs
Normal file
105
TomcatServer/PlutoServer.MSL/Practice_Impl.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
namespace Pluto.Api {
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using PlutoServer.MSL;
|
||||
using PlutoServer.MSL.Connectors;
|
||||
|
||||
[RemObjects.SDK.Server.ClassFactories.StandardClassFactory()]
|
||||
[RemObjects.SDK.Server.Service(Name = "Practice", InvokerClass = typeof(Practice_Invoker), ActivatorClass = typeof(Practice_Activator))]
|
||||
public class Practice : RemObjects.SDK.Server.Service, IPractice {
|
||||
private System.ComponentModel.Container components = null;
|
||||
public Practice() :
|
||||
base() {
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent() {
|
||||
}
|
||||
|
||||
protected override void Dispose(bool aDisposing) {
|
||||
if(aDisposing) {
|
||||
if((this.components != null)) {
|
||||
this.components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(aDisposing);
|
||||
}
|
||||
|
||||
public virtual PracticeInfo1[] GetPracticeList1(string apiKey)
|
||||
{
|
||||
// Not supported for current SystemApiKey Structure.
|
||||
// Each ApiKey binds to one specific practice
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual ProviderInfo1[] GetProviderList1(string apiKey, PracticeInfo1 practiceInfo)
|
||||
{
|
||||
if (ProductType.IsKeyLytec(apiKey))
|
||||
{
|
||||
return LytecConnector.GetProviderList(apiKey);
|
||||
}
|
||||
else if (ProductType.IsKeyMedisoft(apiKey))
|
||||
{
|
||||
return MedisoftConnector.GetProviderList(apiKey);
|
||||
}
|
||||
|
||||
MSLSpecific.Logger.Error("Invalid Product");
|
||||
return null;
|
||||
}
|
||||
|
||||
#region IPractice Members
|
||||
|
||||
public virtual PatientInfo1[] GetPatientList1(string apiKey, string lastName, string firstName, string dateOfBirth)
|
||||
{
|
||||
if (ProductType.IsKeyLytec(apiKey))
|
||||
{
|
||||
return LytecConnector.GetPatientList(apiKey, lastName, firstName, dateOfBirth);
|
||||
}
|
||||
else if (ProductType.IsKeyMedisoft(apiKey))
|
||||
{
|
||||
return MedisoftConnector.GetPatientList(apiKey, lastName, firstName, dateOfBirth);
|
||||
}
|
||||
|
||||
MSLSpecific.Logger.Error("Invalid Product");
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual MessageRecipientInfo1[] GetMessageRecipientList(string apiKey)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual FacilityInfo1[] GetFacilitiesList1(string apiKey)
|
||||
{
|
||||
if (ProductType.IsKeyLytec(apiKey))
|
||||
{
|
||||
return LytecConnector.GetFacilitiesList(apiKey);
|
||||
}
|
||||
else if (ProductType.IsKeyMedisoft(apiKey))
|
||||
{
|
||||
return MedisoftConnector.GetFacilitiesList(apiKey);
|
||||
}
|
||||
|
||||
MSLSpecific.Logger.Error("Invalid Product");
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual ResourceInfo1[] GetResourcesList1(string apiKey)
|
||||
{
|
||||
if (ProductType.IsKeyLytec(apiKey))
|
||||
{
|
||||
return LytecConnector.GetResourcesList(apiKey);
|
||||
}
|
||||
else if (ProductType.IsKeyMedisoft(apiKey))
|
||||
{
|
||||
return MedisoftConnector.GetResourcesList(apiKey);
|
||||
}
|
||||
|
||||
MSLSpecific.Logger.Error("Invalid Product");
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
29
TomcatServer/PlutoServer.MSL/Program.cs
Normal file
29
TomcatServer/PlutoServer.MSL/Program.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.ServiceProcess;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
|
||||
namespace PlutoServer.MSL {
|
||||
static class Program {
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
static void Main()
|
||||
{
|
||||
ServiceBase[] ServicesToRun;
|
||||
ServicesToRun = new ServiceBase[]
|
||||
{
|
||||
new PlutoService()
|
||||
};
|
||||
#if DEBUG
|
||||
PlutoService s = (PlutoService)ServicesToRun[0];
|
||||
s.DebugStart(null);
|
||||
#else
|
||||
ServiceBase.Run(ServicesToRun);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
36
TomcatServer/PlutoServer.MSL/Properties/AssemblyInfo.cs
Normal file
36
TomcatServer/PlutoServer.MSL/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("PlutoServer.MSL")]
|
||||
[assembly: AssemblyDescription("PlutoServer.MSL Service")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("McKesson")]
|
||||
[assembly: AssemblyProduct("PlutoServer.MSL")]
|
||||
[assembly: AssemblyCopyright("MckKesson Copyright © 2012")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("fb1035bf-62b6-4785-aba3-c9cf04917211")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.3.8")]
|
||||
[assembly: AssemblyFileVersion("1.0.3.8")]
|
||||
6
TomcatServer/PlutoServer.MSL/Properties/licenses.licx
Normal file
6
TomcatServer/PlutoServer.MSL/Properties/licenses.licx
Normal file
@@ -0,0 +1,6 @@
|
||||
RemObjects.SDK.Server.IpTcpServerChannel, RemObjects.SDK.Server, Version=7.0.63.1055, Culture=neutral, PublicKeyToken=3df3cad1b7aa5098
|
||||
RemObjects.SDK.Server.IpTcpServerChannel, RemObjects.SDK.Server, Version=6.0.57.993, Culture=neutral, PublicKeyToken=3df3cad1b7aa5098
|
||||
RemObjects.SDK.Server.IpTcpServerChannel, RemObjects.SDK.Server, Version=6.0.61.1033, Culture=neutral, PublicKeyToken=3df3cad1b7aa5098
|
||||
RemObjects.SDK.Server.OlympiaServerSessionManager, RemObjects.SDK.Server, Version=7.0.63.1055, Culture=neutral, PublicKeyToken=3df3cad1b7aa5098
|
||||
RemObjects.SDK.Server.OlympiaServerSessionManager, RemObjects.SDK.Server, Version=6.0.57.993, Culture=neutral, PublicKeyToken=3df3cad1b7aa5098
|
||||
RemObjects.SDK.Server.OlympiaServerSessionManager, RemObjects.SDK.Server, Version=6.0.61.1033, Culture=neutral, PublicKeyToken=3df3cad1b7aa5098
|
||||
53
TomcatServer/PlutoServer.MSL/Provider_Impl.cs
Normal file
53
TomcatServer/PlutoServer.MSL/Provider_Impl.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
namespace Pluto.Api {
|
||||
using System;
|
||||
using RemObjects.SDK;
|
||||
using RemObjects.SDK.Types;
|
||||
using RemObjects.SDK.Server;
|
||||
using RemObjects.SDK.Server.ClassFactories;
|
||||
using PlutoServer.MSL;
|
||||
using System.Linq;
|
||||
|
||||
[RemObjects.SDK.Server.ClassFactories.StandardClassFactory()]
|
||||
[RemObjects.SDK.Server.Service(Name = "Provider", InvokerClass = typeof(Provider_Invoker), ActivatorClass = typeof(Provider_Activator))]
|
||||
public class Provider : RemObjects.SDK.Server.Service, IProvider {
|
||||
private System.ComponentModel.Container components = null;
|
||||
public Provider() :
|
||||
base() {
|
||||
this.InitializeComponent();
|
||||
}
|
||||
private void InitializeComponent() {
|
||||
}
|
||||
protected override void Dispose(bool aDisposing) {
|
||||
if(aDisposing) {
|
||||
if((this.components != null)) {
|
||||
this.components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(aDisposing);
|
||||
}
|
||||
|
||||
#region IProvider Members
|
||||
|
||||
public MailboxFolderInfo1[] GetMailboxFoldersInfo(string apiKey, int providerId)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public FolderItemInfo1[] GetMailboxItems(string apiKey, MailboxFolderTypeEnum folderType)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public MessageInfo1 GetMessage(string apiKey, long messageId)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SendMessage(string apiKey, MessageInfo1 message)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
537
TomcatServer/PlutoServer.MSL/RegistrationWrapper.cs
Normal file
537
TomcatServer/PlutoServer.MSL/RegistrationWrapper.cs
Normal file
@@ -0,0 +1,537 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Pluto.Api;
|
||||
using System.Net;
|
||||
using PlutoServer.MSL.Connectors;
|
||||
|
||||
namespace PlutoServer.MSL
|
||||
{
|
||||
public static class RegistrationWrapper
|
||||
{
|
||||
// Allow the Registration wrapper to let the Service enter into a different 'disconnected' state
|
||||
internal static int HasConnectivityErrorCountInARow = 0;
|
||||
internal static int HasConnectivityErrorCountMaxBeforeStateChange = 10;
|
||||
internal static string RegistrationHOST = "";
|
||||
internal static uint RegistrationPORT = 0;
|
||||
|
||||
#region Connectivity
|
||||
|
||||
/// <summary>
|
||||
/// Check to make sure we can communicate with the Registration Service.
|
||||
/// Check the Server's ip & port for connectivity as well as that this
|
||||
/// computer has connectivity.
|
||||
/// This way we won't throw any connectivity errors, which is good.
|
||||
/// </summary>
|
||||
/// <returns>true, if successfully can connect, false otherwise</returns>
|
||||
private static bool HasConnectivity()
|
||||
{
|
||||
try
|
||||
{
|
||||
bool bCanConnect = false;
|
||||
bool bUseConfiguration = true;
|
||||
|
||||
// Try the overwritten Registration Host and Port first, if exists
|
||||
if (RegistrationHOST != "" && RegistrationPORT > 0)
|
||||
{
|
||||
bCanConnect = Yaulw.Net.IPHostHelper.HasConnectivity(RegistrationHOST, RegistrationPORT, 0);
|
||||
if (bCanConnect)
|
||||
bUseConfiguration = false;
|
||||
}
|
||||
|
||||
// Else, fall-back on the configuration, if we couldn't connect
|
||||
if (!bCanConnect)
|
||||
{
|
||||
bCanConnect = Yaulw.Net.IPHostHelper.HasConnectivity(Configuration.REGISTRATION_HOST_URL, (uint)Configuration.REGISTRATION_CHANNEL_PORT, 0);
|
||||
if (bCanConnect)
|
||||
bUseConfiguration = true;
|
||||
}
|
||||
|
||||
if (bCanConnect)
|
||||
{
|
||||
MSLSpecific.Logger.Info("Network Communication successful with the McKesson's Mobile Gateway bUseConfiguration={0}", bUseConfiguration.ToString());
|
||||
if (bUseConfiguration)
|
||||
{
|
||||
IPAddress ip = Yaulw.Net.IPHostHelper.GetIpForHost(Configuration.REGISTRATION_HOST_URL);
|
||||
RegistrationAPI.API.SetNetworkSettings(ip.ToString(), (uint)Configuration.REGISTRATION_CHANNEL_PORT);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPAddress ip = Yaulw.Net.IPHostHelper.GetIpForHost(RegistrationHOST);
|
||||
RegistrationAPI.API.SetNetworkSettings(ip.ToString(), RegistrationPORT);
|
||||
}
|
||||
HasConnectivityErrorCountInARow = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try to retrieve the latest Host and Port Setting online
|
||||
try
|
||||
{
|
||||
string HostNPortSetOnline = Yaulw.Net.WCHelper.ScreenScrapeFromURL(Configuration.REGISTRATION_HOST_N_PORT_URL);
|
||||
if (!String.IsNullOrEmpty(HostNPortSetOnline))
|
||||
{
|
||||
RegistrationHOST = HostNPortSetOnline.Split(';')[0];
|
||||
RegistrationPORT = uint.Parse(HostNPortSetOnline.Split(';')[1]);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MSLSpecific.Logger.Error("Retrieving Host and Port Setting from REGISTRATION_HOST_N_PORT_URL failed", e);
|
||||
}
|
||||
|
||||
// Try to connection one more time
|
||||
if (RegistrationHOST != "" && RegistrationPORT > 0)
|
||||
bCanConnect = Yaulw.Net.IPHostHelper.HasConnectivity(RegistrationHOST, RegistrationPORT, 0);
|
||||
|
||||
// if we can connect, we are Golden
|
||||
if (bCanConnect)
|
||||
{
|
||||
MSLSpecific.Logger.Info("Network Communication successful with the McKesson's Mobile Gateway bUseConfiguration=False");
|
||||
IPAddress ip = Yaulw.Net.IPHostHelper.GetIpForHost(RegistrationHOST);
|
||||
RegistrationAPI.API.SetNetworkSettings(ip.ToString(), RegistrationPORT);
|
||||
HasConnectivityErrorCountInARow = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Connectivity Errors too plentiful - Change the state of the service to reflect that
|
||||
if (HasConnectivityErrorCountInARow >= HasConnectivityErrorCountMaxBeforeStateChange)
|
||||
{
|
||||
MSLSpecific.Logger.Info("Entering no_Connectivity to McKesson's Mobile Gateway state");
|
||||
PlutoService.state = HostGUIDstate.no_connectivity;
|
||||
}
|
||||
else
|
||||
{
|
||||
MSLSpecific.Logger.Error("Network Communication unsuccessful with McKesson's Mobile Gateway");
|
||||
HasConnectivityErrorCountInARow++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bCanConnect;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MSLSpecific.Logger.Error("HasConnectivity() error thrown", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Registration Specifics that don't require network
|
||||
|
||||
/// <summary>
|
||||
/// Get a Practice Name with (MCK) in it (for internal usuage)
|
||||
/// </summary>
|
||||
/// <param name="PracticeName"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetMCKPractice(string PracticeName)
|
||||
{
|
||||
return RegistrationAPI.API.GetMcKInternalizedPracticeName(PracticeName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Update Server
|
||||
|
||||
/// <summary>
|
||||
/// Update Server Internal / External
|
||||
/// </summary>
|
||||
/// <param name="internalIP"></param>
|
||||
/// <param name="externalIP"></param>
|
||||
/// <param name="Port"></param>
|
||||
public static void UpdateServerIntExt(IPAddress internalIP, IPAddress externalIP, uint Port)
|
||||
{
|
||||
string LocalIP = "";
|
||||
if (Yaulw.Net.IPHostHelper.IsValidIPv4Address(internalIP, false))
|
||||
LocalIP = internalIP.ToString();
|
||||
|
||||
string ExternalIP = "";
|
||||
if (Yaulw.Net.IPHostHelper.IsValidIPv4Address(externalIP, false))
|
||||
ExternalIP = externalIP.ToString();
|
||||
|
||||
if ((!String.IsNullOrEmpty(LocalIP) || !String.IsNullOrEmpty(ExternalIP)) || Port > 0)
|
||||
UpdateServerIntExt(LocalIP, ExternalIP, Port);
|
||||
else
|
||||
MSLSpecific.Logger.Info("UpdateServerIntExt was called with invalid parameters. Registration not updated.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update Server Internal / External (actually does the work)
|
||||
/// </summary>
|
||||
/// <param name="internalIP"></param>
|
||||
/// <param name="externalIP"></param>
|
||||
/// <param name="Port"></param>
|
||||
private static void UpdateServerIntExt(string internalIP, string externalIP, uint Port)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(HasConnectivity())
|
||||
{
|
||||
bool bSuccess = RegistrationAPI.API.UpdateServer(MSLSpecific.GetHostGUID(), internalIP, externalIP, Port);
|
||||
if (bSuccess)
|
||||
MSLSpecific.Logger.Info("Updating IP Internal/External information occured successfully for Host:{0} LocalIP:{1}, ExternalIP:{2}, Port:{3}", MSLSpecific.GetHostGUID(), internalIP, externalIP, Port);
|
||||
else
|
||||
MSLSpecific.Logger.Error("Updating IP Internal/External information failed for Host:{0} LocalIP:{1}, ExternalIP:{2}, Port:{3}", MSLSpecific.GetHostGUID(), internalIP, externalIP, Port);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MSLSpecific.Logger.Error("UdateServerIntExt Error Thrown", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update Server Internal
|
||||
/// </summary>
|
||||
/// <param name="internalIP"></param>
|
||||
/// <param name="Port"></param>
|
||||
public static void UpdateServerInternal(IPAddress internalIP)
|
||||
{
|
||||
string LocalIP = "";
|
||||
if (Yaulw.Net.IPHostHelper.IsValidIPv4Address(internalIP, false))
|
||||
LocalIP = internalIP.ToString();
|
||||
|
||||
if (!String.IsNullOrEmpty(LocalIP))
|
||||
UpdateServerInternal(LocalIP);
|
||||
else
|
||||
MSLSpecific.Logger.Info("UpdateServerInternal was called with invalid parameters. Registration not updated.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update Server Internal (actually does the work)
|
||||
/// </summary>
|
||||
/// <param name="bLog"></param>
|
||||
/// <param name="internalIP"></param>
|
||||
/// <param name="Port"></param>
|
||||
private static void UpdateServerInternal(string internalIP)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (HasConnectivity())
|
||||
{
|
||||
bool bSuccess = RegistrationAPI.API.UpdateServer(MSLSpecific.GetHostGUID(), internalIP, String.Empty, PlutoService.INTERNAL_CHANNEL_PORT);
|
||||
if (bSuccess)
|
||||
MSLSpecific.Logger.Info("Updating IP Internal information occured successfully for Host:{0} LocalIP:{1}, Port:{2}", MSLSpecific.GetHostGUID(), internalIP, PlutoService.INTERNAL_CHANNEL_PORT);
|
||||
else
|
||||
MSLSpecific.Logger.Error("Updating IP Internal information failed for Host:{0} LocalIP:{1}, Port:{2}", MSLSpecific.GetHostGUID(), internalIP, PlutoService.INTERNAL_CHANNEL_PORT);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MSLSpecific.Logger.Error("UpdateServerInternal Error Thrown", e);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Register Update/New Practice
|
||||
|
||||
/// <summary>
|
||||
/// Register New Practice
|
||||
/// </summary>
|
||||
/// <param name="PracticeName">Name of Practice</param>
|
||||
/// <param name="bIsMedisoft">Is Medisoft</param>
|
||||
/// <param name="strApiKey">out ApiKey</param>
|
||||
/// <param name="strPin">out Pin</param>
|
||||
/// <returns>true, if successful, false otherwise</returns>
|
||||
public static bool RegisterNewPractice(string PracticeName, bool bIsMedisoft, out string strApiKey, out string strPin)
|
||||
{
|
||||
strApiKey = "";
|
||||
strPin = "";
|
||||
try
|
||||
{
|
||||
if (HasConnectivity())
|
||||
{
|
||||
// Set up local IP
|
||||
string LocalIP = "";
|
||||
if (Yaulw.Net.IPHostHelper.IsValidIPv4Address(PlutoService.InternalIP, false))
|
||||
LocalIP = PlutoService.InternalIP.ToString();
|
||||
|
||||
// Set up external IP and Port
|
||||
string ExternalIP = "";
|
||||
uint Port = 0;
|
||||
if (PlutoService.IsExtIPandExtPortSet)
|
||||
{
|
||||
if (Yaulw.Net.IPHostHelper.IsValidIPv4Address(PlutoService.ExternalIP, false))
|
||||
ExternalIP = PlutoService.ExternalIP.ToString();
|
||||
Port = PlutoService.ExternalPort;
|
||||
}
|
||||
else
|
||||
{
|
||||
Port = PlutoService.INTERNAL_CHANNEL_PORT;
|
||||
}
|
||||
|
||||
// Set up Practice Name
|
||||
if (PlutoService.IsOnMcKessonNetwork)
|
||||
PracticeName = GetMCKPractice(PracticeName);
|
||||
|
||||
// Set up Product Name
|
||||
string ProductName = ProductType.GetProductName(bIsMedisoft);
|
||||
|
||||
// Make the Registration Call
|
||||
MSLSpecific.Logger.Info("Registering PracticeName:{0}, LocalIP:{1}, ExternalIP:{2}, Port:{3}, ProductName:{4} for Host:{5}", PracticeName, LocalIP, ExternalIP, Port, ProductName, MSLSpecific.GetHostGUID());
|
||||
bool bSuccess = RegistrationAPI.API.RegisterNewServerPractice(MSLSpecific.GetHostGUID(), PracticeName, LocalIP, ExternalIP, Port, ProductName, out strApiKey, out strPin);
|
||||
if (bSuccess)
|
||||
MSLSpecific.Logger.Info("Registering Practice successfully");
|
||||
else
|
||||
MSLSpecific.Logger.Error("Registering Practice failed");
|
||||
return bSuccess;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MSLSpecific.Logger.Error("RegisterNewPractice Error Thrown", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update Practice Name
|
||||
/// </summary>
|
||||
/// <param name="UserApiKey"></param>
|
||||
/// <param name="Pin"></param>
|
||||
/// <param name="NewPracticeName"></param>
|
||||
/// <returns></returns>
|
||||
public static bool UpdatePracticeName(string UserApiKey, string Pin, string NewPracticeName)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (HasConnectivity())
|
||||
{
|
||||
// Set up Practice Name
|
||||
if (PlutoService.IsOnMcKessonNetwork)
|
||||
NewPracticeName = GetMCKPractice(NewPracticeName);
|
||||
|
||||
bool bSuccess = RegistrationAPI.API.UpdatePracticeName(UserApiKey, Pin, NewPracticeName);
|
||||
if (bSuccess)
|
||||
MSLSpecific.Logger.Info("Updating Practice Name successfully");
|
||||
else
|
||||
MSLSpecific.Logger.Error("Updating Practice Name failed");
|
||||
return bSuccess;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MSLSpecific.Logger.Error("UpdatePracticeName Error Thrown", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Other Register Methods
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve Pin for UserApiKey
|
||||
/// </summary>
|
||||
/// <param name="UserApiKey"></param>
|
||||
/// <returns></returns>
|
||||
public static string RetrievePinForUserApiKey(string UserApiKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (HasConnectivity())
|
||||
{
|
||||
if (!String.IsNullOrEmpty(UserApiKey))
|
||||
{
|
||||
string Pin = RegistrationAPI.API.RetrieveUserApiKeyPin(UserApiKey);
|
||||
return Pin;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MSLSpecific.Logger.Error("RetrievePinForUserApiKey Error Thrown", e);
|
||||
}
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this Server reachable online
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool IsServerReachable()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (PlutoService.IsOnMcKessonNetwork)
|
||||
{
|
||||
MSLSpecific.Logger.Info("This host/server is in WIFI only mode, due to being on the McKesson Network");
|
||||
PlutoService.AppLogWarning("This is a host/server is in WIFI only mode, due to being on the McKesson Network");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!PlutoService.IsExtIPandExtPortSet)
|
||||
{
|
||||
MSLSpecific.Logger.Info("This host/server is in WIFI only mode, external connectivity not configured");
|
||||
PlutoService.AppLogWarning("This is a host/server is in WIFI only mode, external connectivity not configured");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (HasConnectivity())
|
||||
{
|
||||
bool bSuccess = RegistrationAPI.API.IsServerReachable(PlutoService.ExternalIP.ToString(), PlutoService.ExternalPort);
|
||||
if (bSuccess)
|
||||
MSLSpecific.Logger.Info("The server/host was reachable (success) on External IP:{0} and Port:{1}", PlutoService.ExternalIP.ToString(), PlutoService.ExternalPort);
|
||||
else
|
||||
MSLSpecific.Logger.Error("The server/host was unreachable (failure) on External IP:{0} and Port:{1}", PlutoService.ExternalIP.ToString(), PlutoService.ExternalPort);
|
||||
return bSuccess;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MSLSpecific.Logger.Error("IsServerReachable Error Thrown", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is a specific Server reachable online
|
||||
/// </summary>
|
||||
/// <param name="bLog"></param>
|
||||
/// <param name="externalIP"></param>
|
||||
/// <param name="Port"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsServerReachable(IPAddress externalIP, uint Port)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Set up external IP
|
||||
string ExtIP = "";
|
||||
if (Yaulw.Net.IPHostHelper.IsValidIPv4Address(externalIP, false))
|
||||
ExtIP = externalIP.ToString();
|
||||
if (String.IsNullOrEmpty(ExtIP))
|
||||
{
|
||||
MSLSpecific.Logger.Info("Invalid External IP passed in");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check Port
|
||||
if (Port <= 0)
|
||||
{
|
||||
MSLSpecific.Logger.Info("Invalid Port passed in");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check Connectivity
|
||||
if (HasConnectivity())
|
||||
{
|
||||
bool bSuccess = RegistrationAPI.API.IsServerReachable(ExtIP, Port);
|
||||
if (bSuccess)
|
||||
MSLSpecific.Logger.Info("The server/host was reachable (success) on External IP:{0} and Port:{1}", ExtIP, Port);
|
||||
else
|
||||
MSLSpecific.Logger.Error("The server/host was unreachable (failure) on External IP:{0} and Port:{1}", ExtIP, Port);
|
||||
return bSuccess;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MSLSpecific.Logger.Error(String.Format("IsServerReachable Error Thrown with ExtIP={0} and Port={1}", externalIP.ToString(), Port.ToString()), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the HostGUID from a Server/Port if that Server Port is running Pluto
|
||||
/// </summary>
|
||||
/// <param name="externalIP"></param>
|
||||
/// <param name="Port"></param>
|
||||
/// <returns>HostGUID or "" if none found</returns>
|
||||
public static string RetrieveHostGUIDForServer(IPAddress externalIP, uint Port)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Set up external IP
|
||||
string ExtIP = "";
|
||||
if (Yaulw.Net.IPHostHelper.IsValidIPv4Address(externalIP, false))
|
||||
ExtIP = externalIP.ToString();
|
||||
if (String.IsNullOrEmpty(ExtIP))
|
||||
{
|
||||
MSLSpecific.Logger.Info("Invalid External IP passed in");
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
// Check Port
|
||||
if (Port <= 0)
|
||||
{
|
||||
MSLSpecific.Logger.Info("Invalid Port passed in");
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
if(HasConnectivity())
|
||||
{
|
||||
string retVal = RegistrationAPI.API.RetrievePlutoHostGUID(externalIP.ToString(), Port);
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MSLSpecific.Logger.Error("RetrieveHostGUIDForServer Error Thrown", e);
|
||||
}
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Connectivity / HOST Guid State * Important for Integrity Checking *
|
||||
/// </summary>
|
||||
public enum HostGUIDstate
|
||||
{
|
||||
exists,
|
||||
not_exists,
|
||||
no_connectivity
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Quick Check to see if our host guid even exists on the server, if it doesn't
|
||||
/// then no need to call UpdateServer() in any form
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static HostGUIDstate DoesServerHostGuidExist()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (HasConnectivity())
|
||||
{
|
||||
bool bExists = RegistrationAPI.API.DoesServerHostGUIDExist(MSLSpecific.GetHostGUID());
|
||||
if (bExists)
|
||||
{
|
||||
MSLSpecific.Logger.Info("HostGuid found on Mobile Gateway Server. Some Practice(s) are registered online");
|
||||
return HostGUIDstate.exists;
|
||||
}
|
||||
else
|
||||
{
|
||||
MSLSpecific.Logger.Info("HostGuid not found on Mobile Gateway Server. No Practice is registered online");
|
||||
return HostGUIDstate.not_exists;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MSLSpecific.Logger.Error("DoesServerHostGuidExist Error Thrown", e);
|
||||
}
|
||||
return HostGUIDstate.no_connectivity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Let the Registration Service know what we have been updated
|
||||
/// </summary>
|
||||
/// <param name="version"></param>
|
||||
public static void ServerHasBeenUpdated(string version)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (HasConnectivity())
|
||||
{
|
||||
RegistrationAPI.API.ServerHasBeenUpdated(MSLSpecific.GetHostGUID(), version);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MSLSpecific.Logger.Error("ServerHasBeenUpdated Error Thrown", e);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
68
TomcatServer/PlutoServer.MSL/Schedule_Impl.cs
Normal file
68
TomcatServer/PlutoServer.MSL/Schedule_Impl.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
namespace Pluto.Api {
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using PlutoServer.MSL;
|
||||
using System;
|
||||
using PlutoServer.MSL.Connectors;
|
||||
|
||||
[RemObjects.SDK.Server.ClassFactories.StandardClassFactory()]
|
||||
[RemObjects.SDK.Server.Service(Name = "Schedule", InvokerClass = typeof(Schedule_Invoker), ActivatorClass = typeof(Schedule_Activator))]
|
||||
public class Schedule : RemObjects.SDK.Server.Service, ISchedule {
|
||||
private System.ComponentModel.Container components = null;
|
||||
public Schedule() :
|
||||
base() {
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent() {
|
||||
}
|
||||
|
||||
protected override void Dispose(bool aDisposing) {
|
||||
if(aDisposing) {
|
||||
if((this.components != null)) {
|
||||
this.components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(aDisposing);
|
||||
}
|
||||
|
||||
public virtual AppointmentInfo1[] GetAppointments1(string apiKey, ProviderInfo1[] providerInfo, ResourceInfo1[] resourceInfo, System.DateTime startDate, System.DateTime endDate)
|
||||
{
|
||||
if (ProductType.IsKeyLytec(apiKey))
|
||||
{
|
||||
return LytecConnector.GetAppointments(apiKey, providerInfo, resourceInfo, startDate, endDate);
|
||||
}
|
||||
else if (ProductType.IsKeyMedisoft(apiKey))
|
||||
{
|
||||
return MedisoftConnector.GetAppointments(apiKey, providerInfo, resourceInfo, startDate, endDate);
|
||||
}
|
||||
|
||||
MSLSpecific.Logger.Error("Invalid Product");
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual AppointmentDetail1 GetAppointmentDetail1(string apiKey, int ApptID,bool bCalculateBalance)
|
||||
{
|
||||
if (ProductType.IsKeyLytec(apiKey))
|
||||
{
|
||||
return LytecConnector.GetAppointmentDetail(apiKey, ApptID, bCalculateBalance);
|
||||
}
|
||||
else if (ProductType.IsKeyMedisoft(apiKey))
|
||||
{
|
||||
return MedisoftConnector.GetAppointmentDetail(apiKey, ApptID, bCalculateBalance);
|
||||
}
|
||||
|
||||
MSLSpecific.Logger.Error("Invalid Product");
|
||||
return null;
|
||||
}
|
||||
|
||||
#region ISchedule Members
|
||||
|
||||
public bool AddAppointment1(string apiKey, AppointmentInfo1 appointmentInfo) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
59
TomcatServer/PlutoServer.MSL/Terminology_Impl.cs
Normal file
59
TomcatServer/PlutoServer.MSL/Terminology_Impl.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
namespace Pluto.Api {
|
||||
using System;
|
||||
using RemObjects.SDK;
|
||||
using RemObjects.SDK.Types;
|
||||
using RemObjects.SDK.Server;
|
||||
using RemObjects.SDK.Server.ClassFactories;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using PlutoServer.MSL;
|
||||
using PlutoServer.MSL.Connectors;
|
||||
|
||||
[RemObjects.SDK.Server.ClassFactories.StandardClassFactory()]
|
||||
[RemObjects.SDK.Server.Service(Name = "Terminology", InvokerClass = typeof(Terminology_Invoker), ActivatorClass = typeof(Terminology_Activator))]
|
||||
public class Terminology : RemObjects.SDK.Server.Service, ITerminology {
|
||||
private System.ComponentModel.Container components = null;
|
||||
public Terminology() :
|
||||
base() {
|
||||
this.InitializeComponent();
|
||||
}
|
||||
private void InitializeComponent() {
|
||||
}
|
||||
protected override void Dispose(bool aDisposing) {
|
||||
if(aDisposing) {
|
||||
if((this.components != null)) {
|
||||
this.components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(aDisposing);
|
||||
}
|
||||
|
||||
#region ITerminology Members
|
||||
|
||||
public TerminologyInfo1[] SearchTerminology(string apiKey, string searchString, TerminologySearchTypeEnum searchType, TerminologyDomainEnum terminologyDomain, string chartID)
|
||||
{
|
||||
bool bDoDiagnosisSearch = (terminologyDomain == TerminologyDomainEnum.DiagnosesAll);
|
||||
bool bDoProceduresSearch = (terminologyDomain == TerminologyDomainEnum.ProceduresAll);
|
||||
|
||||
if (ProductType.IsKeyLytec(apiKey))
|
||||
{
|
||||
if(bDoDiagnosisSearch)
|
||||
return LytecConnector.GetDiagnosisList(apiKey, searchString);
|
||||
if(bDoProceduresSearch)
|
||||
return LytecConnector.GetProceduresList(apiKey, chartID, searchString);
|
||||
}
|
||||
else if (ProductType.IsKeyMedisoft(apiKey))
|
||||
{
|
||||
if (bDoDiagnosisSearch)
|
||||
return MedisoftConnector.GetDiagnosisList(apiKey, searchString);
|
||||
if (bDoProceduresSearch)
|
||||
return MedisoftConnector.GetProceduresList(apiKey, chartID, searchString);
|
||||
}
|
||||
|
||||
// Something Failed
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
15
TomcatServer/PlutoServer.MSL/app.config
Normal file
15
TomcatServer/PlutoServer.MSL/app.config
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v2.0.50727"/>
|
||||
</startup>
|
||||
<appSettings>
|
||||
<add key="REGISTRATION_HOST_N_PORT_URL" value="http://ppsmobile.mckesson.com/mobile1/REGURL.htm" />
|
||||
<add key="REGISTRATION_HOST_URL" value="ppsmobile.mckesson.com" />
|
||||
<add key="REGISTRATION_CHANNEL_PORT" value="443" />
|
||||
<add key="CHECK_VERSION_URL" value="http://ppsmobile.mckesson.com/mobile1/PUBLISH.htm" />
|
||||
<add key="DOWNLOAD_SETUP_URL" value="http://ppsmobile.mckesson.com/mobile1/Setup.exe" />
|
||||
<add key="DOWNLOAD_MINISETUP_URL" value="http://ppsmobile.mckesson.com/mobile1/SetupMini.exe" />
|
||||
<add key="DETERMINE_EXTERNAL_IP_ADDRESS_URL" value="http://ppsmobile.mckesson.com/GetIP/default.aspx" />
|
||||
</appSettings>
|
||||
</configuration>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
C:\Users\Administrator\Projects\Pluto\Server\PlutoServer.MSL\obj\x86\Debug\ResolveAssemblyReference.cache
|
||||
C:\Users\Administrator\Projects\Pluto\Server\PlutoServer.MSL\obj\x86\Debug\PlutoServer.MSL.PlutoService.resources
|
||||
C:\Users\Administrator\Projects\Pluto\Server\PlutoServer.MSL\obj\x86\Debug\ResGen.read.1.tlog
|
||||
C:\Users\Administrator\Projects\Pluto\Server\PlutoServer.MSL\obj\x86\Debug\ResGen.write.1.tlog
|
||||
C:\Users\Administrator\Projects\Pluto\Server\PlutoServer.MSL\obj\x86\Debug\PlutoServer.MSL.exe.licenses
|
||||
C:\Users\Administrator\Projects\Pluto\Server\Target\Debug\MLServer.config
|
||||
C:\Users\Administrator\Projects\Pluto\Server\Target\Debug\PlutoServer.MSL.exe.config
|
||||
C:\Users\Administrator\Projects\Pluto\Server\Target\Debug\PlutoServer.MSL.exe
|
||||
C:\Users\Administrator\Projects\Pluto\Server\Target\Debug\PlutoServer.MSL.pdb
|
||||
C:\Users\Administrator\Projects\Pluto\Server\PlutoServer.MSL\obj\x86\Debug\PlutoServer.MSL.exe
|
||||
C:\Users\Administrator\Projects\Pluto\Server\PlutoServer.MSL\obj\x86\Debug\PlutoServer.MSL.pdb
|
||||
\\192.168.2.7\bin\FTP-Private\Pluto\Server\Target\Debug\PlutoServer.MSL.exe.config
|
||||
\\192.168.2.7\bin\FTP-Private\Pluto\Server\PlutoServer.MSL\obj\x86\Debug\PlutoServer.MSL.exe
|
||||
\\192.168.2.7\bin\FTP-Private\Pluto\Server\PlutoServer.MSL\obj\x86\Debug\PlutoServer.MSL.pdb
|
||||
BIN
TomcatServer/PlutoServer.MSL/obj/x86/Debug/PlutoServer.MSL.exe
Normal file
BIN
TomcatServer/PlutoServer.MSL/obj/x86/Debug/PlutoServer.MSL.exe
Normal file
Binary file not shown.
BIN
TomcatServer/PlutoServer.MSL/obj/x86/Debug/PlutoServer.MSL.pdb
Normal file
BIN
TomcatServer/PlutoServer.MSL/obj/x86/Debug/PlutoServer.MSL.pdb
Normal file
Binary file not shown.
BIN
TomcatServer/PlutoServer.MSL/obj/x86/Debug/ResGen.read.1.tlog
Normal file
BIN
TomcatServer/PlutoServer.MSL/obj/x86/Debug/ResGen.read.1.tlog
Normal file
Binary file not shown.
BIN
TomcatServer/PlutoServer.MSL/obj/x86/Debug/ResGen.write.1.tlog
Normal file
BIN
TomcatServer/PlutoServer.MSL/obj/x86/Debug/ResGen.write.1.tlog
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
C:\Users\Administrator\Projects\Pluto\Server\TargetRelease\PlutoServer.MSL.exe.config
|
||||
C:\Users\Administrator\Projects\Pluto\Server\TargetRelease\PlutoServer.MSL.exe
|
||||
C:\Users\Administrator\Projects\Pluto\Server\TargetRelease\PlutoServer.MSL.pdb
|
||||
C:\Users\Administrator\Projects\Pluto\Server\PlutoServer.MSL\obj\x86\Release\ResolveAssemblyReference.cache
|
||||
C:\Users\Administrator\Projects\Pluto\Server\PlutoServer.MSL\obj\x86\Release\PlutoServer.MSL.PlutoService.resources
|
||||
C:\Users\Administrator\Projects\Pluto\Server\PlutoServer.MSL\obj\x86\Release\ResGen.read.1.tlog
|
||||
C:\Users\Administrator\Projects\Pluto\Server\PlutoServer.MSL\obj\x86\Release\ResGen.write.1.tlog
|
||||
C:\Users\Administrator\Projects\Pluto\Server\PlutoServer.MSL\obj\x86\Release\PlutoServer.MSL.exe.licenses
|
||||
C:\Users\Administrator\Projects\Pluto\Server\PlutoServer.MSL\obj\x86\Release\PlutoServer.MSL.exe
|
||||
C:\Users\Administrator\Projects\Pluto\Server\PlutoServer.MSL\obj\x86\Release\PlutoServer.MSL.pdb
|
||||
C:\Users\Administrator\Projects\Pluto\Server\Target\Release\PlutoServer.MSL.exe.config
|
||||
C:\Users\Administrator\Projects\Pluto\Server\Target\Release\PlutoServer.MSL.exe
|
||||
C:\Users\Administrator\Projects\Pluto\Server\Target\Release\PlutoServer.MSL.pdb
|
||||
C:\Users\Administrator\Projects\Pluto\Server\Target\Release\MLServer.config
|
||||
BIN
TomcatServer/PlutoServer.MSL/obj/x86/Release/PlutoServer.MSL.exe
Normal file
BIN
TomcatServer/PlutoServer.MSL/obj/x86/Release/PlutoServer.MSL.exe
Normal file
Binary file not shown.
BIN
TomcatServer/PlutoServer.MSL/obj/x86/Release/PlutoServer.MSL.pdb
Normal file
BIN
TomcatServer/PlutoServer.MSL/obj/x86/Release/PlutoServer.MSL.pdb
Normal file
Binary file not shown.
BIN
TomcatServer/PlutoServer.MSL/obj/x86/Release/ResGen.read.1.tlog
Normal file
BIN
TomcatServer/PlutoServer.MSL/obj/x86/Release/ResGen.read.1.tlog
Normal file
Binary file not shown.
BIN
TomcatServer/PlutoServer.MSL/obj/x86/Release/ResGen.write.1.tlog
Normal file
BIN
TomcatServer/PlutoServer.MSL/obj/x86/Release/ResGen.write.1.tlog
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user