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 *
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 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 }