RTO EMA Java SDK. Timeout.

Options
PAA_Alex
PAA_Alex Newcomer
edited August 8 in EMA

During integration with the RTO EMA Java SDK 3.9.0.1, we have faced a timeout exception:

com.refinitiv.ema.access.OmmInvalidUsageExceptionImpl: login failed (timed out after waiting 45000 milliseconds) for us-east-1-aws-3-sm.optimized-pricing-api.refinitiv.net:14002)
at com.refinitiv.ema.access.OmmBaseImpl.ommIUExcept(OmmBaseImpl.java:2101)
at com.refinitiv.ema.access.OmmBaseImpl.handleLoginReqTimeout(OmmBaseImpl.java:1888)
at com.refinitiv.ema.access.OmmConsumerImpl.handleAdminDomains(OmmConsumerImpl.java:679)
at com.refinitiv.ema.access.OmmBaseImpl.initialize(OmmBaseImpl.java:369)
at com.refinitiv.ema.access.OmmConsumerImpl.<init>(OmmConsumerImpl.java:105)
at com.refinitiv.ema.access.EmaFactory.createOmmConsumer(EmaFactory.java:346)

Meanwhile, telnet says that we have a connection to the specified host:

telnet us-east-1-aws-3-sm.optimized-pricing-api.refinitiv.net 14002
Trying 34.200.157.185...
Connected to 9860-0d67-d5df-ef6a.static.public.inf0.net.

As credentials, client id and client secret are used.

It should be noticed that if we specify invalid credentials, then we receive an appropriate error, not a timeout:

Failed to request authentication token information with HTTP error 401. Text: {"error":"invalid_client"  ,"error_description":"Invalid client or client credentials." }

As the base for the implementation, the following were used:

Additionally, the EMA Java Batch View sample application also failed to run in two variations — the original and using programmatic config, as it reproduced the timeout error.

Here is the Original version:

///*|----------------------------------------------------------------------------------------------------
// *|            This source code is provided under the Apache 2.0 license      	--
// *|  and is provided AS IS with no warranty or guarantee of fit for purpose.  --
// *|                See the project's LICENSE.md for details.                  					--
// *|           Copyright Refinitiv 2020. All rights reserved.            		--
///*|----------------------------------------------------------------------------------------------------


package com.refinitiv.ema.examples.training.consumer.series300.example375__MarketPrice__BatchView;


import com.refinitiv.ema.access.*;
import com.refinitiv.ema.access.DataType.DataTypes;
import com.refinitiv.ema.rdm.EmaRdm;


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;




class AppClient implements OmmConsumerClient
{
	public void onRefreshMsg(RefreshMsg refreshMsg, OmmConsumerEvent event)
	{
		System.out.println("Item Name: " + (refreshMsg.hasName() ? refreshMsg.name() : "<not set>"));
		System.out.println("Service Name: " + (refreshMsg.hasServiceName() ? refreshMsg.serviceName() : "<not set>"));
		
		System.out.println("Item State: " + refreshMsg.state());
		
		if (DataType.DataTypes.FIELD_LIST == refreshMsg.payload().dataType())
			decode(refreshMsg.payload().fieldList());
		
		System.out.println();
	}
	
	public void onUpdateMsg(UpdateMsg updateMsg, OmmConsumerEvent event) 
	{
		System.out.println("Item Name: " + (updateMsg.hasName() ? updateMsg.name() : "<not set>"));
		System.out.println("Service Name: " + (updateMsg.hasServiceName() ? updateMsg.serviceName() : "<not set>"));
		
		if (DataType.DataTypes.FIELD_LIST == updateMsg.payload().dataType())
			decode(updateMsg.payload().fieldList());
		
		System.out.println();
	}


	public void onStatusMsg(StatusMsg statusMsg, OmmConsumerEvent event) 
	{
		System.out.println("Item Name: " + (statusMsg.hasName() ? statusMsg.name() : "<not set>"));
		System.out.println("Service Name: " + (statusMsg.hasServiceName() ? statusMsg.serviceName() : "<not set>"));


		if (statusMsg.hasState())
			System.out.println("Item State: " +statusMsg.state());
		
		System.out.println();
	}
	
	public void onGenericMsg(GenericMsg genericMsg, OmmConsumerEvent consumerEvent){}
	public void onAckMsg(AckMsg ackMsg, OmmConsumerEvent consumerEvent){}
	public void onAllMsg(Msg msg, OmmConsumerEvent consumerEvent){}


