Why would DeviceClient SetDesiredPropertyUpdateCallbackAsync timeout immediately after OpenAsync succeeded? - azure-iot-hub

As part of my initialization of an IoTHub DeviceClient I explicitly open the connection with OpenAsync and then immediately call SetDesiredPropertyUpdateCallbackAsync. Sometimes when I call SetDesiredPropertyUpdateCallbackAsync it times out with an exception. If my network connection is stable, why don't I get the timeout on OpenAsync instead of SetDesiredPropertyUpdateCallbackAsync? I believe it even makes the same OpenAsync call internally to ensure the connection is open.
ioTHubModuleClient = DeviceClient.CreateFromConnectionString(ConnectionString, settings);
await ioTHubModuleClient.OpenAsync().ConfigureAwait(false);
await ioTHubModuleClient.SetDesiredPropertyUpdateCallbackAsync(OnModulePropertyUpdateRequested, this).ConfigureAwait(false);
Update:
I found that if I register with SetConnectionStatusChangesHandler before that, I can see that its endlessly connecting/disconnecting until it times out when I call SetDesiredPropertyUpdateCallbackAsync.
IoTHub connection is now Connected Reason: Connection_Ok
IoTHub connection is now Disconnected_Retrying Reason: No_Network
IoTHub connection is now Connected Reason: Connection_Ok
IoTHub connection is now Disconnected_Retrying Reason: No_Network
IoTHub connection is now Connected Reason: Connection_Ok
IoTHub connection is now Disconnected_Retrying Reason: No_Network
I used dotPeek to decompile the Microsoft.Azure.Devices stuff and serve it up through a local pdb server. What seems to be happening is that something is generating a SocketException for a successful operation. The exception messages is "The operation completed successfully". This blog indicates this is typically due to a dllimport call not using SetLastError. I don't see anything in the callstack that obviously leads to a pinvoke call though:
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.Devices.Client.Transport.Mqtt.MqttIotHubAdapter.d__40.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.Devices.Client.Transport.Mqtt.MqttIotHubAdapter.d__28.MoveNext()

Generally, when working in a Console App or Service scenario, there is no SynchronizationContext installed (by default), so the continueOnCapturedContext option in ConfigureAwait will have no effect.However if you happen to install or use a library that installs a SynchronizationContext, the behavior of the async methods will be like in UI application. ConfigureAwait(false) will change the context.An important rule is that each async method has its own context,it means that the calling method is not affected by ConfigureAwait. You can refer to these topics to get good know details about Task.ConfigureAwait.
ConfigureAwait(false) not needed in Console/Win service apps, right?
Why would I bother to use Task.ConfigureAwait(continueOnCapturedContext: false);

Related

MassTransit - Socket exception with AmazonMQ when starting bus

I'm trying to get a basic PoC app running with MassTransit using our Amazon MQ instance, and running into the following problem when I call StartAsync on IBusControl:
MassTransit.ActiveMqTransport.ActiveMqConnectException: Connection exception: (user)#(host)
---> Apache.NMS.NMSConnectionException: Error connecting to (host) ---> System.Net.Sockets.SocketException (0xFFFFFFFE): Unknown error (0xfffffffe)
at Apache.NMS.ActiveMQ.Transport.Tcp.TcpTransportFactory.DoConnect(String host, Int32 port, String localAddress, Int32 localPort)
Note: In the exception above, I've edited the items in bold to remove sensitive information. We know that the credentials we are using are in fact correct since we have integration tests for NMS and ActiveMq that use the same credentials. But when trying to connect using MassTransit, we get the above error.
I've tried a number of different approaches but they all produce the same result. Here's some example code to give a general idea of how we're trying to connect:
var busControl = Bus.Factory.CreateUsingActiveMq(configurator =>
{
configurator.Host(host, activeMqHostConfigurator =>
{
activeMqHostConfigurator.Username(activeMqConfiguration.UserName);
activeMqHostConfigurator.Password(activeMqConfiguration.Password);
});
});
await busControl.StartAsync(new CancellationTokenSource(TimeSpan.FromSeconds(10)).Token);
The call to StartAsync is what throws the exception. I have my doubts that this is an issue with MassTransit, it's more likely something that I'm missing but I cannot see what's wrong, and I've had my team review it as well.
As I mentioned in my comment this ended up not being related to MassTransit. It was due to the host being inactive.

How to catch ActiveMQ threads exceptions that are thrown inside a MessageListener

I am programming an ActiveMq 5.9 MessageListener. I'm able to get the messages from the broker properly, but my concern is about how to handle exception cases.
For instance when the ActiveMq broker is shutdown while the listener is still up, the listener prints the following log:
2014-04-16 17:38:50,559 DEBUG [ActiveMQ Transport: tcp://localhost/127.0.0.1:61616#55509] ActiveMQConnection - Async exception with no exception listener: java.io.EOFException
java.io.EOFException
at java.io.DataInputStream.readInt(DataInputStream.java:392)
at org.apache.activemq.openwire.OpenWireFormat.unmarshal(OpenWireFormat.java:275)
at org.apache.activemq.transport.tcp.TcpTransport.readCommand(TcpTransport.java:221)
at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:213)
at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:196)
at java.lang.Thread.run(Thread.java:744)
The problem is that I am not able to catch the exception, even when I tried to catch(Throwable) in the main method of the process. So, my question is:
How I am supposed to catch these kind of problems in the listener so I can program something to recover from the error or at least terminate the process?
Thanks!
That's what the ExceptionListener is for. You can set an ExceptionListener on your Connection instance and then when an out of band failure like this occurs you will be notified.

Exposing wcf service in BizTalk 2010

