TIBCO.EMS.IllegalStateException: connect failed: server in standby mode - c#

We have a big system with bunch of services communicating with each other via TIBCO EMS Messaging.
Now, one of the services keeps throwing this exception when it tries to connect to EMS server:
TIBCO.EMS.IllegalStateException: connect failed: server in standby mode
However, other services on the same EMS server are working just fine without any exception.
I tried to reproduce this by creating a console application which would use same credentials to connect to EMS server on the same destination (Queue) but couldn't reproduce this error.
EMS connection is fault-tolerant and it might have been failed over to secondary server, however, now I see primary server is back up.
I also tried to connect to primary server only (which I can see is up & running) but it fails with the same exception.
Below is the stack trace for reference:
TIBCO.EMS.IllegalStateException: connect failed: server in standby mode
at TIBCO.EMS.CFImpl._CreateConnection(String userName, String password, Boolean xa)
at TIBCO.EMS.ConnectionFactory.CreateConnection(String userName, String password)
at Ems.makeConn()
We're using TIBCO.EMS.dll v. 8.1.0.10 on .NET 4.0.
Any idea what can cause this exception ?

Could your connection string only mention one of the hosts inside an FT/HA setup ? This looks like the error message returned when you are trying to connect to only one of the HA/FT host, but not the one active at the moment.
If it is the case, the connection string will work most of the time, but a proper EMS HA connection string include two (or more!) EMS host and port. Only one is active at the same time.
It typically looks like this:
serverUrl=tcp://server0:7222, tcp://server1:7344
See source doc here in TIBCO docs.