	void decode(FieldList fieldList)
	{
		for (FieldEntry fieldEntry : fieldList)
		{
			System.out.print("Fid: " + fieldEntry.fieldId() + " Name = " + fieldEntry.name() + " DataType: " + DataType.asString(fieldEntry.load().dataType()) + " Value: ");


			if (Data.DataCode.BLANK == fieldEntry.code())
				System.out.println(" blank");
			else
				switch (fieldEntry.loadType())
				{
				case DataTypes.REAL :
					System.out.println(fieldEntry.real().asDouble());
					break;
				case DataTypes.DATE :
					System.out.println(fieldEntry.date().day() + " / " + fieldEntry.date().month() + " / " + fieldEntry.date().year());
					break;
				case DataTypes.TIME :
					System.out.println(fieldEntry.time().hour() + ":" + fieldEntry.time().minute() + ":" + fieldEntry.time().second() + ":" + fieldEntry.time().millisecond());
					break;
				case DataTypes.INT :
					System.out.println(fieldEntry.intValue());
					break;
				case DataTypes.UINT :
					System.out.println(fieldEntry.uintValue());
					break;
				case DataTypes.ASCII :
					System.out.println(fieldEntry.ascii());
					break;
				case DataTypes.ENUM :
					System.out.println(fieldEntry.hasEnumDisplay() ? fieldEntry.enumDisplay() : fieldEntry.enumValue());
					break;
				case DataTypes.ERROR :
					System.out.println("(" + fieldEntry.error().errorCodeAsString() + ")");
					break;
				default :
					System.out.println();
					break;
				}
		}
	}
}


public class Consumer 
{
	public static void main(String argv[])
	{
		OmmConsumer consumer = null;
		try
		{
			AppClient appClient = new AppClient();


            final var host = "us-east-1-aws-3-sm.optimized-pricing-api.refinitiv.net";

            consumer  = EmaFactory.createOmmConsumer(EmaFactory.createOmmConsumerConfig().host(host).clientId("GE-R2Q7HZPBQIHU").clientSecret("1c50d391-a3e9-488e-8df1-c1118ab30d46"));
			
			ElementList batchView = EmaFactory.createElementList();
			
			OmmArray array = EmaFactory.createOmmArray();
			
			array.fixedWidth(2);
			array.add(EmaFactory.createOmmArrayEntry().intValue(22));
			array.add(EmaFactory.createOmmArrayEntry().intValue(25));
			
			OmmArray arrayI = EmaFactory.createOmmArray();
			
			arrayI.add(EmaFactory.createOmmArrayEntry().ascii("AUD="));
			arrayI.add(EmaFactory.createOmmArrayEntry().ascii("JPY="));




			batchView.add(EmaFactory.createElementEntry().array(EmaRdm.ENAME_BATCH_ITEM_LIST, arrayI));
			batchView.add(EmaFactory.createElementEntry().uintValue(EmaRdm.ENAME_VIEW_TYPE, 1));
			batchView.add(EmaFactory.createElementEntry().array(EmaRdm.ENAME_VIEW_DATA, array));
			
			consumer.registerClient(EmaFactory.createReqMsg().serviceName("ELEKTRON_EDGE").payload(batchView), appClient);
			
			Thread.sleep(60000);			// API calls onRefreshMsg(), onUpdateMsg() and onStatusMsg()
		}
		catch (InterruptedException | OmmException excp)
		{
			System.out.println(excp.getMessage());
		}
		finally 
		{
			if (consumer != null) consumer.uninitialize();
		}
	}
}

Programmatic config version:

///*|----------------------------------------------------------------------------------------------------
// *|            This source code is provided under the Apache 2.0 license      	--
// *|  and is provided AS IS with no warranty or guarantee of fit for purpose.  --
// *|                See the project's LICENSE.md for details.                  					--
// *|           Copyright Refinitiv 2020. All rights reserved.            		--
///*|----------------------------------------------------------------------------------------------------

package com.refinitiv.ema.examples.training.consumer.series300.example375__MarketPrice__BatchView;

import com.refinitiv.ema.access.*;
import com.refinitiv.ema.access.DataType.DataTypes;
import com.refinitiv.ema.rdm.EmaRdm;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;


