Is there a way to fetch the incoming/outgoing/heartbeat messages in the code? - quickfixj

I am using QuickFIX/J (1.6.4). I can see all the messages segregated very properly (incoming/outgoing/event)
<20180504-07:32:14, FIX.4.2:CLIENT2/SUB-> , event> (Session FIX.4.2:CLIENT2/SUB-> schedule is daily, 00:00:00-UTC - 00:00:00-UTC) <20180504-07:32:14, FIX.4.2:CLIENT2/SUB-> , event> (Created session: FIX.4.2:CLIENT2/SUB-> ) <20180504-07:32:15, FIX.4.2:CLIENT2/SUB-> , event> (Configured socket addresses for session: [/x.x.x.x:xxxx]) <20180504-07:32:15, FIX.4.2:CLIENT2/SUB-> , event> (MINA session created: local=/y.y.y.y:yyyy, class org.apache.mina.transport.socket.nio.NioSocketSession, remote=/x.x.x.x:xxxx) <20180504-07:32:16, FIX.4.2:CLIENT2/SUB-> , outgoing> (8=FIX.4.29=7935=A34=149=CLIENT252=20180504-07:32:16.386) <20180504-07:32:16, FIX.4.2:CLIENT2/SUB-> , event> (Initiated logon request) <20180504-07:32:16, FIX.4.2:CLIENT2/SUB-> , incoming> (8=FIX.4.29=8035=A34=1) <20180504-07:32:16, FIX.4.2:CLIENT2/SUB-> , event> (Logon contains ResetSeqNumFlag=Y, resetting sequence numbers to 1) <20180504-07:32:16, FIX.4.2:CLIENT2/SUB-> , event> (Received logon)
However, I am unable to find a way to fetch these segregated messages as-is in my code.
PS: I dig deeper, and reached ScreenLogFactory.java which ultimately seems to log what I see on console logs. But could not find a way to extract those incoming/outgoing messages in my code.
Edit1:
How can I capture session level messages?

To start your SocketInitiator, you had to pass it an instance of quickfix.Application. In your implementation, you can peek heartbeats in the toAdmin and fromAdmin implementation.
class YourFixApplication implements Application {
#Override
public void fromAdmin( Message message, SessionID sessionID ) {
MsgType msgType;
try {
msgType = (MsgType) message.getHeader( ).getField( new MsgType( ) );
}
catch( FieldNotFound e ) {
e.printStackTrace();
return;
}
if( msgType.valueEquals( MsgType.HEARTBEAT ) ) {
System.out.println( ">>> Heartbeat <<<" );
}
}
// same deal with toAdmin implementation
// ...
}

TT.'s answer is correct, though some semantics I needed to change for it to work for me:
public void ToAdmin(Message message, SessionID sessionID)
{
msgType = (MsgType).message.Header.GetField(new MsgType());
catch(FieldNotFoundException e)
{
//error message
return;
}
if(msgType.Obj.Equals(MsgType.HEARTBEAT))
{
// print out wherever or do whatever with the heartbeat msg
}
}

Related

spring-amqp: Channel shutdown with NACKS RECEIVED message

Using spring-amqp with heavy load on RabbitMQ bus, we sometimes get logs from org.springframework.amqp.rabbit.connection.CachingConnectionFactory saying :
Channel shutdown: clean channel shutdown; protocol method: #method<channel.close>(reply-code=200, reply-text=NACKS RECEIVED, class-id=0, method-id=0)
Can you explain this log, please, and why is it at ERROR level?
Do we have any adjustments to make?
Thanks in advance for your answer.
The channel throws an exception if all publisher confirms are not returned with the timeout...
#Override
public void waitForConfirmsOrDie(long timeout)
throws IOException, InterruptedException, TimeoutException
{
try {
if (!waitForConfirms(timeout)) {
close(AMQP.REPLY_SUCCESS, "NACKS RECEIVED", true, null, false);
throw new IOException("nacks received");
}
} catch (TimeoutException e) {
close(AMQP.PRECONDITION_FAILED, "TIMEOUT WAITING FOR ACK");
throw(e);
}
}
The DefaultChannelCloseLogger will only skip normal closes (200) if the reply text is OK...
/**
* Return true if the {#link ShutdownSignalException} reason is AMQP.Channel.Close and
* the reply code was AMQP.REPLY_SUCCESS (200) and the text equals "OK".
* #param sig the exception.
* #return true for a normal channel close.
*/
public static boolean isNormalChannelClose(ShutdownSignalException sig) {
Method shutdownReason = sig.getReason();
return isNormalShutdown(sig) ||
(shutdownReason instanceof AMQP.Channel.Close
&& AMQP.REPLY_SUCCESS == ((AMQP.Channel.Close) shutdownReason).getReplyCode()
&& "OK".equals(((AMQP.Channel.Close) shutdownReason).getReplyText()));
}
If you want to ignore these errors, you can configure a custom close exception logger:
/**
* Set the strategy for logging close exceptions; by default, if a channel is closed due to a failed
* passive queue declaration, it is logged at debug level. Normal channel closes (200 OK) are not
* logged. All others are logged at ERROR level (unless access is refused due to an exclusive consumer
* condition, in which case, it is logged at INFO level).
* #param closeExceptionLogger the {#link ConditionalExceptionLogger}.
* #since 1.5
*/
public void setCloseExceptionLogger(ConditionalExceptionLogger closeExceptionLogger) {
Assert.notNull(closeExceptionLogger, "'closeExceptionLogger' cannot be null");
this.closeExceptionLogger = closeExceptionLogger;
if (this.publisherConnectionFactory != null) {
this.publisherConnectionFactory.setCloseExceptionLogger(closeExceptionLogger);
}
}

