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     */
017    package org.apache.activemq.broker.jmx;
018    
019    import javax.jms.InvalidSelectorException;
020    
021    import org.apache.activemq.broker.region.Subscription;
022    import org.apache.activemq.command.ActiveMQDestination;
023    import org.apache.activemq.command.ConsumerInfo;
024    import org.apache.activemq.command.ActiveMQQueue;
025    import org.apache.activemq.command.ActiveMQTopic;
026    import org.apache.activemq.filter.DestinationFilter;
027    
028    /**
029     * @version $Revision: 1.5 $
030     */
031    public 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 getDispachedCounter() {
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    }