Initial Commit
This commit is contained in:
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user