class AppClient implements OmmConsumerClient
{
	public void onRefreshMsg(RefreshMsg refreshMsg, OmmConsumerEvent event)
	{
		System.out.println("Item Name: " + (refreshMsg.hasName() ? refreshMsg.name() : "<not set>"));
		System.out.println("Service Name: " + (refreshMsg.hasServiceName() ? refreshMsg.serviceName() : "<not set>"));
		
		System.out.println("Item State: " + refreshMsg.state());
		
		if (DataType.DataTypes.FIELD_LIST == refreshMsg.payload().dataType())
			decode(refreshMsg.payload().fieldList());
		
		System.out.println();
	}
	
	public void onUpdateMsg(UpdateMsg updateMsg, OmmConsumerEvent event) 
	{
		System.out.println("Item Name: " + (updateMsg.hasName() ? updateMsg.name() : "<not set>"));
		System.out.println("Service Name: " + (updateMsg.hasServiceName() ? updateMsg.serviceName() : "<not set>"));
		
		if (DataType.DataTypes.FIELD_LIST == updateMsg.payload().dataType())
			decode(updateMsg.payload().fieldList());
		
		System.out.println();
	}

	public void onStatusMsg(StatusMsg statusMsg, OmmConsumerEvent event) 
	{
		System.out.println("Item Name: " + (statusMsg.hasName() ? statusMsg.name() : "<not set>"));
		System.out.println("Service Name: " + (statusMsg.hasServiceName() ? statusMsg.serviceName() : "<not set>"));

		if (statusMsg.hasState())
			System.out.println("Item State: " +statusMsg.state());
		
		System.out.println();
	}
	
	public void onGenericMsg(GenericMsg genericMsg, OmmConsumerEvent consumerEvent){}
	public void onAckMsg(AckMsg ackMsg, OmmConsumerEvent consumerEvent){}
	public void onAllMsg(Msg msg, OmmConsumerEvent consumerEvent){}

	void decode(FieldList fieldList)
	{
		for (FieldEntry fieldEntry : fieldList)
		{
			System.out.print("Fid: " + fieldEntry.fieldId() + " Name = " + fieldEntry.name() + " DataType: " + DataType.asString(fieldEntry.load().dataType()) + " Value: ");

			if (Data.DataCode.BLANK == fieldEntry.code())
				System.out.println(" blank");
			else
				switch (fieldEntry.loadType())
				{
				case DataTypes.REAL :
					System.out.println(fieldEntry.real().asDouble());
					break;
				case DataTypes.DATE :
					System.out.println(fieldEntry.date().day() + " / " + fieldEntry.date().month() + " / " + fieldEntry.date().year());
					break;
				case DataTypes.TIME :
					System.out.println(fieldEntry.time().hour() + ":" + fieldEntry.time().minute() + ":" + fieldEntry.time().second() + ":" + fieldEntry.time().millisecond());
					break;
				case DataTypes.INT :
					System.out.println(fieldEntry.intValue());
					break;
				case DataTypes.UINT :
					System.out.println(fieldEntry.uintValue());
					break;
				case DataTypes.ASCII :
					System.out.println(fieldEntry.ascii());
					break;
				case DataTypes.ENUM :
					System.out.println(fieldEntry.hasEnumDisplay() ? fieldEntry.enumDisplay() : fieldEntry.enumValue());
					break;
				case DataTypes.ERROR :
					System.out.println("(" + fieldEntry.error().errorCodeAsString() + ")");
					break;
				default :
					System.out.println();
					break;
				}
		}
	}
}

public class Consumer 
{
    static void createProgramaticConfig(Map configDb, String host, String port)
    {
        Map elementMap = EmaFactory.createMap();
        ElementList elementList = EmaFactory.createElementList();
        ElementList innerElementList = EmaFactory.createElementList();

        innerElementList.add(EmaFactory.createElementEntry().ascii("Channel", "Channel_1"));


        elementMap.add(EmaFactory.createMapEntry().keyAscii("Consumer_1", MapEntry.MapAction.ADD, innerElementList));
        innerElementList.clear();

        elementList.add(EmaFactory.createElementEntry().map("ConsumerList", elementMap));
        elementMap.clear();

        configDb.add(EmaFactory.createMapEntry().keyAscii("ConsumerGroup", MapEntry.MapAction.ADD, elementList));
        elementList.clear();

        innerElementList.add(EmaFactory.createElementEntry().ascii("ChannelType", "ChannelType::RSSL_ENCRYPTED"));

        innerElementList.add(EmaFactory.createElementEntry().ascii("Host", host));
        innerElementList.add(EmaFactory.createElementEntry().ascii("Port", port));
        innerElementList.add(EmaFactory.createElementEntry().intValue("EnableSessionManagement", 1));

        elementMap.add(EmaFactory.createMapEntry().keyAscii("Channel_1", MapEntry.MapAction.ADD, innerElementList));
        innerElementList.clear();

        elementList.add(EmaFactory.createElementEntry().map("ChannelList", elementMap));
        elementMap.clear();

        configDb.add(EmaFactory.createMapEntry().keyAscii("ChannelGroup", MapEntry.MapAction.ADD, elementList));
        elementList.clear();
    }

