/// <summary> /// Reports the casino diagnostics. /// </summary> /// <param name="casinoDiagnosticData">The casino diagnostic data.</param> public void ReportCasinoDiagnostics(CasinoDiagnosticData casinoDiagnosticData) { Logger.Debug( $"On-Site HMS service sending Casino Diagnositcs Data: [{casinoDiagnosticData}] to HMS Cloud Service"); Channel.ReportCasinoDiagnostics(casinoDiagnosticData); }
/// <inheritdoc /> /// <exception cref="T:System.Exception"> /// ServiceConsumerFactory.Create returned null/invalid IHmsCloudService reference. /// Check WCF HMS configuration. /// </exception> public void SendCasinoDiagnosticData(IDictionary <string, IList <byte[]> > diagnosticData) { if (null == diagnosticData || 0 >= diagnosticData.Count) { return; } var casinoCode = Settings.Default.CasinoCode; using ( var cloudServiceProxy = ServiceConsumerFactory.Create <IHmsCloudService>(() => new HmsCloudServerProxy()) ) { try { if (cloudServiceProxy?.Operations == null) { throw new Exception( "ServiceConsumerFactory.Create returned null/invalid IHmsCloudService reference. Check WCF HMS configuration."); } foreach (var diagnosticFilename in diagnosticData.Keys) { var diagnosticFileChunks = diagnosticData[diagnosticFilename]; if (null == diagnosticFileChunks || 0 >= diagnosticFileChunks.Count) { continue; } // create a new ReportGuid - one for each filename being sent (in either one or // multiple messages/chunks - based on size of diagnosticFileChunks IList) var reportGuid = Guid.NewGuid(); var reportedAt = DateTime.UtcNow; // The TransactionScope here will provide behavior such that - if/when the call to // DataAggregator.SuccessfulCasinoDiagnosticReport fails for some reason - the transactional // WCF/MSMQ message delivery will be rolled back (i.e., the messages will be discarded // from the client-side MQ). // // Additionally, we bundle all the chunks for each diagnostic file into a single // transaction. Thus, we will roll back if not all chunks are successfully // processed/sent. var txnOptions = new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }; using (var txnScope = new TransactionScope(TransactionScopeOption.Required, txnOptions)) { for (var iChunk = 0; iChunk < diagnosticFileChunks.Count; ++iChunk) { var chunk = diagnosticFileChunks[iChunk]; if (null == chunk || 0 >= chunk.LongLength) { continue; } var casinoDiagnosticData = new CasinoDiagnosticData { Filename = diagnosticFilename, Chunk = chunk, ChunkIndex = iChunk, NumChunks = diagnosticFileChunks.Count, CasinoCode = casinoCode, ReportGuid = reportGuid, ReportedAt = reportedAt }; cloudServiceProxy.Operations.ReportCasinoDiagnostics(casinoDiagnosticData); } DataAggregator.SuccessfulCasinoDiagnosticReport(diagnosticFilename, reportGuid); txnScope.Complete(); } } } catch (FaultException fe) { Logger.Warn($"Service operation ReportCasinoDiagnostics threw a fault: [{fe.Message}]"); } catch (Exception ex) { Logger.Warn( $"An unexpected error occurred while calling the ReportCasinoDiagnostics service operation: [{ex.Message}]"); var innerEx = ex.InnerException; while (null != innerEx) { Logger.Warn($"[{innerEx.Message}]"); innerEx = innerEx.InnerException; } Logger.Warn($"Stack Trace: [{Environment.StackTrace}]"); } } }