Data contribution issue

Siamak.Delavari
Siamak.Delavari Newcomer
edited 2:21AM in EMA

Hi,


I am contacting from TD Securities, I had some discussion with Douglas Walker as we are trying to submit a test pricing through (ADS/ADH) service via Refinitiv setup
RIC: CA01921I=TEST and the SERVICE= REUTERS
I was told by Douglas to use this portal for any issue(s) and he also mentioned we need to use REUTERS(not DCRA) as a service to connect to contribution server


I am using the example code fom SDK C++ : .. Cpp-C\Ema\Examples\Training\Consumer\300_Series\341_MP_OffStreamPost

When I run the code , I am getting this error on ACK message:

Item Handle: 39483232
Closure: 0x4083ba
Service Name: REUTERS
Ack Id: 1
Text: A9: Service is unavailable.


can you please advise?

Answers

  • Jirapongse
    Jirapongse ✭✭✭✭✭

    @Siamak.Delavari

    Thank you for reaching out to us.

    You need to check the source of the REUTERS (257) service. Which application is responsible for processing the post messages?

    The application retrieved the negative acknowledgement for the post message.

    <!-- rwfMajorVer="14" rwfMinorVer="1" -->

    <ackMsg domainType="RSSL_DMT_MARKET_PRICE" streamId="1" containerType="RSSL_DT_NO_DATA" flags="0x32 (RSSL_AKMF_HAS_TEXT|RSSL_AKMF_HAS_MSG_KEY|RSSL_AKMF_HAS_NAK_CODE)" ackId="1" nakCode="RSSL_NAKC_SOURCE_DOWN" text="A9: Service is unavailable." dataSize="0">
    <key flags="0x3 (RSSL_MKF_HAS_SERVICE_ID|RSSL_MKF_HAS_NAME)" serviceId="257" name="CA01921I=TEST"/>
    <dataBody>
    </dataBody>
    </ackMsg>

  • Siamak.Delavari
    Siamak.Delavari Newcomer
    edited June 12

    Thank you for your reply -

    This is the answer I got from Douglas:
    DCRA – is your contributions service…This is what you would use to post
    REUTERS – is your conflated real time service that you can subscribe/request an image and receive updates from to view the populated FIDS(fields).

    so After your comment , I used service DCRA for post message :
    But I get different error message :
    <ackMsg domainType="RSSL_DMT_MARKET_PRICE" streamId="1" containerType="RSSL_DT_NO_DATA" flags="0x32 (RSSL_AKMF_HAS_TEXT|RSSL_AKMF_HAS_MSG_KEY|RSSL_AKMF_HAS_NAK_CODE)" ackId="1" nakCode="RSSL_NAKC_DENIED_BY_SRC" text="PostMsg received with no update as payload" dataSize="0">
    <key flags="0x7 (RSSL_MKF_HAS_SERVICE_ID|RSSL_MKF_HAS_NAME|RSSL_MKF_HAS_NAME_TYPE)" serviceId="301" name="CA01921I=TEST" nameType="1"/>
    <dataBody>
    </dataBody>
    </ackMsg><!-- End Message (Channel IPC descriptor = 9) -->Siamak-2 Received: AckMsg
    Item Handle: 15263584
    Closure: 0x4083c2
    Service Name: DCRA
    Ack Id: 1
    Text: PostMsg received with no update as payload



    The log is attached




    and here is sample code that I changed :



    ///*|-----------------------------------------------------------------------------
    // *| 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 (C) 2019 LSEG. All rights reserved. --
    ///
    |-----------------------------------------------------------------------------

    #include "Consumer.h"

    using namespace refinitiv::ema::access;
    using namespace refinitiv::ema::rdm;
    using namespace refinitiv::ema;
    using namespace std;

    const EmaString TD_SERVICE = "REUTERS";

    void AppClient::onRefreshMsg( const RefreshMsg& refreshMsg, const OmmConsumerEvent& ommEvent )
    {
    cout << endl << "Received: " << "RefreshMsg" << endl << "Handle: " << ommEvent.getHandle() << " Closure: " << ommEvent.getClosure() << endl;

    cout << endl << "Item Name: " << (refreshMsg.hasName() ? refreshMsg.getName() : EmaString("<not set>")) << endl
    	<< "Service Name: " << (refreshMsg.hasServiceName() ? refreshMsg.getServiceName() : EmaString("<not set>"));
    
    cout << endl << "Item State: " << refreshMsg.getState().toString() << endl;
    
    decode(refreshMsg);
    
    
    
    if (refreshMsg.getDomainType() == MMT_LOGIN &&
    	refreshMsg.getState().getStreamState() == OmmState::OpenEnum &&
    	refreshMsg.getState().getDataState() == OmmState::OkEnum)
    {
    	//_postStreamID = refreshMsg.getStreamId();
    	//_subStreamHandle = ommEvent.getHandle();
    
    	cout << endl << "********************************************************************************************** submit WITH SERVICE=DCRA"  << endl;
    	_pOmmConsumer->submit(
    		PostMsg().postId(postId++).serviceName("DCRA")
    		.name("CA01921I=TEST").solicitAck(true).complete(true)
    		.payload(
    			RefreshMsg().payload(
    				FieldList().addReal( 25, 35, OmmReal::ExponentPos1Enum )
    				.complete()
    			)
    			.complete(true) ), ommEvent.getHandle() );
    
    }
    

    }

    void AppClient::onUpdateMsg( const UpdateMsg& updateMsg, const OmmConsumerEvent& ommEvent )
    {
    cout << endl << "Siamak-4 Received: " << "UpdateMsg" << endl << "Handle: " << ommEvent.getHandle() << " Closure: " << ommEvent.getClosure() << endl;

    cout << endl << "Item Name: " << ( updateMsg.hasName() ? updateMsg.getName() : EmaString( "<not set>" ) ) << endl
    	<< "Service Name: " << (updateMsg.hasServiceName() ? updateMsg.getServiceName() : EmaString( "<not set>" ) ) << endl;
    
    decode( updateMsg );
    

    }

    void AppClient::onStatusMsg( const StatusMsg& statusMsg, const OmmConsumerEvent& ommEvent )
    {
    cout << endl << "Siamak-3 Received: " << "StatusMsg" << endl << "Item Handle: " << ommEvent.getHandle() << " Closure: " << ommEvent.getClosure() << endl;

    cout << endl << "Item Name: " << ( statusMsg.hasName() ? statusMsg.getName() : EmaString( "<not set>" ) ) << endl
    	<< "Service Name: " << (statusMsg.hasServiceName() ? statusMsg.getServiceName() : EmaString( "<not set>" ) );
    
    if ( statusMsg.hasState() )
    	cout << endl << "Item State: " << statusMsg.getState().toString() << endl;
    

    }

    void AppClient::onAckMsg( const AckMsg& ackMsg, const OmmConsumerEvent& event )
    {
    cout << endl << "Siamak-2 Received: AckMsg" << endl << "Item Handle: " << event.getHandle() << endl << "Closure: " << event.getClosure() << endl;

    decode( ackMsg );
    

    }

    void AppClient::decode( const AckMsg& ackMsg )
    {
    cout << "Service Name: " << ( ackMsg.hasServiceName() ? ackMsg.getServiceName() : EmaString( "not set" ) ) << endl;

    cout << "Ack Id: " << ackMsg.getAckId() << endl;
    
    if (ackMsg.hasNackCode() == false) {
    	cout << "Nack Code: " << ackMsg.getNackCodeAsString() << endl;
    }
    if ( ackMsg.hasText() )
    	cout << "Text: " << ackMsg.getText() << endl;
    
    switch ( ackMsg.getAttrib().getDataType() )
    {
    case DataType::ElementListEnum:
    	decode( ackMsg.getAttrib().getElementList() );
    	break;
    case DataType::FieldListEnum:
    	decode( ackMsg.getAttrib().getFieldList() );
    	break;
    }
    
    switch ( ackMsg.getPayload().getDataType() )
    {
    case DataType::ElementListEnum:
    	decode( ackMsg.getPayload().getElementList() );
    	break;
    case DataType::FieldListEnum:
    	decode( ackMsg.getPayload().getFieldList() );
    	break;
    }
    

    }

    void AppClient::decode( const Msg& msg )
    {
    switch ( msg.getAttrib().getDataType() )
    {
    case DataType::ElementListEnum:
    decode( msg.getAttrib().getElementList() );
    break;
    case DataType::FieldListEnum:
    decode( msg.getAttrib().getFieldList() );
    break;
    }

    switch ( msg.getPayload().getDataType() )
    {
    case DataType::ElementListEnum:
    	decode( msg.getPayload().getElementList() );
    	break;
    case DataType::FieldListEnum:
    	decode(msg.getPayload().getFieldList() );
    	break;
    }
    

    }

    void AppClient::decode(const ElementList& el)
    {
    while ( el.forth() )
    {
    const ElementEntry& ee = el.getEntry();

    	cout << "Name: " << ee.getName() << " DataType: " << DataType( ee.getLoad().getDataType() ) << " Value: ";
    
    	if ( ee.getCode() == Data::BlankEnum )
    		cout << " blank" << endl;
    	else
    		switch ( ee.getLoadType() )
    	{
    		case DataType::RealEnum:
    			cout << ee.getReal().getAsDouble() << endl;
    			break;
    		case DataType::DateEnum:
    			cout << (UInt64)ee.getDate().getDay() << " / " << (UInt64)ee.getDate().getMonth() << " / " << (UInt64)ee.getDate().getYear() << endl;
    			break;
    		case DataType::TimeEnum:
    			cout << (UInt64)ee.getTime().getHour() << ":" << (UInt64)ee.getTime().getMinute() << ":" << (UInt64)ee.getTime().getSecond() << ":" << (UInt64)ee.getTime().getMillisecond() << endl;
    			break;
    		case DataType::IntEnum:
    			cout << ee.getInt() << endl;
    			break;
    		case DataType::UIntEnum:
    			cout << ee.getUInt() << endl;
    			break;
    		case DataType::AsciiEnum:
    			cout << ee.getAscii() << endl;
    			break;
    		case DataType::ErrorEnum:
    			cout << ee.getError().getErrorCode() << "( " << ee.getError().getErrorCodeAsString() << " )" << endl;
    			break;
    		case DataType::EnumEnum:
    			cout << ee.getEnum() << endl;
    			break;
    		default:
    			cout << endl;
    			break;
    	}
    }
    

    }

    void AppClient::decode( const FieldList& fl )
    {
    while ( fl.forth() )
    {
    const FieldEntry& fe = fl.getEntry();

    	cout << "Name: " << fe.getName() << " Value: ";
    
    	if ( fe.getCode() == Data::BlankEnum )
    		cout << " blank" << endl;
    	else
    		switch ( fe.getLoadType() )
    	{
    		case DataType::RealEnum:
    			cout << fe.getReal().getAsDouble() << endl;
    			break;
    		case DataType::DateEnum:
    			cout << (UInt64)fe.getDate().getDay() << " / " << (UInt64)fe.getDate().getMonth() << " / " << (UInt64)fe.getDate().getYear() << endl;
    			break;
    		case DataType::TimeEnum:
    			cout << (UInt64)fe.getTime().getHour() << ":" << (UInt64)fe.getTime().getMinute() << ":" << (UInt64)fe.getTime().getSecond() << ":" << (UInt64)fe.getTime().getMillisecond() << endl;
    			break;
    		case DataType::IntEnum:
    			cout << fe.getInt() << endl;
    			break;
    		case DataType::UIntEnum:
    			cout << fe.getUInt() << endl;
    			break;
    		case DataType::AsciiEnum:
    			cout << fe.getAscii() << endl;
    			break;
    		case DataType::ErrorEnum:
    			cout << fe.getError().getErrorCode() << "( " << fe.getError().getErrorCodeAsString() << " )" << endl;
    			break;
    		case DataType::EnumEnum:
    			fe.hasEnumDisplay() ? cout << fe.getEnumDisplay() << endl : cout << fe.getEnum() << endl;
    			break;
    		case DataType::RmtesEnum:
    			cout << fe.getRmtes().toString() << endl;
    			break;
    		default:
    			cout << endl;
    			break;
    	}
    }
    

    }

    AppClient::AppClient() :
    postId( 1 )
    {
    }

    void AppClient::setOmmConsumer( OmmConsumer& consumer )
    {
    _pOmmConsumer = &consumer;
    }

    int main()
    {
    try {

    	AppClient client;
    	//OmmConsumer consumer(OmmConsumerConfig().username("clarkjd"));
    	OmmConsumer consumer(OmmConsumerConfig().username("apaukprod"));
    
    	client.setOmmConsumer( consumer );
    	void* closure = (void*)"1";
    
    
    	// open login stream on which off stream posting will happen
    	UInt64 loginHandle = consumer.registerClient( ReqMsg().domainType( MMT_LOGIN ).serviceName(TD_SERVICE), client, closure);
    	UInt64 handle = consumer.registerClient( ReqMsg().domainType(MMT_MARKET_PRICE).serviceName(TD_SERVICE).name( "CA01921I=TEST" ), client, closure );
    	
    	sleep( 60000 );// API calls onRefreshMsg(), onUpdateMsg(), or onStatusMsg()
    
    
    
    }
    catch ( const OmmException& excp ) {
    	cout << excp << endl;
    }
    return 0;
    

    }

  • Jirapongse
    Jirapongse ✭✭✭✭✭

    According to the provided information, you can't send post messages to the REUTERS service.

    DCRA – is your contributions service…This is what you would use to post

    REUTERS – is your conflated real time service that you can subscribe/request an image and receive updates from to view the populated FIDS(fields).

    You need to send post messages to the contributions service (DCRA).

    The NAK text indicates that "PostMsg received with no update as payload".

    <ackMsg domainType="RSSL_DMT_MARKET_PRICE" streamId="1" containerType="RSSL_DT_NO_DATA" flags="0x32 (RSSL_AKMF_HAS_TEXT|RSSL_AKMF_HAS_MSG_KEY|RSSL_AKMF_HAS_NAK_CODE)" ackId="1" nakCode="RSSL_NAKC_DENIED_BY_SRC" text="PostMsg received with no update as payload" dataSize="0">

    <key flags="0x7 (RSSL_MKF_HAS_SERVICE_ID|RSSL_MKF_HAS_NAME|RSSL_MKF_HAS_NAME_TYPE)" serviceId="301" name="CA01921I=TEST" nameType="1"/>

    <dataBody>

    </dataBody>

    </ackMsg>

    Therefore, a post message should contact an update message, not a refresh message. The code should be changed to:

    _pOmmConsumer->submit( 
    	PostMsg().postId( postId++ ).serviceName("DCRA")
    	.name( "CA01921I=TEST" ).solicitAck( true )
    	.complete()
    	.payload( 
    		UpdateMsg().payload( 
    			FieldList().addReal(25, 35, OmmReal::ExponentPos1Enum)
    			.complete() 
    		) 
    	) , ommEvent.getHandle() );