Package org.cyclopsgroup.jmxterm.cmd

Source Code of org.cyclopsgroup.jmxterm.cmd.WatchCommand$ReportOutput

package org.cyclopsgroup.jmxterm.cmd;

import java.io.IOException;
import java.text.FieldPosition;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.management.JMException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;

import org.apache.commons.lang.Validate;
import org.cyclopsgroup.jcli.annotation.Argument;
import org.cyclopsgroup.jcli.annotation.Cli;
import org.cyclopsgroup.jcli.annotation.MultiValue;
import org.cyclopsgroup.jcli.annotation.Option;
import org.cyclopsgroup.jmxterm.Command;
import org.cyclopsgroup.jmxterm.Session;
import org.cyclopsgroup.jmxterm.io.CommandOutput;
import org.cyclopsgroup.jmxterm.io.JlineCommandInput;

import jline.console.ConsoleReader;

/**
* Command to watch an MBean attribute TODO Consider the use case for CSV file backend generation
*
* @author <a href="mailto:jiaqi.guo@gmail.com">Jiaqi Guo</a>
*/
@Cli( name = "watch", description = "Watch the value of one MBean attribute constantly", note = "DO NOT call this command in a script and expect decent output" )
public class WatchCommand
    extends Command
{
    private static class ConsoleOutput
        extends Output
    {
        private final ConsoleReader console;

        private ConsoleOutput( Session session )
        {
            if ( !( session.getInput() instanceof JlineCommandInput ) )
            {
                throw new IllegalStateException( "Under current context, watch command can't execute." );
            }
            this.console = ( (JlineCommandInput) session.getInput() ).getConsole();
        }

        protected void printLine( String line )
            throws IOException
        {
            console.redrawLine();
            console.print( line );
        }
    }

    private static abstract class Output
    {
        protected abstract void printLine( String line )
            throws IOException;
    }

    private static class ReportOutput
        extends Output
    {
        private final CommandOutput out;

        private ReportOutput( Session session )
        {
            this.out = session.output;
        }

        @Override
        protected void printLine( String line )
        {
            out.println( line );
        }

    }

    private static final String BUILDING_ATTRIBUTE_NOW = "%now";

    private static final int DEFAULT_REFRESH_INTERVAL = 1;

    private List<String> attributes = new ArrayList<String>();

    private String outputFormat;

    private int refreshInterval = DEFAULT_REFRESH_INTERVAL;

    private boolean report;

    private int stopAfter;

    /**
     * @inheritDoc
     */
    @Override
    public List<String> doSuggestArgument()
        throws IOException, JMException
    {
        if ( getSession().getBean() != null )
        {
            MBeanServerConnection con = getSession().getConnection().getServerConnection();
            MBeanAttributeInfo[] ais = con.getMBeanInfo( new ObjectName( getSession().getBean() ) ).getAttributes();
            List<String> results = new ArrayList<String>( ais.length );
            for ( MBeanAttributeInfo ai : ais )
            {
                results.add( ai.getName() );
            }
            results.add( BUILDING_ATTRIBUTE_NOW );
            return results;
        }
        return null;
    }

    /**
     * @inheritDoc
     */
    @Override
    public void execute()
        throws IOException, JMException
    {
        if ( report && stopAfter == 0 )
        {
            throw new IllegalArgumentException( "When --report is sepcified, --stopafter(-s) must be specificed" );
        }
        Session session = getSession();
        String domain = DomainCommand.getDomainName( null, session );
        if ( domain == null )
        {
            throw new IllegalStateException( "Please specify a domain using domain command first." );
        }
        String beanName = BeanCommand.getBeanName( null, domain, session );
        if ( beanName == null )
        {
            throw new IllegalStateException( "Please specify a bean using bean command first." );
        }

        final ObjectName name = new ObjectName( beanName );
        final MBeanServerConnection con = session.getConnection().getServerConnection();
        final Output output;
        if ( report )
        {
            output = new ReportOutput( session );
        }
        else
        {
            output = new ConsoleOutput( session );
            getSession().output.printMessage( "press any key to stop. DO NOT press Ctrl+C !!!" );
        }

        final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
        executor.scheduleWithFixedDelay( new Runnable()
        {
            public void run()
            {
                try
                {
                    printValues( name, con, output );
                }
                catch ( IOException e )
                {
                    getSession().output.printError( e );
                }
            }
        }, 0, refreshInterval, TimeUnit.SECONDS );
        if ( stopAfter > 0 )
        {
            executor.schedule( new Runnable()
            {
                public void run()
                {
                    executor.shutdownNow();
                }
            }, stopAfter, TimeUnit.SECONDS );
        }
        if ( !report )
        {
            System.in.read();
            System.out.println();
            executor.shutdownNow();
        }

        session.output.println( "" );
    }

    private Object getAttributeValue( ObjectName beanName, String attributeName, MBeanServerConnection connection )
        throws IOException
    {
        // $now is a reserved keyword for current java.util.Date
        if ( attributeName.equals( BUILDING_ATTRIBUTE_NOW ) )
        {
            return new Date();
        }
        try
        {
            return connection.getAttribute( beanName, attributeName );
        }
        catch ( JMException e )
        {
            return e.getClass().getSimpleName();
        }
    }

    private void printValues( ObjectName beanName, MBeanServerConnection connection, Output output )
        throws IOException
    {
        StringBuffer result = new StringBuffer();
        if ( outputFormat == null )
        {
            boolean first = true;
            for ( String attributeName : attributes )
            {
                if ( first )
                {
                    first = false;
                }
                else
                {
                    result.append( ", " );
                }
                result.append( getAttributeValue( beanName, attributeName, connection ) );
            }
        }
        else
        {
            Object[] values = new Object[attributes.size()];
            int i = 0;
            for ( String attributeNamne : attributes )
            {
                values[i++] = getAttributeValue( beanName, attributeNamne, connection );
            }
            MessageFormat format = new MessageFormat( outputFormat );
            format.format( values, result, new FieldPosition( 0 ) );
        }
        output.printLine( result.toString() );
    }

    /**
     * @param attributes Name of attributes to watch
     */
    @MultiValue( listType = ArrayList.class, minValues = 1 )
    @Argument( displayName = "attr", description = "Name of attributes to watch" )
    public final void setAttributes( List<String> attributes )
    {
        this.attributes = attributes;
    }

    /**
     * @param outputFormat Pattern used in {@link MessageFormat}
     */
    @Option( name = "f", longName = "format", displayName = "expr", description = "Java pattern(java.text.MessageFormat) to print attribute values" )
    public final void setOutputFormat( String outputFormat )
    {
        this.outputFormat = outputFormat;
    }

    /**
     * @param refreshInterval Refreshing interval in seconds
     */
    @Option( name = "i", longName = "interval", displayName = "sec", description = "Optional number of seconds between consecutive poll, default is 1 second", defaultValue = "1" )
    public final void setRefreshInterval( int refreshInterval )
    {
        Validate.isTrue( refreshInterval > 0, "Invalid interval value " + refreshInterval );
        this.refreshInterval = refreshInterval;
    }

    /**
     * @param report True to output result line by line as report
     */
    @Option( name = "r", longName = "report", description = "Output result line by line as report" )
    public final void setReport( boolean report )
    {
        this.report = report;
    }

    /**
     * @param stopAfter After this number of seconds, stop watching
     */
    @Option( name = "s", longName = "stopafter", displayName = "sec", description = "Stop after watching a number of seconds" )
    public final void setStopAfter( int stopAfter )
    {
        Validate.isTrue( stopAfter >= 0, "Invalid stop after argument " + stopAfter );
        this.stopAfter = stopAfter;
    }
}
TOP

Related Classes of org.cyclopsgroup.jmxterm.cmd.WatchCommand$ReportOutput

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.