Skip to content

Commit 3cfbe19

Browse files
Merge pull request #740 from paolosalvatori/event-hubs-investigation
Abstracting EventHubs EventData
2 parents ad382cc + c90eca8 commit 3cfbe19

File tree

8 files changed

+193
-123
lines changed

8 files changed

+193
-123
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
namespace ServiceBusExplorer.Abstractions
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
using Microsoft.Azure.Amqp;
7+
using Microsoft.ServiceBus.Messaging;
8+
9+
public class EventDataMessage : IDisposable
10+
{
11+
readonly EventData eventData;
12+
Stream stream;
13+
14+
public EventDataMessage(EventData eventData)
15+
{
16+
this.eventData = eventData;
17+
stream = eventData.GetBodyStream();
18+
Properties = eventData.Properties;
19+
PartitionKey = eventData.PartitionKey;
20+
SequenceNumber = eventData.SequenceNumber;
21+
Offset = eventData.Offset;
22+
SerializedSizeInBytes = eventData.SerializedSizeInBytes;
23+
EnqueuedTimeUtc = eventData.EnqueuedTimeUtc;
24+
SystemProperties = eventData.SystemProperties;
25+
}
26+
27+
public string PartitionKey { get; private set; }
28+
public long SequenceNumber { get; private set; }
29+
public long SerializedSizeInBytes { get; private set; }
30+
public string Offset { get; private set; }
31+
public DateTime EnqueuedTimeUtc { get; private set; }
32+
public IDictionary<string, object> Properties { get; private set; }
33+
public IDictionary<string, object> SystemProperties { get; private set; }
34+
35+
public Stream GetBodyStream()
36+
{
37+
var memoryStream = new MemoryStream();
38+
39+
stream.CopyTo(memoryStream);
40+
stream.Seek(0L, SeekOrigin.Begin);
41+
42+
return memoryStream;
43+
}
44+
45+
public void Dispose()
46+
{
47+
eventData.Dispose();
48+
}
49+
}
50+
}

src/Common/Helpers/ServiceBusHelper.cs

Lines changed: 50 additions & 48 deletions
Large diffs are not rendered by default.

src/ServiceBus/Helpers/ServiceBusPurger.cs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
#region Copyright
22
//=======================================================================================
3-
// Microsoft Azure Customer Advisory Team
3+
// Microsoft Azure Customer Advisory Team
44
//
55
// This sample is supplemental to the technical guidance published on my personal
6-
// blog at http://blogs.msdn.com/b/paolos/.
7-
//
6+
// blog at http://blogs.msdn.com/b/paolos/.
7+
//
88
// Author: Paolo Salvatori
99
//=======================================================================================
1010
// Copyright (c) Microsoft Corporation. All rights reserved.
11-
//
12-
// LICENSED UNDER THE APACHE LICENSE, VERSION 2.0 (THE "LICENSE"); YOU MAY NOT USE THESE
13-
// FILES EXCEPT IN COMPLIANCE WITH THE LICENSE. YOU MAY OBTAIN A COPY OF THE LICENSE AT
11+
//
12+
// LICENSED UNDER THE APACHE LICENSE, VERSION 2.0 (THE "LICENSE"); YOU MAY NOT USE THESE
13+
// FILES EXCEPT IN COMPLIANCE WITH THE LICENSE. YOU MAY OBTAIN A COPY OF THE LICENSE AT
1414
// http://www.apache.org/licenses/LICENSE-2.0
15-
// UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE DISTRIBUTED UNDER THE
16-
// LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17-
// KIND, EITHER EXPRESS OR IMPLIED. SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING
15+
// UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE DISTRIBUTED UNDER THE
16+
// LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
// KIND, EITHER EXPRESS OR IMPLIED. SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING
1818
// PERMISSIONS AND LIMITATIONS UNDER THE LICENSE.
1919
//=======================================================================================
2020
#endregion
@@ -100,7 +100,6 @@ private async Task<long> PurgeSessionEntity(TEntity entity)
100100
{
101101
long totalMessagesPurged = 0;
102102
var consecutiveSessionTimeOuts = 0;
103-
ServiceBusSessionReceiver sessionReceiver = null;
104103
long messagesToPurgeCount = await GetMessageCount(entity, deadLetterQueueData: false)
105104
.ConfigureAwait(false);
106105

@@ -117,9 +116,9 @@ private async Task<long> PurgeSessionEntity(TEntity entity)
117116

118117
while (consecutiveSessionTimeOuts < enoughZeroReceives && totalMessagesPurged < messagesToPurgeCount)
119118
{
120-
sessionReceiver = await CreateServiceBusSessionReceiver(entity,
121-
client,
122-
purgeDeadLetterQueueInstead: false)
119+
var sessionReceiver = await CreateServiceBusSessionReceiver(entity,
120+
client,
121+
purgeDeadLetterQueueInstead: false)
123122
.ConfigureAwait(false);
124123

125124
var consecutiveZeroBatchReceives = 0;
@@ -236,7 +235,7 @@ private async Task<long> DoPurgeNonSessionEntity(TEntity entity, long messagesTo
236235
await receiver.CloseAsync().ConfigureAwait(false);
237236
}
238237
}
239-
}); // End of lambda
238+
}); // End of lambda
240239
}
241240

