Author: Paolo Salvatori (@babosbird)
Introduction
Important Note
The zip file contains:
- The source code for the Service Bus Explorer <IP_ADDRESS>. This version of the tool uses the Microsoft.ServiceBus.dll <IP_ADDRESS> that is compatible with the current version of
the Windows Azure Service Bus, but not with the Service Bus 1.1, that is, the current version of the on-premises version of the Service Bus.
- The Service Bus Explorer <IP_ADDRESS>. This version can be used with the Service Bus 1.1. The Service Bus Explorer 2.1 uses the Microsoft.ServiceBus.dll client library which is compatible
with the Service Bus for Windows Server 1.1 RTM version. You can download the source code of the Service Bus Explorer 2.1.3 from my
OneDrive.
- The Service Bus Explorer 1.8. This version can be used with the Service Bus 1.0
Queues and topics represent the foundation of a new cloud-based messaging and integration infrastructure that provides reliable message queuing and durable publish/subscribe messaging capabilities to both cloud and on-premises applications based on Microsoft
and non-Microsoft technologies. .NET applications can use the new functionality offered by queues and topics by using the new messaging API (
Microsoft.ServiceBus.Messaging)
or via WCF by using the new
NetMessagingBinding. Likewise, any Microsoft or non-Microsoft applications can use a
Service Bus REST API to manage and access messaging entities over HTTPS. In November 2012, the
Service Bus for
Windows Server was released. The Service Bus Exploer can be used with manage namespaces hosted by both Windows Azure Service Bus and Service Bus for Windows Server.
Queues and topics were first introduced by the Community Technology Preview (CTP) of Windows Azure that was released in May 2011. At that time, the
Windows Azure Management Portal didn’t provide any user interface to administer, create and delete messaging entities and the only way to accomplish this task was using the .NET or REST API. For this
reason, In June 2011 I decided to build a tool called
Service Bus Explorer that would allow developers and system administrators to connect to a Service Bus namespace and administer its messaging entities.
During the last few months I continued to develop this tool and add new features with the intended goal to facilitate the development and administration of new Service Bus-enabled applications. In the meantime, the
Windows Azure Management Portal introduced the ability for a user to create, disable, update queues, topics, and subscriptions and define their properties, but not to define or display rules for an existing
subscription. Besides, the Service Bus Explorer enables to accomplish functionalities, such as importing, exporting and testing entities, that are not currently provided by the
Windows Azure Management Portal. For this reason, the Service Bus Explorer tool represents the perfect companion for the official Azure portal and it can also be used to explore the features (session-based
correlation, configurable detection of duplicate messages, deferring messages, etc.) provided out-of-the-box by the Service Bus brokered messaging.
For more information on the Service Bus, you can use the following resources:
GitHub
The source code of the tool is now availale on GitHub as a public project. Now you have the opportunity to contribute to the evolution of the tool!
Updates
Follow me on Twitter if you want to receive a post whenever a new version of the tool is available.
Videos
For more information on how to use the Service Bus Explorer, see the following videos on Channel9:
License
Microsoft Corporation (“Microsoft”) grants you a nonexclusive, perpetual, royalty-free right to use and modify the software code provided by us for the purposes of illustration ("Sample Code") and to reproduce and distribute the object
code form of the Sample Code, provided that you agree: (i) to not use our name, logo, or trademarks to market your software product in which the Sample Code is embedded; (ii) to include a valid copyright notice on your software product in which the Sample
Code is embedded; and (iii) to indemnify, hold harmless, and defend us and our suppliers from and against any claims or lawsuits, whether in an action of contract, tort or otherwise, including attorneys’ fees, that arise or result from the use or distribution
of the Sample Code or the use or other dealings in the Sample Code. Unless applicable law gives you more rights, Microsoft reserves all other rights not expressly granted herein, whether by implication, estoppel or otherwise.

