NServiceBus saga not handling messages on azure - azure

I'm getting strange behavior of working NServiceBus sagas deployed on azure cloud service. They never get replied message, never wake up... although if it's deployed locally everything works fine, also sagas works correctly when it's on WebApi cloud service role...
public class EndpointConfiguration : IConfigureThisEndpoint, IWantCustomInitialization,
AsA_Worker, UsingTransport<AzureStorageQueue>
{
public void Init()
{
Feature.Disable<Gateway>();
Feature.Disable<SecondLevelRetries>();
Feature.Enable<TimeoutManager>();
Feature.Enable<Sagas>();
Configure.With()
.UsingContainer<AutofacContainerBuilder>()
.AzureConfigurationSource()
.AzureMessageQueue()
.QueuePerInstance()
.UseNHibernateSagaPersister()
.UseNHibernateSubscriptionPersister()
.UseNHibernateTimeoutPersister()
.UnicastBus();
}
}
that's my config for nsb
<configSections>
<section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
<section name="DBSubscriptionStorageConfig" type="NServiceBus.Config.DBSubscriptionStorageConfig, NServiceBus.NHibernate" />
<section name="NHibernateSagaPersisterConfig" type="NServiceBus.Config.NHibernateSagaPersisterConfig, NServiceBus.NHibernate" />
<section name="TimeoutPersisterConfig" type="NServiceBus.Config.TimeoutPersisterConfig, NServiceBus.NHibernate" />
</configSections>
<UnicastBusConfig>
<MessageEndpointMappings>
<add Messages="Service.InternalMessages" Endpoint="service" />
<add Messages="Messages" Endpoint="service" />
</MessageEndpointMappings>
</UnicastBusConfig>
<DBSubscriptionStorageConfig>
<NHibernateProperties>
<add Key="connection.provider" Value="NHibernate.Connection.DriverConnectionProvider" />
<add Key="connection.driver_class" Value="NHibernate.Driver.SqlClientDriver" />
<add Key="connection.connection_string" Value="Data_Source;Connection Timeout=30;" />
<add Key="dialect" Value="NHibernate.Dialect.MsSql2008Dialect" />
<add Key="hbm2ddl.auto" Value="update" />
</NHibernateProperties>
</DBSubscriptionStorageConfig>
<NHibernateSagaPersisterConfig>
<NHibernateProperties>
<add Key="connection.provider" Value="NHibernate.Connection.DriverConnectionProvider" />
<add Key="connection.driver_class" Value="NHibernate.Driver.SqlClientDriver" />
<add Key="connection.connection_string" Value="Data_Source;Connection Timeout=30;" />
<add Key="dialect" Value="NHibernate.Dialect.MsSql2008Dialect" />
<add Key="hbm2ddl.auto" Value="update" />
</NHibernateProperties>
</NHibernateSagaPersisterConfig>
<TimeoutPersisterConfig>
<NHibernateProperties>
<add Key="connection.provider" Value="NHibernate.Connection.DriverConnectionProvider" />
<add Key="connection.driver_class" Value="NHibernate.Driver.SqlClientDriver" />
<add Key="connection.connection_string" Value="Data_Source;Connection Timeout=30;" />
<add Key="dialect" Value="NHibernate.Dialect.MsSql2008Dialect" />
<add Key="hbm2ddl.auto" Value="update" />
</NHibernateProperties>
</TimeoutPersisterConfig>
that's the configs that I'm using for persisters
NServiceBus.Hosting.Azure, NServiceBus.NHibernate, NServiceBus.Core, NServiceBus.Azure, NServiceBus all of v4.0.30319
I'm using AzureStorageQueue and also I'm sure that I have overridden ConfigureHowToFindSaga with proper ConfigureMapping and I'm replying message with all filed specified correctly...
I would be really appreciate for any ideas, thanks.