	public static void main(String argv[])
	{
		OmmConsumer consumer = null;
		try
		{
			AppClient appClient = new AppClient();

            final var host = "us-east-1-aws-3-sm.optimized-pricing-api.refinitiv.net";
            Map configDb = EmaFactory.createMap();
            createProgramaticConfig(configDb, host, "14002");
            consumer  = EmaFactory.createOmmConsumer(EmaFactory.createOmmConsumerConfig().host(host).config(configDb).clientId("GE-R2Q7HZPBQIHU").clientSecret("1c50d391-a3e9-488e-8df1-c1118ab30d46"));
			
			ElementList batchView = EmaFactory.createElementList();
			
			OmmArray array = EmaFactory.createOmmArray();
			
			array.fixedWidth(2);
			array.add(EmaFactory.createOmmArrayEntry().intValue(22));
			array.add(EmaFactory.createOmmArrayEntry().intValue(25));
			
			OmmArray arrayI = EmaFactory.createOmmArray();
			
			arrayI.add(EmaFactory.createOmmArrayEntry().ascii("AUD="));
			arrayI.add(EmaFactory.createOmmArrayEntry().ascii("JPY="));


			batchView.add(EmaFactory.createElementEntry().array(EmaRdm.ENAME_BATCH_ITEM_LIST, arrayI));
			batchView.add(EmaFactory.createElementEntry().uintValue(EmaRdm.ENAME_VIEW_TYPE, 1));
			batchView.add(EmaFactory.createElementEntry().array(EmaRdm.ENAME_VIEW_DATA, array));
			
			consumer.registerClient(EmaFactory.createReqMsg().serviceName("ELEKTRON_EDGE").payload(batchView), appClient);
			
			Thread.sleep(60000);			// API calls onRefreshMsg(), onUpdateMsg() and onStatusMsg()
		}
		catch (InterruptedException | OmmException excp)
		{
			System.out.println(excp.getMessage());
		}
		finally 
		{
			if (consumer != null) consumer.uninitialize();
		}
	}
}

And its logs:

17:12:39.277 [main] INFO com.refinitiv.ema.access.OmmConsumerImpl -- loggerMsg
    ClientName: EmaConfig
    Severity: Info
    Text:    Missing, unreadable or empty file configuration, path=[/Users/vyemets/Files/projects/uapp/xabeta/backend/EmaConfig.xml]
loggerMsgEnd


17:12:44.353 [main] WARN com.refinitiv.ema.access.OmmConsumerImpl -- loggerMsg
    ClientName: ChannelCallbackClient
    Severity: Warning
    Text:    Received ChannelDownReconnecting event on channel Channel
	RsslReactor @311bf055
	RsslChannel @642a7222
	Error Id 0
	Internal sysError 0
	Error Location Reactor.processWorkerEvent
	Error text Error - exceeded initialization timeout (5 s)
loggerMsgEnd


17:12:50.367 [main] WARN com.refinitiv.ema.access.OmmConsumerImpl -- loggerMsg
    ClientName: ChannelCallbackClient
    Severity: Warning
    Text:    Received ChannelDownReconnecting event on channel Channel
	RsslReactor @311bf055
	RsslChannel @7d322cad
	Error Id 0
	Internal sysError 0
	Error Location Reactor.processWorkerEvent
	Error text Error - exceeded initialization timeout (5 s)
loggerMsgEnd


17:12:57.390 [main] WARN com.refinitiv.ema.access.OmmConsumerImpl -- loggerMsg
    ClientName: ChannelCallbackClient
    Severity: Warning
    Text:    Received ChannelDownReconnecting event on channel Channel
	RsslReactor @311bf055
	RsslChannel @642a7222
	Error Id 0
	Internal sysError 0
	Error Location Reactor.processWorkerEvent
	Error text Error - exceeded initialization timeout (5 s)
loggerMsgEnd


