activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From chir...@apache.org
Subject svn commit: r882835 - in /activemq/sandbox/activemq-apollo: activemq-syscall/ activemq-syscall/src/main/java/org/apache/activemq/syscall/ activemq-syscall/src/main/java/org/apache/activemq/syscall/jni/ activemq-syscall/src/main/java/org/apache/activemq...
Date Sat, 21 Nov 2009 06:52:24 GMT
Author: chirino
Date: Sat Nov 21 06:52:23 2009
New Revision: 882835

URL: http://svn.apache.org/viewvc?rev=882835&view=rev
Log:
Adding a little disk benchmark util for to compare the syscall stuff.


Added:
    activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/util/
    activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/util/DiskBenchmark.java
    activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/cli/
    activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/cli/CommandLineSupport.java
    activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/cli/CommonsCLISupport.java
    activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/cli/OptionBuilder.java
Removed:
    activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/CommandLineSupport.java
Modified:
    activemq/sandbox/activemq-apollo/activemq-syscall/pom.xml
    activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/FileDescriptor.java
    activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/NativeAllocation.java
    activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/jni/IO.java
    activemq/sandbox/activemq-apollo/activemq-util/pom.xml
    activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/DiskBenchmark.java
    activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/IntrospectionSupport.java

Modified: activemq/sandbox/activemq-apollo/activemq-syscall/pom.xml
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo/activemq-syscall/pom.xml?rev=882835&r1=882834&r2=882835&view=diff
==============================================================================
--- activemq/sandbox/activemq-apollo/activemq-syscall/pom.xml (original)
+++ activemq/sandbox/activemq-apollo/activemq-syscall/pom.xml Sat Nov 21 06:52:23 2009
@@ -66,6 +66,12 @@
       <artifactId>activemq-util</artifactId>
     </dependency>
     
+    <dependency>
+      <groupId>commons-cli</groupId>
+      <artifactId>commons-cli</artifactId>
+      <version>1.0</version>
+      <optional>true</optional>
+    </dependency>
 
     <dependency>
       <groupId>junit</groupId>

Modified: activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/FileDescriptor.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/FileDescriptor.java?rev=882835&r1=882834&r2=882835&view=diff
==============================================================================
--- activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/FileDescriptor.java
(original)
+++ activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/FileDescriptor.java
Sat Nov 21 06:52:23 2009
@@ -94,6 +94,18 @@
         return fd;
     }
 