Microsoft Azure Management Portal
In order to use the Brokered and Relay messaging functionality provided by the Service Bus, the first operation to perform is to provision a new Service Bus namespace or modify an existing namespace to include the Service Bus. You can accomplish this task
from the
Windows Azure Management Portal.
Once completed this step, you can start creating and using queues, topics and subscriptions. You have many options to provision and manage messaging entities:
- This first option is to exploit the
CreateQueue,
CreateTopic and
CreateSubscription methods exposed by the
NamespaceManager class that can be used to manage entities, such as queues, topics, subscriptions, and rules, in your service namespace. This is exactly the approach that I followed to build the provisioning functionality exposed by the Service Bus Explorer
tool.
- The second approach is to rely on the
Service Bus REST API to create and delete messaging entities. By using REST, you can write applications in any language that supports HTTP requests, without the need for a client SDK. In particular, this allows applications based on non-Microsoft technologies
(e.g. Java, Ruby, etc.) not only to send and receive messages from the Service Bus, but also to create or delete queues, topics and subscription in a given namespace.
- Finally, you can administer messaging entities from the user interface supplied by the
Windows Azure Management Portal. In particular, the buttons in the
Manage Entities command bar highlighted in red at point 1 in the figure below allow creating a new queue, topic and subscription entity. Then you can use the navigation tree-view shown at point 2 to select an existing entity and display its
properties in the vertical bar highlighted at point 3. To remove the selected entity, you press the
Delete button in the Manage Entities command bar.
Using
Windows Azure Management Portal is a handy and convenient manner to handle the messaging entities in a given Service Bus namespace. However, at least at the moment, the set of operations that a
developer or a system administrator can perform using its user interface is quite limited. For example, the
Windows Azure Management Portal actually allows a user to create queues, topics, and subscriptions and define their properties, but not to create or display rules for an existing subscription. At the moment,
you can accomplish this task only by using the
.NET Messaging API. In particular, to add a new rule to an existing subscription you can use the
AddRule(String, Filter) or the
AddRule(RuleDescription) methods exposed by the
SubscriptionClient class, while to enumerate the rules of an existing subscription, you can use the
GetRules method of the
NamespaceManager class. Besides, the
Windows Azure Management Portal actually does not provide the ability to perform the following operations:
- Properly visualize entities in a hierarchical manner. Actually, the
Windows Azure Management Portal displays queues, topics and subscriptions with a flat treeview. However, you can organize messaging entities in a hierarchical structure simply by specifying their name as an absolute path composed of multiple path segments,
for example crm/prod/queues/orderqueue.
- Export the messaging entities contained in a given Service Bus namespace to an XML binding file (a-la BizTalk Server). Instead, the Service Bus Explorer tool provides the ability to select and export
- Individual entities.
- Entities by type (queues or topics).
- Entities contained in a certain path (e.g. crm/prod/queues).
- All the entities in a given namespace.
- Import queues, topics and subscriptions from an XML file to an existing namespace. The Service Bus Explorer supports the ability to export entities to an XML file and reimport them on the same or another Service Bus namespace. This feature comes in a handy
to perform a backup and restore of a namespace or simply to transfer queues and topics from a testing to a production namespace.
That’s why in June, I created a tool called
Service Bus Explorer that allows a user to create, delete and test queues, topics, subscriptions, and rules. My tool was able to manage entities in the
Labs Beta environment. However, the new version of the
Service Bus API introduced some breaking changes, as you can read
here, so I built a new version of the Service Bus Explorer tool that introduces a significant amount of new features.
Service Bus Explorer
The following picture illustrates the high-level architecture of the Service Bus Explorer tool. The application has been written in C# using
Visual Studio 2010 and requires the installation of the .
NET Framework 4.0 and
Windows Azure SDK for .NET. The tool can be copied and used on any workstation that satisfies the prerequisites mentioned above to manage and test
the Brokered and Relay messaging services defined in a given Service Bus namespace.
Read the full article on
MSDN.
NOTE: I'll continue to develop the tool and add new functionalities. So I strongly recommend you to visit this page from time to time for a new version.
Author: Paolo Salvatori
Update: 28 August 2012
This version introduces the following updates:
- A new flat UI. This change has been done primarily to match Windows 8 and Windows Server 2012 new UI style.
- Two new options in the configuration file and Options form that allow to save respectively the message text and user-defined properties of a BrokeredMessage between 2 runs. This way, you don't have to re-enter user-defined properties when you start a new
session.
- The possibility to define the body of BrokeredMessage as a stream. Now in the Sender tab of a queue and topic you can select 3 different formats for the payload: string, stream and WCF message.
Update: 18 December 2012
This version introduces the following updates:
- Implemented Disable/Enable operations for queues and topics.
- Implemented Update operation for queues, topics and subscriptions.
- Added OData filter support for queues, topics and subscriptions in the ConnectForm.
- Added OData filter support on context menu of queues, topics and subscriptions.
- Added FilterForm that allows to compose a valid OData filter both as free-text or using the UI. The 2 mechanisms are synchronized.
- Added support for Windows Azure Service Bus connection strings in the Connect Form.
- Added support for Service Bus for Windows Server and Windows Azure Service Bus connection strings in the configuration file.
- Added support for F5 shortcut to refresh current entity/entities
- Added connection string textbox in the Connect form.
- Added tooltip with samples for cloud & server connection strings in the Connect form.
- Added checkbox for IsAnonymousAccessible property to topic and queue management control.
- Added checkbox for EnableFilteringMessagesBeforePublishing property to topic management control.
- Added TextBox for UserMetadata property to queue, topic and subscription management control.
- Added TextBox for ForwardTo property to queue and subscription management control.
- Added visualization of IsReadOnly property to queue, topic and subscription management control.
- Added ForwardToForm to select a target queue or topic from a treeview as value for the ForwardTo property.
- Added support for SendBatch to the Sender tab of queue/topic test controls.
- Added support for ReceiveBatch to the Receiver tab of queue/topic/subscription test controls.
- Added support for Get Message Sessions to queue and subscription context menus for session-aware queues and subscriptions.
- Replaced the absolute Uri of a target queue or topic with the value of the Path property (queues) and name property (subscriptions) when loading the value of the ForwardTo property.
- Added ListView for entity information (AccessedAt, UpdatedAt, Status, MessageCountDetail, etc.) to queue, topic and subscription management control.
- Added User Meyadata fields.
- Replaced TextBox with TrackBar for Maximum Size of Queues and Topics.
- Differentiated possible and maximum values for max size of messaging entities for cloud and on-premises Service Bus namespaces.
- Fixed Refresh operation for Subscriptions and Rules nodes.
- Changed the style of DataGridViews in all controls.
- Changed the style of ListViews in all controls.
Adjusted the width of the last column of DataGridViews and ListViews based on control width and vertical scroll bar visibility.
- The main panel is cleared when connecting to a new namespace.
- Fixed minor issues in the Rule control.
- Significantly improved the performance of graph drawing.
- Significantly improved the performance of logging.
- Fixed problems with graphs when stopping load test.
- Fixed problems with graphs when using PrefetchCount > 0
- Hidden the Relay Services node for Service Bus for Windows Server namespaces.
- Hidden the Is Anonymous Accessible settings for cloud Service Bus namespaces.
- The ConnectForm remembers the last connectionstring opened.
- Improved the visualization of the namespace treeview.
- Change icon of the namespace treeview.
- Changed the About form.
- Changed the Windows Azure Logo.
Update: 7 January 2013
This version introduces the following updates:
- Fixed Copy <Queue|Topic|Subscription> URL and Copy Deadletter Queue URL for Service Bus for Windows Server namespaces.
Update: 8 January 2013
This version introduces the following updates:
- Fixed the address format of the To header when sending WCF messages to queues and topics of a Service Bus for Windows Server namespace.
Update: 12 April 2013
This version introduces the following updates:
- This version uses the Microsoft.ServiceBus.dll 2.0 Beta available on NuGet at
http://nuget.org/packages/WindowsAzure.ServiceBus.
- SAS and Authorization Rules: So far, the Windows Azure Service Bus had a strong dependency on ACS for authentication. As you know, Shared Secret is the most commonly used authentication mechanism, but SAML is a good alternative.This generated
some problems, because when ACS is unavailable, applications cannot authenticate and acquire the token necessary to access the Service Bus namespace. That’s why the Service Bus team decided to implement Shared Access Signatures, like in storage services:
you will be able to create authorization rules at the queue and topic level to access them directly with a Primary or Secondary key without the need to authenticate against ACS. This should also speed up the access to messaging entities because it cuts the
hand shacking with ACS. In addition, the Windows Azure management portal will soon provide the ability to create multiple signatures with different rights. These signatures will be available to be used in a Service Bus connection string. The most restrictive
scope always win when you have two SAS, one at the namespace level and one at the entity level, with the same key and different access rights. The Service Bus Explorer 2.0 introduces the possibility to define authorization rules at the queue/topic level
as shown in the picture below:
- Metrics: Windows Azure Service Bus 2.0 introduces the possibility to invoke metrics RESTful services to retrieve useful key performance indicators at the entity level.
- Supported Metrics: Telemetry and usage data include the following metrics:
- Length
- Size
- Incoming Messages
- Outgoing Messages
- Successful operations
- Failed operations
- Internal Server Errors
- Server Busy Errors
- Other Errors
- Metrics support the following granularities:
- PT5M 5 Minutes rollup
- PT1H 1 Hour rollup
- P1D 1 Hour rollup
- P7D 1 Hour rollup
- The Service Bus Explorer 2.0 introduces the ability to query telemetry and metrics data. Right-click the namespace root node and choose
Open Metrics in SDI or MDI mode as shown in the following picture:
- The tool gives the user the ability to define one or more Metrics rules to retrieve metrics data by invokingthe RESTful services exposed by the Service Bus. Note: these are the same services invoked by the Windows Azure Management Portal to show Service
Bus counter in the Dashboard tab. The user can define multiple rules to compare metrics from different entities (e.g. the incoming messages of request queue with the outgoing messages of a response queue in a given timeframe). Metrics from different entities
can be visualized together in the Main Graph, while data and charts for individual metrics can be analyzed on separate tabs. See the following screenshots:
- The rules can be exported/imported to/from an XML file.
- Important Note: to access Metrics data is mandatory to indicate in the configuration file or in the Options form the following values:
- Windows Azure Subscription Id
- Thumbprint of a Windows Azure Management Certificate
- Metrics can also be access at the entity level from the Metrics tab as shown in the following screenshots:
- Monitor: the Service Bus Explorer 2.0 introduces the possibility to monitor in real time and define warning and critical thrshold values for the following properties of for queues, topics and subscriptions:
- Active Message Count
- Deadletter Message Count
- Size
- The current state of a performance counter can be visualized in the Monitor Rules datagrid or in the chart.
- The state is represented by a different color:
- Green: Normal
- Yellow: Warning
- Red: Critical
- State transition events are logged in the Monitor Events listbox.
- The rules can be exported/imported to/from an XML file.
- Sessions: the Service Bus Explorer 2.0 introduces the possibility to retrieve the current sessions for a sessionful queue or subscriptions. You can access this functionality from the new
Sessions button or from the Get Message Sessions context menu of a sessionful entity:
- Peek and Receive Active Messages: the Service Bus Explorer 2.0 introduces the possibility to peek or receive a configurable amount of messages from a queue or subscription. You can access this functionality from the new
Messages button or from the following items in the context menu item of a queue or subscription:
- Receive All Messages
- Receive Top k Messages
- Peek Top k Messages
- When you click the Ok button in the Retrieve messages from queue
(or subscription) dialog, messages are retrieved and showned in the following tab.
- You can browse messages by selecting the corresponding row in the grid. The
Messages tab shows the following information for the selected message:
- Message Text
- Message System Properties
- Message Custom Properties
- Peek and Receive Deadletter Messages: the Service Bus Explorer 2.0 introduces the possibility to peek or receive a configurable amount of messages from the deadletter queue of queues and subscriptions. You can access this functionality
from the new Deadletter button or from the following items in the context menu item of a queue or subscription:
-
- Receive All Deadletter Queue Messages
- Receive Top k Deadletter Queue Messages
- Peek Top k Deadletter Queue Messages
- When you click the Ok button in the Retrieve messages from deadletter queue dialog, messages are retrieved and showned in the following tab.
- You can browse messages by selecting the corresponding row in the grid. The
Deadletter tab shows the following information for the selected message:
-
- Message Text
- Message System Properties
- Message Custom Properties
- Repair and Resubmit Message: the Service Bus Explorer 2.0 introduces the possibility to repair and resubmit a message read or peeked from a queue, subscription or deadletter queue. To perform this operation, just double click a message
in the Messages or Deadletter tab. This action opens a modal dialog from which you can edit the text, system properties and custom properties of the current message and select a queue or topic in the current namespace to which
send the modified message.
- Sender Think Time: the test queue and test topic controls introduce the ability to define a think time in the
Sender tab.
- Receive Think Time: the test queue and test topic controls introduce the ability to define a think time in the
Receiver tab.
- Use multiple files as message template: the Service Bus Explorer 2.0 introduces the possibility to select multiple files from different directories to be used as message templates when testing queues, topics and subscriptions. As
shown in the picture below, in the Message tab select the Files sub-tab and use the
Select Files button to add files to the list of message templates. Select the files that you want to use as message templates during a test. Sender tasks will use the content of these files in a round-robin fashion when sending messages
to queues and topics. All messages will share the custom and system properties defined on the
Message and Sender tabs.
- New configuration settings and Options form: the following settings have been introduced in the Options form and in the configuration file. In addition, the
Options form now provides the ability to persist settings to the configuration file by clicking the
Save button.
- Monitor Refresh Interval
- Subscription Id
- Management Certificate Thumbprint
- Message Path
- Message Text
- Sender Think Time
- Receive Think Time
- New About form: you can access my email address and twitter account in the new about form.
- Auto Delete On Idle: the Service Bus 2.0 introduced for queues, topics and subscriptions the new TimeSpan property
AutoDeleteOnIdle that defines the TimeSpan idle interval after which the topic is automatically deleted. The minimum duration is 5 minutes. The Service Bus Explorer 2.0 has been extended to support this property.
- Minor changes
- Added check to make sure that non-numeric values can be entered in textboxes that expect a number
- Added links to blog, email and twitter in the About form
- Changed the CreateFileName method of the MainForm class that is invoked when exporting entities
- Changed Session Timeout with Server Timeout in test queue/topic/subscription controls
- Deleted Expand and Collapse node from queue node context menu.
- Fixed a problem with in the ForwardTo form.
- The message text in the test queue, topic and relay service controls is now indented when is Xml.
- Added a border to flat comboboxes.
- Changed look & feel of forms
- Dispose dialogs and forms after use.
- Changed Docking properties of chart Legends: moved from right to top.
- Fixed problem with MaxSizeInMegabytes and ForwardTo properties when importing/exporting entities.
- Service Bus for Windows Server support: the Service Bus 2.0 temporarily interrupts the symmetry between the cloud and on-premises version of the Service Bus. In other words, the Microsoft.ServiceBus.dll 2.0 client is not compatible
with the Service Bus for Windows Server 1.0. For this reason, I included the old version of the Service Bus Explorer in a zip file called 1.8 which in turn is contained in the zip file of the current version. The old version of the Service Bus Explorer uses
the Microsoft.ServiceBus.dll 1.8 which is compatible with the Service Bus for Windows Server.
Update: 19 April 2013
This version introduces the following updates:
- Fixed display problems when Control Panel -> Display -> Change the size of all items is set to 125%.
Update: 2 May 2013
This version introduces the following updates:
- RTM version of the Microsoft.ServiceBus.dll
Update: 10 May 2013
This version introduces the following updates:
- Fixed a regression bug affecting the bindingTreeView control in the TestRelayServiceControl.
Update: 30 September 2013
This version introduces the following updates:
- See the following resources for more information on these properties:
- Important Note: when using
TransportType = Amqp, some features are not supported. So expect to see error messages such as "the method or operation is not supported": e.g. transactions and Batch-based APIs are not actually supported. For more information, please see the following
topic:
- The Options Form allows to select the default
ConnectivityMode. This information is saved in the appSettings
section of the configuration file.
- Added
SelectionMode =
MultiExtended to the Log listbox. This feature allows the user to select multiple lines and use the SHIFT, CTRL, and arrow keys to make selections.
- Implemented copy & paste of messages from the Log listbox (Ctrl + C).
- Added a context menu to the Log listbox.
- The context menu allows the user to select the perform actions:
- Copy All: copy all of the lines in the clipboard.
- Copy Selected: copy only the selected lines in the clipboard.
- Clear All: clear all of the lines in the log.
- Clear Selected: clear only the selected lines in the log.
- Save all: save all of the lines in a text file.
- Save Selected: save only the selected lines in a text file.
- This functionality allows to clone and send the selected messages to a the same or alternative queue or topic in the
Service Bus namespace. If you want to edit the payload, system properties or user-defined properties, you have to select, edit and send messages one at a time. In order to do so, double click a message in the DataGridView or right click the
message and click Repair and Resubmit Selected Message from the context menu. This opens up the following dialog that allows to modify and resubmit the message or to save the payload to a text file.
Important Note: the Service Bus does not allow to receive and delete a peeked
BrokeredMessage by
SequenceNumber. Only deferred messages can by received by
SequenceNumber. As a consequence, when editing and resubmitting a peeked message, there's no way to receive and delete the original copy.
- The Service Bus Explorer 2.1 introduces support for
Notification Hubs. See the following resources for more information on this topic:
- The Notification Hubs node under the namespace root node allows to manage notification hubs in defined in
Windows Azue Service Bus namespace.
- The context menu allows to perform the following actions:
- Create Notification Hub: create a new notification hub
- Delete Notification Hubs: delete all the notification hubs defined in the current namespace.
- Refresh Notification Hubs: refreshed the list of notification hubs.
- Export Notification Hubs: exports the definition of all the notification hubs to a XML file.
- Expand Subtree: expands the tree under Notification Hubs node.
- Collapse Subtree: collapse the tree under Notification Hubs node.
- The Create Notification Hub allows to define the path, credentials, and metadata for a new notification hub:
- If you click an existing notification hub, you can view and edit credentials and metadata:
- The Authorization Rules tab allows to review or edit the Shared Access Policies for the selected notification hub.
- The Registrations buttons opens a a dialof that allows the registrations to query:
- You can select one of the following options:
- PNS Handle: this option allows to retrieve registrations by
ChannelUri (Windows Phone 8 and Windows Store Apps registrations),
DevieToken (Apple registrations), GcmRegistrationId (Google registrations)
- Tag: this options allows to find all the registrations sharing the specified tag.
- All: this options allows to receive n registrations where
n is specified by the Top Count parameter. This value specifies also the page size. In fact, the tool supports registration data paging and allows to retrieve more data using the continuation mechanism.
- The Registrations tab allows to select one or multiple registrations from the
DataGridView.
- The navigation control in the bottom of the registrations control allows to navigate through pages.
- The DataGridView context menu provides access to the following actions:
- Update Selected Registrations: update the selected registrations.
- Delete Selected Registrations: delete the selected registrations.
- The PropertyGrid on the right-hand side allows to edit the properties (e.g.
Tags or BodyTemplate) of an existing registration.
- The Create button allows to create a new registration. Select the registration type from the dropdownlist and enter mandatory and optional (e.g.
Tags, Headers) information and click the
Ok button to confirm.
- The Template tab allows to send template notifications:
- The Notification Payload read-only texbox shows the payload in JSON format.
- The Notification Properties datagridview allows to define the template properties.
- The Notification Tags datagridview allows to define one or multiple tags. A separate notification is sent for each tag.
- The Additional Headers datagridview allows to define additional custom headers for the notification.
- The Windows Phone tab allows to send native notifications to
Windows Phone 8 devices.
- The Notification Payload texbox shows the payload in JSON format. When the
Manual option is selected in the dropdownmenu under Notification Template, you can edit or paste the payload direcly in the control. When any of the other options (Tile,
Toast, Raw) is selected, this field is read-only.
- The Notification Template dropdownlist allows to select between the following types of notification:
- When Toast, Tile, or Raw is selected, the datagridview under the
Notification Template section allows to define the properties for the notification, as shown in the figures below.
- The Notification Tags datagridview allows to define one or multiple tags. A separate notification is sent for each tag.
- The Additional Headers datagridview allows to define additional custom headers for the notification.
- The Windows tab allows to send native notifications to Windows Store Apps running on Windows 8 and
Windows 8.1.
- The Notification Payload texbox shows the payload in JSON format. When the
Manual option is selected in the dropdownmenu under Notification Template, you can edit or paste the payload direcly in the control. When any of the other options (Tile, Toast, Raw)
is selected, this field is read-only.
- The Notification Template dropdownlist allows to select between the following types of notification:
- When Toast, Tile, or Raw is selected, the datagridview under the Notification Templatesection allows to define the properties for the notification, as shown
in the figures below.
- The Notification Tags datagridview allows to define one or multiple tags. A separate notification is sent for each tag.
- The Additional Headers datagridview allows to define additional custom headers for the notification.
- The Apple and Google tabs provides the ability to send, respectively, Apple and Gcm native notifications. For brevity, I omit the description of
the Apple tab as it works the same way as the Google one.
- The Json Payload texbox allows to enter the payload in JSON format.
- The Notification Tags datagridview allows to define one or multiple tags. A separate notification is sent for each tag.
- The Additional Headers datagridview allows to define additional custom headers for the notification.
- Added the possibility to select and resubmit multiple messages in a batch mode from the
Messages and Deadletter tabs of queues and subscriptions. It's sufficient to select messages in the
DataGridView as shown in the following picture, right click to show the context menu and choose
Resubmit Selected Messages in Batch Mode.
- Minor changes
- Fixed code of the Click event handler for the Default
button in the Options Form.
- Replaced the
DataContractJsonSerializer with the
JavaScriptSerializer class in the JsonSerializerHelper class.
- Fixed a problem when reading Metrics data from the RESTul services exposed by a
Windows Azure Service Bus namespace.
- Changes the look and feel of messages in the Messages and
Deadletter tabs of queues and subscriptions.
- Introduced indent formatting when showing and editing XML messages.
Update: 9 October 2013
This version introduces the following updates:
- Fixed a bug when accessing a notification hub with no registrations.
- Fixed a bug that prevented the tool to connect to a Windows Azure Service Bus namespace when using a SAS connection string.
Update: 14 October 2013
This version introduces the following updates:
- Fixed a problem affecting Import functionality. When importing a subscription with no default rule ($Default), the code erroneously created the subscription with a default rule. The problem is now fixed.
Update: 29 November 2013
This version introduces the following updates for both the 2.1 and 2.2 version:
- Added support to read the body of a WCF message when the payload is in JSON format.
- Added support to send the body of a WCF message when the payload is in JSON format.
- Implemented the possibility to pass command line arguments for both the 2.1 and 2.2 version:
ServiceBusExplorer.exe [-c|/c] [connectionstring]
[-q|/q] [queue odata filter expression]
[-t|/t] [topic odata filter expression]
[-s|/s] [subscription odata filter expression]
ServiceBusExplorer.exe [-n|/n] [namespace key in the configuration file]
[-q|/q] [queue odata filter expression]
[-t|/t] [topic odata filter expression]
[-s|/s] [subscription odata filter expression]
Example: ServiceBusExplorer.exe -n paolosalvatori -q "Startswith(Path, 'request') Eq true" -t "Startswith(Path, 'request') Eq true"
- Improved check when settings properties for Topics and Subscriptions.
- Fixed an error that added columns to message and deadletter datagridview every time the Update button was pressed.Fixed a error on CellDoubleClick for messages and deadletter datagridview that happened when double clicking a header cell.Improved the visualization
of sessions and added the possibility to sort sessions by column.
- Added sorting capability to messages and deadletter messages datagridview for queues and subscriptions. Click the column header to sort rows by the corresponfing property value in ASC or DESC order.
- Added sorting capability to sessions datagridview for queues and subscriptions. Click the column header to sort rows by the corresponfing property value in ASC or DESC order.
- Added sorting capability to registrations datagridview for notification hubs. Click the column header to sort rows by the corresponfing property value in ASC or DESC order.
- Introduced the possibility to define filter expression for peeked/received messages/deadletter messages. Click the button highlighted in the picture below to open a dialog and define a filtter expression using a SQL Expression (e.g. sys.Size > 300 and
sys.Label='Service Bus Explorer' and City='Pisa'). For more information, see SqlFilter.SqlExpression Property.
- Introduced the possibility to define filter expression for peeked/received messages/deadletter messages. Click the button highlighted in the picture below to open a dialog and define a filtter expression using a SQL Expression on public and n on public
properties of RegistrationDescription class (e.g. PlatformType contains 'windows' and ExpirationTime > '2014-2-5' and TagsString contains 'productservice'). The filter engine supports the following predicates:
- =
- !=
- >
- >=
- <
- <=
- StartsWith
- EndsWith
- Contains
- Introduced support for TagExpressions introduced by Service Bus 2.2. When sending a notification, you can select the Tag Expression or Notification Tags to define, respectively, a tag expression (e.g. productservice && (Italy || UK)) or a list of
tags. This feature is available only in the Service Bus Explorer 2.2.
Update: 2 December 2013
This version introduces the following updates:
- Support for the Microsoft.ServiceBus.ConnectionString appSetting. The connection string defined in this setting will be added to the list of connection strings in the corresponding drop-down-list in the
Connect form.
Update: 18 December 2013
This version introduces the following updates:
- Introduced a new command to start one or more listeners for a given queue or subscription. Right click the queue or subscription and select, respectively,
Create Queue Listerner or Create Subscription Listener from the context menu as shown in the following picture.
- In the listener dialog you can set the following properties:
- MaxConcurrentCalls: gets or sets the maximum number of concurrent calls to the callback the message pump should initiate.
- Refresh Interval (sec): sets a refresh interval in seconds for queue or subscription message count information.
- Graph: enable or disable the graph.
- AutoComplete: gets or sets a value that indicates whether the message-pump should call Complete(Guid) or Complete(Guid) on
messages after the callback has completed processing
- Tracking: enable or disable message tracking. When enabled, you can use the Messages tab to access messages.
- Logging: enable or disable logging.
- Verbose: enable or disable verbose mode when logging is enabled.
- Press the Start button to start the listener.
- The Start button turns into the Stop button.
- Press the Stop button to stop the listener.
- Press the Close the listener dialog. If the listener is open, this operation closes the listener.
- Press the Clear button to clear tracked messages and log content.
- Press the Messages tab to access messages.
- You can click s message row to access its payload, custom and system properties.
- Click the the magnifying glass button to define a filter expression for received messages using a SQL Expression (e.g. sys.Size > 300 and sys.Label='Service Bus Explorer' and City='Pisa'). For more information, see SqlFilter.SqlExpression
Property.
- Double click a row or click Repair and Resubmit Message from the context menu to open a message in the a separate dialog. This functionality allows to clone and send the selected messages to a the same or alternative
queue or topic in the Service Bus namespace. If you want to edit the payload, system properties or user-defined properties, you have to select, edit and send messages one at a time.
- Minor changes:
- Fixed ListView control visualization when the vertical bar is visible
- Increased ReaderQuotas when reading WCF messages. This adds support for large messages.
Update: 10 February 2014
This version introduces the following updates:
- Johann Cooper (@JohannCooper) extended the Import/Export functionality to support SAS rules for Windows Server Service Bus. I included the code in the 2.1 and 2.2 versions of the tool.
Update: 21 May 2014
This version introduces the following updates:
- Improved support for AMQP transport protocol in the
Connect Form. For example, when using the Service Bus Explorer to connect to an on-premises namespace, if you select AMQP as Transport Type in the Connect Form, the tool automatically changes the value of the TransportType and RuntimePort parameters:
- NetMessaging: RuntimePort=9354;TransportType=NetMessaging
- AMQP: RuntimePort=5671;TransportType=Amqp
- Added support for the stsEndpoint parameter in the connection string for cloud namespaces. This feature was specifically requested by the Service Bus team.
- The tool can now use the AMQP transport protocol to read messages from queues, subscriptions and deadletter queues.
- Added full support to namespace-level SAS connection strings, both in the configuration file and
Connect Form.
- Changed Receive label into Receive and Delete in the ReceiveModeForm to make it clear that the receive operation deletes messages from the underlying
queue, subscription or deadletter queue.
- Fixed a bug when reading messages from the deadletter queue of a queue or subscription.
- Fixed a bug in the SelectEntityForm: replaced TreeView.TopNode with
TreeView.Nodes[0]
- Implemented support for the new ForwardDeadLetteredMessagesTo property of the
QueueDescription and SubscriptionDescription classes.
- Implemented batching support in the listener for queues and subscriptions. You can now specify a value for the
PrefetchCount property used by the
MessageReceiver object used by the listener to prefetch multiple messages from a queue or subscription. This greatly improves the overall performance of the listener. Now you can also specify the value for the
Mode property of the the MessageReceiver object used by the listener.
To enable or disable this feature, you can use the showMessageCount setting in the configuration file, or use the new
Show Message Count checkbox in the Options Form
as shown in the picture below.
- As shown in the figure below, numbers in the property list of queues, topics, subscriptions, and notification hubs are now formatted to make it easier to read their value.
- Replaced the logo to reflect the recent change of name from Windows Azure to
Microsoft Azure.
Update: 20 June 2014
This version introduces the following updates:
- Added license.txt file containing the license for the Service Bus Explorer tool
- Updated the Microsoft.ServiceBus.dll from version <IP_ADDRESS> to <IP_ADDRESS>
Update: 18 July 2014
This version introduces the following updates:
- Connect Form now allows to select the type of entities that you want to load and manage in the selected namespace:
- You can specify a default value of the entities that you want to manage in the
selectedEntities appSettings in the configuration file:
XML
Edit|Remove
xml
<appSettings>
...
<add key="selectedEntities" value="Queues,Topics,Relay Services,Event Hubs,Notification Hubs" />
...
</appSettings>
<appSettings>
...
<add key="selectedEntities" value="Queues,Topics,Relay Services,Event Hubs,Notification Hubs" />
...
</appSettings>
- You can also set default selected entities in the Options dialog:
- Event Hubs: this version of the tool introduces the support for a new entity called
Event Hub and related entities, Consumer Groups and
Partitions.
- The tool allows to perform the following actions on an Event Hub:
- Create Event Hub
- Read Event Hub
- Update Event Hub
- Delete Event Hub
- Disable / Enable Event Hub
- Refresh Event Hub
- Copy Event Hub Url to Clipboard
- Export / Import event hub to / from XML file
- Send Event Data to an Event Hubs (more on this below)
- The tool allows to manage the Consumer Groups of a given
Event Hub:
- Create Consumer Group
- Read Consumer Group
- Update Consumer Group
- Delete Consumer Group
- Enable / Disable Consumer Group
- Refresh Consumer Group
- Copy Consumer Group Url to Clipboard
- Create a Listener for the Consumer Group. A receiver is created for each Partition of the Event Hub.
- The tool allows to manage the Partitions of a given
Event Hub. Note: Partitions are located under Consumer Groups in the hierarchy of the entity TreeView:
- Read Partition
- Refresh Partition
- Copy Partition Url to Clipboard
- Create a Listener for the Partition. A receiver is created only for the selected Partition under the Consumer Group.
- Added support for Notification Hubs and Event Hubs to entity
Import & Export functionalities. You can now import / export the definition of Notification Hubs and Event Hubs from / to XML file.
- The JSON serializer helper class is now based on Newtonsoft Json.Net library.
- Added support for the new BrokeredMessage.ForcePersistence property to the testing UI of queues and topics.
- File Templates: This version introduces the possibility to send binary files or messages based on JSON or XML Templates. This feature is available for queues, topics and event hubs.
- For example, when you select Send Messages menu item from the context menu of a queue and you select the
Files tab, now you have 4 options available:
Options:
- Text File: this option allows to select one or more text files. These files specify the payload of the outgoing messages (BrokeredMessage for queues and topics, EventData for event hubs), while the custom properties are defined in the grid
under the Message Properties control group.
- Binary File: this option allows to select one or more binary files. These files specify the payload of the outgoing messages (BrokeredMessage for queues and topics, EventData for event hubs), while the custom properties are defined in the
grid under the Message Properties control group.
- Json Template: this option allows to select one or more Json templates. Each template defines the payload for a BrokeredMessage or EventData and the value of the system and the custom properties:
BrokeredMessage Json Template:
JavaScript
Edit|Remove
js
{
"messageId": "1",
"sessionId": "",
"correlationId": "",
"contentType": "",
"label": "Service Bus Explorer",
"partitionKey": "",
"to": "",
"replyTo": "",
"replyToSessionId": "",
"timeToLive": "",
"scheduledEnqueueTimeUtc": "",
"forcePersistence": "false",
"message": "{\"deviceId\":\"1\", \"value\":\"25\"}",
"properties": [
{
"key": "deviceId",
"type": "Int64",
"value": "1"
},
{
"key": "location",
"type": "String",
"value": "Room 1"
},
{
"key": "city",
"type": "String",
"value": "Milan"
},
{
"key": "country",
"type": "String",
"value": "Italy"
},
{
"key": "value",
"type": "Int32",
"value": "25"
}
]
}
{
"messageId": "1",
"sessionId": "",
"correlationId": "",
"contentType": "",
"label": "Service Bus Explorer",
"partitionKey": "",
"to": "",
"replyTo": "",
"replyToSessionId": "",
"timeToLive": "",
"scheduledEnqueueTimeUtc": "",
"forcePersistence": "false",
"message": "{\"deviceId\":\"1\", \"value\":\"25\"}",
"properties": [
{
"key": "deviceId",
"type": "Int64",
"value": "1"
},
{
"key": "location",
"type": "String",
"value": "Room 1"
},
{
"key": "city",
"type": "String",
"value": "Milan"
},
{
"key": "country",
"type": "String",
"value": "Italy"
},
{
"key": "value",
"type": "Int32",
"value": "25"
}
]
}
EventData Json Template:
JavaScript
Edit|Remove
js
{
"partitionKey": "1",
"message": "{\"deviceId\":\"1\", \"value\":\"25\"}",
"properties": [
{
"key": "deviceId",
"type": "Int64",
"value": "1"
},
{
"key": "location",
"type": "String",
"value": "Room 1"
},
{
"key": "city",
"type": "String",
"value": "Milan"
},
{
"key": "country",
"type": "String",
"value": "Italy"
},
{
"key": "value",
"type": "Int32",
"value": "25"
}
]
}
{
"partitionKey": "1",
"message": "{\"deviceId\":\"1\", \"value\":\"25\"}",
"properties": [
{
"key": "deviceId",
"type": "Int64",
"value": "1"
},
{
"key": "location",
"type": "String",
"value": "Room 1"
},
{
"key": "city",
"type": "String",
"value": "Milan"
},
{
"key": "country",
"type": "String",
"value": "Italy"
},
{
"key": "value",
"type": "Int32",
"value": "25"
}
]
}
- Xml Template: this option allows to select one or more Xml templates. Each template defines the payload for a BrokeredMessage or EventData and the value of the system and the custom properties. Note: the payload is contained in CDATA section.
 Likewise, both Json and Xml templates for