I have ran into this issue the past few weeks ago and I still can not figure out why.
I have a BizTalk orchestration that receives a BizTalk message, processes it and eventually writes it to a file. For simplicity sake, let say, our goal is to take the message (which is actually a survey) and save it to a folder as is. I have created a public receive port to catch the msg and a send port to write the result out to disk.
I have successfully deployed the project and have successfully published it to IIS. I was able to see the WCF service in IIS and have set it to use Framework 4.0. I have set up all the relevant receive and send ports and have started the application successfully from BizTalk management console. (The receive location was automatically created when I published the wcf service, the send location is a type FILE located in a folder in the computer)
From DefaultSite in IIS, I could see my WCF. However, when I tried http://localhost/TestSurvey/TestSurvey_Orchestration_1_getSurveyPort.svc,
I got the following error:
Server Error in '/TestSurvey' Application.
--------------------------------------------------------------------------------
Login failed for user 'Domain\ComputerName$'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Data.SqlClient.SqlException: Login failed for user 'ACAD1\DENBIZDEV$'.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[SqlException (0x80131904): Login failed for user 'Domain\ComputeName$'.]
[TargetInvocationException: Exception has been thrown by the target of an invocation.]
Microsoft.BizTalk.TransportProxy.Interop.IBTTransportProxy.RegisterIsolatedReceiver(String url, IBTTransportConfig callback) +0
Microsoft.BizTalk.Adapter.Wcf.Runtime.WcfIsolatedReceiver`2.RegisterIsolatedReceiver(Uri uri) +1028
Microsoft.BizTalk.Adapter.Wcf.Runtime.WebServiceHostFactory`3.CreateServiceHost(String constructorString, Uri[] baseAddresses) +363
System.ServiceModel.HostingManager.CreateService(String normalizedVirtualPath) +1413
System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +50
System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +1172
[ServiceActivationException: The service '/TestSurvey/TestSurvey_Orchestration_1_getSurveyPort.svc' cannot be activated due to an exception during compilation. The exception message is: Exception has been thrown by the target of an invocation..]
System.Runtime.AsyncResult.End(IAsyncResult result) +901424
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +178638
System.Web.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult ar) +107
--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.272
My question is: what is it that BizTalk was trying to login? Domain\ComputerName$ is definitely not a user. I have not tried to access any database from the orchestration. I believe my IIS was set up correctly as I have created a quick and dirty wcf service test from VS2010 and published it to my IIS, then have successfully created a simple client to consume the wcf service test. I did not encounter the same issue when I created the wcf service test directly.
Any help or hint is highly appreciated!
EDIT
I managed to fix this: it was not the web config as it was created by BizTalk. I had to create a special app pool and tied my application to using it. In the app pool I have to use the custom credential that BizTalk is using. Using the built in credentials caused the issue I experienced. My rookie error! Once BizTalk login credential was used, everything went smoothly.
The database which is throwing the SQL exception is one of the BizTalk databases, probably the management or SSO DB.
The error is almost certainly being caused by the setup of IIS, whether the app pool identity or the web site security settings.
What is hapenning is that when you call the service for the first time IIS is compiling your service, and to do this it obviously needs access to one of the BizTalk databases, but this call is not authenticated for some reason.
This could be because the app pool user must be a member of the BizTalk Isolated Host Users group (which may be called something different depending on how BizTalk was set up.

Cassia Library giving exception when calling any methods

I am trying to run the Cassia library on a remote Windows Server 2008 Terminal Server. Any methods I call I get the response below.
No more data is available
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ComponentModel.Win32Exception: No more data is available
Stack Trace:
[Win32Exception (0x80004005): No more data is available]
Cassia.Impl.NativeMethodsHelper.GetSessionInfos(ITerminalServerHandle server) +159
Cassia.Impl.TerminalServer.GetSessions() +103
I was getting this error as well. Turns out that if there are no sessions for the given server it throws this exception.
Try running qwinsta /server <servername> in a WCP shell. It should return "No session exists for *".
I worked around this by checking exception message for "no more data" and don't throw it if so. It's gross but it's an open source dll.

HELP! - DefaultServiceHostFactory executing before application_startup and container creation

I am using the WCF facility for a service hosted in WAS (net.tcp binding in iis7) and experiencing a weird issue only upon a cold application startup (i.e. not already running).
The following statement should be executed upon first instantiation of my container.
DefaultServiceHostFactory.RegisterContainer(c.Kernel);
When the service is requested, I get the following exception in my WCF tracefile
Kernel was null, did you forgot to call DefaultServiceHostFactory.RegisterContainer()
The issue appears to be that the ServiceHostFactory is attempting to create an instance of the service's host before my container has been created.
Note:
This exception is happening BEFORE the Application_Start is executed
If the application is running (and the container has been initialised) then the service will operate as expected. The application can be started by going to the appropriate IIS site over HTTP or starting a debugging session from Visual Studio.
Steps to recreate issue
Issue a IISReset to shutdown all IIS app pools.
Call the service in question
WCF tracing spits out:
System.ServiceModel.ServiceActivationException: The service '/abcd.svc' cannot be activated due to an exception during compilation. The exception message is: Exception has been thrown by the target of an invocation.. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentNullException: Kernel was null, did you forgot to call DefaultServiceHostFactory.RegisterContainer() ?
Parameter name: kernel
at Castle.Facilities.WcfIntegration.WindsorServiceHostFactory`1..ctor(IKernel kernel)
at Castle.Facilities.WcfIntegration.DefaultServiceHostFactory..ctor()
The problem is that global.asax and all its methods are related only to HTTP processing. Btw. class in global.asax is derived from HttpApplication which should make this pretty clear. Once you host application in WAS (which is case of net.tcp based binding) you can't use these methods. Try to use something like AppInitialize.