how do i get data from azure queue message (service bus) - azure

I need to get data from service bus from my console application, instead of my data I've got System.UnauthorizedAccessException error 401
I've got 2 static readonly string that I don't know how to use
You may require one or both of the services below depending on the level of detail that you need-
//sample usage string briefingDetailsByIdURI = string.Format(Constants.BRIEFING_DETAILS_ID_URI, brfId);
public static readonly string ID_URI = "https://trtrtrtr.servicebus.windows.net/trtrtr/trttrttr/{0}";
//sample usage - string URI = string.Format(Constants.sdgsdgg, sgsgsg, sgsgsg);
public static readonly string DETAIL_ID_URI = "https://trtrtrtr.servicebus.windows.net/trtrtr/trrtrttr/{0}/{1}";
I just went in app.config and put this with the right namespace and password
<appSettings>
<!-- Service Bus specific app setings for messaging connections -->
<add key="Microsoft.ServiceBus.ConnectionString" value="Endpoint=sb://<namespace>.servicebus.windows.net/;
SharedAccessKeyName=Root stManageSharedAccessKey;SharedAccessKey=<paasword> />
after that I went in my console program.cs
Console.Title = "Receiver2";
// Creating the topic if it does not exist already using the service bus connection string stored in the app.config file
string connectionString =
CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
//appSettings dans appsettings getSettings()
//connection au service bus
var namespaceManager =
NamespaceManager.CreateFromConnectionString(connectionString);
//verification si queue existe
if (!namespaceManager.QueueExists("CommentaireQueue"))
{
namespaceManager.CreateQueue("CommentaireQueue");
}
QueueClient client = QueueClient.Create("CommentaireQueue");
Console.WriteLine("test console");
//boucle infini pour recevoir tous les messages
while (true)
{
var message = client.Receive();
if (message != null)
{
var comm = message.GetBody<string>();
string myString = comm.Contenu;
try
{
Console.WriteLine(myString);
}
finally
{
//enlever le message de la queue
message.Complete();
}
}
}
}

This is what I use to connect to the queue
QueueClient _client;
var connectionString = CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);
if (!namespaceManager.QueueExists(QueueName))
{
namespaceManager.CreateQueue(QueueName);
}
_client = QueueClient.CreateFromConnectionString(connectionString, QueueName);
Instead of running a while loop. You could be using OnMessage() like this:
_client.OnMessage(message =>
{
try
{
//do logic
}
catch (Exception e)
{
message.Abandon();
throw new Exception(e.Message);
}
});
Make sure the connections string is set correct in your Azure ServiceConfiguration:
<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="App" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="4" osVersion="*" schemaVersion="2015-04.2.6">
<Role name="App">
<Instances count="1" />
<ConfigurationSettings>
<Setting name="Microsoft.ServiceBus.ConnectionString" value="THE CONNECTION STRING" />
</ConfigurationSettings>
</Role>
</ServiceConfiguration>

Related

How to get notification when webjob status was aborted in azure

Azure WebJob, how to be notified if it aborted?
(1)Always Availability is on for the service.
(2) SCM_COMMAND_IDLE_TIMEOUT = 2000.
WEBJOBS_IDLE_TIMEOUT = 2000.
But as i'm new to this. can you please help me on this one where can i put the logic
You could add the logic in the Function.cs file. For more information you could refer to the detail steps
Steps:
1.follow official document to create a webjob project.
2.Add Functions.cs in the project
using System.IO;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions;
using SendGrid;
public class Functions
{
//demo webjob trigger
public static void ProcessQueueMessage([QueueTrigger("queue")] string message, TextWriter log)
{
log.WriteLine(message);
}
// error monitor
public static void ErrorMonitor([ErrorTrigger("0:30:00", 10, Throttle = "1:00:00")]TraceFilter filter, [SendGrid] SendGridMessage message)
{
message.Subject = "WebJobs Error Alert";
message.Text = filter.GetDetailedMessage(5);
}
}
3.If want to use ErrorTrigger and SendGrid we need to config it in the Program.cs file.
static void Main()
{
var config = new JobHostConfiguration();
if (config.IsDevelopment)
{
config.UseDevelopmentSettings();
}
config.UseCore();
config.UseSendGrid(new SendGridConfiguration
{
ApiKey = "xxxxx",
FromAddress = new Email("emailaddress","name"),
ToAddress = new Email("emailaddress","name")
});
var host = new JobHost(config);
// The following code ensures that the WebJob will be running continuously
host.RunAndBlock();
}
4.If we want to test it locally, we need to add Storage connection string in the App Settings collection.
<connectionStrings>
<add name="AzureWebJobsStorage" connectionString="{storage connection string}" />
</connectionStrings>

How to push data in document db using webjobs?