17:13:06.435 [main] WARN com.refinitiv.ema.access.OmmConsumerImpl -- loggerMsg
    ClientName: ChannelCallbackClient
    Severity: Warning
    Text:    Received ChannelDownReconnecting event on channel Channel
	RsslReactor @311bf055
	RsslChannel @7d322cad
	Error Id 0
	Internal sysError 0
	Error Location Reactor.processWorkerEvent
	Error text Error - exceeded initialization timeout (5 s)
loggerMsgEnd


17:13:16.486 [main] WARN com.refinitiv.ema.access.OmmConsumerImpl -- loggerMsg
    ClientName: ChannelCallbackClient
    Severity: Warning
    Text:    Received ChannelDownReconnecting event on channel Channel
	RsslReactor @311bf055
	RsslChannel @642a7222
	Error Id 0
	Internal sysError 0
	Error Location Reactor.processWorkerEvent
	Error text Error - exceeded initialization timeout (5 s)
loggerMsgEnd


17:13:24.379 [main] ERROR com.refinitiv.ema.access.OmmConsumerImpl -- loggerMsg
    ClientName: EmaConsumer_1
    Severity: Error
    Text:    login failed (timed out after waiting 45000 milliseconds) for us-east-1-aws-3-sm.optimized-pricing-api.refinitiv.net:14002)
loggerMsgEnd


17:13:24.381 [main] ERROR com.refinitiv.ema.access.OmmConsumerImpl -- loggerMsg
    ClientName: ChannelCallbackClient
    Severity: Error
    Text:    Received ChannelDown event on channel Channel
	Instance Name EmaConsumer_1
	RsslReactor @311bf055
	RsslChannel @7d322cad
	Error Id 0
	Internal sysError 0
	Error Location Reactor.processWorkerEvent
	Error text Error - exceeded initialization timeout (5 s)
loggerMsgEnd


login failed (timed out after waiting 45000 milliseconds) for us-east-1-aws-3-sm.optimized-pricing-api.refinitiv.net:14002)

Process finished with exit code 0

Has anyone encountered this problem? What mistakes did we make?

Best Answer

  • PAA_Alex
    PAA_Alex Newcomer
    edited August 11 Answer ✓

    Thanks, everyone, for your help with this issue.

    The non-obvious solution was to add the parameter takeExclusiveSignOnControl = true to the ServiceEndpointDiscoveryOption and OmmConsumerConfig.

    So the consumer initialization would look like this (Kotlin):

    val consumerConfig = EmaFactory.createOmmConsumerConfig()
    val configDb = EmaFactory.createMap()
    createProgrammaticConfig(configDb)
    
    consumer = EmaFactory.createOmmConsumer(
        consumerConfig.consumerName(CONSUMER_NAME)
            .clientId(properties.clientId)
            .clientSecret(properties.clientSecret)
            .takeExclusiveSignOnControl(true) // timeout without the option
            .config(configDb)
    )
    

Answers

  • Jirapongse
    Jirapongse ✭✭✭✭✭

    @PAA_Alex

    Thank you for reaching out to us.

    The API may not be able to connect to the server us-east-1-aws-3-sm.optimized-pricing-api.refinitiv.net on TCP 14002 port.

    The connection may be blocked by the company's firewall. Please check this with your network team.

  • wasin.w V3
    wasin.w V3 admin
    edited August 8

    Hello @PAA_Alex

    The error message "login failed (timed out after waiting 45000 milliseconds) for us-east-1-aws-3-sm.optimized-pricing-api.refinitiv.net:14002)" means:

    1. The API can establish a connection to us-east-1-aws-3-sm.optimized-pricing-api.refinitiv.net endpoint via RSSL connection port 14002
    2. The API did send a RSSL login request message to the endpoint
    3. However, the API did not receive a login response message (confirm login or reject) from the endpoint on time (default 45000 milliseconds == 45 seconds).

    This is most likely a network issue.

    It could be a network between your end to the AWS us-east-1-aws-3-sm.optimized-pricing-api.refinitiv.net endpoint take a long time than 45 seconds.

    • You might try to connect to endpoint in other regions that closer to your end (ap-northeast, ap-southeast, eu-central, eu-west, etc.)
    • You might try to configure the EmaConfig.xml LoginRequestTimeOut parameter to extend a waiting time for a login request message.
    login.png

    If the settings above do not help, it could be your organization firewall/proxy blocks incoming message for TCP port 14002. I strongly suggest you contact your local Network team to check the issue.