Cannot connect to Solace Cloud

I am following the solace tutorial for Publish/Subscribe (link: https://dev.solace.com/samples/solace-samples-java/publish-subscribe/). Therefore, there shouldn't be anything "wrong" with the code.
I am trying to get my TopicSubscriber to connect to the cloud. After building my jar I run the following command:
java -cp target/SOM_Enrichment-1.0-SNAPSHOT.jar TopicSubscriber <host:port> <client-username#message-vpn> <password>
(with the appropriate fields filled in)
I get the following error:
TopicSubscriber initializing...
Jul 12, 2018 2:27:56 PM com.solacesystems.jcsmp.protocol.impl.TcpClientChannel call
INFO: Connecting to host 'blocked out' (host 1 of 1, smfclient 2, attempt 1 of 1, this_host_attempt: 1 of 1)
Jul 12, 2018 2:28:17 PM com.solacesystems.jcsmp.protocol.impl.TcpClientChannel call
INFO: Connection attempt failed to host 'blocked out' ConnectException com.solacesystems.jcsmp.JCSMPTransportException: ('blocked out') - Error communicating with the router. cause: java.net.ConnectException: Connection timed out: no further information ((Client name: 'blocked out' Local port: -1 Remote addr: 'blocked out') - )
Jul 12, 2018 2:28:20 PM com.solacesystems.jcsmp.protocol.impl.TcpClientChannel close
INFO: Channel Closed (smfclient 2)
Exception in thread "main" com.solacesystems.jcsmp.JCSMPTransportException" (Client name: 'blocked out' Local port: -1 Remote addr: 'blocked out') - Error communicating with the router.
Below is the TopicSubscriber.java file:
import java.util.concurrent.CountDownLatch;
import com.solacesystems.jcsmp.BytesXMLMessage;
import com.solacesystems.jcsmp.JCSMPException;
import com.solacesystems.jcsmp.JCSMPFactory;
import com.solacesystems.jcsmp.JCSMPProperties;
import com.solacesystems.jcsmp.JCSMPSession;
import com.solacesystems.jcsmp.TextMessage;
import com.solacesystems.jcsmp.Topic;
import com.solacesystems.jcsmp.XMLMessageConsumer;
import com.solacesystems.jcsmp.XMLMessageListener;
public class TopicSubscriber {
public static void main(String... args) throws JCSMPException {
// Check command line arguments
if (args.length != 3 || args[1].split("#").length != 2) {
System.out.println("Usage: TopicSubscriber <host:port> <client-username#message-vpn> <client-password>");
System.out.println();
System.exit(-1);
}
if (args[1].split("#")[0].isEmpty()) {
System.out.println("No client-username entered");
System.out.println();
System.exit(-1);
}
if (args[1].split("#")[1].isEmpty()) {
System.out.println("No message-vpn entered");
System.out.println();
System.exit(-1);
}
System.out.println("TopicSubscriber initializing...");
final JCSMPProperties properties = new JCSMPProperties();
properties.setProperty(JCSMPProperties.HOST, args[0]); // host:port
properties.setProperty(JCSMPProperties.USERNAME, args[1].split("#")[0]); // client-username
properties.setProperty(JCSMPProperties.PASSWORD, args[2]); // client-password
properties.setProperty(JCSMPProperties.VPN_NAME, args[1].split("#")[1]); // message-vpn
final Topic topic = JCSMPFactory.onlyInstance().createTopic("tutorial/topic");
final JCSMPSession session = JCSMPFactory.onlyInstance().createSession(properties);
session.connect();
final CountDownLatch latch = new CountDownLatch(1); // used for
// synchronizing b/w threads
/** Anonymous inner-class for MessageListener
* This demonstrates the async threaded message callback */
final XMLMessageConsumer cons = session.getMessageConsumer(new XMLMessageListener() {
#Override
public void onReceive(BytesXMLMessage msg) {
if (msg instanceof TextMessage) {
System.out.printf("TextMessage received: '%s'%n",
((TextMessage) msg).getText());
} else {
System.out.println("Message received.");
}
System.out.printf("Message Dump:%n%s%n", msg.dump());
latch.countDown(); // unblock main thread
}
#Override
public void onException(JCSMPException e) {
System.out.printf("Consumer received exception: %s%n", e);
latch.countDown(); // unblock main thread
}
});
session.addSubscription(topic);
System.out.println("Connected. Awaiting message...");
cons.start();
// Consume-only session is now hooked up and running!
try {
latch.await(); // block here until message received, and latch will flip
} catch (InterruptedException e) {
System.out.println("I was awoken while waiting");
}
// Close consumer
cons.close();
System.out.println("Exiting.");
session.closeSession();
}
}
Any help would be greatly appreciated.
java.net.ConnectException: Connection timed out
The log entry indicates that network connectivity to the specified DNS name/IP address cannot be established.
Next step includes:
Verifying that you are able to resolve the DNS name to an IP
address.
Verifying that the correct DNS name/IP address/Port is in use - You need the "SMF Host" in the Solace Cloud Connection Details.
Verifying that the IP address/Port is not blocked by an intermediate network device.

How can I connect into a WCF after get ConnectFailure?

I have a WCF service running in a server and a Windows Application which has a timer each 30 seconds checking by WCF some news values from database.
Everything is going well but if my server (when WCF is running) get offline or out for some reason, I get the Exception System.Reflection.TargetInvocationException or System.Net.WebExceptionStatus.ConnectFailure.
What I want is, well, my timer will check every 30 seconds and I want reestablish the connection when my server come back. Actually the only way to do it is close and open the WinForm app.
How can I check if the connection is back or reconnect without close my app?
public MyClass()
{
proxy = new TaskService.Service1Client();
proxy.GetTarefasCompleted += new EventHandler<GetTarefasCompletedEventArgs>
(proxy_GetTarefasCompleted);
timer = new System.Threading.Timer(Callback, null, 0, 30000);
}
private void Callback(Object state)
{
timer.Change(30000, Timeout.Infinite);
proxy.GetTarefasAsync(Environment.UserDomainName, Environment.UserName);
}
void proxy_GetTarefasCompleted(object sender, GetTarefasCompletedEventArgs e)
{
try
{
tarefas = e.Result.OrderByDescending(t => t.Id).ToList();
//code code code
}
catch (Exception ex)
{
if (ex.GetType().ToString() == "System.Net.WebExceptionStatus.ConnectFailure" ||
ex.GetType().ToString() == "System.Reflection.TargetInvocationException")
{
//treat the error
}
}
}
if (proxy.State != System.ServiceModel.CommunicationState.Opened)
{
proxy.Abort();
proxy.Open();
}
I believe this should do the trick.

grails jms onMessage receives message text?? not Message

I have this in my listener service (following doc):
#Queue(name='queue.web.dev')
def onMessage(Message msg) {
println "DEBUG msgCorrelationID :"+msg.getJMSCorrelationID()
}
but on receiving message, I got error:
"No signature of method: java.lang.String.getJMSCorrelationID()"
If I try adding Message to onMessage args like:
def onMessage(Message msg)
I got error:
java.lang.NoSuchMethodException: MessageListenerService$$EnhancerBySpringCGLIB$$4bfa7a63.onMessage(java.lang.String)
Looks to me that onMessage is getting String message text. Is that true? How can I get whole jms.Message then?
Don't know if this is still open but you have to take the object out of the message yourself ..
def messageContents = ((ObjectMessage) message).getObject()
Is that what your looking for ?
Remove the default message converter
jms {
containers {
standard {
messageConverter = null
}
}
}
Check grails jms docs here

JavaMail store.connect() times out - Can't read gmail Inbox through Java

I am trying to connect to my gmail inbox to read messages through Java Application. I am using..
jdk1.6.0_13
javamail-1.4.3 libs - (mail.jar, mailapi.jar, imap.jar)
Below is my code : MailReader.java
import java.util.Properties;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;
public class MailReader
{
public static void main(String[] args)
{
readMail();
}
public static void readMail()
{
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "imaps");
try
{
Session session = Session.getDefaultInstance(props, null);
Store store = session.getStore("imaps");
store.connect("imap.gmail.com", "myEmailId#gmail.com", "myPwd");
System.out.println("Store Connected..");
//inbox = (Folder) store.getFolder("Inbox");
//inbox.open(Folder.READ_WRITE);
//Further processing of inbox....
}
catch (MessagingException e)
{
e.printStackTrace();
}
}
}
I expect to get store connected, but call to store.connect() never returns and I get below output :
javax.mail.MessagingException: Connection timed out;
nested
exception is:
java.net.ConnectException: Connection timed out
at
com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:441)
at
javax.mail.Service.connect(Service.java:233)
at
javax.mail.Service.connect(Service.java:134)
at
ReadMail.readMail(ReadMail.java:21)
at ReadMail.main(ReadMail.java:10)
However I am able to SEND email by Java using SMTP, Transport.send() and same gmail account. But cannot read emails.
What can be the solution ?
IMAP work off a different port (143 for non-secure, 993 for secure) to sendmail (25) and I suspect that's blocked. Can you telnet on that port to that server e.g.
telnet imap.gmail.com {port number}
That'll indicate if you have network connectivity.

Resources