I have written following code to read the data from text file and then separate the sentences and send them to azure event hub.
I am able to send the data to event hub but not able to push data in document db.
How to push data in document db using webjobs? I am running webjobs from console application, Do I need add more configuration to run it locally?
Program.cs
static void Main(string[] args)
{
JobHostConfiguration config = new JobHostConfiguration();
config.Tracing.ConsoleLevel = System.Diagnostics.TraceLevel.Error;
var eventHubConfig = new EventHubConfiguration();
eventHubConfig.AddReceiver(eventHubName, connectionString);
config.UseEventHub(eventHubConfig);
JobHost host = new JobHost(config);
config.DashboardConnectionString = StorageConnectionString;
if (config.IsDevelopment)
{
config.UseDevelopmentSettings();
}
//Send test messages
Task.Run(() =>
{
SendMessagesToEventHub();
});
host.RunAndBlock();
}
function.cs
class Functions
{
public static void Run([EventHubTrigger("azurepochub")] EventData message, [Microsoft.Azure.WebJobs.DocumentDB("testcosmosdb01122018", "Items", ConnectionStringSetting = "dbConnctionString")]out dynamic document)
{
string data = Encoding.UTF8.GetString(message.GetBytes());
document = data;
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"Message received. Data: '{data}'");
Console.ResetColor();
}
}
You could get answer from github Azure WebJobs SDK Extensions. If we want to insert document to the Azure documentdb, we need to insert the object into it. In your case, your output is string.
Do I need add more configuration to run it locally?
I also do demo for that. The following is the detail steps
1.Create an .net framework Webjob project.
2.Add the AzureWebJobsDocumentDBConnectionString in the App.config file.
<appSettings>
<!-- Service Bus specific app setings for messaging connections -->
<add key="Microsoft.ServiceBus.ConnectionString" value="Endpoint=sb://[your namespace].servicebus.windows.net;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=[your secret]" />
<add key ="AzureWebJobsDocumentDBConnectionString" value="xxxxx"/>
</appSettings>
3.Add the following code in the Program.cs file.
using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DocumentDB;
using Microsoft.Azure.WebJobs.ServiceBus;
using Microsoft.ServiceBus.Messaging;
namespace WebJobTest
{
// To learn more about Microsoft Azure WebJobs SDK, please see https://go.microsoft.com/fwlink/?LinkID=320976
class Program
{
// Please set the following connection strings in app.config for this WebJob to run:
// AzureWebJobsDashboard and AzureWebJobsStorage
private static string eventHubName = "eventhubNam";
private static string connectionString = "eventhub connectionstring";
static void Main()
{
JobHostConfiguration config = new JobHostConfiguration();
config.Tracing.ConsoleLevel = System.Diagnostics.TraceLevel.Error;
var eventHubConfig = new EventHubConfiguration();
eventHubConfig.AddReceiver(eventHubName, connectionString);
config.UseDocumentDB(new DocumentDBConfiguration
{
ConnectionString = "DocumentDB ConnectionString"
});
config.UseEventHub(eventHubConfig);
config.DashboardConnectionString = "storage connection string";
JobHost host = new JobHost(config);
if (config.IsDevelopment)
{
config.UseDevelopmentSettings();
}
//Send test messages
Task.Run(() =>
{
SendMessagesToEventHub();
});
host.RunAndBlock();
}
static void SendMessagesToEventHub()
{
var eventHubClient = EventHubClient.CreateFromConnectionString(connectionString, eventHubName);
try
{
var message = Guid.NewGuid().ToString();
Console.WriteLine("{0} > Sending message: {1}", DateTime.Now, message);
eventHubClient.Send(new EventData(Encoding.UTF8.GetBytes(message)));
}
catch (Exception exception)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("{0} > Exception: {1}", DateTime.Now, exception.Message);
Console.ResetColor();
}
Thread.Sleep(200);
}
}
}
4.In the function.cs
public static void Run([EventHubTrigger("eventhub name")] EventData message, [DocumentDB("document Database name", "collection", ConnectionStringSetting = "AzureWebJobsDocumentDBConnectionString")]out Item document)
{
string data = Encoding.UTF8.GetString(message.GetBytes());
document = new Item{Text = data};
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"Message received. Data: '{data}'");
Console.ResetColor();
}
public class Item
{
public string Text;
}
5.Check the result from console.
Finish debug from the console then check from the Azure documentdb

UWP Bluetooth RFCOMM FindAllAsync

