/// <summary>
 /// Simple constructor.  Make sure to instantiate the settings instance class, which is defined in the base class.
 /// </summary>
 public ConfigurationService()
 {
     settingsInstance = new Trade.StockTraderWebApplicationSettings.Settings();
 }
        /// <summary>
        /// This method performs the logic required when a specific configuration settings key is changed.  This includes 
        /// potentially updating configuration database, notifying nodes, and performing configuration actions.
        /// </summary>
        /// <param name="targetHostNameIdentifier">The name of the target host we are seeking, as specified in the target's HOST_NAME_IDENTIFIER settings key.</param>
        /// <param name="targetConfigServiceName">The fully qualified name of the Configuration Service implementation class for the host we are seeking, used in
        /// conjunction with targetHostNameIdentifier to uniquely identify a target host.</param>
        /// <param name="oldKey">The key prior to update.</param>
        /// <param name="newKey">The updated key.</param>
        /// <param name="notifyNodes">If true, key update will be flowed to peer nodes.</param>
        /// <param name="action">Action to perform.</param>
        /// <param name="traversePath">Network path to the target host.</param>
        /// <param name="csUser">User to authenticate.</param>
        /// <returns>Int representing success code.</returns>
        public override int receiveConfigurationKey(string targetHostNameIdentifier, string targetConfigServiceNameIdentifier, ConfigurationKeyValues oldKey, ConfigurationKeyValues newKey, bool notifyNodes, string action, List<TraverseNode> traversePath, ServiceUsers csUser)
        {
            ServiceConfigHelper configHelper = new ServiceConfigHelper(settingsInstance);
            bool success = true;
            object theSettingsInstance = new Trade.StockTraderWebApplicationSettings.Settings();
            IConfigurationActions configActions;
            int returnCode = ConfigUtility.CLUSTER_UPDATE_FULL_SUCCESS;
            try
            {
                if (!(configHelper.setServiceRights(ref csUser, ConfigUtility.CONFIG_ADMIN_RIGHTS) >= ConfigUtility.CONFIG_ADMIN_RIGHTS))
                    return ConfigUtility.CLUSTER_UPDATE_FAIL_AUTHENTICATION;
                configActions = (IConfigurationActions)ConfigUtility.reflectGetField(settingsInstance, "thisServiceConfigActions");
                if ((action != ConfigUtility.ADD_KEY && action != ConfigUtility.REMOVE_KEY) && (traversePath == null || traversePath.Count <= 1 || traversePath[0] == null))
                {
                    if (targetHostNameIdentifier.Equals(StockTraderUtility.WEB_APPLICATION) || targetHostNameIdentifier.Equals(StockTraderUtility.WEB_APPLICATION_Azure))
                    {
                        if (!configActions.validateConfigurationKey(settingsInstance, newKey))
                            return ConfigUtility.CLUSTER_UPDATE_FAIL_VALIDATION;
                    }
                }
                ConfigUtility.writeConfigConsoleMessage("\nReceived Request for Configuration Key Change, Action: " + action + ". Keyname: " + oldKey.ConfigurationKeyDisplayName + "\n", EventLogEntryType.Information, true, settingsInstance);
                ConfigUtility.writeConfigConsoleMessage("Value: " + newKey.ConfigurationKeyValue + "\n\n", EventLogEntryType.Information, true, settingsInstance);
                if (traversePath == null || traversePath.Count <= 1 || traversePath[0] == null)
                {
                    bool SHARESERVICECONFIGURATIONDATA = (bool)ConfigUtility.reflectGetField(settingsInstance, "SHARESERVICECONFIGURATIONDATA");
                    if (!SHARESERVICECONFIGURATIONDATA)
                    {
                        List<ServiceUsers> thisServiceUsers = (List<ServiceUsers>)ConfigUtility.reflectGetField(settingsInstance, "thisServiceUsers");
                        ServiceUsers userLocalAdmin = thisServiceUsers.Find(delegate(ServiceUsers userExist) { return csUser.UserId.ToLower().Equals("localadmin") && userExist.Password.Equals(csUser.Password) && csUser.Rights == ConfigUtility.CONFIG_ADMIN_RIGHTS; });
                        if (userLocalAdmin == null)
                            return ConfigUtility.CLUSTER_UPDATE_FULL_SUCCESS;
                    }
                    switch (targetHostNameIdentifier)
                    {
                        case StockTraderUtility.IISHOST_BUSINESS_SERVICES:
                            {
                                theSettingsInstance = new Trade.BusinessServiceConfigurationSettings.Settings();
                                Trade.BusinessServiceHostConfigurationImplementation.ConfigurationService configService = new Trade.BusinessServiceHostConfigurationImplementation.ConfigurationService();
                                int bslRetCode = configService.receiveConfigurationKey(targetHostNameIdentifier, targetConfigServiceNameIdentifier, oldKey, newKey, notifyNodes, action, traversePath, csUser);
                                if (bslRetCode == ConfigUtility.CLUSTER_UPDATE_FULL_SUCCESS)
                                    success = true;
                                break;
                            }
                        case StockTraderUtility.ORDER_PROCESSOR_SERVICE_SELFHOST:
                            {
                                theSettingsInstance = new Trade.BusinessServiceConfigurationSettings.Settings();
                                Trade.BusinessServiceHostConfigurationImplementation.ConfigurationService configService = new Trade.BusinessServiceHostConfigurationImplementation.ConfigurationService();
                                int bslRetCode = configService.receiveConfigurationKey(targetHostNameIdentifier, targetConfigServiceNameIdentifier, oldKey, newKey, notifyNodes, action, traversePath, csUser);
                                if (bslRetCode == ConfigUtility.CLUSTER_UPDATE_FULL_SUCCESS)
                                    success = true;
                                break;
                            }

                        case StockTraderUtility.AZURE_BUSINESS_SERVICES:
                            {
                                goto case StockTraderUtility.IISHOST_BUSINESS_SERVICES;
                            }

                        case StockTraderUtility.ORDER_PROCESSOR_SERVICE_AZURE:
                            {
                                goto case StockTraderUtility.ORDER_PROCESSOR_SERVICE_SELFHOST;
                            }

                        default:
                            {
                                if (notifyNodes)
                                    success = configHelper.sendConfigurationKeyUpdateLocal(oldKey, newKey, action, csUser);
                                break;
                            }
                    }
                    if (success)
                    {
                        if (targetHostNameIdentifier.Equals(StockTraderUtility.WEB_APPLICATION) || targetHostNameIdentifier.Equals(StockTraderUtility.WEB_APPLICATION_Azure))
                            success = configActions.checkChangedSetting(theSettingsInstance, newKey, notifyNodes, csUser);
                        if (notifyNodes && success)
                        {
                            RemoteNotifications remoteNotify = new RemoteNotifications(settingsInstance);
                            return remoteNotify.sendKeyUpdateToClusterMembers(targetHostNameIdentifier, targetConfigServiceNameIdentifier, oldKey, newKey, action);
                        }
                    }
                    else
                        returnCode = ConfigUtility.CLUSTER_UPDATE_FAIL_PERSISTED;
                }
                else
                {
                    if (traversePath != null && traversePath.Count > 1)
                    {
                        RemoteNotifications remoteKeyUpdate = new RemoteNotifications(settingsInstance);
                        ConfigUtility.writeConfigConsoleMessage("     Forwarding Key to Remote Connected Service: " + traversePath[traversePath.Count - 1].MyNode.Address + "\n", EventLogEntryType.Information, true, settingsInstance);
                        return (remoteKeyUpdate.sendConfigurationKeyUpdateRemote(targetHostNameIdentifier, targetConfigServiceNameIdentifier, oldKey, newKey, notifyNodes, action, traversePath, csUser));
                    }
                }
            }
            catch (Exception e)
            {
                ServiceConfigHelper.logServiceOperationException(csUser, e.ToString(), settingsInstance);
                throw;
            }
            return (returnCode);
        }