This will be an interesting one to figure out. I don't see anything obviously wrong.
So the symptoms are, it works locally (with the exact same config?) and it works when deployed in a webrole (are these the same saga's or different ones?).
Some background info on the latter: a webrole only differs from a worker role in that IIS is properly configured, that's it. This also means that in a webrole, your code is running in 2 places, in an IIS process and in the roleentrypoint process. So you may want to validate that you're actually hosting in a roleentrypoint (namespace NServiceBus.Azure.Hosting and not the default azure sdk one.)
If you're sure the initialisation is done in the right place, you may want to check if you get any errors in the azure logs?
If that doesn't give more detail, you can also enable intellitrace in your solution and download the traces to see what is going on in more detail.
And as a last option, you can also use windbg on the azure instance (RDP'd in) to debug in real time.
Hope any of the above helps!

Related

Azure API Apps Diagnostics

I have an Azure API App that needs to log trace data, so have chosen to use Azure Diagnostics and .Net System.Diagnostics.Trace.
The trace message logs to Table Storage, but the Event Id field is 0. The documentation online suggests 0 is the default value, but I cannot see an obvious way to set the Event Id.
Trace.TraceError, Trace.TraceInformation and Trace.TraceWarning only take a string or a formatted message.
Would some know if it is possible to set the Event Id and if so how?
Thanks
Andy
Although I cannot take credit for the answer, I thought I should post the answer I found here: https://blogs.msdn.microsoft.com/mcsuksoldev/2014/09/04/adding-trace-to-azure-web-sites-and-web-jobs/
Basically you use the System.Diagnostics.TraceSource type and call the TraceEvent() method. Although this won't work without some configuration first.
There are three trace listeners to be aware of, although for just TableStorage it is only the first:
AzureTableTraceListener
AzureBlobTraceListener
AzureDriveTraceListener
You will need to install the nuget package: Microsoft.WindowsAzure.WebSites.Diagnostics
The code example from the link above is:
public static readonly TraceSource Operational = new TraceSource("Operational");
Operational.TraceEvent(TraceEventType.Verbose, 101, "TraceEvent WebSite Operational");
For the TraceSource to log to TableStorage you need to add the following to the web.config:
<system.diagnostics>
<sharedListeners>
<add name="AzureTableTraceListener" type="Microsoft.WindowsAzure.WebSites.Diagnostics.AzureTableTraceListener, Microsoft.WindowsAzure.WebSites.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</sharedListeners>
<sources>
<source name="Operational" switchName="OperationalSourceSwitch" switchType="System.Diagnostics.SourceSwitch">
<listeners>
<add name="AzureTableTraceListener"/>
<add name="AzureBlobTraceListener"/>
</listeners>
</source>
</sources>
<switches>
<add name="OperationalSourceSwitch" value="All" />
</switches>
<trace autoflush="true" indentsize="4" />
Andy

How do you declare or use variables in web.config

Because our web application is using both Entityframework and System.Data.SqlClient, we need to have 2 .
This is very error prone, as you need to make you update both with the same data.
So i wonder if its posible to add variables to the web.config xml?
<connectionStrings>
<add name="Server" value="sql2014" type="variable" />
<add name="database" value="MyDB" type="variable" />
<add name="userName" value="sqluser" type="variable" />
<add name="password" value="kaldsommer" type="variable" />
<add name="XReport" connectionString="Data Source={Server};Initial Catalog={MyDB};User ID={username};Password={password}" providerName="System.Data.SqlClient" />
<add name="XEntities" connectionString="metadata=res://*/Entities.XModel.csdl|res://*/Entities.XModel.ssdl|res://*/Entities.XModel.msl;provider=System.Data.SqlClient;provider connection string="data source{Server};initial catalog={MyDB};MultipleActiveResultSets=True;App=EntityFramework;;Persist Security Info=True;User ID={username};Password={password}"" providerName="System.Data.EntityClient" />
</connectionStrings>
Pr #Bartude reply in comment.
FAIK, this is not possible. On the other hand maintaining 2 connection
strings is not that complicated, although I agree it's always best to
update things only once

Why is CloudConfigurationManager using my Cloud.cscfg instead of Local.cscfg too?

I do realise that his question was asked and answered, but unfortunately the solution of complete clean, rebuild, restart.. doesn't work in my case and my lowly reputation doesn't allow me to comment. So I am I think compelled to ask it again with my info.
Sample code:
CloudStorageAccount storageAccount;
string settings = CloudConfigurationManager.GetSetting("StorageConnectionString");
storageAccount = CloudStorageAccount.Parse(settings);
I have my web.config section like this:
<appSettings>
<add key="owin:AppStartup" value="zzzz" />
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=xxxx;AccountKey=yyyy"/>
</appSettings>
In the ServiceConfiguration.Cloud.cscfg I have:
<ConfigurationSettings>
<Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="DefaultEndpointsProtocol=https;AccountName=nnnn" />
<Setting name="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=xxxx;AccountKey=yyyy"/>
</ConfigurationSettings>
and in the ServiceConfiguration.Local.cscfg I have:
<ConfigurationSettings>
<Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="UseDevelopmentStorage=true" />
<Setting name="StorageConnectionString" value="UseDevelopmentStorage=true" />
</ConfigurationSettings>
I converted this to an Azure project from a standard MVC web project in order to use the Azure storage blobs etc. I am finding that no matter what I seem to do it always uses the Azure storage.
As I step through the code snippet above.. I can clearly see the returned connection string as the one coming from the web.config app setting... I feel I must be doing something fundamentally wrong or missing something..?
A small point (maybe?) as I converted the project over, there was an error message (on a pop up and not saveable) about a connection string error and it not working. I hadn't even created this particular connection string at that time and the only other one (for localDB does work). That however is in the web.config section and as it ain't broke I didn't fix it to go into the ..
Any help would be appreciated.
Further Addition, from the comments by Igorek below, I did check the Role settings and they appear to be correct.
Then .. after a lot of messing around, some experiments which still didn't work, I've taken a step back. I actually don't want a cloud service, I ended up with one because I thought I needed one to access Blobs and Queues, I had already decided that WebJobs seems like the way to go first to keep as abstracted as possible.
So I have rolled back to prior to the Web SITE that I had before and found but I still CAN'T seem to get it to use development storage.. although I imagine that CLoudConfigurationManager probably doesn't handle Web Sites? Any tips?
Check into settings of your Role within the cloud project. It will have a default for which configuration it starts with. Simply swap from Cloud to Local.

Clear steps for setting up Azure Diagnostics

I am trying to get diagnostics tracing working, but I am confused about necessary steps I have to follow. I will present what I have done until now:
In app.config I have following:
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="ProfileTrace" switchName="profileTraceSwitch" switchType="System.Diagnostics.SourceSwitch">
<listeners>
<add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=2.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="AzureDiagnostics">
<filter type="" initializeData="Warning" />
</add>
<add name="LogFileListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="..\..\..\skype.portal.profile.log" traceOutputOptions="ProcessId, ThreadId" />
</listeners>
</source>
</sources>
<switches>
<add name="profileTraceSwitch" value="Verbose"/>
</switches>
</system.diagnostics>
In Service.Definition I have following:
<Imports>
<Import moduleName="Diagnostics" />
</Imports>
In Service.Configuration I have:
<ConfigurationSettings>
<Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="DefaultEndpointsProtocol=https;AccountName=<snip>;AccountKey=<snip>" />
I have following confusion right now. As you can see in app.config I tried to add a filter for DiagnosticMonitorTraceListener to trace only Warnings, but this filter was ignored. I found this post, which suggests to use custom trace listener that derives from DiagnosticMonitorTraceListener http://social.msdn.microsoft.com/forums/wpapps/en-us/92ed1175-d6b7-4173-a224-0f7eb3e99481/diagnosticmonitortracelistener-ignors-filter
On the other hand in following official link from microsoft http://msdn.microsoft.com/en-us/library/ee758610.aspx they leave filter type empty:
<add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener,
Microsoft.WindowsAzure.Diagnostics,
Version=1.0.0.0,
Culture=neutral,
PublicKeyToken=31bf3856ad364e35"
name="AzureDiagnostics">
<filter type="" />
</add>
Then they mention about configuring Logs property http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.diagnostics.diagnosticmonitorconfiguration.logs.aspx where I see:
public override bool OnStart() {
......
// Filter the logs so that only error-level logs are transferred to persistent storage.
diagnosticConfiguration.Logs.ScheduledTransferLogLevelFilter = LogLevel.Error;
......
return base.OnStart();
}
}
So, I have following 2 questions:
In my current solution I haven't written any code on Start method of WorkerRole to configure Diagnostic Monitor, but after some searching I found that many people do this. I ran my project locally and I was able to see data stored in Azure WADLogsTable. So, is it mandatory to add Diagnostic Monitor configuration code to my Worker role or can I just have diagnostics.wadcfg?
Since filters for DiagnosticMonitorTraceListener in app.config file are ignored, if I skip the use of a custom trace listener that derives from DiagnosticMonitorTraceListener suggested here http://social.msdn.microsoft.com/forums/wpapps/en-us/92ed1175-d6b7-4173-a224-0f7eb3e99481/diagnosticmonitortracelistener-ignors-filter and use ScheduledTransferLogLevelFilter of Logs property in my WorkerRole, will I achieve the log filter I want? Or maybe filter in app.config and ScheduledTransferLogLevelFilter refer to 2 different kind of filters?
I would recommend against setting the Azure diagnostic configuration in code. Instead, I would recommend using the diagnostic.wadcfg file approach. You can find some info here - http://msdn.microsoft.com/en-us/library/hh411551.aspx. Visual Studio will help generate this file as well.
It is not mandatory to set any Azure diagnostic configuration in your role's OnStart() method.
Setting the ScheduledTransferLogLevelFilter should suffice. Plus, that also enables you to easily change the filter level at runtime if needed (via an API call, Visual Studio, or 3rd party tool like Cerebrata Azure Management Studio).

How to add using statement in mvc 5 to all views

There are many examples of adding a using statement for all views in web.config for prior versions, but I have not found one for MVC 5.
Can someone give me an example?
Locate Web.config in the Views folder.
Find the namespace section. It will already have namespaces for Mvc.
Add the desired namespace:
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Optimization"/>
<add namespace="System.Web.Routing" />
<add namespace="MyNamespace" />
</namespaces>
For ASP.NET Core MVC you can also add inside _ViewImports.cshtml a statement such as this at the top if you needed to add the models class to your views.
#using Myprojectnamespace.Models

Resources