I want to build two simple apps, communicating with each other using Bluetooth RFCOMM.
However, when I run client app it doesn't find any devices with _devices = await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.ObexObjectPush));
_devices collection is empty.
Based on the examples from microsoft docs I've managed to write something like this.
Application receiving messages (server) - deployed on Raspberry PI 3.
namespace RaspRFCOMM
{
public sealed partial class MainPage : Page
{
private RfcommServiceProvider _provider;
public MainPage()
{
this.InitializeComponent();
this.Initialize();
}
private async void Initialize()
{
msgStatus.Text = "Inicjalizacja...";
// Initialize the provider for the hosted RFCOMM service
_provider = await RfcommServiceProvider.CreateAsync(RfcommServiceId.ObexObjectPush);
// Create a listener for this service and start listening
StreamSocketListener listener = new StreamSocketListener();
listener.ConnectionReceived += OnConnectionReceived;
await listener.BindServiceNameAsync(
_provider.ServiceId.AsString(),
SocketProtectionLevel
.BluetoothEncryptionAllowNullAuthentication);
// Set the SDP attributes and start advertising
InitializeServiceSdpAttributes(_provider);
_provider.StartAdvertising(listener, true);
}
const uint SERVICE_VERSION_ATTRIBUTE_ID = 0x0300;
const byte SERVICE_VERSION_ATTRIBUTE_TYPE = 0x0A; // UINT32
const uint SERVICE_VERSION = 200;
private void InitializeServiceSdpAttributes(RfcommServiceProvider provider)
{
DataWriter writer = new DataWriter();
// First write the attribute type
writer.WriteByte(SERVICE_VERSION_ATTRIBUTE_TYPE);
// Then write the data
writer.WriteUInt32(SERVICE_VERSION);
IBuffer data = writer.DetachBuffer();
provider.SdpRawAttributes.Add(SERVICE_VERSION_ATTRIBUTE_ID, data);
}
private async void OnConnectionReceived(
StreamSocketListener listener,
StreamSocketListenerConnectionReceivedEventArgs args)
{
msgStatus.Text = "Odczytuje...";
_provider.StopAdvertising();
listener.Dispose();
StreamSocket _socket = args.Socket;
StreamReader reader = new StreamReader(_socket.InputStream.AsStreamForRead());
string response = await reader.ReadLineAsync();
msgStatus.Text = "Odczytałem...";
textboxMsg.Text = response + "To odczytalem";
}
}
}
Sending messages:
namespace WinRFCOMM
{
public sealed partial class MainPage : Page
{
private RfcommDeviceService _service;
private StreamSocket _socket;
private DeviceInformationCollection _devices;
private StreamWriter _writer;
public MainPage()
{
this.InitializeComponent();
this.Initialize();
}
private async void Initialize()
{
msgStatus.Text = "Inicjalizacja...";
_devices = await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.ObexObjectPush));
this.PopulateDevicesListview(_devices);
msgStatus.Text = "Oczekiwanie na wybór...";
}
private void PopulateDevicesListview(DeviceInformationCollection devices)
{
foreach (DeviceInformation di in devices)
{
String deviceInfo = di.Name + " - " + di.Id;
lvDevices.Items.Add(deviceInfo);
}
}
private void btnConnect_Click(object sender, RoutedEventArgs e)
{
var selected = lvDevices.SelectedIndex;
if (selected != -1)
{
ConnectToRFC(_devices[selected]);
}
}
private async void ConnectToRFC(DeviceInformation selectedDevice)
{
_service = await RfcommDeviceService.FromIdAsync(selectedDevice.Id);
_socket = new StreamSocket();
await _socket.ConnectAsync(
_service.ConnectionHostName,
_service.ConnectionServiceName,
SocketProtectionLevel
.BluetoothEncryptionAllowNullAuthentication);
msgStatus.Text = "Połączono...";
_writer = new StreamWriter(_socket.OutputStream.AsStreamForWrite());
_writer.WriteLineAsync("Test");
}
}
}
Both have manifest file set up like this:
<Capabilities>
<Capability Name="internetClient" />
<Capability Name="internetClientServer" />
<Capability Name="privateNetworkClientServer" />
<DeviceCapability Name="bluetooth" />
</Capabilities>
I'd really appreciate any help, because I've been stuck for almost 2 days.
The problem is not reside in the code.
You need pair two devices firstly before running this RFCOMM sample. Because
Use the RfcommDeviceService.GetDeviceSelector* functions to help
generate an AQS query that can be used to enumerated paired device
instances of the desired service.
Ref: Send a file as a client
I found this forum post which got me through it.
My problem was trying to use the DeviceInformation I had discovered for pairing, as my point of connection for RFCOMM.
For rfcomm you will require your AppManifest to look like:
<DeviceCapability Name="bluetooth.rfcomm">
<Device Id="any">
<Function Type ="name:serialPort"/>
</Device>
</DeviceCapability>
Instead of just having the name "bluetooth".

Azure diagnostics multiple AppDomain issues

