com.alachisoft.ncache.client.internal.caching.TopicImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ncache-professional-client Show documentation
Show all versions of ncache-professional-client Show documentation
NCache Professional client for java.
package com.alachisoft.ncache.client.internal.caching;
import Alachisoft.NCache.Common.*;
import Alachisoft.NCache.Common.BitSet;
import Alachisoft.NCache.Common.Enum.SubscriptionType;
import Alachisoft.NCache.Common.Enum.UserObjectType;
import Alachisoft.NCache.Common.Messaging.MessageMetaData;
import Alachisoft.NCache.Common.Messaging.SubscriptionIdentifier;
import Alachisoft.NCache.Common.Messaging.SubscriptionInfo;
import Alachisoft.NCache.Common.Stats.UsageStats;
import Alachisoft.NCache.Common.Threading.ThreadPool;
import Alachisoft.NCache.Common.Util.ReaderWriterLock;
import Alachisoft.NCache.Management.Statistics.StatisticsCounter;
import com.alachisoft.ncache.client.EventCacheItemWrapperInternal;
import com.alachisoft.ncache.client.EventUtil.MessageItemType;
import com.alachisoft.ncache.client.MessageItem;
import com.alachisoft.ncache.client.internal.messaging.MessageCollectionEventItem;
import com.alachisoft.ncache.client.internal.messaging.MessageEventItem;
import com.alachisoft.ncache.client.internal.messaging.MessageManager;
import com.alachisoft.ncache.client.internal.statistics.PerfStatsCollector;
import Alachisoft.NCache.Common.ErrorHandling.ErrorCodes;
import Alachisoft.NCache.Common.ErrorHandling.ErrorMessages;
import com.alachisoft.ncache.client.util.PayLoadDeserializationJson;
import com.alachisoft.ncache.runtime.caching.*;
import com.alachisoft.ncache.runtime.caching.messaging.*;
import com.alachisoft.ncache.runtime.exceptions.CacheException;
import com.alachisoft.ncache.runtime.exceptions.OperationFailedException;
import com.alachisoft.ncache.runtime.exceptions.runtime.OperationFailedRuntimeException;
import com.alachisoft.ncache.runtime.util.HelperFxn;
import com.alachisoft.ncache.runtime.util.NCDateTime;
import com.alachisoft.ncache.runtime.util.TimeSpan;
import java.io.IOException;
import java.text.ParseException;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicInteger;
import static Alachisoft.NCache.Common.Enum.SubscriptionType.*;
import static com.alachisoft.ncache.client.EventUtil.getMessageItemType;
public class TopicImpl implements Topic {
private final String topicName;
private final CacheImplBase cacheImpl;
private final String publisherId;
private final Object syncLock = new Object();
private final MessageManager parent;
private final ReaderWriterLock readerWriterLock;
private boolean isDisposed;
private int refPublisherCount;
private TimeSpan expiration = new TimeSpan(Long.MAX_VALUE);
private AtomicInteger refCount = new AtomicInteger(0);
private HashMap subscriptions;
private TopicListener deleteEventListener;
private TopicListener messageFailedEventListener;
private TopicSearchOptions _searchOptions = TopicSearchOptions.ByName;
private StatisticsCounter _perfStatsCollector;
private boolean _eventRegistered = false;
//#region Constructor
public TopicImpl(String topicName, CacheImplBase cacheImpl, StatisticsCounter perfStatsCollector,
MessageManager parent) {
this.topicName = topicName;
subscriptions = new HashMap();
this.cacheImpl = cacheImpl;
_perfStatsCollector = perfStatsCollector;
this.parent = parent;
this.publisherId = (new Shorter()).getGuidString();
this.readerWriterLock = new ReaderWriterLock();
}
public final TopicSearchOptions getSearchOptions() {
return _searchOptions;
}
public final void setSearchOptions(TopicSearchOptions value) {
this._searchOptions = value;
}
//endregion
//region Public Methods
@Override
public final TopicSubscription createSubscription(MessageReceivedListener messageReceivedListener) throws CacheException {
return createSubscription(messageReceivedListener, DeliveryMode.Sync);
}
private final TopicSubscription createSubscription(MessageReceivedListener messageReceivedListener, DeliveryMode deliveryMode) throws CacheException {
ValidateInput(messageReceivedListener);
String subscriptionName = new Shorter().getGuidString();
return RegisterSubscriptions(subscriptionName, messageReceivedListener, deliveryMode, null, null);
}
public TopicSubscription createEventSubscription(MessageReceivedListener messageReceivedListener) throws CacheException {
ValidateInput(messageReceivedListener);
String subscriptionName = SubscriptionInfo.EventsSubscriptionName;
return RegisterSubscriptions(subscriptionName, messageReceivedListener, DeliveryMode.Sync, SubscriptionPolicyType.EventSubscription, null);
}
@Override
public final boolean getIsClosed() {
return isDisposed;
}
@Override
public final String getName() {
return topicName;
}
public long getMessageCount() throws Exception{
if (getIsClosed()) {
throw new OperationFailedRuntimeException(ErrorCodes.PubSub.TOPIC_DISPOSED, ErrorMessages.getErrorMessage(ErrorCodes.PubSub.TOPIC_DISPOSED, getName()));
}
if (cacheImpl != null) {
return cacheImpl.getMessageCount(topicName);
}
return 0;
}
@Override
public final void close() {
disposeInternal(false);
parent.topicDisposeItself(this);
parent.stopPollingIfRequired(this);
}
@Override
public final TimeSpan getExpirationTime() {
return expiration;
}
@Override
public final void setExpirationTime(TimeSpan value) {
expiration = value;
}
@Override
public final void publish(Message message, DeliveryOption deliverOption) throws Exception {
publish(message, deliverOption,false);
}
@Override
public final void publish(Message message, DeliveryOption deliverOption, boolean notifyDeliveryFailure) throws Exception {
publishInternal(message, deliverOption, null, notifyDeliveryFailure);
}
private final void publish(Message message, DeliveryOption deliverOption, String sequenceName) throws Exception {
publish(message ,deliverOption , sequenceName, false);
}
private final void publish(Message message, DeliveryOption deliverOption, String sequenceName , boolean notifyDeliveryFailure) throws Exception {
if (sequenceName==null || sequenceName.isEmpty())
throw new IllegalArgumentException("sequenceName");
message.setMessageId("{" + sequenceName + "}" + message.getMessageId());
publishInternal(message ,deliverOption , sequenceName, notifyDeliveryFailure);
}
private void publishInternal(Message message, DeliveryOption deliverOption, String sequenceName, boolean notifyDeliveryFailure) throws Exception {
if (TopicSearchOptions.ByName != _searchOptions)
throw new OperationFailedException(ErrorCodes.PubSub.PATTERN_BASED_PUBLISHING_NOT_ALLOWED, ErrorMessages.getErrorMessage(ErrorCodes.PubSub.PATTERN_BASED_PUBLISHING_NOT_ALLOWED));
if (message == null)
throw new IllegalArgumentException("message");
if (isDisposed)
throw new OperationFailedException(ErrorCodes.PubSub.TOPIC_DISPOSED, ErrorMessages.getErrorMessage(ErrorCodes.PubSub.TOPIC_DISPOSED, getName()));
try {
readerWriterLock.AcquireReaderLock();
if (message == null) {
throw new IllegalArgumentException("Value cannot be null."+System.lineSeparator()+"Parameter name: message");
}
if (isDisposed) {
throw new OperationFailedException(ErrorCodes.PubSub.TOPIC_DISPOSED, ErrorMessages.getErrorMessage(ErrorCodes.PubSub.TOPIC_DISPOSED, getName()));
}
UsageStats stats = new UsageStats();
stats.BeginSample();
BitSet flagMap = new BitSet();
long size = 0;
Object value = message.getPayload();
tangible.RefObject tempRef_size = new tangible.RefObject(size);
value = cacheImpl.safeSerialize(value, cacheImpl.getName(), flagMap, cacheImpl,tempRef_size, UserObjectType.CacheItem);
size = tempRef_size.argvalue;
if (_perfStatsCollector != null && value != null && value instanceof byte[])
{
_perfStatsCollector.incrementAvgItemSize(((byte[])value).length);
}
if (cacheImpl.getCompressionEnabled()) {
value = CompressionUtil.Compress((byte[]) value, flagMap, cacheImpl.getCompressionThreshold());
}
if (sequenceName == null)
{
sequenceName = "";
}
Hashtable metaInfo = new Hashtable();
metaInfo.put(TopicConstant.TopicName, TopicConstant.TopicTag + topicName);
metaInfo.put(TopicConstant.DeliveryOption, String.valueOf(deliverOption.getValue()));
metaInfo.put(TopicConstant.NotifyOption, String.valueOf(notifyDeliveryFailure));
metaInfo.put(TopicConstant.SequenceName, sequenceName);
long expiration = GetExpirationTime(message);
cacheImpl.publishMessage(message.getMessageId(), value, message.getCreationTime().getTime(), expiration, metaInfo, flagMap);
if (_perfStatsCollector != null) {
stats.EndSample();
_perfStatsCollector.incrementMsecPerMessagePublish(stats.getCurrent());
_perfStatsCollector.incrementMessagePublishedPerSec(1);
}
} finally {
readerWriterLock.ReleaseReaderLock();
}
}
private java.util.Map publishBulkInternal(Map messages, boolean notifyDeliveryFailure) throws CacheException {
java.util.Map failureResult = null;
java.util.Map keyMessageBulk = new java.util.HashMap();
java.util.HashMap clientKeyMessagesList = new java.util.HashMap();
UsageStats stats = new UsageStats();
stats.BeginSample();
for (Map.Entry entry : messages.entrySet())
{
Message message = entry.getKey();
DeliveryOption deliveryOption = entry.getValue();
try
{
if (message == null)
{
throw new IllegalArgumentException("Value cannot be null."+System.lineSeparator()+"Parameter name: message");
}
BitSet flagMap = new BitSet();
long size = 0;
Object value = message.getPayload();
tangible.RefObject tempRef_size = new tangible.RefObject(size);
value = cacheImpl.safeSerialize(value, cacheImpl.getName(), flagMap, cacheImpl,tempRef_size,UserObjectType.CacheItem);
size = tempRef_size.argvalue;
if (cacheImpl.getCompressionEnabled())
{
value = CompressionUtil.Compress((byte[])value, flagMap, cacheImpl.getCompressionThreshold());
}
long expiration = GetExpirationTime(((Message)message));
if (_perfStatsCollector != null && value != null && value instanceof byte[])
{
_perfStatsCollector.incrementAvgItemSize(((byte[])value).length);
}
clientKeyMessagesList.put(message.getMessageId(), message);
Alachisoft.NCache.Caching.Messaging.Message serverMessage = new Alachisoft.NCache.Caching.Messaging.Message(message.getMessageId());
BitSet bitset = new BitSet();
serverMessage.setPayLoad(value);
serverMessage.setFlagMap(bitset);
serverMessage.setCreationTime(NCDateTime.getUTCDate(message.getCreationTime()));
serverMessage.setMessageMetaData(new MessageMetaData(message.getMessageId()));
serverMessage.getMessageMetaData().setSubscriptionType(SubscriptionType.Subscriber);
serverMessage.getMessageMetaData().setTopicName(topicName);
serverMessage.getMessageMetaData().setIsNotify( notifyDeliveryFailure);
serverMessage.getMessageMetaData().setDeliveryOption(deliveryOption);
serverMessage.getMessageMetaData().setExpirationTime( expiration);
serverMessage.getMessageMetaData().setTimeToLive( AppUtil.DiffSeconds(new java.util.Date()) + (new TimeSpan(expiration)).getTotalSeconds());
keyMessageBulk.put(message.getMessageId(), serverMessage);
}
catch(IllegalArgumentException ex) {
throw ex;
}
catch (ParseException |RuntimeException e)
{
if (failureResult == null)
{
failureResult = new java.util.HashMap();
}
failureResult.put(message, e);
}
}
if (keyMessageBulk.size() < 1)
{
throw new IllegalArgumentException("Specified argument was out of the range of valid values.\r\n" +
"Parameter name: messages is empty");
}
try
{
readerWriterLock.AcquireReaderLock();
// returns Dictionary of MessageKey and Exception
java.util.Map failedMessagesOnServer = cacheImpl.publishMessage(topicName, keyMessageBulk, notifyDeliveryFailure);
if (failedMessagesOnServer != null)
{
if (failureResult == null)
{
failureResult = new java.util.HashMap();
}
for (Object messageId : failedMessagesOnServer.keySet())
{
failureResult.put(clientKeyMessagesList.get(messageId), (RuntimeException)failedMessagesOnServer.get(messageId));
}
}
}
finally
{
readerWriterLock.ReleaseReaderLock();
}
if (_perfStatsCollector != null)
{
stats.EndSample();
_perfStatsCollector.incrementMsecPerMessagePublish(stats.getCurrent());
_perfStatsCollector.incrementMessagePublishedPerSec(keyMessageBulk.size() - (failureResult == null ? 0 : failureResult.size()));
}
return (failureResult != null) ? failureResult : new java.util.HashMap();
}
public final void fireDeleteNotification() {
if (deleteEventListener != null) {
FutureTask task = new FutureTask(() -> {
deleteEventListener.onTopicDeleted(deleteEventListener, new TopicDeleteEventArgs(getName()));
return null;
});
ThreadPool.getInstance().executeTask(task);
}
}
//endregion
//region Internal Methods
public final int getActiveSubscriptions() {
return subscriptions == null ? 0 : subscriptions.size();
}
public final void subscribe(TopicSubscriptionImpl subscription) throws Exception {
subscribe(subscription, SubscriptionPolicyType.NonDurableExclusiveSubscription);
}
public void subscribe(TopicSubscriptionImpl subscription, SubscriptionPolicyType subscriptionPolicyType) throws CacheException {
try {
readerWriterLock.AcquireReaderLock();
if (isDisposed) {
return;
}
cacheImpl.subscribe(getName(), subscription.getSubscriptionName(), SubscriptionType.Subscriber, subscription.getCreationTime(), subscription.getExpiration(), subscriptionPolicyType);
} finally {
readerWriterLock.ReleaseReaderLock();
}
}
public final void unSubscribe(TopicSubscriptionImpl subscription, boolean remove) throws Exception {
unSubscribe(subscription, remove, false);
}
public void unSubscribe(TopicSubscriptionImpl subscription, boolean remove, boolean dispose) throws Exception {
try {
SubscriptionIdentifier subscriptionIdentifier = new SubscriptionIdentifier(subscription.getSubscriptionName(), subscription.getSubscriptionPolicyType());
readerWriterLock.AcquireReaderLock();
if (isDisposed) {
return;
}
cacheImpl.unSubscribe(getName(), subscription.getSubscriptionName(), subscription.getSubscriptionPolicyType(), SubscriptionType.Subscriber , dispose);
if (remove) {
synchronized (subscriptions) {
subscriptions.remove(subscriptionIdentifier);
}
}
parent.stopPollingIfRequired(this);
} finally {
readerWriterLock.ReleaseReaderLock();
}
}
/**
* Returns true if delivery notification is registered
*
* @return
*/
public final boolean getHasFailureDeliveryNotification() {
return messageFailedEventListener != null;
}
public final void disposeInternal(boolean removeTopic) {
try {
readerWriterLock.AcquireWriterLock();
if (isDisposed) {
return;
}
if (refCount.get() > 0) {
refCount.decrementAndGet();
}
if (removeTopic) {
refCount.set(0);
}
if (refCount.get() == 0 && !isDisposed) {
if (subscriptions != null) {
synchronized (subscriptions) {
for (Entry pair : subscriptions.entrySet()) {
pair.getValue().dispose();
}
subscriptions.clear();
}
}
if (getHasFailureDeliveryNotification()) {
cacheImpl.unSubscribe(topicName, publisherId,SubscriptionPolicyType.EventSubscription, Publisher,removeTopic);
}
messageFailedEventListener = null;
subscriptions = null;
isDisposed = true;
}
} catch (Exception ex) {
} finally {
readerWriterLock.ReleaseWriterLock();
}
}
public final void IncrementRefCount() {
try {
refCount.getAndIncrement();
} finally {
}
}
public final void reRegisterSubscribers(TopicSearchOptions searchOption) throws CacheException {
try {
readerWriterLock.AcquireReaderLock();
if (isDisposed) {
return;
}
synchronized (subscriptions) {
switch (searchOption) {
case ByName:
for (Map.Entry subscriptions : subscriptions.entrySet()) {
TopicSubscriptionImpl topicSubscription = subscriptions.getValue();
cacheImpl.subscribe(getName(), topicSubscription.getSubscriptionName(), Subscriber, topicSubscription.getCreationTime(), topicSubscription.getExpiration(), topicSubscription.getSubscriptionPolicyType());
}
break;
}
}
} finally {
readerWriterLock.ReleaseReaderLock();
}
}
public void updateSyncData(java.util.List messageList, String topicName) {
try {
readerWriterLock.AcquireReaderLock();
if (isDisposed) {
return;
}
for (MessageItem messageItem : messageList) {
try {
GetMessagePayLoad(messageItem);
java.util.ArrayList subscriptionReciepientList = null;
if (messageItem.getSubscriptionType() == Publisher || messageItem.getDeliveryOption() == DeliveryOption.Any) {
subscriptionReciepientList = messageItem.getSubscriptionIdentifierList();
} else {
synchronized (subscriptions) {
subscriptionReciepientList = new ArrayList(this.subscriptions.keySet());
}
}
for (SubscriptionIdentifier info : subscriptionReciepientList) {
switch (messageItem.getSubscriptionType()) {
case PatternSubscription:
case Subscriber:
if (subscriptions.containsKey(info)) {
subscriptions.get(info).onMessageRecieved(GetMessageEventArgs(messageItem, topicName));
}
break;
case PatternPublisher:
case Publisher:
if (!publisherId.equals(info.getSubscriptionName())) {
continue;
}
OnMessageDeliveryFailure(GetMessageFailureEventArgs(messageItem));
break;
}
}
} catch (Exception ex) {
}
}
} finally {
readerWriterLock.ReleaseReaderLock();
}
}
public void unSubscribeEventTopic(TopicSubscriptionImpl subscription, boolean remove) throws Exception {
try {
readerWriterLock.AcquireReaderLock();
unSubscribe(subscription, remove);
_eventRegistered = false;
} finally {
readerWriterLock.ReleaseReaderLock();
}
}
//endregion
//region Private Methods
private long GetExpirationTime(Message message) {
long expiration = 0;
if (message.getExpirationTime() != null) {
expiration = message.getExpirationTime().getTotalTicks();
} else if (getExpirationTime() != null) {
expiration = getExpirationTime().getTotalTicks();
}
return expiration;
}
private MessageFailedEventArgs GetMessageFailureEventArgs(MessageItem messageItem) {
Message message = GetMessage(messageItem);
return new MessageFailedEventArgs(message, messageItem.getDeliveryOption(), this, messageItem.getMessageFailureReason());
}
private MessageEventArgs GetMessageEventArgs(MessageItem messageItem, String topicName) {
Message message = GetMessage(messageItem);
return new MessageEventArgs(message, messageItem.getDeliveryOption(), this, topicName);
}
private Message GetMessage(MessageItem messageItem) {
PayLoadDeserializationJson payLoadDeserializationJson = new PayLoadDeserializationJson();
Message message = new Message(messageItem.getPayload(), messageItem.getExpirationTime());
message.setSerializationDataInternal(payLoadDeserializationJson, messageItem.getSerializedJson());
message.setCreationTime(messageItem.getCreationTime());
message.setMessageId(messageItem.getMessageId());
return message;
}
private void GetMessagePayLoad(MessageItem messageItem) throws CacheException, IOException {
if (messageItem != null && messageItem.getPayload() != null) {
MessageItemType type = getMessageItemType(messageItem);
switch (type) {
case MessageItems:
GetMessageItemPayLoad(messageItem);
break;
case MessageEventItem:
messageItem.setPayload(GetMessageEventItemPayLoad((MessageEventItem) messageItem.getPayload()));
break;
case MessageEventItems:
MessageEventItem[] items = (MessageEventItem[]) messageItem.getPayload();
if (items != null) {
MessageEventItem[] payLoads = new MessageEventItem[items.length];
for (int count = 0; count < items.length; count++) {
payLoads[count] = GetMessageEventItemPayLoad(items[count]);
}
messageItem.setPayload(payLoads);
}
break;
case MessageEventCollections:
MessageCollectionEventItem[] citems = (MessageCollectionEventItem[]) messageItem.getPayload();
if (citems != null) {
for (MessageCollectionEventItem eventItem : citems) {
messageItem.setPayload(GetMessageEventCollectionPayLoad(eventItem));
}
}
break;
case MessageEventCollection:
messageItem.setPayload(GetMessageEventCollectionPayLoad((MessageCollectionEventItem) messageItem.getPayload()));
break;
}
}
}
private MessageCollectionEventItem GetMessageEventCollectionPayLoad(MessageCollectionEventItem eventItem) throws OperationFailedException {
if (eventItem != null && eventItem.getCollectionItem() != null) {
eventItem.setCollectionItem(cacheImpl.safeDeserialize(eventItem.getCollectionItem(), cacheImpl.getName(), new BitSet(), cacheImpl, UserObjectType.CacheItem, null));
}
return eventItem;
}
private MessageEventItem GetMessageEventItemPayLoad(MessageEventItem eventItem) throws CacheException, IOException {
if (eventItem != null && eventItem.getItem() != null) {
if (EventCacheItemWrapperInternal.getFlagMap(eventItem.getItem()) != null) {
if (EventCacheItemWrapperInternal.getFlagMap(eventItem.getItem()).IsBitSet((byte) BitSetConstants.Compressed)) {
EventCacheItemWrapperInternal.setValue(eventItem.getItem() ,CompressionUtil.Decompress((byte[]) eventItem.getItem().getValue(null)));
}
IncrementCompressionCounter((byte[]) eventItem.getItem().getValue(null));
}
EventCacheItemWrapperInternal.setValue(eventItem.getItem(),cacheImpl.safeDeserialize(eventItem.getItem().getValue(null), cacheImpl.getName(), EventCacheItemWrapperInternal.getFlagMap(eventItem.getItem()), cacheImpl, UserObjectType.CacheItem, null));
EventCacheItemWrapperInternal.setValue(eventItem.getOldItem(),cacheImpl.safeDeserialize(eventItem.getOldItem().getValue(null),cacheImpl.getName(),EventCacheItemWrapperInternal.getFlagMap(eventItem.getItem()),cacheImpl,UserObjectType.CacheItem,null));
}
return eventItem;
}
private void GetMessageItemPayLoad(MessageItem messageItem) throws CacheException, IOException {
if (messageItem != null && !messageItem.getDeserialized()) {
if (messageItem.getPayload() != null) {
if (messageItem.getFlag().IsBitSet((byte) BitSetConstants.Compressed)) {
messageItem.setPayload(CompressionUtil.Decompress((byte[]) messageItem.getPayload()));
}
}
IncrementCompressionCounter((byte[]) messageItem.getPayload());
messageItem.setSerializedJson(messageItem.getPayload());
messageItem.setPayload(cacheImpl.safeDeserialize(messageItem.getPayload(), cacheImpl.getName(), messageItem.getFlag(), cacheImpl, UserObjectType.CacheItem, null));
messageItem.setDeserialized(true);
}
}
private void IncrementEncryptionCounter(UsageStats statsEncryption) {
if (_perfStatsCollector != null) {
_perfStatsCollector.incrementMsecPerDecryptionSample(statsEncryption.getCurrent());
}
}
private void IncrementCompressionCounter(byte[] messageItem) {
if (_perfStatsCollector != null && messageItem != null) {
_perfStatsCollector.incrementAvgItemSize(messageItem.length);
}
}
private void UnRegisterPublisher(String publisherId) throws Exception {
cacheImpl.unSubscribe(topicName, publisherId, SubscriptionPolicyType.NonDurableExclusiveSubscription, Publisher,true);
parent.stopPollingIfRequired(this);
}
private void RegisterPublisher(String publisherId) throws Exception {
long expiration = TimeSpan.MaxValue.getTotalTicks();
cacheImpl.subscribe(topicName, publisherId, Publisher, HelperFxn.getTicks(new Date()), expiration,SubscriptionPolicyType.NonDurableExclusiveSubscription);
parent.startPolling();
}
private void OnMessageDeliveryFailure(MessageFailedEventArgs args) {
try {
if (messageFailedEventListener != null) {
TopicImpl topicImpl=this;
Runnable asyncTask=new Runnable() {
@Override
public void run() {
messageFailedEventListener.onMessageDeliveryFailure(topicImpl, args);
}
};
ThreadPool.getInstance().executeTask(asyncTask);
}
} catch (RuntimeException e) {
}
}
protected TopicSubscription RegisterSubscriptions(String subscriptionName,
MessageReceivedListener onMessageReceivedListener,
DeliveryMode deliveryMode,
SubscriptionPolicyType subscriptionPolicy, TimeSpan timeSpan) throws CacheException {
try {
readerWriterLock.AcquireReaderLock();
if (deliveryMode == null)
deliveryMode = DeliveryMode.Sync;
if (subscriptionPolicy == null)
subscriptionPolicy = SubscriptionPolicyType.NonDurableExclusiveSubscription;
SubscriptionIdentifier subscriptionIdentifier = new SubscriptionIdentifier(subscriptionName, subscriptionPolicy);
TopicSubscriptionImpl topicSubscription = GetExistingSubscription(subscriptionIdentifier, subscriptionPolicy);
if (topicSubscription == null) {
topicSubscription = new TopicSubscriptionImpl(this, subscriptionName, subscriptionPolicy, onMessageReceivedListener, deliveryMode);
java.util.Date creationTime = new java.util.Date();
topicSubscription.setCreationTime(HelperFxn.getTicks(creationTime));
topicSubscription.setSubscriptionPolicy(subscriptionPolicy);
if (timeSpan == null) {
topicSubscription.setExpiration(TimeSpan.MaxValue.getTotalTicks());
} else {
topicSubscription.setExpiration(timeSpan.getTotalTicks());
}
subscribe(topicSubscription, subscriptionPolicy);
synchronized (subscriptions) {
TopicSubscription existingSubscription = GetExistingSubscription(subscriptionIdentifier, subscriptionPolicy);
if (existingSubscription == null) {
subscriptions.put(subscriptionIdentifier, topicSubscription);
} else {
return existingSubscription;
}
}
parent.onSubscriptionCreated(this, topicSubscription);
}
return topicSubscription;
} finally {
readerWriterLock.ReleaseReaderLock();
}
}
private TopicSubscriptionImpl GetExistingSubscription(SubscriptionIdentifier subscriptionIdentifier, SubscriptionPolicyType subscriptionPolicy) throws CacheException {
TopicSubscriptionImpl topicSubscription = subscriptions.get(subscriptionIdentifier);
if (topicSubscription != null) {
if (subscriptionPolicy != SubscriptionPolicyType.EventSubscription) {
throw new OperationFailedException(ErrorCodes.PubSub.SUBSCRIPTION_EXISTS, ErrorMessages.getErrorMessage(ErrorCodes.PubSub.SUBSCRIPTION_EXISTS));
} else {
topicSubscription.UpdateCount();
}
}
return topicSubscription;
}
private void ValidateInput(MessageReceivedListener messageReceivedListener) throws OperationFailedException {
if (isDisposed) {
throw new OperationFailedException(ErrorCodes.PubSub.TOPIC_DISPOSED, ErrorMessages.getErrorMessage(ErrorCodes.PubSub.TOPIC_DISPOSED, getName()));
}
if (messageReceivedListener == null) {
throw new IllegalArgumentException("Value cannot be null."+System.lineSeparator()+"Parameter name: messageReceivedListener");
}
}
//endregion
}