/* * #%L * Nazgul Project: nazgul-core-cache-impl-hazelcast * %% * Copyright (C) 2010 - 2017 jGuru Europe AB * %% * Licensed under the jGuru Europe AB license (the "License"), based * on Apache License, Version 2.0; you may not use this file except * in compliance with the License. * * You may obtain a copy of the License at * * http://www.jguru.se/licenses/jguruCorporateSourceLicense-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% * */ package se.jguru.nazgul.core.cache.impl.hazelcast; import com.hazelcast.core.ITopic; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import se.jguru.nazgul.core.cache.api.distributed.async.LightweightTopic; import se.jguru.nazgul.core.cache.api.distributed.async.LightweightTopicListener; import java.io.Serializable; import java.util.Map; import java.util.TreeMap; /** * LightweightTopic implementation for Hazelcast. * * @author <a href="mailto:lj@jguru.se">Lennart Jörelid</a>, jGuru Europe AB */ public class HazelcastLightweightTopic<MessageType extends Serializable> implements LightweightTopic<MessageType> { // Our log private static final Logger log = LoggerFactory.getLogger(HazelcastLightweightTopic.class); // Internal state private final Object lock = new Object(); private ITopic<MessageType> hazelcastTopic; private Map<String, HazelcastLightweightTopicListenerAdapter<MessageType>> knownListeners; /** * Creates a new HazelcastLightweightTopic (LightweightTopic wrapper), delegating its calls to the provided ITopic * instance. * * @param hazelcastTopic The ITopic received from Hazelcast. */ public HazelcastLightweightTopic(final ITopic<MessageType> hazelcastTopic) { this.hazelcastTopic = hazelcastTopic; knownListeners = new TreeMap<String, HazelcastLightweightTopicListenerAdapter<MessageType>>(); } /** * Sends/Publishes the provided message through this LightweightTopic. * * @param message The message to publish in this Topic. */ @Override public void publish(final MessageType message) { hazelcastTopic.publish(message); } /** * Adds a new LightweightTopicListener to this Topic. The LightweightTopicListener is invoked whenever a message is * sent through this LightweightTopic. * * @param listener The LightweightTopicListener to register to this Topic. */ @Override public void addListener(final LightweightTopicListener<MessageType> listener) { synchronized (lock) { final HazelcastLightweightTopicListenerAdapter<MessageType> lst = new HazelcastLightweightTopicListenerAdapter<MessageType>(listener); // Add to map and topic knownListeners.put(lst.getClusterId(), lst); hazelcastTopic.addMessageListener(lst); } } /** * Removes the provided LightweightTopicListener from this LightweightTopic. * * @param listener The listener to remove. */ @Override public void removeListener(final LightweightTopicListener<MessageType> listener) { // Check sanity. if (listener == null) { throw new IllegalArgumentException("Cannot handle null listener argument."); } // Get the Wrapper final HazelcastLightweightTopicListenerAdapter<MessageType> toRemove = knownListeners.get(listener.getClusterId()); if (toRemove == null) { log.warn("HazelcastLightweightTopicListenerAdapter [" + listener.getClusterId() + "] not found. Aborting."); return; } synchronized (lock) { final String clusterId = listener.getClusterId(); knownListeners.remove(clusterId); hazelcastTopic.removeMessageListener(clusterId); } } /** * @return a human-readable, cluster-unique Identifier for this instance. */ @Override public String getClusterId() { return hazelcastTopic.getName(); } }