I've bumped into a following problem with Azure Diagnostic Monitor:
When I create a new AppDomain in OnStart() event in WorkerRole entry point the diagnostics works only in the parent AppDomain. I've tried initializing Diagnostics Monitor in the child AppDomain but it doesn't help. (Traces are collected only from the parent domain)
Example repro code:
public class WorkerRole : RoleEntryPoint
{
public override void Run()
{
// This is a sample worker implementation. Replace with your logic.
InitializeDiagnostics();
Trace.TraceInformation("WorkerRole1 entry point called", "Information");
while (true)
{
Thread.Sleep(10000);
Trace.TraceInformation("Parent domain working", "Information");
}
}
public override bool OnStart()
{
// Set the maximum number of concurrent connections
ServicePointManager.DefaultConnectionLimit = 12;
InitializeDiagnostics();
var setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
setup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
var newDomain = System.AppDomain.CreateDomain("NewApplicationDomain",null, setup);
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies().Where(x => !x.GlobalAssemblyCache))
{
newDomain.Load(assembly.GetName());
}
newDomain.Load(typeof (Worker).Assembly.FullName);
var worker = newDomain.CreateInstanceAndUnwrap(this.GetType().Assembly.FullName, typeof (Worker).FullName) as Worker;
worker.DoWork();
return base.OnStart();
}
public void InitializeDiagnostics()
{
var roleInstanceDiagnosticManager = new RoleInstanceDiagnosticManager(RoleEnvironment.GetConfigurationSettingValue("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString"),
RoleEnvironment.DeploymentId,
RoleEnvironment.CurrentRoleInstance
.Role.Name,
RoleEnvironment.CurrentRoleInstance.Id);
var dmc = roleInstanceDiagnosticManager.GetCurrentConfiguration();
var dictionaryConfiguration = new DirectoryConfiguration();
DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", dmc);
}
}
public class Worker : MarshalByRefObject
{
public void DoWork()
{
new Task(() =>
{
while (true)
{
Thread.Sleep(1000);
Trace.TraceInformation(AppDomain.CurrentDomain.FriendlyName + " Worker working...", "Information");
}
}).Start();
}
}
}
App config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<trace>
<listeners>
<add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="AzureDiagnostics">
<filter type="" />
</add>
</listeners>
</trace>
</system.diagnostics>
</configuration>
Expected output:
Lots of logged messages:
"{Domain Name} Wokrer working..."
Some
"Parent domain working"
Actual output:
"Parent domain working"
I'm using Azure SDK 2.0. Have any of you came across a similar issue ?
Ok, finally solved it. Upgrading Azure SDK to 2.3 did the thing... It's interesting that messages still doesn't appear in Compute emulator console, but after upgrade they are correctly logged to WADLog table.

Trace.WriteLine() Messages only Persisted in OnStart() for an Azure WorkerRole

I'm developing an Azure WorkerRole(). In the Compute Emulator console, I see all Trace.WriteLine() messages, but only those generated in OnStart() seem to be persisted into storage.
My ServiceConfiguration.Local.csfg has:
<Role name="MyWorkerRole">
<Instances count="1" />
<ConfigurationSettings>
<Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="UseDevelopmentStorage=true" />
</ConfigurationSettings>
</Role>
My WorkerRole.cs has:
public override void Run() {
Trace.WriteLine("Called from Run(), where does this trace go???", "Information");
// ... SNIP ...
}
public override bool OnStart() {
// Set the maximum number of concurrent connections
ServicePointManager.DefaultConnectionLimit = 12;
DiagnosticMonitorConfiguration dmc = DiagnosticMonitor.GetDefaultInitialConfiguration();
dmc.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
dmc.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;
DiagnosticMonitor.Start("DiagnosticsConnectionString", dmc);
Trace.WriteLine("This trace appears in WADLogsTable", "Information");
return base.OnStart();
}
That looks correct - I wonder why you don't see anything. I wonder if Start is ignoring your config changes somehow. Here is some code I have used that will transfer the trace logs (I know this works):
private static void EnableDiagnostics(int transferTime)
{
string wadConnectionString = "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString";
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue(wadConnectionString));
RoleInstanceDiagnosticManager roleInstanceDiagnosticManager = storageAccount.CreateRoleInstanceDiagnosticManager(RoleEnvironment.DeploymentId, RoleEnvironment.CurrentRoleInstance.Role.Name, RoleEnvironment.CurrentRoleInstance.Id);
DiagnosticMonitorConfiguration config = roleInstanceDiagnosticManager.GetCurrentConfiguration();
if (config == null)
{
config = DiagnosticMonitor.GetDefaultInitialConfiguration();
}
config.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(transferTime);
config.Logs.ScheduledTransferLogLevelFilter = LogLevel.Undefined;
CrashDumps.EnableCollection(true);
roleInstanceDiagnosticManager.SetCurrentConfiguration(config);
}

Resources