/*********************************************************************************** * * Copyright (c) 2014 Kamil Baczkowicz * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v1.0 which accompany this distribution. * * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html * * The Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * * Kamil Baczkowicz - initial API and implementation and/or initial documentation * */ package pl.baczkowicz.mqttspy.connectivity.topicmatching; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.moquette.spi.impl.subscriptions.Subscription; import org.eclipse.moquette.spi.impl.subscriptions.SubscriptionsStore; import org.eclipse.moquette.proto.messages.AbstractMessage.QOSType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This class is responsible for matching topics against subscriptions, and * figure out which subscription the message has been received for. It uses * moquette's SubscriptionStore to achieve that. */ public class TopicMatcher { /** Diagnostic logger. */ private static final Logger logger = LoggerFactory.getLogger(TopicMatcher.class); /** Subscription store - used to matching topics against subscriptions - from moquette. */ private SubscriptionsStore subscriptionsStore; /** All topics that are in the store. */ private Set<String> topics = new HashSet<>(); /** * Creates the topic matcher. */ public TopicMatcher() { // Manage subscriptions, uses moquette's SubscriptionsStore subscriptionsStore = new SubscriptionsStore(); subscriptionsStore.init(new MapBasedSubscriptionStore()); } /** * Returns matching subscriptions for the given topic. * * @param topic The topic to get active subscriptions for * * @return List of subscription topics matching the given topic */ public List<String> getMatchingSubscriptions(final String topic) { // Check matching subscription final List<Subscription> matchingSubscriptions = subscriptionsStore.matches(topic); final List<String> matchingSubscriptionTopics = new ArrayList<String>(); // For all found subscriptions for (final Subscription matchingSubscription : matchingSubscriptions) { matchingSubscriptionTopics.add(matchingSubscription.getTopicFilter()); } return matchingSubscriptionTopics; } /** * Adds the given topic to the subscription store - used for topic to subscription matching. * * @param topic Topic to add */ public void addSubscriptionToStore(final String topic, final String clientId) { final Subscription subscription = new Subscription(clientId, topic, QOSType.MOST_ONE, true); if (!topics.contains(subscription)) { logger.debug("Added subscription " + topic + " (" + clientId + ") to store"); // Store the subscription topic for further matching subscriptionsStore.add(subscription); topics.add(topic); } } /** * Removes the given topic from the subscription store - used for topic to subscription matching. * * @param topic Topic to remove */ public void removeSubscriptionFromStore(final String topic, final String clientId) { subscriptionsStore.removeSubscription(topic, clientId); topics.remove(topic); } }