It turned out tools we were using to check if server is active (we don't have admin rights on the servers) was misbehaving (showing incorrect status), so none of those servers were really active (not primary nor secondary).
As soon as server was brought up this error message went away.

Related

Connect to Azure Redis Cache via HTTP

I'm using "ServiceStack.Redis" to connect to Redis and it works correctly on my development machine.
Basically, I open the connection via this line:
client = new RedisClient(host);
Where host, on my development machine, is "localhost".
Now, I'd like to upload my application to Azure, so I created a cache in Azure and I'm trying to connect to it by passing the following connection string:
XXX.redis.cache.windows.net,ssl=false,password=YYY
The creation of the "RedisClient" seems to work but when I try to perform an operation (the first one to be executed being client.RemoveByPattern("...")), I get the following error:
Exception Details: System.Net.Sockets.SocketException: No such host is
known
Note that I allowed the cache to be connected to via HTTP, so normally, the port 6379 is unblocked and accessible.
All the example I found over Internet are using "ConnectionMultiplexer" but this class does not seem to be found in the NuGet package "ServiceStack.Redis".
What am I doing wrong?
I was having the same(similar?) issue connecting to Azure Redis with ServiceStack, in the end it was working out the correct syntax for the connection that worked for me. XXX.redis.cache.windows.net?ssl=true
Found some help here https://github.com/ServiceStack/ServiceStack.Redis, but to quote the connection strings section had examples;
"Redis Connection strings have been expanded to support the more versatile URI format which is now able to capture most of Redis Client settings in a single connection string (akin to DB Connection strings).
Redis Connection Strings supports multiple URI-like formats, from a simple hostname or IP Address and port pair to a fully-qualified URI with multiple options specified on the QueryString."
Some examples of supported formats:
localhost
127.0.0.1:6379
redis://localhost:6379
password#localhost:6379
clientid:password#localhost:6379
redis://clientid:password#localhost:6380?ssl=true&db=1
NOTE: I used the final example here but without the redis:// bit as I found this was not needed in Azure.

Connecting to Websphere MQ queue manager works in application A but not in application B

I have two console applications, A and B.
The application A was created for test purposes and works as expected.
The application B does not work although it is basically a copy-paste of A's code:
System.Console.Write("User Name: ");
string username = System.Console.ReadLine();
System.Console.Write("Password: ");
string password = ConsoleReadPassword();
System.Console.WriteLine();
//user and password required because I am also a privileged user
//(member of mqm group)
MQEnvironment.UserId = username;
MQEnvironment.Password = password;
//for application B this line throws exception with code 2538
var queueManager = new MQQueueManager("TEST.QUEUE.MANAGER", "CLIENT.CONN.CHANNEL", "localhost(1414)");
Error code 2538 means "Host not available" which is weird because application A has no problems connecting to the same host.
This is how the MQ Server looks in MQ Explorer:
Queue managers:
Queues:
Listeners:
Channels:
Two server channels
Channel auth records:
Default channel authentication record which prevents MQ admins from connecting to queue managers. It was slightly modified (added ~ prefix) so now it does not block anyone.
The MQ Server and applications are running on the same machine so imho network problems are excluded.
The queue manager error log does not report any errors but the general error log looks like this:
08/02/2016 15:15:23 - Process(13720.10) User([username])
Program(B.EXE) AMQ9202: Remote host 'localhost(1414)' not
available, retry later.
EXPLANATION: The attempt to allocate a conversation using TCP/IP to
host 'localhost(1414)' for channel (Exception) was not successful.
However the error may be a transitory one and it may be possible to
successfully allocate a TCP/IP conversation later.
For both application I use the same version of amqmdnet.dll: 8.0.0.4
Both programs A and B have the same target framework: 4.5
While testing I didn't tried to run the both applications in the same time and I checked in MQ Explorer if the channel is free (Inactive).
I also tried to change the name of resulting assemblies but with no effect.
Does anyone know what could cause application B to be unable to connect?
When using the hostname localhost networking is still involved, it just all happens inside the one machine. If application A is running in the same machine as your queue manager then having application A connect using the connection name localhost(1414) will certainly work but it is not necessary to make the connection like this (i.e. using TCP/IP) you could instead make a local bindings connection.
On the other hand, if you are using TCP/IP because application B is running on a different machine to where the queue manager is running, then using localhost(1414) will not work because localhost on one machine does not connect to localhost on another machine. You should change what is specified in the application's connection name from localhost(1414) to use the IP address (or hostname) of the queue manager's machine (followed as before with the port number).
Although I was unable to find the cause of the problem the solution was to simply
delete and re-create the project.
This is what I tried before and what led me to this action:
In B I removed and then added back the reference to amqmdnet.dll - not working
I created yet another project (let's call it C): console application, same code - working
I renamed* the C project with the same name as B - still working
*The name of the non-working project contained a dot so I thought that this could cause the problem - it was not the case.

SQL Server Connection Issue - I can connect but other users can't

[edit] so not sure what happened, but we ended up resetting the server and turning off/on TCP/IP and Named Pipes and after a restart and updating the settings everything started working again. weirdest thing. anyways thanks for the help guys.
I'm building a C# WPF application for my job, and I'm getting a weird problem that I've been trying to figure out for the past week. The application connects to the server and imports several tables on start up. So I built it out and was testing it with no issues, but when i pass it to our testers, and everyone is getting the following errors:
Provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server
The users are able to connect to the server through other methods (SSMS/Excel VBA), but just through the application it won't work.
I've checked the following:
Remote connections enabled
TCP/IP connections enabled
Firewall settings are the exact same across all users (me included)
application is compiled as 32 bit (saw this in another thread)
We're using SQL Server 2008 and I've tried several connection strings/methods.
below is the code I'm using to connect:
public void Open_DB_Conn(string Connection_Str)
{
try
{
Sql_Conn = new SqlConnection(Conn_Str);
Sql_Conn.Open();
}
catch (Exception e)
{
MessageBox.Show(string.Format("Error Message:{0} Conn String: {1}",e.Message,Conn_Str));
}
}
Below is my connection string (this is just one of many iterations I've used trying to get it working):
Data Source=IP Address;Initial Catalog=DB_Name;User ID=LOGIN;Password=PWD
Anyone know why I would be the only one able to get it to work and that the users are able to login to the server using other applications without a problem? They use it for logging their excel VBA scripts and there aren't any issues there.
Try this - it may be your answer
"The error is reported by client library. While your server is listeing on remote TCP, client will still try TCP and NP connection in order. So the error client behavior is expected. From what you have described, I believe that even though you enabled the remote TCP connection on the XPSP2 machine, you didn't make the TCP listening port an exception of XPSP2 personal firewall. You should follow steps below to resolve this issue.
check the SQL Server Errorlog to make sure SQL Server is now listening on TCP/IP and confirm which port it is listening on. Usually 1433. In the Errorlog, you will see several lines that discuss what SQL Server is listening on. Below is an example:
2006-01-04 01:41:07.65 server SQL server listening on 10.254.1.150: 1433. <--Shows the IP Address and the port.
2006-01-04 01:41:07.65 server SQL server listening on 127.0.0.1: 1433. <--Shows another IP Address and the port.
2006-01-04 01:41:07.69 server SQL server listening on TCP, Shared Memory, Named Pipes.
2006-01-04 01:41:07.69 server SQL Server is ready for client connections
2, Make sure on Windows XP that the firewall is not blocking that port.
3, go to your client machine and run the client network configuration tool (cliconfg.exe) Make sure TCP/IP is enabled, click properties and make sure the port number is the same one as SQL Server is listening on. Here you can enable NP or disable client NP as well.
Once both the client and the server are using TCP/IP with the same port number and the firewall on server machines is not blocked, you should be able to connect.
Hope this helps."
(Ref: http://social.technet.microsoft.com/Forums/sqlserver/en-US/c488cf76-2515-440f-b3f8-9cfad689c5b6/named-pipes-provider-error-40-could-not-open-a-connection-to-sql-server?forum=sqldataaccess)
You have to configured your SQl server so that other IP can connect it for that you have to gone through mentioned link
Configure SQL server
What authentication are you using for the SQL Server? Windows Authentication or SQL Server authentication? My suggestion is to first turn on SQL Server authentication and use the sa\password to connect to the server. If you are successful, then ask the others (users of your application) to try with the same connection string. Let me know what you find out.
Be sure that the port specified in:
Data Source="IPAddress,port";Initial Catalog=DB_Name;User ID=LOGIN;Password=PWD
matches the port on your SQL Server. You can check that by going on SQL Server COnfiguration Manager and viewing TCP/IP properties.
EDIT :
It is also the case the port defined by blocked by an external firewall. And the rest Applications use other ports. Try to find out which port you can use (if indeed the are restrictions to your network)
Make sure your SQL Server instance is properly configured to use TCP using Sql Server Configuration Manager.
It is by default disabled in SQL Express, as show below.
I'd like to know more about your "Sql_Conn" class.
Also, try using this for your connection.
using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
string cmdText = "SELECT name FROM sys.tables"
cmd.CommandText = cmdText;
cmd.ExecuteNonQuery();
}
}

Configuring mq websphere 7 with .net

I am trying to connect to a remote queue using c#.
I tried many ways to connect to the remote queue but it always fails with common errors like: MQRC_CHANNEL_CONFIG_ERROR or MQRC_HOST_NOT_AVAILABLE.
What I am doing is this:
string channel = "QM_TEST.SVRCONN";
string hostname = "<serverIp>";
string queueName = "QM_TEST";
string port = 1414;
props.Add(MQC.HOST_NAME_PROPERTY, hostname);
props.Add(MQC.CHANNEL_PROPERTY, channel);
props.Add(MQC.PORT_PROPERTY, port );
props.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
MQQueueManager mqQueue = new MQQueueManager(queueName, props);
I have tried changing this but all failed.
I think that my problem is the server configurations..
can you point me to a full guide to how to configure a server and connect to it with .net?
My problem is connecting to a REMOTE server using .net and not to a local server.
Thank you!
The problem was that the CCSID between the client and the server were different.
http://publib.boulder.ibm.com/infocenter/wmqv7/v7r0/index.jsp?topic=%2Fcom.ibm.mq.csqzaf.doc%2Fcs12480_.htm
On the client side I had to put
Environment.SetEnvironmentVariable("MQCCSID", "437");
Thats why I got:
MQRC_CHANNEL_CONFIG_ERROR
I'm guessing the problem (or at least a problem) is here:
MQQueue mqQueue = new MQQueueManager(queueName, props);
This should be
queueManager = new MQQueueManager(queueManagerName, properties);
If you have installed the WebSphere MQ client to the default location, there are many sample programs under the following directory:
C:\Program Files (x86)\IBM\WebSphere MQ\tools\dotnet\samples\cs\base\
There are a number of sample programs there for various tasks. If you have the latest V7.1 client installed then you will see the following programs:
SimpleAsyncPut
SimpleClientAutoReconnectGet
SimpleClientAutoReconnectPut
SimpleGet
SimpleMessageProperties
SimplePublish
SimplePut
SimpleReadAhead
SimpleSharingConversation
SimpleSubscribe
SimpleXAGet
SimpleXAPut
There are also WCF and XMS samples.
If you need the client code, please see my response to another SO question here for links.
Update:
Here's the normal diagnostic process.
If the WMQ components were installed by relocating libraries or classes from somewhere else, perform an install using the full vendor-supplied client media. This includes troubleshooting utilities such as trace, dspmqver, etc. It also resolves any library or class mismatch issues.
Use the pre-compiled client programs to test the connection. The amqsputc, amqsgetc and amqsbcgc programs require the MQSERVER environment variable as described here. The Q program from SupportPac MA01 is a separate download but has the advantage of NOT requiring any environment variables, CCDT files or other dependencies.
If the sample programs fail, check the QMgr's error logs at [WMQ install]/qmgrs/[QMgr name]/errors/AMQERR01.LOG for messages. Also check for FDC files and errors in [WMQ install]/errors.
If no errors on the QMgr side, attempt the connection again while using a client-side trace as described here and here.
Most client problems are resolved through installation of the full WMQ client as supplied by IBM. (Conversely that implies most people are installing by grabbing DLL or JAR files.) If the problem persists, error log inspection on the QMgr and client side usually reveals the underlying cause. If these do not work then tracing usually diagnoses the remaining issues.
UPDATE 2:
Per the error messages posted at MQSeries.net, the channel has a security exit set. A security exit is external code that the channel calls out to when starting a channel. There is no way to know what the exit expects or does without having access to the code or docs of the exit. If the exit is written in-house, you'll need to talk to the programmer to figure out what it requires. If the exit is a commercial product then you will need to get the documentation for it.
Alternatively, alter the channel so that SCYEXIT is blank to disable the exit.
The data posted at MQSeries.net was as follows:
MQ9575: DCE Security: failed to get the user's login name.
EXPLANATION:
System call 192.168.50.55 to get the login name of the user running WebSphere
MQ client application process 5 failed with error value -1. This occurred in
security exit function create_cred. The exit will now attempt to open channel
using the DCE default login context.
ACTION:
If you wish to run using the DCE default login context take no action. If you
wish to run using the user's login name as the DCE security exit principal
examine the documentation for the operating system on which you are running MQ
clients and reconfigure the operating system as necessary to allow the
192.168.50.55 call to succeed.
Note that it states the call is failing in the security exit.

TIBCO EMS Failover reconnect for C# (TIBCO.EMS.dll)

We have a TIBCO EMS solution that uses built-in server failover in a 2-4 server environment. If the TIBCO admins fail-over services from one EMS server to another, connections are supposed to be transfered to the new server automatically at the EMS service level. For our C# applications using the EMS service, this is not happening - our user connections are not being transfered to the new server after failover and we're not sure why.
Our application connection to EMS at startup only so if the TIBCO admins failover after users have started our application, they users need to restart the app in order to reconnect to the new server (our EMS connection uses a server string including all 4 production EMS servers - if the first attempt fails, it moves to the next server in the string and tries again).
I'm looking for an automated approach that will attempt to reconnect to EMS periodically if it detects that the connection is dead but I'm not sure how best to do that.
Any ideas? We are using TIBCO.EMS.dll version 4.4.2 and .Net 2.x (SmartClient app)
Any help would be appreciated.
First off, yes, I am answering my own question. Its important to note, however, that without ajmastrean, I would be nowhere. thank you so much!
ONE:
ConnectionFactory.SetReconnAttemptCount, SetReconnAttemptDelay, SetReconnAttemptTimeout should be set appropriately. I think the default values re-try too quickly (on the order of 1/2 second between retries). Our EMS servers can take a long time to failover because of network storage, etc - so 5 retries at 1/2s intervals is nowhere near long enough.
TWO:
I believe its important to enable the client-server and server-client heartbeats. Wasn't able to verify but without those in place, the client might not get the notification that the server is offline or switching in failover mode. This, of course, is a server side setting for EMS.
THREE:
you can watch for failover event by setting Tibems.SetExceptionOnFTSwitch(true); and then wiring up a exception event handler. When in a single-server environment, you will see a "Connection has been terminated" message. However, if you are in a fault-tolerant multi-server environment, you will see this: "Connection has performed fault-tolerant switch to ". You don't strictly need this notification, but it can be useful (especially in testing).
FOUR:
Apparently not clear in the EMS documentation, connection reconnect will NOT work in a single-server environment. You need to be in a multi-server, fault tolerant environment. There is a trick, however. You can put the same server in the connection list twice - strange I know, but it works and it enables the built-in reconnect logic to work.
some code:
private void initEMS()
{
Tibems.SetExceptionOnFTSwitch(true);
_ConnectionFactory = new TIBCO.EMS.TopicConnectionFactory(<server>);
_ConnectionFactory.SetReconnAttemptCount(30); // 30retries
_ConnectionFactory.SetReconnAttemptDelay(120000); // 2minutes
_ConnectionFactory.SetReconnAttemptTimeout(2000); // 2seconds
_Connection = _ConnectionFactory.CreateTopicConnectionM(<username>, <password>);
_Connection.ExceptionHandler += new EMSExceptionHandler(_Connection_ExceptionHandler);
}
private void _Connection_ExceptionHandler(object sender, EMSExceptionEventArgs args)
{
EMSException e = args.Exception;
// args.Exception = "Connection has been terminated" -- single server failure
// args.Exception = "Connection has performed fault-tolerant switch to <server url>" -- fault-tolerant multi-server
MessageBox.Show(e.ToString());
}
This post should sum up my current comments and explain my approach in more detail...
The TIBCO 'ConnectionFactory' and 'Connection' types are heavyweight, thread-safe types. TIBCO suggests that you maintain the use of one ConnectionFactory (per server configured factory) and one Connection per factory.
The server also appears to be responsible for in-place 'Connection' failover and re-connection, so let's confirm it's doing its job and then lean on that feature.
Creating a client side solution is going to be slightly more involved than fixing a server or client setup problem. All sessions you have created from a failed connection need to be re-created (not to mention producers, consumers, and destinations). There are no "reconnect" or "refresh" methods on either type. The sessions do not maintain a reference to their parent connection either.
You will have to manage a lookup of connection/session objects and go nuts re-initializing everyone! or implement some sort of session failure event handler that can get the new connection and reconnect them.
So, for now, let's dig in and see if the client is setup to receive failover notification (tib ems users guide pg 292). And make sure the raised exception is caught, contains the failover URL, and is being handled properly.
Client applications may receive notification of a failover by setting the tibco.tibjms.ft.switch.exception system property
Perhaps the library needs that to work?

Categories

Resources