com.thomsonreuters.ema.access.DictionaryCallbackClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ema Show documentation
Show all versions of ema Show documentation
Enterprise Message API (EMA) Java Edition
///*|-----------------------------------------------------------------------------
// *| 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 Thomson Reuters 2015. All rights reserved. --
///*|-----------------------------------------------------------------------------
package com.thomsonreuters.ema.access;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import com.thomsonreuters.ema.access.DirectoryServiceStore.ServiceIdInteger;
import com.thomsonreuters.ema.access.OmmLoggerClient.Severity;
import com.thomsonreuters.ema.rdm.EmaRdm;
import com.thomsonreuters.upa.codec.Buffer;
import com.thomsonreuters.upa.codec.CloseMsg;
import com.thomsonreuters.upa.codec.CodecFactory;
import com.thomsonreuters.upa.codec.CodecReturnCodes;
import com.thomsonreuters.upa.codec.DataDictionary;
import com.thomsonreuters.upa.codec.DataStates;
import com.thomsonreuters.upa.codec.DataTypes;
import com.thomsonreuters.upa.codec.DecodeIterator;
import com.thomsonreuters.upa.codec.EncodeIterator;
import com.thomsonreuters.upa.codec.Int;
import com.thomsonreuters.upa.codec.Msg;
import com.thomsonreuters.upa.codec.MsgClasses;
import com.thomsonreuters.upa.codec.MsgKey;
import com.thomsonreuters.upa.codec.MsgKeyFlags;
import com.thomsonreuters.upa.codec.RefreshMsg;
import com.thomsonreuters.upa.codec.RequestMsg;
import com.thomsonreuters.upa.codec.State;
import com.thomsonreuters.upa.codec.StateCodes;
import com.thomsonreuters.upa.codec.StatusMsg;
import com.thomsonreuters.upa.codec.StreamStates;
import com.thomsonreuters.upa.rdm.DomainTypes;
import com.thomsonreuters.upa.valueadd.domainrep.rdm.dictionary.DictionaryRefresh;
import com.thomsonreuters.upa.valueadd.domainrep.rdm.dictionary.DictionaryRequest;
import com.thomsonreuters.upa.valueadd.domainrep.rdm.dictionary.DictionaryStatus;
import com.thomsonreuters.upa.valueadd.reactor.RDMDictionaryMsgCallback;
import com.thomsonreuters.upa.valueadd.reactor.RDMDictionaryMsgEvent;
import com.thomsonreuters.upa.valueadd.reactor.ReactorCallbackReturnCodes;
import com.thomsonreuters.upa.valueadd.reactor.ReactorChannel;
import com.thomsonreuters.upa.valueadd.reactor.ReactorErrorInfo;
import com.thomsonreuters.upa.valueadd.reactor.ReactorReturnCodes;
import com.thomsonreuters.upa.valueadd.reactor.ReactorSubmitOptions;
class DictionaryCallbackClient extends CallbackClient implements RDMDictionaryMsgCallback
{
private static final String CLIENT_NAME = "DictionaryCallbackClient";
private static final int MAX_DICTIONARY_BUFFER_SIZE = 448000;
protected static final String DICTIONARY_RWFFID = "RWFFld";
protected static final String DICTIONARY_RWFENUM = "RWFEnum";
private List> _channelDictList;
private List> _channelDictPool;
private com.thomsonreuters.upa.codec.DataDictionary _rsslLocalDictionary;
private com.thomsonreuters.upa.codec.Buffer _rsslEncBuffer;
private com.thomsonreuters.upa.transport.Error _rsslError;
private com.thomsonreuters.upa.codec.Int _rsslCurrentFid;
private OmmBaseImpl _ommBaseImpl;
DictionaryCallbackClient(OmmBaseImpl baseImpl)
{
super(baseImpl, CLIENT_NAME);
_ommBaseImpl = baseImpl;
}
void initialize()
{
if (_ommBaseImpl.activeConfig().rsslFldDictRequest != null && _ommBaseImpl.activeConfig().rsslEnumDictRequest != null)
_ommBaseImpl.activeConfig().dictionaryConfig.isLocalDictionary = false;
else if (_ommBaseImpl.activeConfig().rsslFldDictRequest != null && _ommBaseImpl.activeConfig().rsslEnumDictRequest == null)
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Invalid dictionary configuration was specified through the addAdminMsg() method")
.append(OmmLoggerClient.CR)
.append("Enumeration type definition request message was not populated.");
if (_baseImpl.loggerClient().isErrorEnabled())
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(CLIENT_NAME, temp.toString(),
Severity.ERROR).toString());
throw (_ommBaseImpl.ommIUExcept().message(temp.toString()));
}
else if (_ommBaseImpl.activeConfig().rsslFldDictRequest == null && _ommBaseImpl.activeConfig().rsslEnumDictRequest != null)
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Invalid dictionary configuration was specified through the addAdminMsg() method")
.append(OmmLoggerClient.CR)
.append("RDM Field Dictionary request message was not populated.");
if (_baseImpl.loggerClient().isErrorEnabled())
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(CLIENT_NAME, temp.toString(),
Severity.ERROR).toString());
throw (_ommBaseImpl.ommIUExcept().message(temp.toString()));
}
if (_ommBaseImpl.activeConfig().dictionaryConfig.isLocalDictionary)
loadDictionaryFromFile();
else
{
_channelDictList = new ArrayList<>();
_channelDictPool = new ArrayList<>();
_channelDictPool.add(new ChannelDictionary(_ommBaseImpl));
}
}
@SuppressWarnings("unchecked")
@Override
public int rdmDictionaryMsgCallback(RDMDictionaryMsgEvent event)
{
_baseImpl.eventReceived();
if (_channelDictList != null)
{
for (ChannelDictionary entry : _channelDictList)
{
if (entry == event.streamInfo().userSpecObject())
{
return entry.processCallback(event);
}
}
}
return processCallback(event,(DictionaryItem) (event.streamInfo().userSpecObject()));
}
int processCallback(RDMDictionaryMsgEvent event, DictionaryItem item)
{
Msg msg = event.msg();
ReactorChannel rsslChannel = event.reactorChannel();
if (msg == null)
{
if (_baseImpl.loggerClient().isErrorEnabled())
{
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(DictionaryCallbackClient.CLIENT_NAME,
"Internal error. Received RsslRDMDictionaryMsgEvent with no RsslRDMDictionaryMsg in DictionaryCallbackClient.processCallback()", Severity.ERROR));
}
return ReactorCallbackReturnCodes.SUCCESS;
}
switch (msg.msgClass())
{
case MsgClasses.REFRESH:
{
if (_refreshMsg == null)
_refreshMsg = new RefreshMsgImpl(_baseImpl.objManager());
_refreshMsg.decode(msg, rsslChannel.majorVersion(), rsslChannel.minorVersion(), null);
processRefreshMsg(_refreshMsg, item );
return ReactorCallbackReturnCodes.SUCCESS;
}
case MsgClasses.STATUS:
{
if (_statusMsg == null)
_statusMsg = new StatusMsgImpl(_baseImpl.objManager());
_statusMsg.decode(msg, rsslChannel.majorVersion(), rsslChannel.minorVersion(), null );
processStatusMsg(_statusMsg, item );
return ReactorCallbackReturnCodes.SUCCESS;
}
default:
{
if (_baseImpl.loggerClient().isErrorEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Received unknown RDMDictionary message type").append(OmmLoggerClient.CR)
.append("message type ").append(msg.msgClass()).append(OmmLoggerClient.CR)
.append("streamId ").append(msg.streamId()).append(OmmLoggerClient.CR);
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(DictionaryCallbackClient.CLIENT_NAME, temp.toString(), Severity.ERROR));
}
break;
}
}
return ReactorCallbackReturnCodes.SUCCESS;
}
void loadDictionaryFromFile()
{
if (_rsslLocalDictionary == null)
_rsslLocalDictionary = CodecFactory.createDataDictionary();
else
_rsslLocalDictionary.clear();
rsslError();
if (_rsslLocalDictionary.loadFieldDictionary(_ommBaseImpl.activeConfig().dictionaryConfig.rdmfieldDictionaryFileName, _rsslError) < 0)
{
StringBuilder temp = _baseImpl.strBuilder();
if (_baseImpl.loggerClient().isErrorEnabled())
{
temp.append("Unable to load RDMFieldDictionary from file named ")
.append(_ommBaseImpl.activeConfig().dictionaryConfig.rdmfieldDictionaryFileName)
.append(OmmLoggerClient.CR)
.append("Current working directory ")
.append(System.getProperty("user.dir"))
.append(OmmLoggerClient.CR)
.append("Error text ")
.append(_rsslError.toString());
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(CLIENT_NAME, temp.toString(),
Severity.ERROR).toString());
}
_baseImpl.handleInvalidUsage(temp.toString());
return;
}
if (_rsslLocalDictionary.loadEnumTypeDictionary(_ommBaseImpl.activeConfig().dictionaryConfig.enumtypeDefFileName, _rsslError) < 0)
{
StringBuilder temp = _baseImpl.strBuilder();
if (_baseImpl.loggerClient().isErrorEnabled())
{
temp.append(_ommBaseImpl.activeConfig().dictionaryConfig.enumtypeDefFileName)
.append(OmmLoggerClient.CR)
.append("Current working directory ")
.append(System.getProperty("user.dir"))
.append(OmmLoggerClient.CR)
.append("Error text ")
.append(_rsslError.toString());
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(CLIENT_NAME, temp.toString(),
Severity.ERROR).toString());
}
_baseImpl.handleInvalidUsage(temp.toString());
return;
}
if (_baseImpl.loggerClient().isTraceEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Successfully loaded local dictionaries: ")
.append(OmmLoggerClient.CR)
.append("RDMFieldDictionary file named ")
.append(_ommBaseImpl.activeConfig().dictionaryConfig.rdmfieldDictionaryFileName)
.append(OmmLoggerClient.CR)
.append("EnumTypeDef file named ")
.append(_ommBaseImpl.activeConfig().dictionaryConfig.enumtypeDefFileName);
_baseImpl.loggerClient().trace(_baseImpl.formatLogMessage(CLIENT_NAME, temp.toString(),
Severity.TRACE).toString());
}
}
void processRefreshMsg(RefreshMsgImpl refreshMsg, DictionaryItem dictItem)
{
if ( refreshMsg.hasServiceId() )
{
specifyServiceNameFromId(refreshMsg);
}
_eventImpl._item = dictItem;
notifyOnAllMsg(refreshMsg);
notifyOnRefreshMsg();
if (refreshMsg.state().streamState() == OmmState.StreamState.NON_STREAMING)
{
if (refreshMsg.complete())
_eventImpl._item.remove();
}
else if (refreshMsg.state().streamState() != OmmState.StreamState.OPEN)
_eventImpl._item.remove();
return;
}
void processStatusMsg(StatusMsgImpl statusMsg, DictionaryItem dictItem)
{
if ( statusMsg.hasServiceId() )
{
specifyServiceNameFromId(statusMsg);
}
_eventImpl._item = dictItem;
notifyOnAllMsg(statusMsg);
notifyOnStatusMsg();
if (statusMsg.state().streamState() != OmmState.StreamState.OPEN)
_eventImpl._item.remove();
return;
}
private void specifyServiceNameFromId(MsgImpl msgImpl)
{
Directory directory = _ommBaseImpl.directoryCallbackClient().directory(msgImpl._rsslMsg.msgKey().serviceId());
if ( directory != null )
{
int flags = msgImpl._rsslMsg.msgKey().flags();
flags &= ~MsgKeyFlags.HAS_SERVICE_ID;
msgImpl._rsslMsg.msgKey().flags(flags);
msgImpl.msgServiceName(directory.serviceName());
msgImpl._rsslMsg.msgKey().flags( flags | MsgKeyFlags.HAS_SERVICE_ID);
}
}
ChannelDictionary pollChannelDict(OmmBaseImpl baseImpl)
{
if (_channelDictPool != null && !_channelDictPool.isEmpty())
return (_channelDictPool.get(0).clear());
else
return (new ChannelDictionary(baseImpl));
}
void returnToChannelDictPool(ChannelDictionary channelDict)
{
_channelDictPool.add(channelDict);
}
DataDictionary defaultRsslDictionary()
{
if (_channelDictList != null && !_channelDictList.isEmpty())
{
if (_channelDictList.get(0).isLoaded())
return _channelDictList.get(0).rsslDictionary();
}
else
return _rsslLocalDictionary;
return null;
}
int fldStreamId()
{
if (_channelDictList != null && !_channelDictList.isEmpty())
return _channelDictList.get(0).fldStreamId();
else
return 3;
}
int enumStreamId()
{
if (_channelDictList != null && !_channelDictList.isEmpty())
return _channelDictList.get(0).enumStreamId();
else
return 4;
}
List< ChannelDictionary > channelDictionaryList()
{
return _channelDictList;
}
DictionaryItem dictionaryItem(ReqMsg reqMsg , T client , Object obj)
{
return null;
}
boolean downloadDictionary(Directory directory)
{
if (_ommBaseImpl.activeConfig().dictionaryConfig.isLocalDictionary)
{
if (_rsslLocalDictionary != null && _rsslLocalDictionary.numberOfEntries() > 0)
directory.channelInfo().rsslDictionary(_rsslLocalDictionary);
return true;
}
if (directory.channelInfo().rsslDictionary() != null || _ommBaseImpl.activeConfig().dictionaryConfig.isLocalDictionary)
return true;
if (_ommBaseImpl.activeConfig().rsslFldDictRequest != null && _ommBaseImpl.activeConfig().rsslEnumDictRequest != null)
{
if (_ommBaseImpl.activeConfig().rsslFldDictRequest.serviceId() == directory.service().serviceId() ||
( _ommBaseImpl.activeConfig().fldDictReqServiceName != null && _ommBaseImpl.activeConfig().fldDictReqServiceName.equals(directory.serviceName())))
downloadDictionaryFromService(directory);
return true;
}
com.thomsonreuters.upa.codec.RequestMsg rsslRequestMsg = rsslRequestMsg();
rsslRequestMsg.domainType(DomainTypes.DICTIONARY);
rsslRequestMsg.containerType(com.thomsonreuters.upa.codec.DataTypes.NO_DATA);
rsslRequestMsg.applyStreaming();
MsgKey msgKey = rsslRequestMsg.msgKey();
msgKey.applyHasName();
msgKey.applyHasFilter();
msgKey.filter(com.thomsonreuters.upa.rdm.Dictionary.VerbosityValues.NORMAL);
ChannelDictionary dictionary = pollChannelDict(_ommBaseImpl);
dictionary.channelInfo(directory.channelInfo());
ReactorSubmitOptions rsslSubmitOptions = _ommBaseImpl.rsslSubmitOptions();
ReactorErrorInfo rsslErrorInfo = _ommBaseImpl.rsslErrorInfo();
ReactorChannel rsslChannel = directory.channelInfo().rsslReactorChannel();
rsslSubmitOptions.serviceName(directory.serviceName());
rsslSubmitOptions.requestMsgOptions().userSpecObj(dictionary);
int streamId = 3;
List dictionariesUsed = directory.service().info().dictionariesUsedList();
for (String dictName : dictionariesUsed)
{
msgKey.name().data(dictName);
rsslRequestMsg.streamId(streamId++);
rsslErrorInfo.clear();
if (ReactorReturnCodes.SUCCESS > rsslChannel.submit(rsslRequestMsg, rsslSubmitOptions, rsslErrorInfo))
{
if (_baseImpl.loggerClient().isErrorEnabled())
{
com.thomsonreuters.upa.transport.Error error = rsslErrorInfo.error();
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Internal error: rsslChannel.submit() failed").append(OmmLoggerClient.CR)
.append(directory.channelInfo().toString()).append(OmmLoggerClient.CR)
.append("RsslChannel ").append(Integer.toHexString(error.channel() != null ? error.channel().hashCode() : 0)).append(OmmLoggerClient.CR)
.append("Error Id ").append(error.errorId()).append(OmmLoggerClient.CR)
.append("Internal sysError ").append(error.sysError()).append(OmmLoggerClient.CR)
.append("Error Location ").append(rsslErrorInfo.location()).append(OmmLoggerClient.CR)
.append("Error Text ").append(error.text());
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(CLIENT_NAME, temp.toString(),
Severity.ERROR).toString());
returnToChannelDictPool(dictionary);
}
return false;
}
else
{
if (_baseImpl.loggerClient().isTraceEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Requested Dictionary ")
.append(dictName).append(OmmLoggerClient.CR)
.append("from Service ").append(directory.serviceName()).append(OmmLoggerClient.CR)
.append("on Channel ").append(OmmLoggerClient.CR)
.append(directory.channelInfo().toString());
_baseImpl.loggerClient().trace(_baseImpl.formatLogMessage(CLIENT_NAME, temp.toString(),
Severity.TRACE).toString());
}
}
}
_channelDictList.add(dictionary);
return true;
}
boolean downloadDictionaryFromService(Directory directory)
{
com.thomsonreuters.upa.codec.RequestMsg rsslRequestMsg = rsslRequestMsg();
rsslRequestMsg.domainType(DomainTypes.DICTIONARY);
rsslRequestMsg.containerType(com.thomsonreuters.upa.codec.DataTypes.NO_DATA);
DictionaryRequest rsslDictRequest = _ommBaseImpl.activeConfig().rsslFldDictRequest;
if (rsslDictRequest.checkStreaming())
rsslRequestMsg.applyStreaming();
MsgKey msgKey = rsslRequestMsg.msgKey();
msgKey.applyHasName();
msgKey.applyHasFilter();
msgKey.filter(rsslDictRequest.verbosity());
msgKey.name(rsslDictRequest.dictionaryName());
rsslRequestMsg.streamId(3);
ChannelDictionary dictionary = pollChannelDict(_ommBaseImpl);
dictionary.channelInfo(directory.channelInfo());
ReactorSubmitOptions rsslSubmitOptions = _ommBaseImpl.rsslSubmitOptions();
ReactorErrorInfo rsslErrorInfo = _ommBaseImpl.rsslErrorInfo();
ReactorChannel rsslChannel = directory.channelInfo().rsslReactorChannel();
rsslSubmitOptions.serviceName(directory.serviceName());
rsslSubmitOptions.requestMsgOptions().userSpecObj(dictionary);
rsslErrorInfo.clear();
if (ReactorReturnCodes.SUCCESS > rsslChannel.submit(rsslRequestMsg, rsslSubmitOptions, rsslErrorInfo))
{
if (_baseImpl.loggerClient().isErrorEnabled())
{
com.thomsonreuters.upa.transport.Error error = rsslErrorInfo.error();
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Internal error: rsslChannel.submit() failed").append(OmmLoggerClient.CR)
.append(directory.channelInfo().toString()).append(OmmLoggerClient.CR)
.append("RsslChannel ").append(Integer.toHexString(error.channel() != null ? error.channel().hashCode() : 0)).append(OmmLoggerClient.CR)
.append("Error Id ").append(error.errorId()).append(OmmLoggerClient.CR)
.append("Internal sysError ").append(error.sysError()).append(OmmLoggerClient.CR)
.append("Error Location ").append(rsslErrorInfo.location()).append(OmmLoggerClient.CR)
.append("Error Text ").append(error.text());
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(CLIENT_NAME, temp.toString(),
Severity.ERROR).toString());
returnToChannelDictPool(dictionary);
}
return false;
}
else
{
if (_baseImpl.loggerClient().isTraceEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Requested Dictionary ")
.append(rsslDictRequest.dictionaryName().toString()).append(OmmLoggerClient.CR)
.append("from Service ").append(directory.serviceName()).append(OmmLoggerClient.CR)
.append("on Channel ").append(OmmLoggerClient.CR)
.append(directory.channelInfo().toString());
_baseImpl.loggerClient().trace(_baseImpl.formatLogMessage(CLIENT_NAME, temp.toString(),
Severity.TRACE).toString());
}
}
rsslRequestMsg.clear();
rsslRequestMsg.msgClass(MsgClasses.REQUEST);
rsslRequestMsg.domainType(DomainTypes.DICTIONARY);
rsslRequestMsg.containerType(com.thomsonreuters.upa.codec.DataTypes.NO_DATA);
DictionaryRequest rsslEnumDictRequest = _ommBaseImpl.activeConfig().rsslEnumDictRequest;
if (rsslEnumDictRequest.checkStreaming())
rsslRequestMsg.applyStreaming();
msgKey = rsslRequestMsg.msgKey();
msgKey.applyHasName();
msgKey.applyHasFilter();
msgKey.filter(rsslEnumDictRequest.verbosity());
msgKey.name(rsslEnumDictRequest.dictionaryName());
rsslRequestMsg.streamId(4);
rsslErrorInfo.clear();
if (ReactorReturnCodes.SUCCESS > rsslChannel.submit(rsslRequestMsg, rsslSubmitOptions, rsslErrorInfo))
{
if (_baseImpl.loggerClient().isErrorEnabled())
{
com.thomsonreuters.upa.transport.Error error = rsslErrorInfo.error();
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Internal error: rsslChannel.submit() failed").append(OmmLoggerClient.CR)
.append(directory.channelInfo().toString()).append(OmmLoggerClient.CR)
.append("RsslChannel ").append(Integer.toHexString(error.channel() != null ? error.channel().hashCode() : 0)).append(OmmLoggerClient.CR)
.append("Error Id ").append(error.errorId()).append(OmmLoggerClient.CR)
.append("Internal sysError ").append(error.sysError()).append(OmmLoggerClient.CR)
.append("Error Location ").append(rsslErrorInfo.location()).append(OmmLoggerClient.CR)
.append("Error Text ").append(error.text());
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(CLIENT_NAME, temp.toString(),
Severity.ERROR).toString());
returnToChannelDictPool(dictionary);
}
return false;
}
else
{
if (_baseImpl.loggerClient().isTraceEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Requested Dictionary ")
.append(rsslDictRequest.dictionaryName().toString()).append(OmmLoggerClient.CR)
.append("from Service ").append(directory.serviceName()).append(OmmLoggerClient.CR)
.append("on Channel ").append(OmmLoggerClient.CR)
.append(directory.channelInfo().toString());
_baseImpl.loggerClient().trace(_baseImpl.formatLogMessage(CLIENT_NAME, temp.toString(),
Severity.TRACE).toString());
}
}
_channelDictList.add(dictionary);
return true;
}
boolean isDictionaryReady()
{
if (_rsslLocalDictionary != null && _rsslLocalDictionary.numberOfEntries() > 0
&& _rsslLocalDictionary.enumTableCount() > 0)
return true;
else
{
if (_channelDictList == null || _channelDictList.isEmpty())
return false;
for (ChannelDictionary entry : _channelDictList)
{
if (!(entry.isLoaded()))
return false;
}
return true;
}
}
boolean isLocalDictionary()
{
return _rsslLocalDictionary == null ? false : true;
}
Int rsslCurrentFid()
{
if (_rsslCurrentFid == null)
_rsslCurrentFid = CodecFactory.createInt();
else
_rsslCurrentFid.clear();
return _rsslCurrentFid;
}
Buffer rsslDictEncBuffer()
{
if (_rsslEncBuffer == null)
{
_rsslEncBuffer = CodecFactory.createBuffer();
_rsslEncBuffer.data(ByteBuffer.allocate(MAX_DICTIONARY_BUFFER_SIZE));
}
else
{
ByteBuffer byteBuf = _rsslEncBuffer.data();
byteBuf.clear();
_rsslEncBuffer.data(byteBuf, 0, byteBuf.capacity());
}
return _rsslEncBuffer;
}
com.thomsonreuters.upa.transport.Error rsslError()
{
if (_rsslError == null)
_rsslError = com.thomsonreuters.upa.transport.TransportFactory.createError();
else
_rsslError.clear();
return _rsslError;
}
}
class DictionaryCallbackClientConsumer extends DictionaryCallbackClient
{
DictionaryCallbackClientConsumer(OmmBaseImpl baseImpl) {
super(baseImpl);
}
@Override
void notifyOnAllMsg(com.thomsonreuters.ema.access.Msg msg)
{
_eventImpl._item.client().onAllMsg(msg, _eventImpl);
}
@Override
void notifyOnRefreshMsg()
{
_eventImpl._item.client().onRefreshMsg(_refreshMsg, _eventImpl);
}
@Override
void notifyOnStatusMsg()
{
_eventImpl._item.client().onStatusMsg(_statusMsg, _eventImpl);
}
}
class DictionaryCallbackClientProvider extends DictionaryCallbackClient
{
DictionaryCallbackClientProvider(OmmBaseImpl baseImpl) {
super(baseImpl);
_eventImpl._ommProvider = (OmmProvider)baseImpl;
}
@Override
void notifyOnAllMsg(com.thomsonreuters.ema.access.Msg msg)
{
_eventImpl._item.client().onAllMsg(msg, _eventImpl);
}
@Override
void notifyOnRefreshMsg()
{
_eventImpl._item.client().onRefreshMsg(_refreshMsg, _eventImpl);
}
@Override
void notifyOnStatusMsg()
{
_eventImpl._item.client().onStatusMsg(_statusMsg, _eventImpl);
}
}
class ChannelDictionary
{
private static final String CLIENT_NAME = "ChannelDictionary";
private OmmBaseImpl _baseImpl;
private ChannelInfo _channelInfo;
private boolean _isFldLoaded;
private boolean _isEnumLoaded;
private int _fldStreamId;
private int _enumStreamId;
private ReentrantLock _channelDictLock;
private List> _listenerList;
private DataDictionary _rsslDictionary = CodecFactory.createDataDictionary();
ChannelDictionary(OmmBaseImpl baseImpl)
{
_baseImpl = baseImpl;
}
ChannelInfo channelInfo()
{
return _channelInfo;
}
ChannelDictionary channelInfo(ChannelInfo channelInfo)
{
_channelInfo = channelInfo;
_channelInfo.rsslDictionary(_rsslDictionary);
return this;
}
ChannelDictionary clear()
{
_channelInfo = null;
_isFldLoaded = false;
_isEnumLoaded = false;
_fldStreamId = 0;
_enumStreamId = 0;
_rsslDictionary.clear();
if (_listenerList != null && _listenerList.size() > 0)
{
for (DictionaryItem entry : _listenerList)
{
entry.returnToPool();
}
_listenerList.clear();
}
return this;
}
DataDictionary rsslDictionary()
{
return _rsslDictionary;
}
boolean isLoaded()
{
return _isEnumLoaded && _isFldLoaded;
}
int fldStreamId()
{
return _fldStreamId;
}
int enumStreamId()
{
return _enumStreamId;
}
ReentrantLock channelDictionaryLock()
{
if (_channelDictLock == null)
_channelDictLock = new java.util.concurrent.locks.ReentrantLock();
return _channelDictLock;
}
void addListener(DictionaryItem item)
{
if (_listenerList == null)
_listenerList = new ArrayList<>();
_listenerList.add(item);
}
void removeListener(DictionaryItem item)
{
if (_listenerList == null || _listenerList.isEmpty())
return;
_listenerList.remove(item);
}
void notifyStatusToListener(OmmBaseImpl baseImpl, com.thomsonreuters.upa.codec.State rsslStatus, int streamId)
{
channelDictionaryLock().lock();
if (_listenerList == null || _listenerList.isEmpty())
{
channelDictionaryLock().unlock();
return;
}
DictionaryItem dictItem = null;
ReactorChannel rsslChannel = baseImpl.rsslReactorChannel();
EncodeIterator rsslEncIter = baseImpl.rsslEncIter();
DictionaryCallbackClient dictCallbackClient = baseImpl.dictionaryCallbackClient();
StatusMsg rsslStatusMsg = dictCallbackClient.rsslStatusMsg();
Buffer rsslEncDictBuf;
int numOfListeners = _listenerList.size();
for(int index = 0 ; index < numOfListeners; index++)
{
dictItem = _listenerList.get(index);
if (dictItem.streamId() != streamId)
continue;
rsslStatusMsg.msgClass(MsgClasses.STATUS);
rsslStatusMsg.streamId(streamId);
rsslStatusMsg.domainType(DomainTypes.DICTIONARY);
rsslStatusMsg.containerType(DataTypes.NO_DATA);
rsslStatusMsg.applyHasState();
rsslStatusMsg.state().streamState(rsslStatus.streamState());
rsslStatusMsg.state().dataState(rsslStatus.dataState());
rsslStatusMsg.state().code(rsslStatus.code());
rsslStatusMsg.state().text(rsslStatus.text());
rsslStatusMsg.applyHasMsgKey();
rsslStatusMsg.msgKey().applyHasName();
rsslStatusMsg.msgKey().name().data(dictItem.name());
rsslEncIter.clear();
rsslEncDictBuf = dictCallbackClient.rsslDictEncBuffer();
int retCode = rsslEncIter.setBufferAndRWFVersion(rsslEncDictBuf, rsslChannel.majorVersion(), rsslChannel.minorVersion());
if (retCode != CodecReturnCodes.SUCCESS)
{
if (baseImpl.loggerClient().isErrorEnabled())
{
baseImpl.loggerClient().error(baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME,
"Internal error. Failed to set encode iterator with buffer in ChannelDictionary.notifyStatusToListener()",
Severity.ERROR));
}
return;
}
if ((retCode = rsslStatusMsg.encode(rsslEncIter)) != CodecReturnCodes.SUCCESS)
{
if (baseImpl.loggerClient().isErrorEnabled())
{
baseImpl.loggerClient().error(baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME,
"Internal error. Failed to encode msg in ChannelDictionary.notifyStatusToListener()",
Severity.ERROR));
}
return;
}
if (dictCallbackClient._statusMsg == null)
dictCallbackClient._statusMsg = new StatusMsgImpl(_baseImpl._objManager);
dictCallbackClient._statusMsg.decode(rsslEncDictBuf, rsslChannel.majorVersion(), rsslChannel.minorVersion(), null, null);
dictCallbackClient.processStatusMsg(dictCallbackClient._statusMsg, dictItem );
if (rsslStatus.streamState() != StreamStates.OPEN)
{
_listenerList.remove(index);
--index;
}
break;
}
channelDictionaryLock().unlock();
}
int processCallback(RDMDictionaryMsgEvent event)
{
Msg msg = event.msg();
ReactorChannel rsslChannel = event.reactorChannel();
ChannelInfo channelInfo = (ChannelInfo)rsslChannel.userSpecObj();
if (msg == null)
{
com.thomsonreuters.upa.transport.Error error = event.errorInfo().error();
if (_baseImpl.loggerClient().isErrorEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Received event without RDMDictionary message").append(OmmLoggerClient.CR)
.append("ChannelInfo ").append(OmmLoggerClient.CR)
.append(channelInfo.toString()).append(OmmLoggerClient.CR)
.append("RsslChannel ").append(Integer.toHexString(error.channel() != null ? error.channel().hashCode() : 0)).append(OmmLoggerClient.CR)
.append("Error Id ").append(error.errorId()).append(OmmLoggerClient.CR)
.append("Internal sysError ").append(error.sysError()).append(OmmLoggerClient.CR)
.append("Error Location ").append(event.errorInfo().location()).append(OmmLoggerClient.CR)
.append("Error Text ").append(error.text());
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME, temp.toString(), Severity.ERROR));
}
_baseImpl.closeRsslChannel(event.reactorChannel());
return ReactorCallbackReturnCodes.SUCCESS;
}
switch (msg.msgClass())
{
case MsgClasses.REFRESH:
{
com.thomsonreuters.upa.codec.RefreshMsg rsslMsg = (com.thomsonreuters.upa.codec.RefreshMsg)msg;
com.thomsonreuters.upa.codec.State state = rsslMsg.state();
if (state.streamState() != StreamStates.OPEN && state.streamState() != StreamStates.NON_STREAMING)
{
if (_baseImpl.loggerClient().isErrorEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("RDMDictionary stream was closed with refresh message").append(OmmLoggerClient.CR)
.append("ChannelInfo").append(OmmLoggerClient.CR)
.append(channelInfo.toString()).append(OmmLoggerClient.CR)
.append("Reason ").append(state.toString());
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME, temp.toString(), Severity.ERROR));
}
break;
}
else if (state.dataState() == DataStates.SUSPECT)
{
if (_baseImpl.loggerClient().isWarnEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("RDMDictionary stream state was changed to suspect with refresh message").append(OmmLoggerClient.CR)
.append("ChannelInfo").append(OmmLoggerClient.CR)
.append(channelInfo.toString()).append(OmmLoggerClient.CR)
.append("Reason ").append(state.toString());
_baseImpl.loggerClient().warn(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME, temp.toString(), Severity.WARNING));
}
break;
}
if (_baseImpl.loggerClient().isTraceEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Received RDMDictionary refresh message").append(OmmLoggerClient.CR)
.append("Dictionary name ").append(rsslMsg.msgKey().name().toString()).append(OmmLoggerClient.CR)
.append("streamId ").append(rsslMsg.streamId());
_baseImpl.loggerClient().trace(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME, temp.toString(), Severity.TRACE));
}
DictionaryRefresh rsslRefresh = (DictionaryRefresh)event.rdmDictionaryMsg();
if (rsslRefresh.checkHasInfo())
{
switch (rsslRefresh.dictionaryType())
{
case com.thomsonreuters.upa.rdm.Dictionary.Types.FIELD_DEFINITIONS :
{
if (_fldStreamId == 0)
_fldStreamId = rsslMsg.streamId();
else if (_fldStreamId != rsslMsg.streamId())
{
if (_baseImpl.loggerClient().isErrorEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Received RDMDictionary refresh message with FieldDefinitions but changed streamId")
.append(OmmLoggerClient.CR)
.append("Initial streamId ").append(_fldStreamId).append(OmmLoggerClient.CR)
.append("New streamId ").append(rsslMsg.streamId());
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME,
temp.toString(), Severity.ERROR));
}
return ReactorCallbackReturnCodes.SUCCESS;
}
break;
}
case com.thomsonreuters.upa.rdm.Dictionary.Types.ENUM_TABLES :
{
if (_enumStreamId == 0)
_enumStreamId = rsslMsg.streamId();
else if (_enumStreamId != rsslMsg.streamId())
{
if (_baseImpl.loggerClient().isErrorEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Received RDMDictionary refresh message with EnumTables but changed streamId")
.append(OmmLoggerClient.CR)
.append("Initial streamId ").append(_fldStreamId).append(OmmLoggerClient.CR)
.append("New streamId ").append(rsslMsg.streamId());
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME,
temp.toString(), Severity.ERROR));
}
return ReactorCallbackReturnCodes.SUCCESS;
}
break;
}
default:
{
if (_baseImpl.loggerClient().isErrorEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Received RDMDictionary message with unknown dictionary type").append(OmmLoggerClient.CR)
.append("Dictionary type ").append(rsslRefresh.dictionaryType());
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME,
temp.toString(), Severity.ERROR));
}
return ReactorCallbackReturnCodes.SUCCESS;
}
}
}
DecodeIterator dIter = _baseImpl.rsslDecIter();
dIter.clear();
if (CodecReturnCodes.SUCCESS != dIter.setBufferAndRWFVersion(rsslMsg.encodedDataBody(), rsslChannel.majorVersion(), rsslChannel.minorVersion()))
{
if (_baseImpl.loggerClient().isErrorEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Internal error: failed to set buffer while decoding dictionary").append(OmmLoggerClient.CR)
.append("Trying to set ").append(rsslChannel.majorVersion())
.append(".").append(rsslChannel.minorVersion());;
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME,
temp.toString(), Severity.ERROR));
}
return ReactorCallbackReturnCodes.SUCCESS;
}
com.thomsonreuters.upa.transport.Error rsslError = _baseImpl.dictionaryCallbackClient().rsslError();
if (_fldStreamId == rsslMsg.streamId())
{
if (_isFldLoaded == true && _isEnumLoaded == true)
_rsslDictionary.clear();
if (CodecReturnCodes.SUCCESS == _rsslDictionary.decodeFieldDictionary(dIter,
com.thomsonreuters.upa.rdm.Dictionary.VerbosityValues.VERBOSE,
rsslError))
{
if (rsslRefresh.checkRefreshComplete())
{
_isFldLoaded = true;
if (_baseImpl.loggerClient().isTraceEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Received RDMDictionary refresh complete message").append(OmmLoggerClient.CR)
.append("dictionary name ").append(rsslRefresh.dictionaryName().toString()).append(OmmLoggerClient.CR)
.append("streamId ").append(rsslMsg.streamId());
_baseImpl.loggerClient().trace(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME,
temp.toString(), Severity.TRACE));
}
}
else
_isFldLoaded = false;
}
else
{
_isFldLoaded = false;
if (_baseImpl.loggerClient().isErrorEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Internal error: failed to decode FieldDictionary").append(OmmLoggerClient.CR)
.append("Error text ").append(rsslError.text());
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME,
temp.toString(), Severity.ERROR));
}
return ReactorCallbackReturnCodes.SUCCESS;
}
}
else if (_enumStreamId == rsslMsg.streamId())
{
rsslError.clear();
if (CodecReturnCodes.SUCCESS == _rsslDictionary.decodeEnumTypeDictionary(dIter,
com.thomsonreuters.upa.rdm.Dictionary.VerbosityValues.VERBOSE, rsslError))
{
if (rsslRefresh.checkRefreshComplete())
{
_isEnumLoaded = true;
if (_baseImpl.loggerClient().isTraceEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Received RDMDictionary refresh complete message").append(OmmLoggerClient.CR)
.append("dictionary name ").append(rsslRefresh.dictionaryName().toString()).append(OmmLoggerClient.CR)
.append("streamId ").append(rsslMsg.streamId());
_baseImpl.loggerClient().trace(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME,
temp.toString(), Severity.TRACE));
}
}
else
_isEnumLoaded = false;
}
else
{
_isEnumLoaded = false;
if (_baseImpl.loggerClient().isErrorEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Internal error: failed to decode EnumTable dictionary").append(OmmLoggerClient.CR)
.append("Error text ").append(rsslError.text());
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME,
temp.toString(), Severity.ERROR));
}
return ReactorCallbackReturnCodes.SUCCESS;
}
}
else
{
if (_baseImpl.loggerClient().isErrorEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Received unexpected RDMDictionary refresh message on streamId ").append(OmmLoggerClient.CR)
.append(rsslMsg.streamId());
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME,
temp.toString(), Severity.ERROR));
}
return ReactorCallbackReturnCodes.SUCCESS;
}
break;
}
case MsgClasses.STATUS:
{
com.thomsonreuters.upa.codec.StatusMsg rsslMsg = (com.thomsonreuters.upa.codec.StatusMsg)msg;
DictionaryStatus rsslStatus = (DictionaryStatus)event.rdmDictionaryMsg();
if (rsslMsg.checkHasState())
{
State state =rsslMsg.state();
if (state.streamState() != StreamStates.OPEN)
{
if (_baseImpl.loggerClient().isWarnEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("RDMDictionary stream was closed with status message").append(OmmLoggerClient.CR)
.append("streamId ").append(rsslMsg.streamId()).append(OmmLoggerClient.CR)
.append("Reason ").append(state.toString());
_baseImpl.loggerClient().warn(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME, temp.toString(), Severity.WARNING));
}
notifyStatusToListener(_baseImpl, rsslStatus.state(), rsslMsg.streamId());
break;
}
else if (state.dataState() == DataStates.SUSPECT)
{
if (_baseImpl.loggerClient().isWarnEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("RDMDictionary stream state was changed to suspect with status message").append(OmmLoggerClient.CR)
.append("streamId ").append(rsslMsg.streamId()).append(OmmLoggerClient.CR)
.append("Reason ").append(state.toString());
_baseImpl.loggerClient().warn(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME, temp.toString(), Severity.WARNING));
}
notifyStatusToListener(_baseImpl, rsslStatus.state(), rsslMsg.streamId());
break;
}
if (_baseImpl.loggerClient().isTraceEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("RDMDictionary stream was open with status message").append(OmmLoggerClient.CR)
.append("streamId ").append(rsslMsg.streamId()).append(OmmLoggerClient.CR)
.append("Reason ").append(state.toString());
_baseImpl.loggerClient().trace(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME, temp.toString(), Severity.TRACE));
}
}
else
{
if (_baseImpl.loggerClient().isWarnEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Received RDMDictionary status message without the state").append(OmmLoggerClient.CR)
.append("streamId ").append(rsslMsg.streamId()).append(OmmLoggerClient.CR);
_baseImpl.loggerClient().warn(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME, temp.toString(), Severity.WARNING));
}
}
break;
}
default:
{
if (_baseImpl.loggerClient().isErrorEnabled())
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Received unknown RDMDictionary message type").append(OmmLoggerClient.CR)
.append("message type ").append(msg.msgClass()).append(OmmLoggerClient.CR)
.append("streamId ").append(msg.streamId()).append(OmmLoggerClient.CR);
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(ChannelDictionary.CLIENT_NAME, temp.toString(), Severity.ERROR));
}
break;
}
}
return ReactorCallbackReturnCodes.SUCCESS;
}
}
class DictionaryItem extends SingleItem implements TimeoutClient
{
private static final String CLIENT_NAME = "DictionaryItem";
private int _rsslFilter;
private int _currentFid;
private boolean _needRemoved;
private boolean _removed;
private String _name;
DictionaryItem(OmmBaseImpl baseImpl, T client, Object closure)
{
super(baseImpl, client, closure, null);
_rsslFilter = 0;
_currentFid = 0;
_needRemoved = false;
_removed = false;
}
@Override
void reset(OmmBaseImpl baseImpl, T client, Object closure, Item item)
{
super.reset(baseImpl, client, closure, null);
_rsslFilter = 0;
_currentFid = 0;
_needRemoved = false;
}
@Override
boolean open(ReqMsg reqMsg)
{
RequestMsg rsslReqMsg = ((ReqMsgImpl)reqMsg).rsslMsg();
_name = rsslReqMsg.msgKey().name().toString();
DictionaryCallbackClient dictCBClient = _baseImpl.dictionaryCallbackClient();
if (rsslReqMsg.msgKey().checkHasFilter())
_rsslFilter = (int)rsslReqMsg.msgKey().filter();
/* User is asking for a specific service's dictionary, submit the request to the Reactor */
if ( reqMsg.hasServiceName() || rsslReqMsg.msgKey().checkHasServiceId() )
return super.open( reqMsg );
else
{
/* This ensures that a valid handle is assigned to the request. */
_baseImpl._itemCallbackClient.addToItemMap(_baseImpl.nextLongId(), this);
DataDictionary rsslDictionary = dictCBClient.defaultRsslDictionary();
if (rsslDictionary != null)
{
/* EMA will generate the Dictionary from the cached values */
if (_name.equals(DictionaryCallbackClient.DICTIONARY_RWFFID))
{
_currentFid = rsslDictionary.minFid();
_streamId = dictCBClient.fldStreamId();
}
else if (_name.equals(DictionaryCallbackClient.DICTIONARY_RWFENUM))
{
_currentFid = 0;
_streamId = dictCBClient.enumStreamId();
}
else
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Invalid ReqMsg's name : ")
.append(_name)
.append("\nReqMsg's name must be \"").append(DictionaryCallbackClient.DICTIONARY_RWFFID)
.append("\" or \"").append(DictionaryCallbackClient.DICTIONARY_RWFENUM).append("\" for MMT_DICTIONARY domain type. ")
.append("Instance name='").append(_baseImpl.instanceName()).append("'.");
if (_baseImpl.loggerClient().isErrorEnabled())
{
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(DictionaryItem.CLIENT_NAME, temp.toString(), Severity.ERROR));
}
_baseImpl.handleInvalidUsage( temp.toString() );
return false;
}
if (!dictCBClient.isLocalDictionary())
{
ChannelDictionary channelDict = dictCBClient.channelDictionaryList().get(0);
channelDict.channelDictionaryLock().lock();
channelDict.addListener(this);
channelDict.channelDictionaryLock().unlock();
}
_baseImpl.addTimeoutEvent(500, this);
return true;
}
else
{
if (_baseImpl.loggerClient().isErrorEnabled())
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(DictionaryItem.CLIENT_NAME,
"Ema must have to receive a dictionary before open a dictionary request",
Severity.ERROR));
return false;
}
}
}
@Override
boolean modify(ReqMsg reqMsg)
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Invalid attempt to modify dictionary stream. ").append("Instance name='")
.append(_baseImpl.instanceName()).append("'.");
if (_baseImpl.loggerClient().isErrorEnabled())
_baseImpl.loggerClient()
.error(_baseImpl.formatLogMessage(DictionaryItem.CLIENT_NAME, temp.toString(), Severity.ERROR));
_baseImpl.handleInvalidUsage(temp.toString());
return false;
}
@Override
boolean submit(PostMsg postMsg)
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Invalid attempt to submit PostMsg on dictionary stream. ").append("Instance name='")
.append(_baseImpl.instanceName()).append("'.");
if (_baseImpl.loggerClient().isErrorEnabled())
_baseImpl.loggerClient()
.error(_baseImpl.formatLogMessage(DictionaryItem.CLIENT_NAME, temp.toString(), Severity.ERROR));
_baseImpl.handleInvalidUsage(temp.toString());
return false;
}
@Override
boolean submit(GenericMsg genericMsg)
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Invalid attempt to submit GenericMsg on dictionary stream. ").append("Instance name='")
.append(_baseImpl.instanceName()).append("'.");
if (_baseImpl.loggerClient().isErrorEnabled())
_baseImpl.loggerClient()
.error(_baseImpl.formatLogMessage(DictionaryItem.CLIENT_NAME, temp.toString(), Severity.ERROR));
_baseImpl.handleInvalidUsage(temp.toString());
return false;
}
@Override
boolean close()
{
if (_streamId > 4)
{
super.close();
}
else
{
if (_needRemoved == false)
{
_needRemoved = true;
DictionaryCallbackClient dictCBClient = _baseImpl.dictionaryCallbackClient();
if (dictCBClient.channelDictionaryList() != null && !dictCBClient.channelDictionaryList().isEmpty())
{
ChannelDictionary channelDict = dictCBClient.channelDictionaryList().get(0);
channelDict.channelDictionaryLock().lock();
channelDict.removeListener(this);
channelDict.channelDictionaryLock().unlock();
}
_baseImpl.addTimeoutEvent(2000, this);
}
}
return true;
}
@Override
void remove()
{
if (!_needRemoved)
{
_needRemoved = true;
_baseImpl.addTimeoutEvent(2000, this);
}
}
@Override
public void handleTimeoutEvent()
{
if (_needRemoved)
{
if(!_removed)
{
_baseImpl.itemCallbackClient().removeFromMap(this);
this.itemIdObj().returnToPool();
this.returnToPool();
_removed = true;
}
return;
}
DictionaryCallbackClient dictCallbackClient = _baseImpl.dictionaryCallbackClient();
DataDictionary rsslDictionary = dictCallbackClient.defaultRsslDictionary();
ReactorChannel rsslChannel = _baseImpl.rsslReactorChannel();
boolean firstPart = false;
int ret = CodecReturnCodes.FAILURE;
Buffer rsslDictEncBuffer = _baseImpl.dictionaryCallbackClient().rsslDictEncBuffer();
if (rsslDictionary != null && (rsslDictionary.enumTableCount() > 0 || rsslDictionary.numberOfEntries() > 0))
{
if (_name.equals(DictionaryCallbackClient.DICTIONARY_RWFFID))
{
if (_currentFid == rsslDictionary.minFid())
firstPart = true;
ret = encodeDataDictionaryResp( firstPart, rsslDictionary, rsslDictEncBuffer);
}
else if (_name.equals(DictionaryCallbackClient.DICTIONARY_RWFENUM))
{
if (_currentFid == 0)
firstPart = true;
ret = encodeDataDictionaryResp( firstPart, rsslDictionary, rsslDictEncBuffer);
}
if ((ret == CodecReturnCodes.SUCCESS) || (ret == CodecReturnCodes.DICT_PART_ENCODED))
{
if (dictCallbackClient._refreshMsg == null)
dictCallbackClient._refreshMsg = new RefreshMsgImpl(_baseImpl._objManager);
dictCallbackClient._refreshMsg.decode(rsslDictEncBuffer, rsslChannel.majorVersion(), rsslChannel.minorVersion(), null, null);
if (ret == CodecReturnCodes.SUCCESS)
dictCallbackClient._refreshMsg.complete(true);
dictCallbackClient.processRefreshMsg(dictCallbackClient._refreshMsg, this);
}
if (ret == CodecReturnCodes.DICT_PART_ENCODED)
{
_baseImpl.addTimeoutEvent(500, this);
return;
}
if (ret != CodecReturnCodes.SUCCESS)
{
EncodeIterator rsslEncIter = _baseImpl.rsslEncIter();
StatusMsg rsslStatusMsg = dictCallbackClient.rsslStatusMsg();
rsslStatusMsg.streamId(_streamId);
rsslStatusMsg.domainType(DomainTypes.DICTIONARY);
rsslStatusMsg.containerType(DataTypes.NO_DATA);
rsslStatusMsg.applyHasState();
rsslStatusMsg.state().streamState(StreamStates.CLOSED);
rsslStatusMsg.state().dataState(DataStates.SUSPECT);
rsslStatusMsg.state().code(StateCodes.NONE);
rsslStatusMsg.state().text().data("Failed to provide data dictionary: Internal error.");
rsslStatusMsg.applyHasMsgKey();
rsslStatusMsg.msgKey().applyHasName();
rsslStatusMsg.msgKey().name().data(_name);
rsslEncIter.clear();
int retCode = rsslEncIter.setBufferAndRWFVersion(rsslDictEncBuffer, rsslChannel.majorVersion(), rsslChannel.minorVersion());
if (retCode != CodecReturnCodes.SUCCESS)
{
if (_baseImpl.loggerClient().isErrorEnabled())
{
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(DictionaryItem.CLIENT_NAME,
"Internal error. Failed to set encode iterator RWF version in DictionatyItem.handleTimeoutEvent()",
Severity.ERROR));
}
return;
}
if ((retCode = rsslStatusMsg.encode(rsslEncIter)) != CodecReturnCodes.SUCCESS)
{
if (_baseImpl.loggerClient().isErrorEnabled())
{
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(DictionaryItem.CLIENT_NAME,
"Internal error. Failed to encode msg in DictionatyItem.handleTimeoutEvent()",
Severity.ERROR));
}
return;
}
if (dictCallbackClient._statusMsg == null)
dictCallbackClient._statusMsg = new StatusMsgImpl(_baseImpl._objManager);
dictCallbackClient._statusMsg.decode(rsslDictEncBuffer, rsslChannel.majorVersion(), rsslChannel.minorVersion(), null, null);
dictCallbackClient.processStatusMsg(dictCallbackClient._statusMsg, this);
return;
}
}
else
{
EncodeIterator rsslEncIter = _baseImpl.rsslEncIter();
StatusMsg rsslStatusMsg = dictCallbackClient.rsslStatusMsg();
rsslStatusMsg.streamId(_streamId);
rsslStatusMsg.domainType(DomainTypes.DICTIONARY);
rsslStatusMsg.containerType(DataTypes.NO_DATA);
rsslStatusMsg.applyHasState();
rsslStatusMsg.state().streamState(StreamStates.CLOSED_RECOVER);
rsslStatusMsg.state().dataState(DataStates.SUSPECT);
rsslStatusMsg.state().code(StateCodes.NONE);
rsslStatusMsg.state().text().data("Data dictionary is not ready to provide.");
rsslEncIter.clear();
int retCode = rsslEncIter.setBufferAndRWFVersion(rsslDictEncBuffer, rsslChannel.majorVersion(), rsslChannel.minorVersion());
if (retCode != CodecReturnCodes.SUCCESS)
{
if (_baseImpl.loggerClient().isErrorEnabled())
{
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(DictionaryItem.CLIENT_NAME,
"Internal error. Failed to set encode iterator RWF version in DictionatyItem.handleTimeoutEvent()",
Severity.ERROR));
}
return;
}
if ((retCode = rsslStatusMsg.encode(rsslEncIter)) != CodecReturnCodes.SUCCESS)
{
if (_baseImpl.loggerClient().isErrorEnabled())
{
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(DictionaryItem.CLIENT_NAME,
"Internal error. Failed to encode msg in DictionatyItem.handleTimeoutEvent()",
Severity.ERROR));
}
return;
}
if (dictCallbackClient._statusMsg == null)
dictCallbackClient._statusMsg = new StatusMsgImpl(_baseImpl._objManager);
dictCallbackClient._statusMsg.decode(rsslDictEncBuffer, rsslChannel.majorVersion(), rsslChannel.minorVersion(), null, null);
dictCallbackClient.processStatusMsg(dictCallbackClient._statusMsg, this);
return;
}
}
int currentFid()
{
return _currentFid;
}
String name()
{
return _name;
}
int rsslFilters()
{
return _rsslFilter;
}
int encodeDataDictionaryResp(boolean firstMultiRefresh, DataDictionary rsslDataDictionary, Buffer rsslDictEncBuffer)
{
ReactorChannel rsslChannel = _baseImpl.rsslReactorChannel();
EncodeIterator rsslEncIter = _baseImpl.rsslEncIter();
DictionaryCallbackClient dictCallbackClient = _baseImpl.dictionaryCallbackClient();
rsslEncIter.clear();
int retCode = rsslEncIter.setBufferAndRWFVersion(rsslDictEncBuffer, rsslChannel.majorVersion(), rsslChannel.minorVersion());
if (retCode != CodecReturnCodes.SUCCESS)
return retCode;
RefreshMsg rsslRefreshMsg = dictCallbackClient.rsslRefreshMsg();
com.thomsonreuters.upa.transport.Error rsslError = dictCallbackClient.rsslError();
rsslRefreshMsg.domainType(DomainTypes.DICTIONARY);
rsslRefreshMsg.containerType(DataTypes.SERIES);
rsslRefreshMsg.state().streamState(StreamStates.OPEN);
rsslRefreshMsg.state().dataState(DataStates.OK);
rsslRefreshMsg.state().code(StateCodes.NONE);
rsslRefreshMsg.applySolicited();
rsslRefreshMsg.applyHasMsgKey();
rsslRefreshMsg.msgKey().filter(_rsslFilter);
rsslRefreshMsg.msgKey().applyHasFilter();
if (firstMultiRefresh)
rsslRefreshMsg.applyClearCache();
rsslRefreshMsg.msgKey().applyHasName();
rsslRefreshMsg.msgKey().name().data(_name);
rsslRefreshMsg.streamId(_streamId);
Int rsslCurrentFid = dictCallbackClient.rsslCurrentFid();
rsslCurrentFid.value(_currentFid);
boolean complete = false;
if ((retCode = rsslRefreshMsg.encodeInit(rsslEncIter, 0)) < CodecReturnCodes.SUCCESS)
return retCode;
if (_name.equals(DictionaryCallbackClient.DICTIONARY_RWFFID))
{
retCode = rsslDataDictionary.encodeFieldDictionary(rsslEncIter, rsslCurrentFid, _rsslFilter, rsslError);
}
else if (_name.equals(DictionaryCallbackClient.DICTIONARY_RWFENUM))
{
retCode = rsslDataDictionary.encodeEnumTypeDictionaryAsMultiPart(rsslEncIter, rsslCurrentFid, _rsslFilter, rsslError);
}
else
return CodecReturnCodes.FAILURE;
if (retCode != CodecReturnCodes.SUCCESS)
{
if (retCode == CodecReturnCodes.DICT_PART_ENCODED)
_currentFid = (int)rsslCurrentFid.toLong();
else
return retCode;
}
else
{
complete = true;
}
if ((retCode = rsslRefreshMsg.encodeComplete(rsslEncIter, true)) < CodecReturnCodes.SUCCESS)
return retCode;
return complete ? CodecReturnCodes.SUCCESS : CodecReturnCodes.DICT_PART_ENCODED;
}
}
class NiProviderDictionaryItem extends SingleItem implements ProviderItem
{
private static final String CLIENT_NAME = "NiProviderDictionaryItem";
protected MsgKey _rsslMsgKey = CodecFactory.createMsgKey();
protected ItemWatchList _itemWatchList;
protected int _serviceId;
protected boolean _isPrivateStream;
protected boolean _specifiedServiceInReq;
private TimeoutEvent _reqTimeoutEvent;
private boolean _receivedInitResp;
NiProviderDictionaryItem(OmmBaseImpl baseImpl, T client, Object closure)
{
super(baseImpl, client, closure, null);
_itemWatchList = ((OmmNiProviderImpl)baseImpl).itemWatchList();
}
@Override
void reset(OmmBaseImpl baseImpl, T client, Object closure, Item item)
{
super.reset(baseImpl, client, closure, null);
_itemWatchList = ((OmmNiProviderImpl)baseImpl).itemWatchList();
}
@Override
boolean open(ReqMsg reqMsg)
{
ReqMsgImpl reqMsgImpl = ((ReqMsgImpl)reqMsg);
String serviceName = null;
if ( reqMsgImpl.hasServiceName() )
{
ServiceIdInteger serviceId = ((OmmNiProviderImpl)_baseImpl).directoryServiceStore().serviceId(reqMsgImpl.serviceName());
if ( serviceId == null )
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Service name of '")
.append(reqMsg.serviceName())
.append("' is not found.");
_baseImpl._itemCallbackClient.addToItemMap(_baseImpl.nextLongId(), this);
scheduleItemClosedStatus(_baseImpl.itemCallbackClient(),
this, ((ReqMsgImpl)reqMsg).rsslMsg(),
temp.toString(), reqMsg.serviceName());
return true;
}
else if (serviceId != null)
{
_serviceId = serviceId.value();
reqMsgImpl.rsslMsg().msgKey().applyHasServiceId();
reqMsgImpl.rsslMsg().msgKey().serviceId(_serviceId);
serviceName = reqMsgImpl.serviceName();
_specifiedServiceInReq = true;
}
}
else if ( reqMsgImpl.hasServiceId() )
{
serviceName = ((OmmNiProviderImpl)_baseImpl).directoryServiceStore().serviceName(reqMsgImpl.serviceId());
if ( serviceName == null )
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Service id of '")
.append(reqMsg.serviceId())
.append("' is not found.");
_baseImpl._itemCallbackClient.addToItemMap(LongIdGenerator.nextLongId(), this);
scheduleItemClosedStatus(_baseImpl.itemCallbackClient(),
this, ((ReqMsgImpl)reqMsg).rsslMsg(),
temp.toString(), null);
return true;
}
_serviceId = reqMsgImpl.serviceId();
_specifiedServiceInReq = true;
}
_isPrivateStream = reqMsgImpl.privateStream();
_directory = new Directory(serviceName);
_itemWatchList.addItem(this);
reqMsgImpl.rsslMsg().msgKey().copy(_rsslMsgKey);
return rsslSubmit(((ReqMsgImpl)reqMsg).rsslMsg());
}
@Override
void remove()
{
cancelReqTimerEvent();
super.remove();
((OmmNiProviderImpl)_baseImpl).returnProviderStreamId(_streamId);
_itemWatchList.removeItem(this);
}
@Override
boolean modify(com.thomsonreuters.ema.access.ReqMsg reqMsg)
{
if (_closedStatusClient != null) return false;
ReqMsgImpl reqMsgImpl = (ReqMsgImpl)reqMsg;
if ( reqMsgImpl.hasServiceName() )
{
if ( _specifiedServiceInReq && ( _directory != null ) && reqMsgImpl.serviceName().equals(_directory.serviceName()) )
{
reqMsgImpl.rsslMsg().msgKey().applyHasServiceId();
reqMsgImpl.rsslMsg().msgKey().serviceId(_serviceId);
}
else
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Service name of '")
.append(reqMsg.serviceName())
.append("' does not match existing request.").append("Instance name='")
.append(_baseImpl.instanceName()).append("'.");
if (_baseImpl.loggerClient().isErrorEnabled())
_baseImpl.loggerClient()
.error(_baseImpl.formatLogMessage(NiProviderDictionaryItem.CLIENT_NAME, temp.toString(), Severity.ERROR));
_baseImpl.handleInvalidUsage(temp.toString());
return false;
}
}
else if ( reqMsgImpl.hasServiceId() )
{
if ( !_specifiedServiceInReq || ( reqMsgImpl.serviceId() != _serviceId ) )
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Service id of '")
.append(reqMsg.serviceId())
.append("' does not match existing request.").append("Instance name='")
.append(_baseImpl.instanceName()).append("'.");
if (_baseImpl.loggerClient().isErrorEnabled())
_baseImpl.loggerClient()
.error(_baseImpl.formatLogMessage(NiProviderDictionaryItem.CLIENT_NAME, temp.toString(), Severity.ERROR));
_baseImpl.handleInvalidUsage(temp.toString());
return false;
}
}
else
{
if ( _specifiedServiceInReq )
{
reqMsgImpl.rsslMsg().msgKey().applyHasServiceId();
reqMsgImpl.rsslMsg().msgKey().serviceId(_serviceId);
}
}
if ( reqMsgImpl.hasName() )
{
if ( reqMsgImpl.name().equals(_rsslMsgKey.name().toString()) == false )
{
StringBuilder temp = _baseImpl.strBuilder();
temp.append("Name of '")
.append(reqMsgImpl.name())
.append("' does not match existing request.").append("Instance name='")
.append(_baseImpl.instanceName()).append("'.");
if (_baseImpl.loggerClient().isErrorEnabled())
_baseImpl.loggerClient()
.error(_baseImpl.formatLogMessage(NiProviderDictionaryItem.CLIENT_NAME, temp.toString(), Severity.ERROR));
_baseImpl.handleInvalidUsage(temp.toString());
return false;
}
}
else
{
reqMsgImpl.name(_rsslMsgKey.name().toString());
reqMsgImpl.nameType(_rsslMsgKey.nameType());
}
((ReqMsgImpl)reqMsg).rsslMsg().domainType(EmaRdm.MMT_DICTIONARY);
return super.modify(reqMsgImpl);
}
@Override
int getNextStreamId(int numOfItem) {
return ((OmmNiProviderImpl)_baseImpl).nextProviderStreamId();
}
@Override
boolean rsslSubmit(com.thomsonreuters.upa.codec.RequestMsg rsslRequestMsg)
{
ReactorSubmitOptions rsslSubmitOptions = _baseImpl.rsslSubmitOptions();
rsslSubmitOptions.serviceName(null);
int domainType = rsslRequestMsg.domainType();
if (_streamId == 0)
{
rsslRequestMsg.streamId(getNextStreamId(0));
_streamId = rsslRequestMsg.streamId();
_baseImpl._itemCallbackClient.addToMap(_baseImpl.nextLongId(), this);
}
else
rsslRequestMsg.streamId(_streamId);
if (_domainType == 0)
_domainType = domainType;
else
rsslRequestMsg.domainType(_domainType);
ReactorErrorInfo rsslErrorInfo = _baseImpl.rsslErrorInfo();
rsslErrorInfo.clear();
ReactorChannel rsslChannel = _baseImpl.loginCallbackClient().activeChannelInfo().rsslReactorChannel();
int ret;
if (ReactorReturnCodes.SUCCESS > (ret = rsslChannel.submit(rsslRequestMsg, rsslSubmitOptions, rsslErrorInfo)))
{
StringBuilder temp = _baseImpl.strBuilder();
if (_baseImpl.loggerClient().isErrorEnabled())
{
com.thomsonreuters.upa.transport.Error error = rsslErrorInfo.error();
temp.append("Internal error: rsslChannel.submit() failed in NiProviderDictionaryItem.submit(RequestMsg)")
.append("RsslChannel ").append(Integer.toHexString(error.channel() != null ? error.channel().hashCode() : 0))
.append(OmmLoggerClient.CR)
.append("Error Id ").append(error.errorId()).append(OmmLoggerClient.CR)
.append("Internal sysError ").append(error.sysError()).append(OmmLoggerClient.CR)
.append("Error Location ").append(rsslErrorInfo.location()).append(OmmLoggerClient.CR)
.append("Error Text ").append(error.text());
_baseImpl.loggerClient().error(_baseImpl.formatLogMessage(NiProviderDictionaryItem.CLIENT_NAME, temp.toString(), Severity.ERROR));
temp.setLength(0);
}
temp.append("Failed to open or modify item request. Reason: ")
.append(ReactorReturnCodes.toString(ret))
.append(". Error text: ")
.append(rsslErrorInfo.error().text());
_baseImpl.handleInvalidUsage(temp.toString());
return false;
}
int requestTimeout = ((OmmNiProviderImpl)_baseImpl).requestTimeout();
if ( requestTimeout > 0 )
{
cancelReqTimerEvent();
_reqTimeoutEvent = _baseImpl.addTimeoutEvent(requestTimeout * 1000, new ItemTimeOut( this ) );
}
return true;
}
@Override
boolean submit(com.thomsonreuters.ema.access.GenericMsg genericMsg)
{
return false;
}
public TimeoutEvent reqTimeoutEvent()
{
return _reqTimeoutEvent;
}
@Override
public void scheduleItemClosedRecoverableStatus(String statusText, boolean initiateTimeout) {
if (_closedStatusClient != null) return;
cancelReqTimerEvent();
_closedStatusClient = new ClosedStatusClient(_baseImpl.itemCallbackClient(), this, _rsslMsgKey, _isPrivateStream, statusText, _directory.serviceName());
if ( initiateTimeout )
_baseImpl.addTimeoutEvent(100, _closedStatusClient);
else
_closedStatusClient.handleTimeoutEvent();
}
@Override
public MsgKey rsslMsgKey() {
return _rsslMsgKey;
}
@Override
public void sendCloseMsg() {
CloseMsg rsslCloseMsg = _baseImpl.itemCallbackClient().rsslCloseMsg();
rsslCloseMsg.containerType(DataTypes.NO_DATA);
rsslCloseMsg.domainType(_domainType);
rsslSubmit(rsslCloseMsg);
}
@Override
public ClientSession clientSession() {
return null;
}
@Override
public int serviceId() {
return _serviceId;
}
@Override
int type()
{
return ItemType.NIPROVIDER_DICTIONARY_ITEM;
}
@Override
public boolean processInitialResp(RefreshMsg refreshMsg)
{
boolean result = true;
if ( _receivedInitResp == false )
{
if ( _domainType != refreshMsg.domainType() )
result = false;
_isPrivateStream = refreshMsg.checkPrivateStream();
if (!_rsslMsgKey.equals(refreshMsg.msgKey()) )
{
result = false;
}
_receivedInitResp = true;
}
return result;
}
@Override
public ItemWatchList itemWatchList()
{
return _itemWatchList;
}
@Override
public void cancelReqTimerEvent()
{
if ( _reqTimeoutEvent != null )
{
if ( _reqTimeoutEvent.cancelled() == false )
{
_reqTimeoutEvent.cancel();
}
}
}
@Override
public boolean requestWithService()
{
return _specifiedServiceInReq;
}
}
class IProviderDictionaryItem extends IProviderSingleItem
{
private boolean _receivedInitResp;
IProviderDictionaryItem(OmmServerBaseImpl baseImpl, OmmProviderClient client, Object closure)
{
super(baseImpl, client, closure, null);
}
@Override
void reset(OmmServerBaseImpl baseImpl, OmmProviderClient client, Object closure, Item item)
{
super.reset(baseImpl, client, closure, null);
}
@Override
int type()
{
return ItemType.IPROVIDER_DICTIONARY_ITEM;
}
@Override
boolean modify(com.thomsonreuters.ema.access.ReqMsg reqMsg)
{
if (_closedStatusClient != null) return false;
((ReqMsgImpl)reqMsg).rsslMsg().domainType(EmaRdm.MMT_DICTIONARY);
return super.modify(reqMsg);
}
@Override
public boolean processInitialResp(RefreshMsg refreshMsg)
{
boolean result = true;
if ( _receivedInitResp == false )
{
if ( _domainType != refreshMsg.domainType() )
result = false;
_isPrivateStream = refreshMsg.checkPrivateStream();
if (!_rsslMsgKey.equals(refreshMsg.msgKey()) )
{
result = false;
}
_receivedInitResp = true;
}
return result;
}
}