/**
* 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.services.mtxml;
import java.util.List;
import org.helios.apmrouter.server.unification.pipeline2.FlushOnCloseBufferAggregator;
import org.helios.apmrouter.server.unification.pipeline2.ProtocolSwitchContext;
import org.helios.apmrouter.server.unification.pipeline2.ProtocolSwitchDecoder;
import org.helios.apmrouter.server.unification.pipeline2.SwitchPhase;
import org.helios.apmrouter.server.unification.pipeline2.content.ConfigurableStaxContentClassifier;
import org.helios.apmrouter.util.ByteSequenceIndexFinder;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.ChannelHandler;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.springframework.beans.factory.annotation.Autowired;
/**
* <p>Title: SanStatsContentClassifier</p>
* <p>Description: A content classifier to detect SAN Stats XML content</p>
* <p>Company: Helios Development Group LLC</p>
* @author Whitehead (nwhitehead AT heliosdev DOT org)
* <p><code>org.helios.apmrouter.server.services.mtxml.SanStatsContentClassifier</code></p>
*/
public class SanStatsContentClassifier extends ConfigurableStaxContentClassifier {
/** The san stats parser tracer */
@Autowired(required=true)
protected SanStatsParserTracer sanStatsParserTracer = null;
/** A byte sequence finder for <b><code><sample>></code></b> */
private static final ByteSequenceIndexFinder SAMPLE_FINDER = new ByteSequenceIndexFinder("<sample>".getBytes());
/**
* Creates a new SanStatsContentClassifier
*/
public SanStatsContentClassifier() {
super("SanStatsXml");
this.targetTags.put("sample", "sample");
}
public Object match(ChannelBuffer buff) {
int rb = buff.readableBytes();
int maxLength = 100 > rb ? rb : 100;
if(SAMPLE_FINDER.findIn(0, maxLength, buff)!=-1) return true;
return super.match(buff);
}
/** The name of this decoder in the pipeline */
public static final String PIPE_NAME = "SanStatsXml";
/**
* {@inheritDoc}
* @see org.helios.apmrouter.server.unification.pipeline2.Initiator#process(org.helios.apmrouter.server.unification.pipeline2.ProtocolSwitchContext, java.lang.Object)
*/
@Override
public SwitchPhase process(final ProtocolSwitchContext context, Object matchKey) {
log.info("Classifier identified content as [" + name + "]");
ChannelPipeline pipeline = context.getPipeline();
// ========================================================================
// Remove the logging and protocol switch handlers from the pipeline
// ========================================================================
try { pipeline.remove("logging"); } catch (Exception ex) {/* No Op */}
try { pipeline.remove(ProtocolSwitchDecoder.PIPE_NAME); } catch (Exception ex) {/* No Op */}
// StringBuilder b = new StringBuilder("\n\t========\n\tRemoved Handlers\n\t========");
// List<String> names = pipeline.getNames();
// for(String handlerName: names) {
// if("exec".equals(handlerName) || PIPE_NAME.equals(handlerName)) continue;
// ChannelHandler ch = pipeline.remove(handlerName);
// b.append("\n\t").append(handlerName).append(" [").append(ch.getClass().getSimpleName()).append("]");
// }
// b.append("\n\t========");
// log.info(b);
// ===============================================================
if(!context.aggregationHasOccured()) {
// ----> send to aggregator, then SanStatsParserTracer
pipeline.addLast(FlushOnCloseBufferAggregator.PIPE_NAME, FlushOnCloseBufferAggregator.getInstance());
pipeline.addLast(FlushOnCloseBufferAggregator.PIPE_NAME + "-Complete", new SimpleChannelUpstreamHandler(){
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
log.info("[" + FlushOnCloseBufferAggregator.PIPE_NAME + "-Complete] FlushOnCloseBufferAggregator Complete Event");
context.setAggregationHasOccured();
super.messageReceived(ctx, e);
}
});
// what if the channel is already closed ?
}
pipeline.addLast(SanStatsParserTracer.PIPE_NAME, sanStatsParserTracer);
if(!context.getChannel().isOpen()) {
System.err.println("\n\t=================\n\tChannel Already Closed\n\t=================\n");
}
// context.sendCurrentBufferUpstream(FlushOnCloseBufferAggregator.PIPE_NAME);
// context.sendCurrentBufferUpstream(context.getPipeline().getNames().get(0));
try {
FlushOnCloseBufferAggregator.getInstance().handleUpstream(context.getCtx(), context.getUpstreamEvent());
} catch (Exception e) {
e.printStackTrace();
}
return SwitchPhase.COMPLETE;
}
}