/** * Helios, OpenSource Monitoring * Brought to you by the Helios Development Group * * Copyright 2007, Helios Development Group and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. * */ package org.helios.apmrouter.server.net.listener.netty.handlers; import java.net.SocketAddress; import org.helios.apmrouter.OpCode; import org.helios.apmrouter.dataservice.json.JsonResponse; import org.helios.apmrouter.dataservice.json.JsonSubConfirm; import org.helios.apmrouter.dataservice.json.catalog.MetricURI; import org.helios.apmrouter.dataservice.json.catalog.MetricURISubscriptionService; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jmx.export.annotation.ManagedMetric; import org.springframework.jmx.support.MetricType; /** * <p>Title: MetricURISubscriptionHandler</p> * <p>Description: Agent request handler for managing {@link MetricURI} subscriptions for remote agents.</p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.server.net.listener.netty.handlers.MetricURISubscriptionHandler</code></p> */ public class MetricURISubscriptionHandler extends AbstractAgentRequestHandler { /** The OpCodes handled by this handler */ protected static final OpCode[] HANDLED_OP_CODES = new OpCode[]{OpCode.METRIC_URI_SUBSCRIBE, OpCode.METRIC_URI_UNSUBSCRIBE}; /** The metric uri subscription service */ protected MetricURISubscriptionService subService = null; /** * Returns the total number of subscription requests received * @return the total number of subscription requests received */ @ManagedMetric(category="MetricURISubscriptionHandler", displayName="SubRequests", metricType=MetricType.COUNTER, description="The total number of subscription requests received") public long getTotalSubRequests() { return getMetricValue("SubRequests"); } /** * Returns the total number of unsubscription requests received * @return the total number of unsubscription requests received */ @ManagedMetric(category="MetricURISubscriptionHandler", displayName="UnSubRequests", metricType=MetricType.COUNTER, description="The total number of unsubscription requests received") public long getTotalUnSubRequests() { return getMetricValue("UnSubRequests"); } /** * Creates a new MetricURISubscriptionHandler */ public MetricURISubscriptionHandler() { super(); } /** * {@inheritDoc} * @see org.helios.apmrouter.server.net.listener.netty.handlers.AgentRequestHandler#processAgentRequest(org.helios.apmrouter.OpCode, org.jboss.netty.buffer.ChannelBuffer, java.net.SocketAddress, org.jboss.netty.channel.Channel) */ @Override public void processAgentRequest(OpCode opCode, ChannelBuffer buff, SocketAddress remoteAddress, Channel channel) { buff.skipBytes(1); switch(opCode) { case METRIC_URI_SUBSCRIBE: incr("SubRequests"); subscribe(buff, getChannelForRemote(channel, remoteAddress) , true); break; case METRIC_URI_UNSUBSCRIBE: incr("UnSubRequests"); subscribe(buff, getChannelForRemote(channel, remoteAddress) , false); break; default: break; } } /** * Subscribes or unsubscribes the passed channel to a {@link MetricURI} * @param buff The buffer containing a {@link OpCode#METRIC_URI_SUBSCRIBE} or {@link OpCode#METRIC_URI_UNSUBSCRIBE} request. * @param channel The subscribing channel * @param sub true for a subscribe, false for an unsubscribe */ protected void subscribe(ChannelBuffer buff, Channel channel, boolean sub) { try { final long rid = buff.readLong(); int uriLength = buff.readInt(); byte[] uriBytes = new byte[uriLength]; buff.readBytes(uriBytes); String uri = new String(uriBytes); JsonResponse responder = new JsonSubConfirm(rid, JsonResponse.RESP_TYPE_SUB, uri); final ChannelBuffer response = ChannelBuffers.buffer(10); // opCode(1) + success(1) + rid(8) = 10 if(sub) { response.writeByte(OpCode.METRIC_URI_SUB_CONFIRM.op()); try { subService.subscribeMetricURI(MetricURI.getMetricURI(uri), responder, channel); response.writeByte(1); } catch (Exception ex) { response.writeByte(0); } } else { response.writeByte(OpCode.METRIC_URI_UNSUB_CONFIRM.op()); try { subService.cancelMetricURISubscription(MetricURI.getMetricURI(uri), channel); response.writeByte(1); } catch (Exception ex) { response.writeByte(0); } } response.writeLong(rid); channel.write(response); } catch (Exception ex) { warn("Failed to subscribe to MetricURI from channel [", channel, "]", ex); } } /** * {@inheritDoc} * @see org.helios.apmrouter.server.net.listener.netty.handlers.AgentRequestHandler#getHandledOpCodes() */ @Override public OpCode[] getHandledOpCodes() { return HANDLED_OP_CODES; } /** * Sets the metric uri subscription service * @param subService the metric uri subscription service */ @Autowired(required=true) public void setSubService(MetricURISubscriptionService subService) { this.subService = subService; } }