242241
await Task.WhenAll(tasks).ConfigureAwait(false);

src/ServiceBusExplorer/Controls/HandleQueueControl.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,6 @@ public partial class HandleQueueControl : UserControl
235235

236236
private QueueDescription queueDescription = default!;
237237
private readonly ServiceBusHelper serviceBusHelper = default!;
238-
private readonly ServiceBusHelper2 serviceBusHelper2 = default!;
239238
private readonly WriteToLogDelegate writeToLog = default!;
240239
private readonly string path = default!;
241240
private readonly List<TabPage> hiddenPages = new List<TabPage>();
@@ -297,9 +296,9 @@ public HandleQueueControl(WriteToLogDelegate writeToLog, ServiceBusHelper servic
297296
{
298297
this.writeToLog = writeToLog;
299298
this.serviceBusHelper = serviceBusHelper;
300-
this.serviceBusHelper2 = serviceBusHelper.GetServiceBusHelper2();
301299
this.path = path;
302300
this.queueDescription = queueDescription;
301+
var serviceBusHelper2 = serviceBusHelper.GetServiceBusHelper2();
303302

304303
if (!serviceBusHelper2.ConnectionStringContainsEntityPath())
305304
{

src/ServiceBusExplorer/Controls/HandleTopicControl.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ public partial class HandleTopicControl : UserControl
125125
private readonly List<TabPage> hiddenPages = new List<TabPage>();
126126
private TopicDescription topicDescription;
127127
private readonly ServiceBusHelper serviceBusHelper;
128-
private readonly ServiceBusHelper2 serviceBusHelper2 = default!;
129128
private readonly WriteToLogDelegate writeToLog;
130129
private readonly bool premiumNamespace;
131130
private readonly string path;
@@ -153,7 +152,7 @@ public HandleTopicControl(WriteToLogDelegate writeToLog, ServiceBusHelper servic
153152
{
154153
this.writeToLog = writeToLog;
155154
this.serviceBusHelper = serviceBusHelper;
156-
this.serviceBusHelper2 = serviceBusHelper.GetServiceBusHelper2();
155+
var serviceBusHelper2 = serviceBusHelper.GetServiceBusHelper2();
157156

158157
if (!serviceBusHelper2.ConnectionStringContainsEntityPath())
159158
{

src/ServiceBusExplorer/Controls/PartitionListenerControl.cs

Lines changed: 47 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
#region Copyright
22
//=======================================================================================
3-
// Microsoft Azure Customer Advisory Team
3+
// Microsoft Azure Customer Advisory Team
44
//
55
// This sample is supplemental to the technical guidance published on my personal
6-
// blog at http://blogs.msdn.com/b/paolos/.
7-
//
6+
// blog at http://blogs.msdn.com/b/paolos/.
7+
//
88
// Author: Paolo Salvatori
99
//=======================================================================================
1010
// Copyright (c) Microsoft Corporation. All rights reserved.
11-
//
12-
// LICENSED UNDER THE APACHE LICENSE, VERSION 2.0 (THE "LICENSE"); YOU MAY NOT USE THESE
13-
// FILES EXCEPT IN COMPLIANCE WITH THE LICENSE. YOU MAY OBTAIN A COPY OF THE LICENSE AT
11+
//
12+
// LICENSED UNDER THE APACHE LICENSE, VERSION 2.0 (THE "LICENSE"); YOU MAY NOT USE THESE
13+
// FILES EXCEPT IN COMPLIANCE WITH THE LICENSE. YOU MAY OBTAIN A COPY OF THE LICENSE AT
1414
// http://www.apache.org/licenses/LICENSE-2.0
15-
// UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE DISTRIBUTED UNDER THE
16-
// LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17-
// KIND, EITHER EXPRESS OR IMPLIED. SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING
15+
// UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE DISTRIBUTED UNDER THE
16+
// LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
// KIND, EITHER EXPRESS OR IMPLIED. SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING
1818
// PERMISSIONS AND LIMITATIONS UNDER THE LICENSE.
1919
//=======================================================================================
2020
#endregion
@@ -45,6 +45,8 @@
4545

4646
namespace ServiceBusExplorer.Controls
4747
{
48+
using Abstractions;
49+
4850
public partial class PartitionListenerControl : UserControl
4951
{
5052
#region Private Constants
@@ -115,14 +117,13 @@ public partial class PartitionListenerControl : UserControl
115117
private readonly WriteToLogDelegate writeToLog;
116118
private readonly Func<Task> stopLog;
117119
private readonly Action startLog;
118-
private EventData currentEventData;
119-
private int grouperEventDataCustomPropertiesWidth;
120+
private EventDataMessage currentEventData;
120121
private int currentMessageRowIndex;
121122
private readonly int partitionCount;
122123
private bool sorting;
123-
private readonly SortableBindingList<EventData> eventDataBindingList = new SortableBindingList<EventData> { AllowNew = false, AllowEdit = false, AllowRemove = false };
124+
private readonly SortableBindingList<EventDataMessage> eventDataBindingList = new SortableBindingList<EventDataMessage> { AllowNew = false, AllowEdit = false, AllowRemove = false };
124125
private readonly IList<PartitionRuntimeInformation> partitionRuntumeInformationList = new List<PartitionRuntimeInformation>();
125-
private BlockingCollection<EventData> eventDataCollection = new BlockingCollection<EventData>();
126+
private BlockingCollection<EventDataMessage> eventDataCollection = new BlockingCollection<EventDataMessage>();
126127
private System.Timers.Timer timer;
127128
private long receiverMessageNumber;
128129
private long receiverMessageSizeTotal;
@@ -151,6 +152,7 @@ public partial class PartitionListenerControl : UserControl
151152
private bool clearing;
152153
private bool cleared;
153154
private readonly string iotHubConnectionString;
155+
int grouperEventDataCustomPropertiesWidth;
154156
public Task AsyncTrackEventDataTask { get; private set; }
155157

156158
#endregion
@@ -315,12 +317,12 @@ private void InitializeControls()
315317
eventDataDataGridView.DefaultCellStyle.SelectionBackColor = Color.FromArgb(92, 125, 150);
316318
eventDataDataGridView.DefaultCellStyle.SelectionForeColor = SystemColors.Window;
317319

318-
// Set RowHeadersDefaultCellStyle.SelectionBackColor so that its default
320+
// Set RowHeadersDefaultCellStyle.SelectionBackColor so that its default
319321
// value won't override DataGridView.DefaultCellStyle.SelectionBackColor.
320322
eventDataDataGridView.RowHeadersDefaultCellStyle.SelectionBackColor = Color.FromArgb(153, 180, 209);
321323

322-
// Set the background color for all rows and for alternating rows.
323-
// The value for alternating rows overrides the value for all rows.
324+
// Set the background color for all rows and for alternating rows.
325+
// The value for alternating rows overrides the value for all rows.
324326
eventDataDataGridView.RowsDefaultCellStyle.BackColor = SystemColors.Window;
325327
eventDataDataGridView.RowsDefaultCellStyle.ForeColor = SystemColors.ControlText;
326328
//eventDataDataGridView.AlternatingRowsDefaultCellStyle.BackColor = Color.White;
@@ -631,7 +633,7 @@ private void CalculateLastColumnWidth(object sender)
631633

632634
private void eventDataDataGridView_RowEnter(object sender, DataGridViewCellEventArgs e)
633635
{
634-
var bindingList = eventDataBindingSource.DataSource as BindingList<EventData>;
636+
var bindingList = eventDataBindingSource.DataSource as BindingList<EventDataMessage>;
635637
currentMessageRowIndex = e.RowIndex;
636638
if (bindingList == null)
637639
{
@@ -644,11 +646,26 @@ private void eventDataDataGridView_RowEnter(object sender, DataGridViewCellEvent
644646
currentEventData = bindingList[e.RowIndex];
645647
eventDataPropertyGrid.SelectedObject = currentEventData;
646648

647-
LanguageDetector.SetFormattedMessage(serviceBusHelper, currentEventData.Clone(), txtMessageText);
649+
try
650+
{
651+
//var eventData = currentEventData.Clone();
652+
LanguageDetector.SetFormattedMessage(serviceBusHelper, currentEventData, txtMessageText);
653+
}
654+
catch (Exception exception)
655+
{
656+
HandleException(exception);
657+
}
648658

649-
var listViewItems = currentEventData.Properties.Select(p => new ListViewItem(new[] { p.Key, (p.Value ?? string.Empty).ToString() })).ToArray();
650-
eventDataPropertyListView.Items.Clear();
651-
eventDataPropertyListView.Items.AddRange(listViewItems);
659+
try
660+
{
661+
var listViewItems = currentEventData.Properties.Select(p => new ListViewItem(new[] { p.Key, (p.Value ?? string.Empty).ToString() })).ToArray();
662+
eventDataPropertyListView.Items.Clear();
663+
eventDataPropertyListView.Items.AddRange(listViewItems);
664+
}
665+
catch (Exception exception)
666+
{
667+
HandleException(exception);
668+
}
652669
}
653670

654671
private void tabPageMessages_Resize(object sender, EventArgs e)
@@ -691,7 +708,7 @@ private void eventDataDataGridView_CellDoubleClick(object sender, DataGridViewCe
691708
{
692709
return;
693710
}
694-
var bindingList = eventDataBindingSource.DataSource as BindingList<EventData>;
711+
var bindingList = eventDataBindingSource.DataSource as BindingList<EventDataMessage>;
695712
if (bindingList == null)
696713
{
697714
return;
@@ -831,7 +848,7 @@ private async void btnStart_Click(object sender, EventArgs e)
831848
checkBoxCheckpoint,
832849
cancellationTokenSource.Token)
833850
{
834-
TrackEvent = ev => Invoke(new Action<EventData>(m => eventDataCollection.Add(m)), ev),
851+
TrackEvent = ev => Invoke(new Action<EventData>(m => eventDataCollection.Add(new EventDataMessage(m))), ev),
835852
GetElapsedTime = GetElapsedTime,
836853
UpdateStatistics = UpdateStatistics,
837854
WriteToLog = writeToLog,
@@ -953,7 +970,7 @@ private void btnClear_Click(object sender, EventArgs e)
953970
clearing = true;
954971
cleared = true;
955972
eventDataCollection.Dispose();
956-
eventDataCollection = new BlockingCollection<EventData>();
973+
eventDataCollection = new BlockingCollection<EventDataMessage>();
957974
ClearTrackedMessages();
958975
ClearStatistics();
959976
ClearCharts();
@@ -1166,8 +1183,8 @@ private void RefreshGraph()
11661183
if (InvokeRequired)
11671184
{
11681185
Invoke(new Action<long, long, long, bool>(InternalUpdateStatistics),
1169-
new object[] { receiveTuple.Item1,
1170-
receiveTuple.Item2,
1186+
new object[] { receiveTuple.Item1,
1187+
receiveTuple.Item2,
11711188
receiveTuple.Item3,
11721189
graph});
11731190
}
@@ -1338,7 +1355,7 @@ private void PartitionListenerControl_Paint(object sender, PaintEventArgs e)
13381355
cboReceiverInspector.Size.Height + 1);
13391356
}
13401357

1341-
/// <summary>
1358+
/// <summary>
13421359
/// Clean up any resources being used.
13431360
/// </summary>
13441361
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
@@ -1501,7 +1518,7 @@ private void saveSelectedEventToolStripMenuItem_Click(object sender, EventArgs e
15011518
{
15021519
return;
15031520
}
1504-
var bindingList = eventDataBindingSource.DataSource as BindingList<EventData>;
1521+
var bindingList = eventDataBindingSource.DataSource as BindingList<EventDataMessage>;
15051522
if (bindingList == null)
15061523
{
15071524
return;
@@ -1543,8 +1560,8 @@ private void saveSelectedEventsToolStripMenuItem_Click(object sender, EventArgs
15431560
{
15441561
return;
15451562
}
1546-
var messages = eventDataDataGridView.SelectedRows.Cast<DataGridViewRow>().Select(r => r.DataBoundItem as EventData);
1547-
IEnumerable<EventData> events = messages as EventData[] ?? messages.ToArray();
1563+
var messages = eventDataDataGridView.SelectedRows.Cast<DataGridViewRow>().Select(r => r.DataBoundItem as EventDataMessage);
1564+
IEnumerable<EventDataMessage> events = messages as EventDataMessage[] ?? messages.ToArray();
15481565
if (!events.Any())
15491566
{
15501567
return;

0 commit comments

Comments
 (0)