+    public long seek(long offset) throws IOException {
+        return seek(offset, SEEK_SET);
+    }
+    
+    public long seek(long offset, int whence) throws IOException {
+        long rc = IO.lseek(fd, offset, whence);
+        if (rc == -1) {
+            throw error();
+        }
+        return rc;
+    }
+
     public long write(NativeAllocation buffer) throws IOException {
         long rc = IO.write(fd, buffer.pointer(), buffer.length());
         if (rc == -1) {
@@ -217,7 +229,11 @@
         agent().watch(aiocbp, callback);
     }
 
-    public void sync() {
+    public void sync() throws IOException {
+        int rc = IO.fsync(fd);
+        if( rc == -1 ) {
+            throw error();
+        }
     }
 
     public boolean isfullSyncSupported() {

Modified: activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/NativeAllocation.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/NativeAllocation.java?rev=882835&r1=882834&r2=882835&view=diff
==============================================================================
--- activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/NativeAllocation.java
(original)
+++ activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/NativeAllocation.java
Sat Nov 21 06:52:23 2009
@@ -44,7 +44,7 @@
         this.length = length;
     }
     
-    private static NativeAllocation allocate(byte[] value) {
+    public static NativeAllocation allocate(byte[] value) {
         int size = value.length;
         NativeAllocation rc = allocate(size);
         memmove(rc.pointer(), value, size);

Modified: activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/jni/IO.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/jni/IO.java?rev=882835&r1=882834&r2=882835&view=diff
==============================================================================
--- activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/jni/IO.java
(original)
+++ activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/jni/IO.java
Sat Nov 21 06:52:23 2009
@@ -210,6 +210,21 @@
     @JniMethod(conditional="defined(HAVE_FCNTL_FUNCTION)")
     public static final native int fcntl(int fd, int cmd, long arg);
 
+    @JniField(flags={CONSTANT})
+    public static int SEEK_SET;
+    @JniField(flags={CONSTANT})
+    public static int SEEK_CUR;
+    @JniField(flags={CONSTANT})
+    public static int SEEK_END;
+
+    public static final native int fsync(int fd);
+
+    @JniMethod(cast="off_t")
+    public static final native long lseek(
+            int fd, 
+            @JniArg(cast="off_t") long buffer, 
+            int whence);
+    
     @JniMethod(cast="size_t")
     public static final native long read(
             int fd, 

Added: activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/util/DiskBenchmark.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/util/DiskBenchmark.java?rev=882835&view=auto
==============================================================================
--- activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/util/DiskBenchmark.java
(added)
+++ activemq/sandbox/activemq-apollo/activemq-syscall/src/main/java/org/apache/activemq/syscall/util/DiskBenchmark.java
Sat Nov 21 06:52:23 2009
@@ -0,0 +1,610 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.syscall.util;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.RandomAccessFile;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.activemq.syscall.FileDescriptor;
+import org.apache.activemq.syscall.NativeAllocation;
+import org.apache.activemq.util.cli.CommonsCLISupport;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.PosixParser;
+
+import static java.util.concurrent.TimeUnit.*;
+import static org.apache.activemq.syscall.jni.IO.*;
+import static org.apache.activemq.util.cli.OptionBuilder.*;
+
+/**
+ * This class is used to get a benchmark the raw disk performance.
+ */
+public class DiskBenchmark {
+
+    private static final HashSet<String> OPS = new HashSet<String>();
+    private static String op(String v) {
+        OPS.add(v);
+        return v;
+    }
+    private static final String WRITE_OP = op("write");
+    private static final String READ_OP = op("read");
+    
+    private static final HashSet<String> APIS = new HashSet<String>();
+    private static String api(String v) {
+        APIS.add(v);
+        return v;
+    }
+    private static final String NATIVE_BIO_API = api("native-bio");
+    private static final String JAVA_API = api("java");
+    
+    boolean verbose;
+    // reads and writes work with 4k of data at a time.
+    int blockSize=1024*4; 
+    long blocks=128000;
+    String file;
+    int sampleCount = 10;
+    double samplePeriod = 1;
+    
+    String[] api = { JAVA_API, NATIVE_BIO_API };
+    String[] operation = { WRITE_OP };
+    boolean[] random={ false };
+    boolean[] memcopy={ false };
+    boolean[] sync={ false };
+    
+    static private Options createOptions() {
+        Options options = new Options();
+        options.addOption("h", "help",    false, "Display help information");
+        options.addOption("v", "verbose", false, "Verbose");
+
+        options.addOption(ob()
+                .id("f")
+                .name("file")
+                .arg("path")
+                .description("").op());
+
+        options.addOption(ob()
+                .id("s")
+                .name("block-size")
+                .arg("bytes")
+                .description("").op());
+
+        options.addOption(ob()
+                .id("b")
+                .name("blocks")
+                .arg("count")
+                .description("").op());
+
+        options.addOption(ob()
+                .id("c")
+                .name("sample-count")
+                .arg("number")
+                .description("").op());
+        
+        options.addOption(ob()
+                .id("p")
+                .name("sample-period")
+                .arg("seconds")
+                .description("").op());
+
+        options.addOption(ob()
+                .name("sync")
+                .args(2)
+                .sperator(',')
+                .arg("true,false")
+                .description("").op());
+
+        return options;
+    }
+
+
+    public static void main(String[] args) {
+        String jv = System.getProperty("java.version").substring(0, 3);
+        if (jv.compareTo("1.5") < 0) {
+            System.err.println("This application requires jdk 1.5 or higher to run, the current
java version is " + System.getProperty("java.version"));
+            System.exit(-1);
+            return;
+        }
+
+        DiskBenchmark app = new DiskBenchmark();
+        System.exit(app.execute(args));
+    }
+    
+    ///////////////////////////////////////////////////////////////////
+    // Entry point for an embedded users who want to call us with
+    // via command line arguments.
+    ///////////////////////////////////////////////////////////////////
+    public int execute(String[] args) {
+        CommandLine cli = null;
+        try {
+            cli = new PosixParser().parse(createOptions(), args, true);
+        } catch (ParseException e) {
+            System.err.println( "Unable to parse command line options: " + e.getMessage()
);
+            displayHelp();
+            return 1;
+        }
+
+        if( cli.hasOption("h") ) {
+            displayHelp();
+            return 0;
+        }
+        
+        DiskBenchmark benchmark = new DiskBenchmark();
+        args = CommonsCLISupport.setOptions(benchmark, cli);
+        try {
+            benchmark.benchmark();
+            return 0;
+        } catch (UsageException e) {
+            System.out.println("Invalid Usage: "+e.getMessage());
+            displayHelp();
+            return -1;
+        } catch (Throwable e) {
+            System.out.flush();
+            if (benchmark.verbose) {
+                System.err.println("ERROR:");
+                e.printStackTrace();
+            } else {
+                System.err.println("ERROR: " + e);
+            }
+            System.err.flush();
+            return -2;
+        }
+    }
+    
+    @SuppressWarnings("serial")
+    static class UsageException extends Exception {
+        public UsageException(String msg) {
+            super(msg);
+        }
+    }
+    
+    public void benchmark() throws IOException, UsageException {
+        if( file==null ) {
+            throw new UsageException("file not specified.");
+        }
+        
+        for (String v : api) {
+            if( !APIS.contains(v) ) {
+                throw new UsageException("invalid api: "+v);
+            }
+        }
+        for (String v : operation) {
+            if( !OPS.contains(v) ) {
+                throw new UsageException("invalid operation: "+v);
+            }
+        }
+        
+        PrintWriter pw = new PrintWriter(new FileOutputStream("report.html"));
+        writeReportHeader(pw);
+        int chartCounter=0;
+        for (boolean memcopy : this.memcopy) {
+            for (String operation : this.operation) {
+                for (boolean random : this.random) {
+                    for (boolean sync : this.sync) {
+                        ArrayList<Benchmark> results = new ArrayList<Benchmark>(this.api.length);

+                        for (String apiName : this.api) {
+                            Benchmark benchmark = createBenchmark(apiName);
+                            benchmark.random = random;
+                            benchmark.sync = sync;
+                            benchmark.memcopy = memcopy;
+                            benchmark.apiName = apiName;
+                            benchmark.operation = operation;
+                            benchmark.execute();
+                            results.add(benchmark);
+                        }
+                        writeReportChart(pw, chartCounter++, results);
+                    }
+                }
+            }
+        }
+        
+        writeReportFooter(pw);
+        pw.close();
+
+    }
+
+    private void writeReportHeader(PrintWriter pw) {
+        if(pw==null) 
+            return;
+        pw.println("<html>");
+        pw.println("  <head>");
+        pw.println("    <script type='text/javascript' src='http://www.google.com/jsapi'></script>");
+        pw.println("    <script type='text/javascript'>");
+        pw.println("      google.load('visualization', '1', {'packages':['linechart']});");
+        pw.println("    </script>");
+        pw.println("    <style type='text/css'>");
+        pw.println("      .chart-section {width:640px; padding-left: 30px}");
+        pw.println("      .chart-props {width:140px; padding:0; padding-top:20px; float:left;}");
+        pw.println("      .chart-graph {width: 500px; height: 200px; float:right; }");
+        pw.println("    </style>");
+        pw.println("  </head>");
+        pw.println("  <body>");
+    }
+    
+    private void writeReportChart(PrintWriter pw, int id, ArrayList<Benchmark> data)
{
+        if(pw==null) 
+            return;
+        Benchmark d1 = data.get(0);
+        
+        String titleX = String.format("Period (%.2f seconds)", samplePeriod);
+        String titleY = "IO Operations";
+        
+        pw.println("    <div class='chart-section'>");
+        pw.println("      <ul class='chart-props'>");
+        pw.println("        <li>operation: "+d1.operation+"</li><li>sync:
"+d1.sync+"</li><li>memcopy: "+d1.memcopy+"</li><li>random: "+d1.random+"</li>");
+        pw.println("      </ul>");
+        pw.println("      <div id='chart_"+id+"' class='chart-graph '></div>");
+        pw.println("    </div>");
+        pw.println("    <script type='text/javascript'>");
+        pw.println("      google.setOnLoadCallback(draw_chart_"+id+");");
+        pw.println("      function draw_chart_"+id+"() {");
+        pw.println("        var data = new google.visualization.DataTable();");
+        pw.println("        data.addColumn('string', 'Period');");
+        
+        for (Benchmark d : data) {
+            pw.println("        data.addColumn('number', '"+d.apiName+"');");
+        }
+        pw.println("        data.addRows([");
+        for( int i=0; i < sampleCount; i++ ) {
+            if( i!=0 ) {
+                pw.println(",");
+            }
+            pw.print("          ['"+i+"'");
+            for (Benchmark d : data) {
+                long value = 0;
+                if( d.samples.size() >i ) {
+                    value = d.samples.get(i);
+                }
+                pw.print(", "+value);
+            }
+            pw.print("]");
+        }
+        
+        pw.println("        ]);");
+        pw.println("        var chart = new google.visualization.LineChart(document.getElementById('chart_"+id+"'));");
+        pw.println("        chart.draw(data, {legend: 'bottom', smoothLine:true, titleX:'"+titleX+"',
titleY:'"+titleY+"' });");
+        pw.println("      }");
+        pw.println("    </script>");
+        
+    }
+
+    private String title(ArrayList<Benchmark> data) {
+        Benchmark d = data.get(0);
+        return "operation: "+d.operation+", sync: "+d.sync+", memcopy: "+d.memcopy+", random:
"+d.random;
+    }
+
+
+    private void writeReportFooter(PrintWriter pw) {
+        if(pw==null) 
+            return;
+        pw.println("  </body>");
+        pw.println("</html>");
+    }
+
+    private Benchmark createBenchmark(String api) {
+        if( JAVA_API.equals(api) ) 
+            return new JavaApi();
+        if( NATIVE_BIO_API.equals(api) ) 
+            return new NativeBioApi();
+        throw new RuntimeException("Unsupported API: "+api);
+    }
+
+    static public class Sampler extends Thread {
+        private final AtomicReference<ArrayList<Long>> samples = new AtomicReference<ArrayList<Long>>();
+        private final AtomicLong metric;
+        private final int count;
+        private final long period;
+        public boolean verbose;
+        
+        public Sampler(AtomicLong metric, int count, double periodInSecs) {
+            super("Sampler");
+            this.metric = metric;
+            this.count = count;
+            this.period = ns(periodInSecs);
+            setPriority(MAX_PRIORITY);
+            setDaemon(true);
+        }
+        
+        static private long ns(double v) {
+            return (long)(v*NANOSECONDS.convert(1, SECONDS));
+        }
+
+        @Override
+        public void run() {
+            ArrayList<Long> samples = new ArrayList<Long>(count);
+            try {
+                long sleepMS = period/1000000;
+                int sleepNS = (int) (period%1000000);
+                long currentValue;
+                long lastValue = metric.get();
+                for (int i = 0; i < count; i++) {
+                    if( verbose ) {
+                        System.out.print(".");
+                    }
+                    Thread.sleep(sleepMS,sleepNS);
+                    currentValue = metric.get();
+                    samples.add(currentValue-lastValue);
+                    lastValue=currentValue;
+                }
+            } catch (InterruptedException e) {
+            } finally {
+                if( verbose ) {
+                    System.out.println();
+                }
+                this.samples.set(samples);
+            }
+        }
+        
+        public synchronized ArrayList<Long> getSamples() {
+            return samples.get();
+        }
+    }
+    
+    abstract class Benchmark {
+        
+        public String apiName;
+        public String operation;
+        public boolean random; 
+        public boolean sync;
+        public boolean memcopy;
+        public ArrayList<Long> samples;
+        
+        final public void execute() throws IOException {
+            
+            boolean write;
+            if( WRITE_OP.equals(operation) ) {
+                write = true;
+            } else if( READ_OP.equals(operation) ) {
+                write = false;
+            } else {
+                throw new RuntimeException();
+            }
+            
+            System.out.print("Benchmarking: api: "+apiName+", operation: "+operation+", random:
"+random+", sync: "+sync+", memcopy: "+memcopy+" ");
+
+            AtomicLong ioCount=new AtomicLong();
+            Sampler sampler = new Sampler(ioCount, sampleCount, samplePeriod);
+            sampler.verbose = verbose;
+            try {
+                init(true);
+                sampler.start();
+                outer: while( true ) {
+                    seek(0);
+                    for( long i=0; i < blocks; i++) {
+                        if( write ) {
+                            write();
+                            if( sync ) {
+                                sync();
+                            }
+                        } else {
+                            read();
+                        }
+                        ioCount.incrementAndGet();
+                        if( !sampler.isAlive() ) {
+                            break outer;
+                        }
+                    }
+                }
+            } finally {
+                dispose();
+            }
+            samples = sampler.getSamples();
+            System.out.println("  results: "+samples);
+            System.out.println();
+
+        }
+
+        abstract protected void init(boolean write) throws IOException;
+        abstract protected void dispose() throws IOException;
+        abstract protected void seek(long pos) throws IOException;
+        abstract protected void write() throws IOException;
+        abstract protected void read() throws IOException;
+        abstract protected void sync() throws IOException;
+        
+    }
+    
+    class NativeBioApi extends Benchmark {
+        
+        private FileDescriptor fd;
+        private NativeAllocation data;
+
+        @Override
+        protected void init(boolean write) throws IOException {
+            data = NativeAllocation.allocate(block());
+            if( write ) {
+                int oflags =  O_CREAT | O_TRUNC | O_WRONLY;
+                int mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
+                fd = FileDescriptor.open(file, oflags, mode);
+            } else {
+                int oflags =  O_RDONLY;
+                fd = FileDescriptor.open(file, oflags);
+            }
+        }
+
+        @Override
+        protected void dispose() throws IOException {
+            if( data!=null ) 
+                data.free();
+            if( fd!=null ) 
+                fd.close();
+        }
+
+        @Override
+        protected void seek(long pos) throws IOException {
+            fd.seek(pos);
+        }
+
+        @Override
+        protected void sync() throws IOException {
+            fd.sync();
+        }
+
+        @Override
+        protected void write() throws IOException {
+            fd.write(data);
+        }
+        
+        @Override
+        protected void read() throws IOException {
+            fd.read(data);
+        }
+    }
+    
+    class JavaApi extends Benchmark {
+        
+        private RandomAccessFile raf;
+        private byte data[];
+
+        @Override
+        protected void init(boolean write) throws IOException {
+            data = block();
+            if( write ) {
+                raf = new RandomAccessFile(file, "rw");
+            } else {
+                raf = new RandomAccessFile(file, "r");
+            }
+        }
+
+        @Override
+        protected void dispose() throws IOException {
+            if( raf!=null ) 
+                raf.close();
+        }
+
+        @Override
+        protected void seek(long pos) throws IOException {
+            raf.seek(pos);
+        }
+
+        @Override
+        protected void sync() throws IOException {
+            raf.getFD().sync();
+        }
+
+        @Override
+        protected void write() throws IOException {
+            raf.write(data);
+        }
+        
+        @Override
+        protected void read() throws IOException {
+            raf.readFully(data);
+        }
+    }
+    
+    private byte[] block() {
+        byte []data = new byte[blockSize];
+        for (int i = 0; i < data.length; i++) {
+            data[i] = (byte)('a'+(i%26));
+        }
+        return data;
+    }
+
+    private void displayHelp() {
+        System.err.flush();
+        String app = System.getProperty("diskbenchmark.application");
+        if( app == null ) {
+            try {
+                URL location = getClass().getProtectionDomain().getCodeSource().getLocation();
+                String[] split = location.toString().split("/");
+                if( split[split.length-1].endsWith(".jar") ) {
+                    app = split[split.length-1];
+                }
+            } catch (Throwable e) {
+            }
+            if( app == null ) {
+                app = getClass().getSimpleName();
+            }
+        }
+
+        // The commented out line is 80 chars long.  We have it here as a visual reference
+//      p("                                                                             
  ");
+        p();
+        p("Usage: "+ app +" [options]");
+        p();
+        p("Description:");
+        p();
+        pw("  "+app+" is a disk benchmarker.", 2);
+        p();
+
+        p("Options:");
+        p();
+        PrintWriter out = new PrintWriter(System.out);
+        HelpFormatter formatter = new HelpFormatter();
+        formatter.printOptions(out, 78, createOptions(), 2, 2);
+        out.flush();
+        p();
+    }
+    
+
+    private void p() {
+        System.out.println();
+    }
+    private void p(String s) {
+        System.out.println(s);
+    }
+    private void pw(String message, int indent) {
+        PrintWriter out = new PrintWriter(System.out);
+        HelpFormatter formatter = new HelpFormatter();
+        formatter.printWrapped(out, 78, indent, message);
+        out.flush();
+    }
+
+
+    public void setVerbose(boolean verbose) {
+        this.verbose = verbose;
+    }
+    public void setBlockSize(int blockSize) {
+        this.blockSize = blockSize;
+    }
+    public void setBlocks(long blocks) {
+        this.blocks = blocks;
+    }
+    public void setFile(String file) {
+        this.file = file;
+    }
+    public void setSampleCount(int sampleCount) {
+        this.sampleCount = sampleCount;
+    }
+    public void setSamplePeriod(double samplePeriod) {
+        this.samplePeriod = samplePeriod;
+    }
+    public void setApi(String[] api) {
+        this.api = api;
+    }
+    public void setOperation(String[] operation) {
+        this.operation = operation;
+    }
+    public void setRandom(boolean[] random) {
+        this.random = random;
+    }
+    public void setMemcopy(boolean[] memcopy) {
+        this.memcopy = memcopy;
+    }
+    public void setSync(boolean[] sync) {
+        this.sync = sync;
+    }
+    
+}

Modified: activemq/sandbox/activemq-apollo/activemq-util/pom.xml
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo/activemq-util/pom.xml?rev=882835&r1=882834&r2=882835&view=diff
==============================================================================
--- activemq/sandbox/activemq-apollo/activemq-util/pom.xml (original)
+++ activemq/sandbox/activemq-apollo/activemq-util/pom.xml Sat Nov 21 06:52:23 2009
@@ -60,6 +60,13 @@
       <optional>true</optional>
     </dependency>
                 
+    <dependency>
+      <groupId>commons-cli</groupId>
+      <artifactId>commons-cli</artifactId>
+      <version>1.0</version>
+      <optional>true</optional>
+    </dependency>
+                
     <!-- Testing Dependencies -->    
     <dependency>
       <groupId>junit</groupId>

Modified: activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/DiskBenchmark.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/DiskBenchmark.java?rev=882835&r1=882834&r2=882835&view=diff
==============================================================================
--- activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/DiskBenchmark.java
(original)
+++ activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/DiskBenchmark.java
Sat Nov 21 06:52:23 2009
@@ -23,6 +23,8 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 
+import org.apache.activemq.util.cli.CommandLineSupport;
+
 
 /**
  * This class is used to get a benchmark the raw disk performance.

Modified: activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/IntrospectionSupport.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/IntrospectionSupport.java?rev=882835&r1=882834&r2=882835&view=diff
==============================================================================
--- activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/IntrospectionSupport.java
(original)
+++ activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/IntrospectionSupport.java
Sat Nov 21 06:52:23 2009
@@ -32,7 +32,6 @@
 
 
 
-
 public final class IntrospectionSupport {
 	
 	static {
@@ -69,13 +68,13 @@
             optionPrefix = "";
         }
 
-        Class clazz = target.getClass();
+        Class<?> clazz = target.getClass();
         Method[] methods = clazz.getMethods();
         for (int i = 0; i < methods.length; i++) {
             Method method = methods[i];
             String name = method.getName();
-            Class type = method.getReturnType();
-            Class params[] = method.getParameterTypes();
+            Class<?> type = method.getReturnType();
+            Class<?> params[] = method.getParameterTypes();
             if ((name.startsWith("is") || name.startsWith("get")) && params.length
== 0 && type != null && isSettableType(type)) {
 
                 try {
@@ -174,7 +173,7 @@
 
     public static boolean setProperty(Object target, String name, Object value) {
         try {
-            Class clazz = target.getClass();
+            Class<?> clazz = target.getClass();
             Method setter = findSetterMethod(clazz, name);
             if (setter == null) {
                 return false;
@@ -194,7 +193,19 @@
         }
     }
 
-    private static Object convert(Object value, Class type) {
+    private static Object convert(Object value, Class<?> type) {
+        if( type.isArray() ) {
+            if( value.getClass().isArray() ) {
+                int length = Array.getLength(value);
+                Class<?> componentType = type.getComponentType();
+                Object rc = Array.newInstance(componentType, length);
+                for (int i = 0; i < length; i++) {
+                    Object o = Array.get(value, i);
+                    Array.set(rc, i, convert(o, componentType));
+                }
+                return rc;
+            }
+        }
         PropertyEditor editor = PropertyEditorManager.findEditor(type);
         if (editor != null) {
             editor.setAsText(value.toString());
@@ -203,7 +214,7 @@
         return null;
     }
 
-    public static String convertToString(Object value, Class type) {
+    public static String convertToString(Object value, Class<?> type) {
         PropertyEditor editor = PropertyEditorManager.findEditor(type);
         if (editor != null) {
             editor.setValue(value);
@@ -212,13 +223,13 @@
         return null;
     }
 
-    private static Method findSetterMethod(Class clazz, String name) {
+    private static Method findSetterMethod(Class<?> clazz, String name) {
         // Build the method name.
         name = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
         Method[] methods = clazz.getMethods();
         for (int i = 0; i < methods.length; i++) {
             Method method = methods[i];
-            Class params[] = method.getParameterTypes();
+            Class<?> params[] = method.getParameterTypes();
             if (method.getName().equals(name) && params.length == 1 ) {
                 return method;
             }
@@ -226,7 +237,7 @@
         return null;
     }
 
-    private static boolean isSettableType(Class clazz) {
+    private static boolean isSettableType(Class<?> clazz) {
         if (PropertyEditorManager.findEditor(clazz) != null) {
             return true;
         }
@@ -238,11 +249,11 @@
         return toString(target, Object.class, null);
     }
     
-    public static String toString(Object target, Class stopClass) {
+    public static String toString(Object target, Class<?> stopClass) {
     	return toString(target, stopClass, null);
     }
 
-    public static String toString(Object target, Class stopClass, Map<String, Object>
overrideFields) {
+    public static String toString(Object target, Class<?> stopClass, Map<String,
Object> overrideFields) {
         LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
         addFields(target, target.getClass(), stopClass, map);
         if (overrideFields != null) {
@@ -280,7 +291,7 @@
 //        }
     }
 
-    public static String simpleName(Class clazz) {
+    public static String simpleName(Class<?> clazz) {
         String name = clazz.getName();
         int p = name.lastIndexOf(".");
         if (p >= 0) {
@@ -289,7 +300,7 @@
         return name;
     }
 
-    private static void addFields(Object target, Class startClass, Class<Object> stopClass,
LinkedHashMap<String, Object> map) {
+    private static void addFields(Object target, Class<?> startClass, Class<?>
stopClass, LinkedHashMap<String, Object> map) {
 
         if (startClass != stopClass) {
             addFields(target, startClass.getSuperclass(), stopClass, map);

Added: activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/cli/CommandLineSupport.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/cli/CommandLineSupport.java?rev=882835&view=auto
==============================================================================
--- activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/cli/CommandLineSupport.java
(added)
+++ activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/cli/CommandLineSupport.java
Sat Nov 21 06:52:23 2009
@@ -0,0 +1,117 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.util.cli;
+
+import java.util.ArrayList;
+
+import org.apache.activemq.util.IntrospectionSupport;
+
+/**
+ * Support utility that can be used to set the properties on any object
+ * using command line arguments.
+ * 
+ * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
+ */
+public class CommandLineSupport {
+	
+	/**
+	 * Sets the properties of an object given the command line args.
+	 * 
+	 * if args contains: --ack-mode=AUTO --url=tcp://localhost:61616 --persistent 
+	 * 
+	 * then it will try to call the following setters on the target object.
+	 * 
+	 * target.setAckMode("AUTO");
+	 * target.setURL(new URI("tcp://localhost:61616") );
+	 * target.setPersistent(true);
+	 * 
+	 * Notice the the proper conversion for the argument is determined by examining the 
+	 * setter argument type.  
+	 * 
+	 * @param target the object that will have it's properties set
+	 * @param args the command line options
+	 * @return any arguments that are not valid options for the target
+	 */
+	static public String[] setOptions(Object target, String []args) {
+		ArrayList<String> rc = new ArrayList<String>();
+		
+		for (int i = 0; i < args.length; i++) {
+			if( args[i] == null )
+				continue;
+			
+			if( args[i].startsWith("--") ) {
+				
+				// --options without a specified value are considered boolean flags that are enabled.
+				String value="true";
+				String name = args[i].substring(2);
+				
+				// if --option=value case
+				int p = name.indexOf("=");
+				if( p > 0 ) {
+					value = name.substring(p+1);
+					name = name.substring(0,p);
+				}
+				
+				// name not set, then it's an unrecognized option
+				if( name.length()==0 ) {
+					rc.add(args[i]);
+					continue;
+				}
+				
+				String propName = convertOptionToPropertyName(name);
+				if( !IntrospectionSupport.setProperty(target, propName, value) ) {					
+					rc.add(args[i]);
+					continue;
+				}
+			} else {
+                            rc.add(args[i]);
+			}
+			
+		}
+		
+		String r[] = new String[rc.size()];
+		rc.toArray(r);
+		return r;
+	}
+
+	/**
+	 * converts strings like: test-enabled to testEnabled
+	 * @param name
+	 * @return
+	 */
+	private static String convertOptionToPropertyName(String name) {
+		String rc="";
+		
+		// Look for '-' and strip and then convert the subsequent char to uppercase
+		int p = name.indexOf("-");
+		while( p > 0 ) {
+			// strip
+			rc += name.substring(0, p);
+			name = name.substring(p+1);
+			
+			// can I convert the next char to upper?
+			if( name.length() >0 ) {
+				rc += name.substring(0,1).toUpperCase();
+				name = name.substring(1);
+			}
+			
+			p = name.indexOf("-");
+		}
+		return rc+name;
+	}
+}

Added: activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/cli/CommonsCLISupport.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/cli/CommonsCLISupport.java?rev=882835&view=auto
==============================================================================
--- activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/cli/CommonsCLISupport.java
(added)
+++ activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/cli/CommonsCLISupport.java
Sat Nov 21 06:52:23 2009
@@ -0,0 +1,61 @@
+package org.apache.activemq.util.cli;
+
+import org.apache.activemq.util.IntrospectionSupport;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+
+public class CommonsCLISupport {
+    
+    /**
+     */
+    static public String[] setOptions(Object target,  CommandLine cli) {
+        Option[] options = cli.getOptions();
+        for (Option option : options) {
+            String name = option.getLongOpt();
+            if( name==null ) 
+                continue;
+            
+            String propName = convertOptionToPropertyName(name);
+            
+            
+            String value = option.getValue();
+            if( value!=null ) {
+                if( !IntrospectionSupport.setProperty(target, propName, option.getValues())
) {
+                    if( !IntrospectionSupport.setProperty(target, propName, option.getValuesList()))
{
+                        IntrospectionSupport.setProperty(target, propName, value);
+                    }
+                }                
+            } else {
+                IntrospectionSupport.setProperty(target, propName, true);               
  
+            }
+        }
+        return cli.getArgs();
+    }
+
+    /**
+     * converts strings like: test-enabled to testEnabled
+     * @param name
+     * @return
+     */
+    private static String convertOptionToPropertyName(String name) {
+        String rc="";
+        
+        // Look for '-' and strip and then convert the subsequent char to uppercase
+        int p = name.indexOf("-");
+        while( p > 0 ) {
+            // strip
+            rc += name.substring(0, p);
+            name = name.substring(p+1);
+            
+            // can I convert the next char to upper?
+            if( name.length() >0 ) {
+                rc += name.substring(0,1).toUpperCase();
+                name = name.substring(1);
+            }
+            
+            p = name.indexOf("-");
+        }
+        return rc+name;
+    }
+
+}

Added: activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/cli/OptionBuilder.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/cli/OptionBuilder.java?rev=882835&view=auto
==============================================================================
--- activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/cli/OptionBuilder.java
(added)
+++ activemq/sandbox/activemq-apollo/activemq-util/src/main/java/org/apache/activemq/util/cli/OptionBuilder.java
Sat Nov 21 06:52:23 2009
@@ -0,0 +1,102 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.util.cli;
+
+import org.apache.commons.cli.Option;
+
+/**
+ * a better version of org.apache.commons.cli.OptionBuilder
+ * IDE provides nicer auto complete and less compiler warnings.
+ * 
+ * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
+ */
+public class OptionBuilder {
+
+    private String id;
+    private String name;
+    private String description;
+    private boolean required;
+    private boolean optional;
+    private int args =-1;
+    private String arg;
+    private Object type;
+    private char sperator;
+
+    public static OptionBuilder ob() {
+        return new OptionBuilder();
+    }
+
+    public Option op() {
+        Option option = new Option( id!=null ? id : " ", description );
+        option.setLongOpt(name);
+        option.setRequired( required );
+        option.setOptionalArg(optional);
+        option.setType( type );
+        option.setValueSeparator(sperator);
+        if( arg !=null && args==-1 ) {
+            args=1;
+        }
+        option.setArgs(args);
+        option.setArgName(arg);
+        return option;
+    }
+
+    public OptionBuilder arg(String argName) {
+        this.arg = argName;
+        return this;
+    }
+
+    public OptionBuilder args(int args) {
+        this.args = args;
+        return this;
+    }
+
+    public OptionBuilder description(String description) {
+        this.description = description;
+        return this;
+    }
+
+    public OptionBuilder name(String lname) {
+        this.name = lname;
+        return this;
+    }
+
+    public OptionBuilder id(String name) {
+        this.id = name;
+        return this;
+    }
+
+    public OptionBuilder optional(boolean optional) {
+        this.optional = optional;
+        return this;
+    }
+
+    public OptionBuilder required(boolean required) {
+        this.required = required;
+        return this;
+    }
+
+    public OptionBuilder sperator(char sperator) {
+        this.sperator = sperator;
+        return this;
+    }
+
+    public OptionBuilder type(Object type) {
+        this.type = type;
+        return this;
+    }
+}
\ No newline at end of file



Mime
View raw message