EventData objects are defined by the EventaDataTemplate class.
- Note: when using Files, the number of messages to send is still determined by the value of the
Message Count textbox under the Sender tab. If the number of messages to send is higher than the number of selected files or templates, these are treated as a circular list.
- Brokered Message Generators: this release introduces the possibility to extend the tool with extension components. In particular, BrokeredMessage generators are components that allows to create a configurable amount of messages to send
to a queue or topic.
- These components needs to implement the IBrokeredMessageGenerator interface defined by the tool:
C#
Edit|Remove
csharp
namespace Microsoft.WindowsAzure.CAT.ServiceBusExplorer
{
public interface IBrokeredMessageGenerator
{
IEnumerable<BrokeredMessage> GenerateBrokeredMessageCollection(int messageCount,
WriteToLogDelegate writeToLog = null);
}
}
namespace Microsoft.WindowsAzure.CAT.ServiceBusExplorer
{
public interface IBrokeredMessageGenerator
{
IEnumerable<BrokeredMessage> GenerateBrokeredMessageCollection(int messageCount,
WriteToLogDelegate writeToLog = null);
}
}
- The dll containing these components needs to be copied in the directory containing the tool. Finally, you need to specify the fully qualified name of the class in the
brokeredMessageGenerators section of the configuration file as shown below:
XML
Edit|Remove
xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
...
<brokeredMessageGenerators>
<add key="OnOffDeviceBrokeredMessageGenerator"
value="Microsoft.WindowsAzure.CAT.ServiceBusExplorer.OnOffDeviceBrokeredMessageGenerator,ServiceBusExplorer" />
<add key="ThresholdDeviceBrokeredMessageGenerator"
value="Microsoft.WindowsAzure.CAT.ServiceBusExplorer.ThresholdDeviceBrokeredMessageGenerator,ServiceBusExplorer" />
</brokeredMessageGenerators>
...
</configuration>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
...
<brokeredMessageGenerators>
<add key="OnOffDeviceBrokeredMessageGenerator"
value="Microsoft.WindowsAzure.CAT.ServiceBusExplorer.OnOffDeviceBrokeredMessageGenerator,ServiceBusExplorer" />
<add key="ThresholdDeviceBrokeredMessageGenerator"
value="Microsoft.WindowsAzure.CAT.ServiceBusExplorer.ThresholdDeviceBrokeredMessageGenerator,ServiceBusExplorer" />
</brokeredMessageGenerators>
...
</configuration>
- The tool provides two brokered message generators out of the box:
- OnOffDeviceBrokeredMessageGenerator: this components allows to simulate signals coming from a configurable amount of devices with can assume of two values: On (1) and Off (0). The component can be configured to send the payload in JSON
or XML format.
Messages generated by the component have the following payload and properties.
JavaScript
Edit|Remove
js
Payload:
{"deviceid":93,"value":0}
Properties:
- Key=[deviceId] Value=[93]
- Key=[value] Value=[0]
- Key=[time] Value=[635398156544407695]
- Key=[city] Value=[Milan]
- Key=[country] Value=[Italy]
Payload:
{"deviceid":93,"value":0}
Properties:
- Key=[deviceId] Value=[93]
- Key=[value] Value=[0]
- Key=[time] Value=[635398156544407695]
- Key=[city] Value=[Milan]
- Key=[country] Value=[Italy]
-
- ThresholdDeviceBrokeredMessageGenerator: this components allows to simulate signals coming from a configurable amount of devices with can assume values within a range defined by . The component can be configured to send the payload in JSON
or XML format.
Messages generated by the component have the following payload and properties.
JavaScript
Edit|Remove
js
Payload:
{"deviceid":93,"value":97}
Properties:
- Key=[deviceId] Value=[93]
- Key=[value] Value=[97]
- Key=[time] Value=[635398156544407695]
- Key=[city] Value=[Milan]
- Key=[country] Value=[Italy]
Payload:
{"deviceid":93,"value":97}
Properties:
- Key=[deviceId] Value=[93]
- Key=[value] Value=[97]
- Key=[time] Value=[635398156544407695]
- Key=[city] Value=[Milan]
- Key=[country] Value=[Italy]
- BrokeredMessage generators can be selected in the Send Messages dialog or in the
Test queue / topic in SDI / MDI control as selecting the
Generator tab as shown in the figure below:
- Note: when this option is selected, the properties defined in the grid under the Message Properties control group are ignored.
- Brokered Message Inspectors: the tool now allows to create a message inspector that can be used to intercept and eventually modify any outgoing or upcoming message sent to a queue or topic or received from a queue or a subscription.
- These components needs to implement the IBrokeredMessageGenerator interface defined by the tool:
C#
Edit|Remove
csharp
namespace Microsoft.WindowsAzure.CAT.ServiceBusExplorer
{
public interface IBrokeredMessageInspector
{
BrokeredMessage BeforeSendMessage(BrokeredMessage message,
WriteToLogDelegate writeToLog = null);
BrokeredMessage AfterReceiveMessage(BrokeredMessage message,
WriteToLogDelegate writeToLog = null);
}
}
namespace Microsoft.WindowsAzure.CAT.ServiceBusExplorer
{
public interface IBrokeredMessageInspector
{
BrokeredMessage BeforeSendMessage(BrokeredMessage message,
WriteToLogDelegate writeToLog = null);
BrokeredMessage AfterReceiveMessage(BrokeredMessage message,
WriteToLogDelegate writeToLog = null);
}
}
- The dll containing these components needs to be copied in the directory containing the tool. Finally, you need to specify the fully qualified name of the class in the
brokeredMessageGenerators section of the configuration file as shown below:
XML
Edit|Remove
xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
...
<brokeredMessageInspectors>
<add key="LogBrokeredMessageInspector"
value="Microsoft.WindowsAzure.CAT.ServiceBusExplorer.LogBrokeredMessageInspector,ServiceBusExplorer" />
<add key="ZipBrokeredMessageInspector"
value="Microsoft.WindowsAzure.CAT.ServiceBusExplorer.ZipBrokeredMessageInspector,ServiceBusExplorer" />
</brokeredMessageInspectors>
...
</configuration>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
...
<brokeredMessageInspectors>
<add key="LogBrokeredMessageInspector"
value="Microsoft.WindowsAzure.CAT.ServiceBusExplorer.LogBrokeredMessageInspector,ServiceBusExplorer" />
<add key="ZipBrokeredMessageInspector"
value="Microsoft.WindowsAzure.CAT.ServiceBusExplorer.ZipBrokeredMessageInspector,ServiceBusExplorer" />
</brokeredMessageInspectors>
...
</configuration>
The tool provides two BrokeredMessage generators out of the box:
- ZipBrokeredMessageInspector: this component can be used to zip the body of outgoing messages sent to queue or topic and/or to unzip the content of messages received from a queue or subscription.
- LogBrokeredMessageInspector: this component can be used to log the body and custom properties of outgoing messages sent to queue or topic and/or incoming messages read from a queue or subscription. The log is saved in the same directory
of the tool.
BrokeredMessage inspectors can be selected under the following dialogs:
- In the Sender tab of the Send Messages dialog
- Under the Sender and Receiver tab in the
Test queue / topic in SDI / MDI dialog:
- In the Listener dialog for a queue or subscription.
- Note: when resubmitting multiple messages, it's not possible to select a brokered message inspector
- Listener Dialog for Queues and Subscriptions: the following features have been added to the Listener dialog for queues and subscriptions:
- The possibility to select a BrokeredMessage inspector (see point 1 in the figure below)
- The Average Time performance counter (see point 3 in the figure below)
- The KB/Sec performance counter (see point 4 in the figure below)
- The possibility to select a scale factor (see points 2, 3 and 4 in the figure below)
- messages in the listener forms are now tracked in an asynchronous way by a dedicated Task T. Receiver tasks just add messages to a BlockingCollection, while T reads messages out of the collection and writes them to the messages Grid control.
- EventData Generators: this release introduces the possibility to extend the tool with extension components. In particular, EventData generators are components that allows to create a configurable amount
of EventData objects to send to an event hub.
- These components needs to implement the IEventDataGenerator interface defined by the tool:
C#
Edit|Remove
csharp
namespace Microsoft.WindowsAzure.CAT.ServiceBusExplorer
{
public interface IEventDataGenerator
{
IEnumerable<EventData> GenerateEventDataCollection(int eventDataCount,
WriteToLogDelegate writeToLog = null);
}
}
namespace Microsoft.WindowsAzure.CAT.ServiceBusExplorer
{
public interface IEventDataGenerator
{
IEnumerable<EventData> GenerateEventDataCollection(int eventDataCount,
WriteToLogDelegate writeToLog = null);
}
}
- The dll containing these components needs to be copied in the directory containing the tool. Finally, you need to specify the fully qualified name of the class in the
eventDataGenerators section of the configuration file as shown below:
XML
Edit|Remove
xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
...
<eventDataInspectors>
<add key="LogEventDataInspector"
value="Microsoft.WindowsAzure.CAT.ServiceBusExplorer.LogEventDataInspector,ServiceBusExplorer" />
<add key="ZipEventDataInspector"
value="Microsoft.WindowsAzure.CAT.ServiceBusExplorer.ZipEventDataInspector,ServiceBusExplorer" />
</eventDataInspectors>
...
</configuration>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
...
<eventDataInspectors>
<add key="LogEventDataInspector"
value="Microsoft.WindowsAzure.CAT.ServiceBusExplorer.LogEventDataInspector,ServiceBusExplorer" />
<add key="ZipEventDataInspector"
value="Microsoft.WindowsAzure.CAT.ServiceBusExplorer.ZipEventDataInspector,ServiceBusExplorer" />
</eventDataInspectors>
...
</configuration>
- The tool provides two brokered message generators out of the box:
- OnOffDeviceEventDataGenerator: this components allows to simulate signals coming from a configurable amount of devices with can assume of two values: On (1) and Off (0). The component can be configured to send the payload in JSON or XML
format.
Messages generated by the component have the following payload and properties.
JavaScript
Edit|Remove
js
Payload:
{"deviceid":93,"value":0}
Properties:
- Key=[deviceId] Value=[93]
- Key=[value] Value=[0]
- Key=[time] Value=[635398156544407695]
- Key=[city] Value=[Milan]
- Key=[country] Value=[Italy]
Payload:
{"deviceid":93,"value":0}
Properties:
- Key=[deviceId] Value=[93]
- Key=[value] Value=[0]
- Key=[time] Value=[635398156544407695]
- Key=[city] Value=[Milan]
- Key=[country] Value=[Italy]
-
- ThresholdDeviceEventDataGenerator: this components allows to simulate signals coming from a configurable amount of devices with can assume values within a range defined by . The component can be configured to send the payload in JSON or
XML format.
Messages generated by the component have the following payload and properties.
JavaScript
Edit|Remove
js
Payload:
{"deviceid":93,"value":97}
Properties:
- Key=[deviceId] Value=[93]
- Key=[value] Value=[97]
- Key=[time] Value=[635398156544407695]
- Key=[city] Value=[Milan]
- Key=[country] Value=[Italy]
Payload:
{"deviceid":93,"value":97}
Properties:
- Key=[deviceId] Value=[93]
- Key=[value] Value=[97]
- Key=[time] Value=[635398156544407695]
- Key=[city] Value=[Milan]
- Key=[country] Value=[Italy]
- EventData generators can be selected in the Send Messages dialog or in the
Test queue / topic in SDI / MDI control as selecting the
Generator tab as shown in the figure below:
- Note: when this option is selected, the properties defined in the grid under the Message Properties control group are ignored.
- EventData Inspectors: this release of the tool now allows to create an EventData inspector that can be used to intercept and eventually modify any outgoing or upcoming EventData sent to an event hub or received from an event hub partition.
- These components needs to implement the IEventDataGenerator interface defined by the tool:
C#
Edit|Remove
csharp
namespace Microsoft.WindowsAzure.CAT.ServiceBusExplorer
{
public interface IEventDataInspector
{
EventData BeforeSendMessage(EventData eventData,
WriteToLogDelegate writeToLog = null);
EventData AfterReceiveMessage(EventData eventData,
WriteToLogDelegate writeToLog = null);
}
}
namespace Microsoft.WindowsAzure.CAT.ServiceBusExplorer
{
public interface IEventDataInspector
{
EventData BeforeSendMessage(EventData eventData,
WriteToLogDelegate writeToLog = null);
EventData AfterReceiveMessage(EventData eventData,
WriteToLogDelegate writeToLog = null);
}
}
- The dll containing these components needs to be copied in the directory containing the tool. Finally, you need to specify the fully qualified name of the class in the
eventDataGenerators section of the configuration file as shown below:
XML
Edit|Remove
xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
...
<eventDataGenerators>
<add key="OnOffDeviceEventDataGenerator"
value="Microsoft.WindowsAzure.CAT.ServiceBusExplorer.OnOffDeviceEventDataGenerator,ServiceBusExplorer" />
<add key="ThresholdDeviceEventDataGenerator"
value="Microsoft.WindowsAzure.CAT.ServiceBusExplorer.ThresholdDeviceEventDataGenerator,ServiceBusExplorer" />
</eventDataGenerators>
...
</configuration>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
...
<eventDataGenerators>
<add key="OnOffDeviceEventDataGenerator"
value="Microsoft.WindowsAzure.CAT.ServiceBusExplorer.OnOffDeviceEventDataGenerator,ServiceBusExplorer" />
<add key="ThresholdDeviceEventDataGenerator"
value="Microsoft.WindowsAzure.CAT.ServiceBusExplorer.ThresholdDeviceEventDataGenerator,ServiceBusExplorer" />
</eventDataGenerators>
...
</configuration>
- The tool provides two EventData generators out of the box:
- ZipEventDataInspector: this component can be used to zip the body of outgoing event data objects sent to an event hub and/or to unzip the content of event data objects received from an event hub partition.
- LogEventDataInspector: this component can be used to log the body and custom properties of event data objects sent to an event hub and/or incoming event data objects read from an event hub partition. The log is saved in the same directory
of the tool.
EventData inspectors can be selected under the following dialogs:
- In the Sender tab of the Send Messages dialog
- In the Listener dialog for a queue or subscription.
- Listener Dialog for Consumer Groups or individual Partitions: this release of the tool allows to create a listener to receive even data messages from all the partitions of an event hub or just from an single partition:
- The possibility to select an EventData inspector (see point 1 in the figure below)
- The Listener dialog exposes the following performance counters:
- Events Total (see point 2 in the figure below)
- Events/sec (see point 3 in the figure below)
- The Average Time (see point 4 in the figure below)
- The KB/Sec (see point 5 in the figure below)
- The possibility to select a scale factor (see points 2, 3 , 4, 5 in the figure below)
- You can select a Partition from the dropdown list to see its information in the panel below (see point 6)
- When message tracking is enabled using the corresponding checkbox, event data messages are saved in the grid available in the Events tab (see point 7)
- In the Options panel you can specify options:
- Refresh Interval: the amount of time expressed in seconds after which partition information is refreshed from the server.
- Receive Timeout: the timeout used by the ReceiveAsync method used by receivers, one for each partition. Note: when the Checkpoint option is enabled, a checkpoint is executed at every timeout.
- Prefetch Count: defines a value for the PrefetchCount property of receivers.
- Offset: specify the offset at which each receiver will start receiving event data from a partition.
- Checkpoint Count: when Checkpoint option is enabled, specifies after how many event data each receiver performs a checkpoint.
Note: in the current version this option is disabled because is not supported by the current version of the Microsoft.ServiceBus.dll.
- Logging: enable or disable logging.
- Verbose: enable or disable verbose logging.
- Tracking: enable of disable event data tracking.
- Graph: enable or disable the graph.
- Checkpoint: enable or disable checkpoints. Note: in the current version this option is disabled because is not supported by the current version of the Microsoft.ServiceBus.dll.
- Messages in the listener forms are now tracked in an asynchronous way by a dedicated Task T. Receiver tasks just add messages to a BlockingCollection, while T reads messages out of the collection and writes them to the messages Grid control.
- Message Payload Visualization: The font used to show the payload of messages has been hanged from
Microsoft Sans Serif to Consolas.
- Binary Messages support: The tool now supports the possibility to send binary files (more on this below in the file template section). Likewise, the tool adds support to display binary files in hexadecimal format. The empiric rule
to establish if the payload of a BrokeredMessage or EventData object is binay is the presence of control characters other than line feed, carriage return and horizontal tab.
- Other improvements
- Greatly improved the Dispose of user controls.
- Increased the performance and stability of logging.
Update: 22 July 2014
This version introduces the following updates:
- Changed logging: now when you stop a queue, subscription, consumer group or partition listener, the log stops immediately.
- Updated Microsoft.ServiceBus.dll to version <IP_ADDRESS>.
- Minor UI changes.
Update: 19 September 2014
This version introduces the following updates:
- The code of the Service Bus Explorer is now avalable on
GitHub as a public project!
- Updated Microsoft.ServiceBus.dll to version <IP_ADDRESS>.
- Added controls to specify the epoch and offsetInclusive
parameters for the CreateReceiverAsync method of the
EventHubConsumerGroup class.
Update: 22 September 2014
This version introduces the following updates:
- Added SequenceNumber column to the data grid under the
Events tab of the PartitionListenerControl.
- Added SequenceNumber to the log control of the
PartitionListenerControl.
- Changed the labels under the he Events tab of the PartitionListenerControl.
- Changed the default value of the Epoch textbox from 0 to -1.
Update: 4 December 2014
This version introduces the following updates:
- Updated Microsoft.ServiceBus.dll to version <IP_ADDRESS>.
- Added support for the EnableExpress property of queues and topics:
- The following bug has been fixed:
- Go to a topic with two or more enabled subscriptions. All the subscription icons show enabled state.
- Right click one subscription and click 'Disable Subscription', icon shows disabled state.
- Go to parent 'Subscriptions' node and 'Refresh': the disabled subscription shows an *enabled* icon even though it is disabled.
- The logging mechanism in the PartitionListernerControl has been highly improved. Now logging stops as soon as the user clicks the
Stop or Close button in the Consumer Group
and Partition Listener dialog.
- The code of the Consumer Group and Partition Listener has been dramatically improved:
- The tool now uses the EventProcessorFactory<T> :
IEventProcessorFactory class for creating instances of the EventProcessor
: IEventProcessor class that are used to process events from event hub partitions.
- The tool provides a custom checkpoint manager class: EventProcessorCheckpointManager :
ICheckpointManager. In order to use the client-side checkpoint mechanism introduced by the tool, make sure to check the
Checkpoint control in the Consumer Group and Partition Listener dialog as shown in the picture below.
- The application uses the checkpoint manager to perform checkpoints in the in-process memory and persists checkpoints to a JSON file at the exit. At the start, the application reads checkpoints from the EventHubPartitionCheckpoints.json
file located in the same directory of the tool. To remove all checkpoints, it's sufficient to delete the file. You can also open the file and selectively delete checkpoints for specific event hub partitions.
JavaScript
Edit|Remove
js
[
{
"namespace": "eventhubs",
"eventHub": "basicsampleeventhub",
"leases": {
"0": {
"PartitionId": "0",
"Owner": "ServiceBusExplorer",
"Token": null,
"Epoch": 0,
"Offset": "244712",
"SequenceNumber": 1699
},
"1": {
"PartitionId": "1",
"Owner": "ServiceBusExplorer",
"Token": null,
"Epoch": 0,
"Offset": "127416",
"SequenceNumber": 885
},
"7": {
"PartitionId": "7",
"Owner": "ServiceBusExplorer",
"Token": null,
"Epoch": 0,
"Offset": "335176",
"SequenceNumber": 2327
},
"2": {
"PartitionId": "2",
"Owner": "ServiceBusExplorer",
"Token": null,
"Epoch": 0,
"Offset": "86152",
"SequenceNumber": 599
},
"4": {
"PartitionId": "4",
"Owner": "ServiceBusExplorer",
"Token": null,
"Epoch": 0,
"Offset": "238264",
"SequenceNumber": 1654
},
"3": {
"PartitionId": "3",
"Owner": "ServiceBusExplorer",
"Token": null,
"Epoch": 0,
"Offset": "-1",
"SequenceNumber": 0
},
"5": {
"PartitionId": "5",
"Owner": "ServiceBusExplorer",
"Token": null,
"Epoch": 0,
"Offset": "-1",
"SequenceNumber": 0
},
"6": {
"PartitionId": "6",
"Owner": "ServiceBusExplorer",
"Token": null,
"Epoch": 0,
"Offset": "-1",
"SequenceNumber": 0
}
}
}
]
[
{
"namespace": "eventhubs",
"eventHub": "basicsampleeventhub",
"leases": {
"0": {
"PartitionId": "0",
"Owner": "ServiceBusExplorer",
"Token": null,
"Epoch": 0,
"Offset": "244712",
"SequenceNumber": 1699
},
"1": {
"PartitionId": "1",
"Owner": "ServiceBusExplorer",
"Token": null,
"Epoch": 0,
"Offset": "127416",
"SequenceNumber": 885
},
"7": {
"PartitionId": "7",
"Owner": "ServiceBusExplorer",
"Token": null,
"Epoch": 0,
"Offset": "335176",
"SequenceNumber": 2327
},
"2": {
"PartitionId": "2",
"Owner": "ServiceBusExplorer",
"Token": null,
"Epoch": 0,
"Offset": "86152",
"SequenceNumber": 599
},
"4": {
"PartitionId": "4",
"Owner": "ServiceBusExplorer",
"Token": null,
"Epoch": 0,
"Offset": "238264",
"SequenceNumber": 1654
},
"3": {
"PartitionId": "3",
"Owner": "ServiceBusExplorer",
"Token": null,
"Epoch": 0,
"Offset": "-1",
"SequenceNumber": 0
},
"5": {
"PartitionId": "5",
"Owner": "ServiceBusExplorer",
"Token": null,
"Epoch": 0,
"Offset": "-1",
"SequenceNumber": 0
},
"6": {
"PartitionId": "6",
"Owner": "ServiceBusExplorer",
"Token": null,
"Epoch": 0,
"Offset": "-1",
"SequenceNumber": 0
}
}
}
]
- This version of the tool introduces the possibility to send events directly to a specific event hub partition using the
EventHubSender class.
- A bug affecting the dimension of the controls in the Messages
and Deadletter Messages dialogs for queues and subscriptions has been fixed. To send messages to a specific event hub partition, right click a partition and choose
Send Events as shown in the picture below.
- When you send messages to a specific partition, the
EventData.PartitionKey property is ignored. For this reason, the Update PartitionKey and
No PartitionKey checkboxes are not available when sending messages to a given event hub partition.
- When a queue or subscription is partitioned, now the tool invokes the
MessageReceiver.Peek and
MessageReceiver.Receive methods respectively, to peek and read messages one by one from the current queue, subscription or deadletter queue, instead of using the
MessageReceiver.PeekBatch or
MessageReceiver.ReceiveBatch methods. In fact, when the entity is partitioned, the batch methods read messages only from a single partition, hence they don't return all the messages from the
16 partitions or fragments that form the entity.
- Fxed the value shown by the Max Size in Gigabytes slider when the queue or topic is partitioned. In fact, when the queue or subscription is partitioned, the
QueueDescription.MaxSizeInMegabytes and
TopicDescription.MaxSizeInMegabytes property contains the size you specified when you created the entity (1024;2048;3072;4096;5120) multiplied by 16, that is, the number of fragments that compose the partitioned entity.
- Fixed a problem that happened when updating the value of the ForwardTo and ForwardDeadLetteredMessagesTo properties of a subscription.
- This version of the Service Bus Explorer introduces the possibility to save individual or multiple messages to a file in
JSON format. See below for details.
- In the Messages or Deadletter tab of a queue or subscription you can save a single message to a JSON file: right click the message to open the context menu and click Save Selected Message
as shown in the picture below.
This opens the Save File As dialog as shown in the picture below.
The JSON file contains the body and properties of the selected
BrokeredMessage object. Properties are in camel case.
JavaScript
Edit|Remove
js
{
"body": {
"deviceid": 84,
"value": 68
},
"contentType": null,
"correlationId": null,
"deliveryCount": 1,
"enqueuedSequenceNumber": 1,
"enqueuedTimeUtc": "2014-12-03T16:39:48.4958476Z",
"expiresAtUtc": "9999-12-31T23:59:59.9999999",
"forcePersistence": false,
"isBodyConsumed": false,
"isLargeMessage": false,
"label": "Service Bus Explorer",
"lockedUntilUtc": null,
"lockToken": null,
"messageId": "5cbc08aa-dca5-434b-bc27-afc8ba98307f",
"partitionKey": "18",
"properties": {
"deviceId": 84,
"value": 68,
"time":<PHONE_NUMBER>78943345,
"city": "Milan",
"country": "Italy"
},
"replyTo": null,
"replyToSessionId": null,
"scheduledEnqueueTimeUtc": "0001-01-01T00:00:00",
"sequenceNumber":<PHONE_NUMBER>10657,
"sessionId": null,
"size": 229,
"state": 0,
"timeToLive": "10675199.02:48:05.4775807",
"to": null,
"viaPartitionKey": null
}
{"body": {"deviceid": 84,
"value": 68},
"contentType": null,
"correlationId": null,
"deliveryCount": 1,
"enqueuedSequenceNumber": 1,
"enqueuedTimeUtc": "2014-12-03T16:39:48.4958476Z",
"expiresAtUtc": "9999-12-31T23:59:59.9999999",
"forcePersistence": false,
"isBodyConsumed": false,
"isLargeMessage": false,
"label": "Service Bus Explorer",
"lockedUntilUtc": null,
"lockToken": null,
"messageId": "5cbc08aa-dca5-434b-bc27-afc8ba98307f",
"partitionKey": "18",
"properties": {"deviceId": 84,
"value": 68,
"time":<PHONE_NUMBER>78943345,
"city": "Milan",
"country": "Italy"},
"replyTo": null,
"replyToSessionId": null,
"scheduledEnqueueTimeUtc": "0001-01-01T00:00:00",
"sequenceNumber":<PHONE_NUMBER>10657,
"sessionId": null,
"size": 229,
"state": 0,
"timeToLive": "10675199.02:48:05.4775807",
"to": null,
"viaPartitionKey": null
}
- As an alternative, you can double click a message in the Messages
or Deadletter tab for queue or subscription to open the
Repair and Resubmit Message dialog and then click the Save
button as shown in the picture below.
- In the Messages or Deadletter tab of a queue or subscription you can save multiple messages to a JSON file: select multiple messages and right click one of them to open the context menu and
then click Save Selected Messages as shown in the picture below.
This opens the Save File As dialog as shown in the picture below.
The JSON file contains an array of items. Each item contains the body and properties of one of the selected BrokeredMessage objects. Properties are
in camel case.
JavaScript
Edit|Remove
js
[
{
"body": {
"deviceid": 36,
"value": 93
},
"contentType": null,
"correlationId": null,
"deliveryCount": 1,
"enqueuedSequenceNumber": 1,
"enqueuedTimeUtc": "2014-12-03T16:39:48.7794889Z",
"expiresAtUtc": "9999-12-31T23:59:59.9999999",
"forcePersistence": false,
"isBodyConsumed": false,
"isLargeMessage": false,
"label": "Service Bus Explorer",
"lockedUntilUtc": null,
"lockToken": null,
"messageId": "197c5f6b-635c-437e-b419-5b346b626c35",
"partitionKey": "0",
"properties": {
"deviceId": 36,
"value": 93,
"time":<PHONE_NUMBER>78943345,
"city": "Milan",
"country": "Italy"
},
"replyTo": null,
"replyToSessionId": null,
"scheduledEnqueueTimeUtc": "0001-01-01T00:00:00",
"sequenceNumber":<PHONE_NUMBER>081153,
"sessionId": null,
"size": 228,
"state": 0,
"timeToLive": "10675199.02:48:05.4775807",
"to": null,
"viaPartitionKey": null
},
{
"body": {
"deviceid": 85,
"value": 29
},
"contentType": null,
"correlationId": null,
"deliveryCount": 1,
"enqueuedSequenceNumber": 2,
"enqueuedTimeUtc": "2014-12-03T16:39:56.5925297Z",
"expiresAtUtc": "9999-12-31T23:59:59.9999999",
"forcePersistence": false,
"isBodyConsumed": false,
"isLargeMessage": false,
"label": "Service Bus Explorer",
"lockedUntilUtc": null,
"lockToken": null,
"messageId": "fa9482b5-6dff-4268-9a5c-3d9b08bb358c",
"partitionKey": "942",
"properties": {
"deviceId": 85,
"value": 29,
"time":<PHONE_NUMBER>62583503,
"city": "Milan",
"country": "Italy"
},
"replyTo": null,
"replyToSessionId": null,
"scheduledEnqueueTimeUtc": "0001-01-01T00:00:00",
"sequenceNumber":<PHONE_NUMBER>21314,
"sessionId": null,
"size": 230,
"state": 0,
"timeToLive": "10675199.02:48:05.4775807",
"to": null,
"viaPartitionKey": null
},
{
"body": {
"deviceid": 84,
"value": 68
},
"contentType": null,
"correlationId": null,
"deliveryCount": 1,
"enqueuedSequenceNumber": 1,
"enqueuedTimeUtc": "2014-12-03T16:39:48.4958476Z",
"expiresAtUtc": "9999-12-31T23:59:59.9999999",
"forcePersistence": false,
"isBodyConsumed": false,
"isLargeMessage": false,
"label": "Service Bus Explorer",
"lockedUntilUtc": null,
"lockToken": null,
"messageId": "5cbc08aa-dca5-434b-bc27-afc8ba98307f",
"partitionKey": "18",
"properties": {
"deviceId": 84,
"value": 68,
"time":<PHONE_NUMBER>78943345,
"city": "Milan",
"country": "Italy"
},
"replyTo": null,
"replyToSessionId": null,
"scheduledEnqueueTimeUtc": "0001-01-01T00:00:00",
"sequenceNumber":<PHONE_NUMBER>10657,
"sessionId": null,
"size": 229,
"state": 0,
"timeToLive": "10675199.02:48:05.4775807",
"to": null,
"viaPartitionKey": null
}
]
[
{"body": {"deviceid": 36,
"value": 93},
"contentType": null,
"correlationId": null,
"deliveryCount": 1,
"enqueuedSequenceNumber": 1,
"enqueuedTimeUtc": "2014-12-03T16:39:48.7794889Z",
"expiresAtUtc": "9999-12-31T23:59:59.9999999",
"forcePersistence": false,
"isBodyConsumed": false,
"isLargeMessage": false,
"label": "Service Bus Explorer",
"lockedUntilUtc": null,
"lockToken": null,
"messageId": "197c5f6b-635c-437e-b419-5b346b626c35",
"partitionKey": "0",
"properties": {"deviceId": 36,
"value": 93,
"time":<PHONE_NUMBER>78943345,
"city": "Milan",
"country": "Italy"},
"replyTo": null,
"replyToSessionId": null,
"scheduledEnqueueTimeUtc": "0001-01-01T00:00:00",
"sequenceNumber":<PHONE_NUMBER>081153,
"sessionId": null,
"size": 228,
"state": 0,
"timeToLive": "10675199.02:48:05.4775807",
"to": null,
"viaPartitionKey": null
},
{"body": {"deviceid": 85,
"value": 29},
"contentType": null,
"correlationId": null,
"deliveryCount": 1,
"enqueuedSequenceNumber": 2,
"enqueuedTimeUtc": "2014-12-03T16:39:56.5925297Z",
"expiresAtUtc": "9999-12-31T23:59:59.9999999",
"forcePersistence": false,
"isBodyConsumed": false,
"isLargeMessage": false,
"label": "Service Bus Explorer",
"lockedUntilUtc": null,
"lockToken": null,
"messageId": "fa9482b5-6dff-4268-9a5c-3d9b08bb358c",
"partitionKey": "942",
"properties": {"deviceId": 85,
"value": 29,
"time":<PHONE_NUMBER>62583503,
"city": "Milan",
"country": "Italy"},
"replyTo": null,
"replyToSessionId": null,
"scheduledEnqueueTimeUtc": "0001-01-01T00:00:00",
"sequenceNumber":<PHONE_NUMBER>21314,
"sessionId": null,
"size": 230,
"state": 0,
"timeToLive": "10675199.02:48:05.4775807",
"to": null,
"viaPartitionKey": null
},
{"body": {"deviceid": 84,
"value": 68},
"contentType": null,
"correlationId": null,
"deliveryCount": 1,
"enqueuedSequenceNumber": 1,
"enqueuedTimeUtc": "2014-12-03T16:39:48.4958476Z",
"expiresAtUtc": "9999-12-31T23:59:59.9999999",
"forcePersistence": false,
"isBodyConsumed": false,
"isLargeMessage": false,
"label": "Service Bus Explorer",
"lockedUntilUtc": null,
"lockToken": null,
"messageId": "5cbc08aa-dca5-434b-bc27-afc8ba98307f",
"partitionKey": "18",
"properties": {"deviceId": 84,
"value": 68,
"time":<PHONE_NUMBER>78943345,
"city": "Milan",
"country": "Italy"},
"replyTo": null,
"replyToSessionId": null,
"scheduledEnqueueTimeUtc": "0001-01-01T00:00:00",
"sequenceNumber":<PHONE_NUMBER>10657,
"sessionId": null,
"size": 229,
"state": 0,
"timeToLive": "10675199.02:48:05.4775807",
"to": null,
"viaPartitionKey": null
}
]
- In the Consumer Group or Partition Listener dialog you can save a single event to a JSON file: right click the event under the
Events tab to open the context menu and click Save Selected Event as shown in the picture below.
This opens the Save File As dialog as shown in the picture below.
The JSON file contains the body and properties of the selected
EventData object. Properties are in camel case.
JavaScript
Edit|Remove
js
{
"body": {
"deviceid": 6,
"name": "device006",
"value": 50,
"location": "Milan"
},
"enqueuedTimeUtc": "2014-11-06T17:18:01.057Z",
"offset": "208",
"partitionKey": "device006",
"properties": {
"id": 6,
"name": "device006",
"location": "Milan",
"value": 50
},
"sequenceNumber": 1,
"systemProperties": {
"Publisher": "device006",
"PartitionKey": "device006",
"EnqueuedTimeUtc": "2014-11-06T17:18:01.057Z",
"SequenceNumber": 1,
"Offset": "208"
}
}
{
"body": {
"deviceid": 6,
"name": "device006",
"value": 50,
"location": "Milan"
},
"enqueuedTimeUtc": "2014-11-06T17:18:01.057Z",
"offset": "208",
"partitionKey": "device006",
"properties": {
"id": 6,
"name": "device006",
"location": "Milan",
"value": 50
},
"sequenceNumber": 1,
"systemProperties": {
"Publisher": "device006",
"PartitionKey": "device006",
"EnqueuedTimeUtc": "2014-11-06T17:18:01.057Z",
"SequenceNumber": 1,
"Offset": "208"
}
}
- As an alternative, you can double click an event in the Consumer Group or Partition Listener dialog to open the View Event Data dialog and then click the
Save button as shown in the picture below.
- In the Consumer Group or Partition Listener dialog you can save multiple events to a JSON file: select multiple events and right click one of them to open the context menu and then click Save Selected
Events as shown in the picture below.
This opens the Save File As dialog as shown in the picture below.
The JSON file contains an array of items. Each item contains the body and properties of one of the selected
EventData objects. Properties are in camel case.
JavaScript
Edit|Remove
js
[
{
"body": {
"deviceid": 6,
"name": "device006",
"value": 26,
"location": "Milan"
},
"enqueuedTimeUtc": "2014-11-06T17:18:03.267Z",
"offset": "624",
"partitionKey": "device006",
"properties": {
"id": 6,
"name": "device006",
"location": "Milan",
"value": 26
},
"sequenceNumber": 3,
"systemProperties": {
"Publisher": "device006",
"PartitionKey": "device006",
"EnqueuedTimeUtc": "2014-11-06T17:18:03.267Z",
"SequenceNumber": 3,
"Offset": "624"
}
},
{
"body": {
"deviceid": 6,
"name": "device006",
"value": 23,
"location": "Milan"
},
"enqueuedTimeUtc": "2014-11-06T17:18:02.173Z",
"offset": "416",
"partitionKey": "device006",
"properties": {
"id": 6,
"name": "device006",
"location": "Milan",
"value": 23
},
"sequenceNumber": 2,
"systemProperties": {
"Publisher": "device006",
"PartitionKey": "device006",
"EnqueuedTimeUtc": "2014-11-06T17:18:02.173Z",
"SequenceNumber": 2,
"Offset": "416"
}
},
{
"body": {
"deviceid": 6,
"name": "device006",
"value": 50,
"location": "Milan"
},
"enqueuedTimeUtc": "2014-11-06T17:18:01.057Z",
"offset": "208",
"partitionKey": "device006",
"properties": {
"id": 6,
"name": "device006",
"location": "Milan",
"value": 50
},
"sequenceNumber": 1,
"systemProperties": {
"Publisher": "device006",
"PartitionKey": "device006",
"EnqueuedTimeUtc": "2014-11-06T17:18:01.057Z",
"SequenceNumber": 1,
"Offset": "208"
}
}
]
[
{
"body": {
"deviceid": 6,
"name": "device006",
"value": 26,
"location": "Milan"
},
"enqueuedTimeUtc": "2014-11-06T17:18:03.267Z",
"offset": "624",
"partitionKey": "device006",
"properties": {
"id": 6,
"name": "device006",
"location": "Milan",
"value": 26
},
"sequenceNumber": 3,
"systemProperties": {
"Publisher": "device006",
"PartitionKey": "device006",
"EnqueuedTimeUtc": "2014-11-06T17:18:03.267Z",
"SequenceNumber": 3,
"Offset": "624"
}
},
{
"body": {
"deviceid": 6,
"name": "device006",
"value": 23,
"location": "Milan"
},
"enqueuedTimeUtc": "2014-11-06T17:18:02.173Z",
"offset": "416",
"partitionKey": "device006",
"properties": {
"id": 6,
"name": "device006",
"location": "Milan",
"value": 23
},
"sequenceNumber": 2,
"systemProperties": {
"Publisher": "device006",
"PartitionKey": "device006",
"EnqueuedTimeUtc": "2014-11-06T17:18:02.173Z",
"SequenceNumber": 2,
"Offset": "416"
}
},
{
"body": {
"deviceid": 6,
"name": "device006",
"value": 50,
"location": "Milan"
},
"enqueuedTimeUtc": "2014-11-06T17:18:01.057Z",
"offset": "208",
"partitionKey": "device006",
"properties": {
"id": 6,
"name": "device006",
"location": "Milan",
"value": 50
},
"sequenceNumber": 1,
"systemProperties": {
"Publisher": "device006",
"PartitionKey": "device006",
"EnqueuedTimeUtc": "2014-11-06T17:18:01.057Z",
"SequenceNumber": 1,
"Offset": "208"
}
}
]
Update: 18 December 2014
This version introduces the following updates:
- Starting on 17 December 2014, Event Hubs are available in public preview in the Microsoft Azure datacenter in China. Hence, the version <IP_ADDRESS> of Service Bus Explorer introduces support for the uri of Microsoft Azure DC in China.


