Coverage Report - kg.apc.jmeter.jmxmon.JMXMonCollector
 
Classes in this File Line Coverage Branch Coverage Complexity
JMXMonCollector
62%
86/138
44%
16/36
2.588
 
 1  
 package kg.apc.jmeter.jmxmon;
 2  
 
 3  
 import kg.apc.jmeter.JMeterPluginsUtils;
 4  
 import kg.apc.jmeter.vizualizers.CorrectedResultCollector;
 5  
 import org.apache.jmeter.samplers.SampleEvent;
 6  
 import org.apache.jmeter.samplers.SampleSaveConfiguration;
 7  
 import org.apache.jmeter.testelement.property.CollectionProperty;
 8  
 import org.apache.jmeter.testelement.property.JMeterProperty;
 9  
 import org.apache.jmeter.util.JMeterUtils;
 10  
 import org.apache.jorphan.logging.LoggingManager;
 11  
 import org.apache.log.Logger;
 12  
 
 13  
 import javax.management.MBeanServerConnection;
 14  
 import javax.management.remote.JMXConnector;
 15  
 import javax.management.remote.JMXConnectorFactory;
 16  
 import javax.management.remote.JMXServiceURL;
 17  
 import java.io.File;
 18  
 import java.io.IOException;
 19  
 import java.net.MalformedURLException;
 20  
 import java.text.SimpleDateFormat;
 21  
 import java.util.*;
 22  
 
 23  
 public class JMXMonCollector
 24  
         extends CorrectedResultCollector
 25  
         implements Runnable, JMXMonSampleGenerator {
 26  
 
 27  
 
 28  
     private static final long serialVersionUID = 1437356057522465756L;
 29  
 
 30  
     private static final boolean autoGenerateFiles;
 31  
     private static final String JMXMON = "JmxMon";
 32  1
     private static final Logger log = LoggingManager.getLoggerForClass();
 33  
     public static final String DATA_PROPERTY = "samplers";
 34  
     private int interval;
 35  13
     private Thread workerThread = null;
 36  13
     protected List<JMXMonSampler> jmxMonSamplers = new ArrayList<JMXMonSampler>();
 37  13
     private String autoFileBaseName = null;
 38  1
     private static int counter = 0;
 39  13
     private String workerHost = null;
 40  
 
 41  
     static {
 42  1
         autoGenerateFiles = (JMeterUtils.getPropDefault("forceJmxMonFile", "false")).trim().equalsIgnoreCase("true");
 43  1
     }
 44  
 
 45  
     private synchronized String getAutoFileName() {
 46  0
         String ret = "";
 47  0
         counter++;
 48  0
         if (autoFileBaseName == null) {
 49  0
             Calendar now = Calendar.getInstance();
 50  0
             SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd-HHmmss");
 51  0
             autoFileBaseName = "jmxMon_" + formatter.format(now.getTime());
 52  
         }
 53  0
         ret = ret + autoFileBaseName;
 54  0
         if (counter > 1) {
 55  0
             ret = ret + "_" + counter;
 56  
         }
 57  0
         ret = ret + ".csv";
 58  
 
 59  0
         return ret;
 60  
     }
 61  
 
 62  13
     public JMXMonCollector() {
 63  13
         interval = JMeterUtils.getPropDefault("jmeterPlugin.jmxmon.interval", 1000);
 64  13
     }
 65  
 
 66  
     public void setData(CollectionProperty rows) {
 67  4
         setProperty(rows);
 68  4
     }
 69  
 
 70  
     public JMeterProperty getSamplerSettings() {
 71  4
         return getProperty(DATA_PROPERTY);
 72  
     }
 73  
 
 74  
     @Override
 75  
     public synchronized void run() {
 76  
         try {
 77  
             while (true) {
 78  15
                 processConnectors();
 79  15
                 this.wait(interval);
 80  
             }
 81  0
         } catch (InterruptedException ex) {
 82  0
             log.debug("Monitoring thread was interrupted", ex);
 83  
         }
 84  0
     }
 85  
 
 86  
     //ensure we start only on one host (if multiple slaves)
 87  
     private synchronized boolean isWorkingHost(String host) {
 88  2
         if (workerHost == null) {
 89  2
             workerHost = host;
 90  2
             return true;
 91  
         } else {
 92  0
             return host.equals(workerHost);
 93  
         }
 94  
     }
 95  
 
 96  
     @Override
 97  
     public void testStarted(String host) {
 98  
 
 99  2
         if (!isWorkingHost(host)) {
 100  0
             return;
 101  
         }
 102  
 
 103  
         //ensure the data will be saved
 104  2
         if (getProperty(FILENAME) == null || getProperty(FILENAME).getStringValue().trim().length() == 0) {
 105  2
             if (autoGenerateFiles) {
 106  0
                 setupSaving(getAutoFileName());
 107  
             } else {
 108  2
                 log.info("JmxMon metrics will not be recorded! Please specify a file name in the gui or run the test with -JforceJmxMonFile=true");
 109  
             }
 110  
         }
 111  
         try {
 112  2
             initiateConnectors();
 113  0
         } catch (MalformedURLException ex) {
 114  
             //throw new RuntimeException(ex);
 115  0
             log.error("Malformed JMX url", ex);
 116  0
         } catch (IOException ex) {
 117  0
             log.error("IOException reading JMX", ex);
 118  2
         }
 119  
 
 120  2
         workerThread = new Thread(this);
 121  2
         workerThread.start();
 122  
 
 123  2
         super.testStarted(host);
 124  2
     }
 125  
 
 126  
     private void setupSaving(String fileName) {
 127  0
         SampleSaveConfiguration config = getSaveConfig();
 128  0
         JMeterPluginsUtils.doBestCSVSetup(config);
 129  0
         setSaveConfig(config);
 130  0
         setFilename(fileName);
 131  0
         log.info("JMXMon metrics will be stored in " + new File(fileName).getAbsolutePath());
 132  0
     }
 133  
 
 134  
     @Override
 135  
     public void testEnded(String host) {
 136  2
         log.debug("Start testEnded");
 137  2
         workerHost = null;
 138  2
         if (workerThread == null) {
 139  1
             log.debug("End   testEnded workerThread == null");
 140  1
             return;
 141  
         }
 142  
 
 143  1
         workerThread.interrupt();
 144  1
         shutdownConnectors();
 145  
 
 146  
         //reset autoFileName for next test run
 147  1
         autoFileBaseName = null;
 148  1
         counter = 0;
 149  1
         super.testEnded(host);
 150  1
         log.debug("End   testEnded");
 151  1
     }
 152  
 
 153  
     private void initiateConnectors() throws IOException {
 154  2
         JMeterProperty prop = getSamplerSettings();
 155  2
         jmxMonSamplers.clear();
 156  2
         if (!(prop instanceof CollectionProperty)) {
 157  1
             log.warn("Got unexpected property: " + prop);
 158  1
             return;
 159  
         }
 160  1
         CollectionProperty rows = (CollectionProperty) prop;
 161  
 
 162  3
         for (int i = 0; i < rows.size(); i++) {
 163  2
             ArrayList<Object> row = (ArrayList<Object>) rows.get(i).getObjectValue();
 164  2
             String label = ((JMeterProperty) row.get(0)).getStringValue();
 165  2
             String jmxUrl = ((JMeterProperty) row.get(1)).getStringValue();
 166  2
             String username = ((JMeterProperty) row.get(2)).getStringValue();
 167  2
             String password = ((JMeterProperty) row.get(3)).getStringValue();
 168  2
             String objectName = ((JMeterProperty) row.get(4)).getStringValue();
 169  2
             String attribute = ((JMeterProperty) row.get(5)).getStringValue();
 170  2
             String key = ((JMeterProperty) row.get(6)).getStringValue();
 171  2
             boolean isDelta = ((JMeterProperty) row.get(7)).getBooleanValue();
 172  
 
 173  2
             JMXServiceURL u = new JMXServiceURL(jmxUrl);
 174  2
             Hashtable attributes = new Hashtable();
 175  2
             String[] buffer = {username, password};
 176  2
             attributes.put("jmx.remote.credentials", (String[]) buffer);
 177  
 
 178  2
             initiateConnector(u, attributes, jmxUrl, label, isDelta, objectName, attribute, key);
 179  
         }
 180  1
     }
 181  
 
 182  
     protected void initiateConnector(JMXServiceURL u, Hashtable attributes, String jmxUrl, String name, boolean delta, String objectName, String attribute, String key) throws IOException {
 183  0
         JMXConnector jmxConnector = null;
 184  0
         MBeanServerConnection mBeanServerConn = findConnectionSameUrl(jmxUrl);
 185  
 
 186  0
         if (mBeanServerConn == null) {
 187  0
             log.debug("Create new connection url = " + jmxUrl);
 188  0
             jmxConnector = JMXConnectorFactory.connect(u, attributes);
 189  0
             mBeanServerConn = jmxConnector.getMBeanServerConnection();
 190  
         } else {
 191  0
             log.debug("Reused the same connection for url = " + jmxUrl);
 192  
         }
 193  
 
 194  0
         jmxMonSamplers.add(new JMXMonSampler(mBeanServerConn, jmxConnector, jmxUrl, name, objectName, attribute, key, delta));
 195  0
     }
 196  
 
 197  
     private MBeanServerConnection findConnectionSameUrl(String url) {
 198  0
         MBeanServerConnection conn = null;
 199  0
         boolean continueFind = true;
 200  0
         Iterator<JMXMonSampler> it = jmxMonSamplers.iterator();
 201  
 
 202  0
         while (it.hasNext() && continueFind) {
 203  0
             JMXMonSampler jmxSampler = it.next();
 204  0
             String urlTemp = jmxSampler.getUrl();
 205  0
             if (urlTemp != null && urlTemp.equals(url)) {
 206  0
                 conn = jmxSampler.getRemote();
 207  0
                 continueFind = false;
 208  
             }
 209  0
         }
 210  
 
 211  0
         return conn;
 212  
     }
 213  
 
 214  
     private void shutdownConnectors() {
 215  1
         log.debug("Start shutdownConnectors");
 216  
 
 217  1
         for (JMXMonSampler jmxSampler : jmxMonSamplers) {
 218  2
             JMXConnector jmxConnector = jmxSampler.getJmxConnector();
 219  2
             if (jmxConnector != null) {
 220  
                 try {
 221  0
                     jmxConnector.close();
 222  0
                     log.debug("jmx connector is closed");
 223  0
                 } catch (Exception ex) {
 224  0
                     log.debug("Can't close jmx connector, but continue");
 225  0
                 }
 226  
             } else {
 227  2
                 log.debug("jmxConnector == null, don't try to close connection");
 228  
             }
 229  2
         }
 230  1
         jmxMonSamplers.clear();
 231  1
         log.debug("End  shutdownConnectors");
 232  1
     }
 233  
 
 234  
     protected void processConnectors() {
 235  19
         for (JMXMonSampler sampler : jmxMonSamplers) {
 236  6
             sampler.generateSamples(this);
 237  6
         }
 238  19
     }
 239  
 
 240  
     @Override
 241  
     public void sampleOccurred(SampleEvent event) {
 242  
         // just dropping regular test samples
 243  6
     }
 244  
 
 245  
     protected void jmxMonSampleOccurred(SampleEvent event) {
 246  2
         super.sampleOccurred(event);
 247  2
     }
 248  
 
 249  
     @Override
 250  
     public void generateSample(double value, String label) {
 251  6
         JMXMonSampleResult res = new JMXMonSampleResult();
 252  6
         res.setSampleLabel(label);
 253  6
         res.setValue(value);
 254  6
         res.setSuccessful(true);
 255  6
         SampleEvent e = new SampleEvent(res, JMXMON);
 256  6
         jmxMonSampleOccurred(e);
 257  6
     }
 258  
 }