001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.activemq.broker.jmx;
018
019import javax.jms.InvalidSelectorException;
020
021import org.apache.activemq.broker.region.Subscription;
022import org.apache.activemq.command.ActiveMQDestination;
023import org.apache.activemq.command.ConsumerInfo;
024import org.apache.activemq.command.ActiveMQQueue;
025import org.apache.activemq.command.ActiveMQTopic;
026import org.apache.activemq.filter.DestinationFilter;
027
028/**
029 * 
030 */
031public class SubscriptionView implements SubscriptionViewMBean {
032
033    protected final Subscription subscription;
034    protected final String clientId;
035
036    /**
037     * Constructor
038     * 
039     * @param subs
040     */
041    public SubscriptionView(String clientId, Subscription subs) {
042        this.clientId = clientId;
043        this.subscription = subs;
044    }
045
046    /**
047     * @return the clientId
048     */
049    public String getClientId() {
050        return clientId;
051    }
052
053    /**
054     * @return the id of the Connection the Subscription is on
055     */
056    public String getConnectionId() {
057        ConsumerInfo info = getConsumerInfo();
058        if (info != null) {
059            return info.getConsumerId().getConnectionId();
060        }
061        return "NOTSET";
062    }
063
064    /**
065     * @return the id of the Session the subscription is on
066     */
067    public long getSessionId() {
068        ConsumerInfo info = getConsumerInfo();
069        if (info != null) {
070            return info.getConsumerId().getSessionId();
071        }
072        return 0;
073    }
074
075    /**
076     * @return the id of the Subscription
077     */
078    public long getSubcriptionId() {
079        ConsumerInfo info = getConsumerInfo();
080        if (info != null) {
081            return info.getConsumerId().getValue();
082        }
083        return 0;
084    }
085
086    /**
087     * @return the destination name
088     */
089    public String getDestinationName() {
090        ConsumerInfo info = getConsumerInfo();
091        if (info != null) {
092            ActiveMQDestination dest = info.getDestination();
093            return dest.getPhysicalName();
094        }
095        return "NOTSET";
096    }
097
098    public String getSelector() {
099        if (subscription != null) {
100            return subscription.getSelector();
101        }
102        return null;
103    }
104
105    public void setSelector(String selector) throws InvalidSelectorException, UnsupportedOperationException {
106        if (subscription != null) {
107            subscription.setSelector(selector);
108        } else {
109            throw new UnsupportedOperationException("No subscription object");
110        }
111    }
112
113    /**
114     * @return true if the destination is a Queue
115     */
116    public boolean isDestinationQueue() {
117        ConsumerInfo info = getConsumerInfo();
118        if (info != null) {
119            ActiveMQDestination dest = info.getDestination();
120            return dest.isQueue();
121        }
122        return false;
123    }
124
125    /**
126     * @return true of the destination is a Topic
127     */
128    public boolean isDestinationTopic() {
129        ConsumerInfo info = getConsumerInfo();
130        if (info != null) {
131            ActiveMQDestination dest = info.getDestination();
132            return dest.isTopic();
133        }
134        return false;
135    }
136
137    /**
138     * @return true if the destination is temporary
139     */
140    public boolean isDestinationTemporary() {
141        ConsumerInfo info = getConsumerInfo();
142        if (info != null) {
143            ActiveMQDestination dest = info.getDestination();
144            return dest.isTemporary();
145        }
146        return false;
147    }
148
149    /**
150     * @return true if the subscriber is active
151     */
152    public boolean isActive() {
153        return true;
154    }
155
156    /**
157     * The subscription should release as may references as it can to help the
158     * garbage collector reclaim memory.
159     */
160    public void gc() {
161        if (subscription != null) {
162            subscription.gc();
163        }
164    }
165
166    /**
167     * @return whether or not the subscriber is retroactive or not
168     */
169    public boolean isRetroactive() {
170        ConsumerInfo info = getConsumerInfo();
171        return info != null ? info.isRetroactive() : false;
172    }
173
174    /**
175     * @return whether or not the subscriber is an exclusive consumer
176     */
177    public boolean isExclusive() {
178        ConsumerInfo info = getConsumerInfo();
179        return info != null ? info.isExclusive() : false;
180    }
181
182    /**
183     * @return whether or not the subscriber is durable (persistent)
184     */
185    public boolean isDurable() {
186        ConsumerInfo info = getConsumerInfo();
187        return info != null ? info.isDurable() : false;
188    }
189
190    /**
191     * @return whether or not the subscriber ignores local messages
192     */
193    public boolean isNoLocal() {
194        ConsumerInfo info = getConsumerInfo();
195        return info != null ? info.isNoLocal() : false;
196    }
197
198    /**
199     * @return the maximum number of pending messages allowed in addition to the
200     *         prefetch size. If enabled to a non-zero value then this will
201     *         perform eviction of messages for slow consumers on non-durable
202     *         topics.
203     */
204    public int getMaximumPendingMessageLimit() {
205        ConsumerInfo info = getConsumerInfo();
206        return info != null ? info.getMaximumPendingMessageLimit() : 0;
207    }
208
209    /**
210     * @return the consumer priority
211     */
212    public byte getPriority() {
213        ConsumerInfo info = getConsumerInfo();
214        return info != null ? info.getPriority() : 0;
215    }
216
217    /**
218     * @return the name of the consumer which is only used for durable
219     *         consumers.
220     */
221    public String getSubcriptionName() {
222        ConsumerInfo info = getConsumerInfo();
223        return info != null ? info.getSubscriptionName() : null;
224    }
225
226    /**
227     * @return number of messages pending delivery
228     */
229    public int getPendingQueueSize() {
230        return subscription != null ? subscription.getPendingQueueSize() : 0;
231    }
232
233    /**
234     * @return number of messages dispatched
235     */
236    public int getDispatchedQueueSize() {
237        return subscription != null ? subscription.getDispatchedQueueSize() : 0;
238    }
239    
240    public int getMessageCountAwaitingAcknowledge() {
241        return getDispatchedQueueSize();
242    }
243
244    /**
245     * @return number of messages that matched the subscription
246     */
247    public long getDispatchedCounter() {
248        return subscription != null ? subscription.getDispatchedCounter() : 0;
249    }
250
251    /**
252     * @return number of messages that matched the subscription
253     */
254    public long getEnqueueCounter() {
255        return subscription != null ? subscription.getEnqueueCounter() : 0;
256    }
257
258    /**
259     * @return number of messages queued by the client
260     */
261    public long getDequeueCounter() {
262        return subscription != null ? subscription.getDequeueCounter() : 0;
263    }
264
265    protected ConsumerInfo getConsumerInfo() {
266        return subscription != null ? subscription.getConsumerInfo() : null;
267    }
268
269    /**
270     * @return pretty print
271     */
272    public String toString() {
273        return "SubscriptionView: " + getClientId() + ":" + getConnectionId();
274    }
275
276    /**
277     */
278    public int getPrefetchSize() {
279        return subscription != null ? subscription.getPrefetchSize() : 0;
280    }
281
282    public boolean isMatchingQueue(String queueName) {
283        if (isDestinationQueue()) {
284            return matchesDestination(new ActiveMQQueue(queueName));
285        }
286        return false;
287    }
288
289    public boolean isMatchingTopic(String topicName) {
290        if (isDestinationTopic()) {
291            return matchesDestination(new ActiveMQTopic(topicName));
292        }
293        return false;
294    }
295
296    /**
297     * Return true if this subscription matches the given destination
298     *
299     * @param destination the destination to compare against
300     * @return true if this subscription matches the given destination
301     */
302    public boolean matchesDestination(ActiveMQDestination destination) {
303        ActiveMQDestination subscriptionDestination = subscription.getActiveMQDestination();
304        DestinationFilter filter = DestinationFilter.parseFilter(subscriptionDestination);
305        return filter.matches(destination);
306    }
307
308}