OCTOPUSSY (1983) A film review by Andrew Hicks Copyright 1996 Andrew Hicks / Fatboy Productions
OCTOPUSSY (1983) **1/2
I had no idea what this movie was about but decided to watch it anyway because--hey, who can resist a title like that? And it makes you wonder what kind of woman actually has eight of those. Fine, I'm a pervert, but what kind of a reaction does a title like OCTOPUSSY expect to elicit?
OCTOPUSSY is one of the more absurd episodes in the James Bond series, but then I'm pretty sure every Roger Moore effort tips the scale of absurdness. And when the female lead is someone named Octopussy, the absurdity springs up. The perversity seems to spring up too, at least in a small dose, especially when Octopussy reveals that her name was given to her by her father, who always called her "my little Octopussy." Funny, I didn't know Jerry Lee Lewis had a daughter.
This time, Bond is out to some some Faberge egg forgers (the bastards!), led by Octopussy and her male partner Kamal (at least they didn't name him Octodick). Bond meddles in Kabal's business one time too many and ends up captive in his palace. He escapes, but comes back a little later to get some octopussy. The two find out afterwards that they have more in common than just compatible body parts and, when Kabal doublecrosses her by placing the customary atomic bomb (no Bond movie would be complete without one), Octopussy joins Bond's side.
OCTOPUSSY has its share of good and bad scenes. Good-- the plane chase teaser, the auction scene, the train chase and the circus scenes at the end. Bad--the other plane chase, the stuffed sheep head dinner (which pushes the limits of good taste... Monkey brains are okay, sheep's heads, no.) and that overlong chase through the streets of India, culminating in one of the bad guys being impaled on a bed of nails. "Get off my bed!" an Indian yells. A failed comic relief moment, to say the least. Almost as bad as my Octodick joke.
Visit the Movie Critic at LARGE website at http://www.missouri.edu/~c667778/movies.html
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


PLANET SICK-BOY: http://www.sick-boy.com
I admit it. I was actually looking forward to seeing this movie.   What a disappointment.
This is the first pot movie since the heyday of Cheech & Chong and, sadly, left me yearning for the days of Nice Dreams. Half Baked tries to double the fun with four stoners instead of the conventional two. There's Thurgood Jenkins (Chappelle), a janitor at Frankensence & Burr Laboratories, who narrates the story. There's Brian (Breur) a burnt record store employee and Scarface (Diaz), who works in a burger joint. And don't forget Kenny (Williams), the sensitive kindergarten teacher.
After work each day, they meet at Jenkins house and light up Billy Bong Thornton and then fight over which toker is on `munchie' patrol. On this fateful evening, Kenny goes out for the snack foods and happens upon a police horse named Buttercup. Kenny feeds the horse all of the junk food and is horrified to see the horse drop dead. Apparently, Buttercup was diabetic and Kenny is arrested for killing an officer in the line of duty. The bail is set at $1,000,000 and, thus, the plot comes to life: Sell enough pot to free Kenny!
Somehow, Jenkins has access to an unlimited supply of pharmaceutical marijuana at work and the four hit the streets to raise Kenny's bail. Of course, a film like this wouldn't be complete with out the following stock characters: the love interest (named Mary Jane and played by Rachel True), the rival drug lord (Clarence Williams III) and the strange guy who's been asleep on the couch for years (Steven Wright). OK, maybe that last one wasn't standard fare. There were also a few bad cameos (Snoop Doggy Dogg, Janeane Garofalo & John Stewart) and a few good ones (Bob Saget, Willie Nelson & Tommy Chong). `David', the guy who got thrown out of house on the second season of MTV's `The Real World' also makes an appearance, but who cares?
Don't get me wrong, there were some very funny scenes. There is a high point when Thurgood takes Mary Jane on a date with only $8 in his pocket. As the date progresses, a counter on the bottom of the screen shows how much he has left.
I expected better from this group of people. Director Tamra Davis worked on the hilarious Billy Madison and CB4. Maybe it was the script, which was co-written by Chappelle (The Nutty Professor). In addition to Jenkins, he also played rap star Sir Smoke A Lot.
Granted, this probably would have been a lot better if I burnt a big fatty before it started and I'm sure that's what the target audience of this film will probably do. Maybe the theaters should hand weed out to the patrons as they file into the theater.
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


| Did You Know Text | Label | Question Category | Question Code | Question Group | Question Text | Question Type | Required Answer | Sort Order | Survey | |
|---|---|---|---|---|---|---|---|---|---|---|
| {{instance.did_you_know_text}} | {{instance.label}} | {{instance.question_category_id}} | {{instance.question_code_id}} | {{instance.question_group}} | {{instance.question_text}} | {{instance.question_type_id}} | {{instance.required_answer}} | {{instance.sort_order}} | {{instance.survey_id}} |


Density Population! =D
Ally
Resource
Lv Resource
Tradegood
All
Wine
Marble
Sulfur
Glass
Lv Tradegood
Scan!
Players


Home
Tutorials
Web Services
Projects
Blogs
Login
Cannis Learning with Best Detailed Technologies
HTML
CSS
Javasript


Retiree born on July 1st 1950, who earned roughly the average US wage for most of their career.
Retiree born on August 2nd 1950, who earned the maximum Social Security wages over five years, but nothing otherwise.
Earner early in their career, born September 3rd 1985, with a $40,000 per year salary in 2005 and a 4% annual raise.
| Year | Age | Taxed Earnings | Multiplier | Indexed Earnings | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| {{earningRecord.year}} | {{recipient.exampleAge(earningRecord.year).age}} | Not yet recorded | ${{earningRecord.taxedEarnings | number:0}} | x | {{earningRecord.indexFactor | number:2}} | = | ${{earningRecord.indexedEarning() | number:0}} | Top 35 Value |
| I plan to work for |
|
more years, |
| Earning approximately |
|
per year. |
| Year | Age | Taxed Earnings | Multiplier | Indexed Earnings | ||||
|---|---|---|---|---|---|---|---|---|
| {{year}} | {{recipient.exampleAge(year).age}} | ${{futureWageWorkSlider.minValue | number:0}} | x | 1.00 | = | ${{futureWageWorkSlider.minValue | number:0}} | Top 35 Value |


Logging
By default, ETLBox uses NLog. NLog already comes with different log targets that be configured either via your app.config or programatically. Please see the NLog-documentation for a full reference. https://nlog-project.org/ ETLBox already comes with NLog as dependency - so the necessary packages will be retrieved from nuget automatically through your package manager.
Simple Configuration File
In order to use logging, you have to create a nlog.config file with the exact same name and put it into the root folder of your project.
A simple nlog.config could look like this
<?xml version="1.0" encoding="utf-8"?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xsi:schemaLocation="NLog NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<rules>
<logger name="*" minlevel="Info" writeTo="console" />
</rules>
<targets>
<target name="console" xsi:type="Console" />
</targets>
</nlog>
After adding a file with this configuration, you will already get some logging output to your debugger output.
Logging to database
But there is more. If you want to have logging tables in your database, ETLBox comes with some handy stuff that helps you to do this.
Extend the nlog.config
As a first step to have nlog log into your database, you must exend your nlog configuration. It should then look like this:
<?xml version="1.0" encoding="utf-8"?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xsi:schemaLocation="NLog NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="console" xsi:type="Console" />
<target xsi:type="Database" name="database"
useTransactions="false" keepConnection="true">
<commandText>
insert into etl.Log (LogDate, Level, Stage, Message, TaskType, TaskAction, TaskHash, Source, LoadProcessKey)
select @LogDate
, @Level
, cast(@Stage as nvarchar(20))
, cast(@Message as nvarchar(4000))
, cast(@Type as nvarchar(40))
, @Action
, @Hash
, cast(@Logger as nvarchar(20))
, case when @LoadProcessKey=0 then null else @LoadProcessKey end
</commandText>
<parameter name="@LogDate" layout="${date:format=yyyy-MM-ddTHH\:mm\:ss.fff}" />
<parameter name="@Level" layout="${level}" />
<parameter name="@Stage" layout="${etllog:LogType=Stage}" />
<parameter name="@Message" layout="${etllog}" />
<parameter name="@Type" layout="${etllog:LogType=Type}" />
<parameter name="@Action" layout="${etllog:LogType=Action}" />
<parameter name="@Hash" layout="${etllog:LogType=Hash}" />
<parameter name="@LoadProcessKey" layout="${etllog:LogType=LoadProcessKey}" />
<parameter name="@Logger" layout="${logger}" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="database" />
<logger name="*" minlevel="Info" writeTo="console" />
</rules>
</nlog>
Copy to output directory
Make sure the config file is copied into the output directory where you build executables are dropped. Your project configuration file .csproj should contain something like this:
<Itemgroup>
...
<None Update="nlog.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</Itemgroup>
Create database tables
Now you need some tables in the database to store your log information.
You can use the task CreateLogTables
. This task will create two tables:
etl.LoadProcess
and etl.Log
.
It will also create some stored procedure to access this tables. This can be useful if you want
to log into these table in your sql code or stored procedures.
Note: Don't forget the setup the connection for the control flow.
CreateLogTablesTask.CreateLog();
LoadProcess table
The table etl.LoadProcess contains information about the etl processes that you started programatically with the StartLoadProcessTask
.
To end or abort a process, you can use the EndLoadProcessTask
or AbortLoadProcessTask
. To set the TransferCompletedDate in this table, use
the TransferCompletedForLoadProcessTask
This is an example for logging into the load process table.
StartLoadProcessTask.Start("Process 1 started");
/*..*/
TransferCompletedForLoadProcessTask.Complete();
/*..*/
if (error)
AbortLoadProcessTask.Abort("This is the abort message");
else
EndLoadProcessTask.End("Process 1 ended successfully");
Log Table
The etl.Log table will store all log message generated from any control flow or data flow task.
You can even use your own LogTask to create your own log message in there.
The following example with create 6 rows in your etl.Log
table. Everytime a Control Flow Tasks starts, it will create a log entry with an action
'START'. When it's done with its execution, it will create another log entry with action type 'END'
SqlTask.ExecuteNonQuery("some sql", "Select 1 as test");
Sequence.Execute("some custom code", () => { });
LogTask.Warn("Some warning!");
The sql task will produce two log entries - one entry when it started and one entry when it ended its execution.
Further log tasks
Clean up or remove log table
You can clean up your log with the CleanUpLogTask.
CleanUpLogTask.Clean();
Or you can remove the log tables and all its procedure from the database.
RemoveLogTablesTask.Remove();
Get log and loadprocess table in JSON
If you want to get the content of the etl.LoadProcess table or etl.Log in JSON-Format, there are two tasks for that:
GetLoadProcessAsJSONTask.GetJSON();
GetLogAsJSONTask.GetJSON();
Custom log messages
If you want to create an entry in the etl.Log table (just one entry, no START/END messages) you can do this using the LogTask. Also you can define the nlog level.
LogTask.Trace("Some text!");
LogTask.Debug("Some text!");
LogTask.Info("Some text!");
LogTask.Warn("Some text!");
LogTask.Error("Some text!");
LogTask.Fatal("Some text!");