Initial Commit

This commit is contained in:
2016-07-27 00:32:34 -04:00
commit 8d162b2035
701 changed files with 188672 additions and 0 deletions

View 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
}
}