990 lines · 41.3 KB · C#
RawDownload
        /// </summary>        /// <exception cref="ConfigurationErrorsException"><see cref="SettingsCategory"/> has a value of null or empty string.</exception>        public void LoadSettings()        {            if (m_persistSettings)            {                // Ensure that settings category is specified.                if (string.IsNullOrEmpty(m_settingsCategory))                    throw new ConfigurationErrorsException("SettingsCategory property has not been set");                 // Load settings from the specified category.                ConfigurationFile config = ConfigurationFile.Current;                CategorizedSettingsElementCollection settings = config.Settings[m_settingsCategory];                 settings.Add(nameof(Username), m_username, "Username to be used for authentication with the service.", false, SettingScope.User);                settings.Add(nameof(Password), m_password, "Password to be used for authentication with the service.", true, SettingScope.User);                settings.Add(nameof(SerializationFormat), m_serializationFormat, "Message serialization format for interactions with service, one of: Xml, Json or Binary. Default is Binary.");                settings.Add(nameof(StatusMessageFilter), m_statusMessageFilter, "Command used to negotiate status message filter when client connects to the ServiceHelper.");                 Username = settings[nameof(Username)].ValueAs(m_username);                Password = settings[nameof(Password)].ValueAs(m_password);                SerializationFormat = settings[nameof(SerializationFormat)].ValueAs(m_serializationFormat);                StatusMessageFilter = settings[nameof(StatusMessageFilter)].ValueAs(m_statusMessageFilter);            }        }         /// <summary>        /// Connects <see cref="RemotingClient"/> to <see cref="ServiceHelper.RemotingServer"/> and wait until authentication is complete.        /// </summary>        public void Connect()        {            if ((object)m_remotingClient == null)                throw new InvalidOperationException("RemotingClient property of ClientHelper component is not set");             m_authenticationComplete = false;             // Wait for connection.            m_remotingClient.Connect();             while (!m_authenticationComplete && m_remotingClient.Enabled)            {                // Wait for authentication.                Thread.Sleep(100);                 // If remoting client has been disposed (and set to null) while sleeping, go ahead and exit...                if ((object)m_remotingClient == null)                    return;            }             if (m_remotingClient.Enabled)                m_attemptReconnection = true;        }         /// <summary>        /// Disconnects <see cref="RemotingClient"/> from <see cref="ServiceHelper.RemotingServer"/>.        /// </summary>        public void Disconnect()        {            m_attemptReconnection = false;             if ((object)m_remotingClient != null)                m_remotingClient.Disconnect();        }         /// <summary>        /// Sends a request to the <see cref="ServiceHelper"/> using <see cref="RemotingClient"/>.        /// </summary>        /// <param name="request">Request text to be sent.</param>        public void SendRequest(string request)        {            ClientRequest requestInstance = ClientRequest.Parse(request);             if ((object)requestInstance != null)                SendRequest(requestInstance);            else                UpdateStatus(UpdateType.Warning, "Request command \"{0}\" is invalid\r\n\r\n", request);        }         /// <summary>        /// Sends a request to the <see cref="ServiceHelper"/> using <see cref="RemotingClient"/>.        /// </summary>        /// <param name="request"><see cref="ClientRequest"/> object to be sent.</param>        public void SendRequest(ClientRequest request)        {            try            {                // Intercept TRANSFER requests for uploads.                if (request.Command == "TRANSFER" && request.Arguments.Exists("upload"))                {                    string source = FilePath.GetAbsolutePath(request.Arguments["orderedarg1"]);                    if (File.Exists(source))                    {                        // Attach the file content.                        request.Attachments.Add(File.ReadAllBytes(source));                    }                    else                    {                        // File does not exist.                        throw new FileNotFoundException(string.Format("File '{0}' does not exist", source));                    }                }                 // Pass the request along.                m_remotingClient.SendAsync(request);            }            catch (Exception ex)            {                UpdateStatus(UpdateType.Alarm, "Error processing request - {0}", ex.Message);            }        }         /// <summary>        /// Raises the <see cref="ReceivedServiceUpdate"/> event.        /// </summary>        /// <param name="type">One of the <see cref="UpdateType"/> values.</param>        /// <param name="update">Update message received.</param>        protected virtual void OnReceivedServiceUpdate(UpdateType type, string update)        {            if ((object)ReceivedServiceUpdate != null)                ReceivedServiceUpdate(this, new EventArgs<UpdateType, string>(type, update));        }         /// <summary>        /// Raises the <see cref="ReceivedServiceResponse"/> event.        /// </summary>        /// <param name="response"><see cref="ServiceResponse"/> received.</param>        protected virtual void OnReceivedServiceResponse(ServiceResponse response)        {            if ((object)ReceivedServiceResponse != null)                ReceivedServiceResponse(this, new EventArgs<ServiceResponse>(response));        }         /// <summary>        /// Raises the <see cref="ServiceStateChanged"/> event.        /// </summary>        /// <param name="state">New <see cref="ServiceState"/>.</param>        protected virtual void OnServiceStateChanged(ObjectState<ServiceState> state)        {            if ((object)ServiceStateChanged != null)                ServiceStateChanged(this, new EventArgs<ObjectState<ServiceState>>(state));        }         /// <summary>        /// Raises the <see cref="ProcessStateChanged"/> event.        /// </summary>        /// <param name="state">New <see cref="ServiceProcessState"/>.</param>        protected virtual void OnProcessStateChanged(ObjectState<ServiceProcessState> state)        {            if ((object)ProcessStateChanged != null)                ProcessStateChanged(this, new EventArgs<ObjectState<ServiceProcessState>>(state));        }         /// <summary>        /// Raises the <see cref="AuthenticationSuccess"/> event.        /// </summary>        protected virtual void OnAuthenticationSuccess()        {            if ((object)AuthenticationSuccess != null)                AuthenticationSuccess(this, EventArgs.Empty);             m_authenticationComplete = true;        }         /// <summary>        /// Raises the <see cref="AuthenticationFailure"/> event.        /// </summary>        protected virtual void OnAuthenticationFailure()        {            CancelEventArgs args = new CancelEventArgs(true);             if ((object)AuthenticationFailure != null)                AuthenticationFailure(this, args);             // Continue connection attempts if requested.            if (args.Cancel)            {                m_attemptReconnection = false;                m_authenticationComplete = true;            }        }         /// <summary>        /// Raises the <see cref="TelnetSessionEstablished"/> event.        /// </summary>        protected virtual void OnTelnetSessionEstablished()        {            if ((object)TelnetSessionEstablished != null)                TelnetSessionEstablished(this, EventArgs.Empty);        }         /// <summary>        /// Raises the <see cref="TelnetSessionTerminated"/> event.        /// </summary>        protected virtual void OnTelnetSessionTerminated()        {            if ((object)TelnetSessionTerminated != null)                TelnetSessionTerminated(this, EventArgs.Empty);        }         /// <summary>        /// Releases the unmanaged resources used by the <see cref="ClientHelper"/> object and optionally releases the managed resources.        /// </summary>        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>        protected override void Dispose(bool disposing)        {            if (!m_disposed)            {                try                {                    // This will be done regardless of whether the object is finalized or disposed.                    if (disposing)                    {                        // This will be done only when the object is disposed by calling Dispose().                        Disconnect();                        SaveSettings();                         if ((object)m_remotingClient != null)                        {                            // Detach events from any existing instance                            m_remotingClient.ConnectionEstablished -= RemotingClient_ConnectionEstablished;                            m_remotingClient.ConnectionAttempt -= RemotingClient_ConnectionAttempt;                            m_remotingClient.ConnectionException -= RemotingClient_ConnectionException;                            m_remotingClient.ConnectionTerminated -= RemotingClient_ConnectionTerminated;                            m_remotingClient.ReceiveDataComplete -= RemotingClient_ReceiveDataComplete;                        }                    }                }                finally                {                    m_disposed = true;          // Prevent duplicate dispose.                    base.Dispose(disposing);    // Call base class Dispose().                }            }        }         private void UpdateStatus(UpdateType type, string message, params object[] args)        {            OnReceivedServiceUpdate(type, string.Format(message, args));        }         private void RemotingClient_ConnectionAttempt(object sender, EventArgs e)        {            UpdateStatus(UpdateType.Information, "Connecting to {0}...\r\n\r\n", m_remotingClient.ServerUri);        }         private void RemotingClient_ConnectionEstablished(object sender, EventArgs e)        {            // Upon establishing connection with the service's communication client, we'll send our information to the            // service so the service can keep track of all the client that are connected to its communication server.            m_remotingClient.SendAsync(new ClientInfo(this));             StringBuilder status = new StringBuilder();            status.AppendFormat("Connected to {0}:", m_remotingClient.ServerUri);            status.AppendLine();            status.AppendLine();            status.Append(m_remotingClient.Status);            status.AppendLine();            UpdateStatus(UpdateType.Information, "{0}", status.ToString());            SendRequest(StatusMessageFilter);        }         private void RemotingClient_ConnectionException(object sender, EventArgs<Exception> e)        {            StringBuilder status = new StringBuilder();            TcpClient tcpClient;            TlsClient tlsClient;             status.AppendFormat("Exception during connection attempt: {0}", e.Argument.Message);            status.AppendLine();            status.AppendLine();            UpdateStatus(UpdateType.Alarm, "{0}", status.ToString());             tlsClient = m_remotingClient as TlsClient;             if ((object)tlsClient != null)            {                tlsClient.NetworkCredential = null;            }            else            {                tcpClient = m_remotingClient as TcpClient;                 if ((object)tcpClient != null)                    tcpClient.NetworkCredential = null;            }        }         private void RemotingClient_ConnectionTerminated(object sender, EventArgs e)        {            StringBuilder status = new StringBuilder();            status.AppendFormat("Disconnected from {0}:", m_remotingClient.ServerUri);            status.AppendLine();            status.AppendLine();            status.Append(m_remotingClient.Status);            status.AppendLine();            UpdateStatus(UpdateType.Warning, "{0}", status.ToString());             // Attempt reconnection on a separate thread.            if (m_attemptReconnection)            {                new Thread(state =>                {                    Thread.Sleep(1000);                    Connect();                })                .Start();            }        }         private void RemotingClient_ReceiveDataComplete(object sender, EventArgs<byte[], int> e)        {            ServiceResponse response;             Serialization.TryDeserialize(e.Argument1.BlockCopy(0, e.Argument2), m_serializationFormat, out response);             if ((object)response != null)            {                switch (response.Type)                {                    case "UPDATECLIENTSTATUS-INFORMATION":                        UpdateStatus(UpdateType.Information, "{0}", response.Message);                        break;                    case "UPDATECLIENTSTATUS-WARNING":                        UpdateStatus(UpdateType.Warning, "{0}", response.Message);                        break;                    case "UPDATECLIENTSTATUS-ALARM":                        UpdateStatus(UpdateType.Alarm, "{0}", response.Message);                        break;                    case "AUTHENTICATIONSUCCESS":                        OnAuthenticationSuccess();                        break;                    case "AUTHENTICATIONFAILURE":                        OnAuthenticationFailure();                        break;                    case "SERVICESTATECHANGED":                        if (response.Attachments.Count > 0)                        {                            ObjectState<ServiceState> state = response.Attachments[0] as ObjectState<ServiceState>;                             if ((object)state != null)                            {                                // Notify change in service state by raising an event.                                OnServiceStateChanged(state);                                 // Provide a status update for change in state of the service.                                UpdateType type = UpdateType.Information;                                switch (state.CurrentState)                                {                                    case ServiceState.Stopped:                                    case ServiceState.Paused:                                    case ServiceState.Shutdown:                                        type = UpdateType.Warning;                                        break;                                }                                UpdateStatus(type, "State of service \"{0}\" has changed to \"{1}\".\r\n\r\n", state.ObjectName, state.CurrentState);                            }                        }                        break;                    case "PROCESSSTATECHANGED":                        if (response.Attachments.Count > 0)                        {                            ObjectState<ServiceProcessState> state = response.Attachments[0] as ObjectState<ServiceProcessState>;                             if ((object)state != null)                            {                                // Notify change in process state by raising an event.                                OnProcessStateChanged(state);                                 // Provide a status update for change in state of the service process.                                UpdateType type = UpdateType.Information;                                switch (state.CurrentState)                                {                                    case ServiceProcessState.Aborted:                                    case ServiceProcessState.Exception:                                        type = UpdateType.Alarm;                                        break;                                 }                                UpdateStatus(type, "State of process \"{0}\" has changed to \"{1}\".\r\n\r\n", state.ObjectName, state.CurrentState);                            }                        }                        break;                    case "TELNETSESSION":                        switch (response.Message.ToUpper())                        {                            case "ESTABLISHED":                                OnTelnetSessionEstablished();                                break;                            case "TERMINATED":                                OnTelnetSessionTerminated();                                break;                        }                        break;                    case "TRANSFER:SUCCESS":                        if (response.Attachments.Count == 2)                        {                            // Extract data from response.                            byte[] content = (byte[])response.Attachments[0];                            Arguments arguments = (Arguments)response.Attachments[1];                            string target = arguments["orderedarg2"];                            bool overwrite = arguments.Exists("overwrite");                             target = FilePath.GetAbsolutePath(target);                            if (!File.Exists(target) || overwrite)                            {                                // Save the received file.                                UpdateStatus(UpdateType.Information, "Saving file '{0}'...\r\n\r\n", target);                                File.WriteAllBytes(target, content);                                UpdateStatus(UpdateType.Information, "File '{0}' saved successfully.\r\n\r\n", target);                            }                            else                            {                                // File exists and cannot be overwritten.                                UpdateStatus(UpdateType.Alarm, "File '{0}' already exists.\r\n\r\n", target);                            }                        }                        else                        {                            // Response is malformed.                            UpdateStatus(UpdateType.Alarm, "{0} response is malformed.\r\n\r\n", response.Type);                        }                        break;                    default:                        OnReceivedServiceResponse(response);                        break;                }            }        }         #endregion         #region [ Static ]         /// <summary>        /// Returns an <see cref="ClientRequestInfo"/> object for the specified <paramref name="requestCommand"/> that can be used         /// to invoke <see cref="ServiceHelper.ClientRequestHandlers"/> manually as if the request was sent by a <see cref="ClientHelper"/> remotely.        /// </summary>        /// <param name="requestCommand">Command for which an <see cref="ClientRequestInfo"/> object is to be created.</param>        /// <returns>An <see cref="ClientRequestInfo"/> object.</returns>        public static ClientRequestInfo PretendRequest(string requestCommand)        {            ClientRequest request = ClientRequest.Parse(requestCommand);            ClientRequestInfo requestInfo = new ClientRequestInfo(new ClientInfo(), request);             return requestInfo;        }         /// <summary>        /// Attempts to parse an actionable response sent from the service.        /// </summary>        /// <param name="serviceResponse"><see cref="ServiceResponse"/> to test for actionable response.</param>        /// <param name="sourceCommand">Command that invoked <paramref name="serviceResponse"/>.</param>        /// <param name="responseSuccess">Boolean success state of <paramref name="serviceResponse"/>.</param>        /// <returns><c>true</c> if actionable response was able to be parsed successfully; otherwise <c>false</c>.</returns>        public static bool TryParseActionableResponse(ServiceResponse serviceResponse, out string sourceCommand, out bool responseSuccess)        {            bool parseSucceeded = false;             sourceCommand = null;            responseSuccess = false;             try            {                string response = serviceResponse.Type;                 // Attempt to parse response message                if (!string.IsNullOrWhiteSpace(response))                {                    // Response types are formatted as "Command:Success" or "Command:Failure"                    string[] parts = response.Split(':');                     if (parts.Length > 1)                    {                        sourceCommand = parts[0].Trim().ToTitleCase();                        responseSuccess = (string.Compare(parts[1].Trim(), "Success", StringComparison.OrdinalIgnoreCase) == 0);                        parseSucceeded = true;                    }                }            }            catch            {                parseSucceeded = false;            }             return parseSucceeded;        }         #endregion    }}

Lines 501–990 of 990. Previous lines

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t