1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package org.apache.jmeter.protocol.java.sampler; 20 21 import java.io.FileInputStream; 22 23 import org.apache.bsf.BSFEngine; 24 import org.apache.bsf.BSFException; 25 import org.apache.bsf.BSFManager; 26 import org.apache.commons.io.IOUtils; 27 import org.apache.jmeter.samplers.Entry; 28 import org.apache.jmeter.samplers.SampleResult; 29 import org.apache.jmeter.samplers.Sampler; 30 import org.apache.jmeter.util.BSFTestElement; 31 import org.apache.jorphan.logging.LoggingManager; 32 import org.apache.log.Logger; 33 34 /** 35 * A sampler which understands BSF 36 * 37 */ 38 public class BSFSampler extends BSFTestElement implements Sampler { 39 40 private static final Logger log = LoggingManager.getLoggerForClass(); 41 42 //+ JMX file attributes - do not change 43 private static final String FILENAME = "BSFSampler.filename"; //$NON-NLS-1$ 44 45 private static final String SCRIPT = "BSFSampler.query"; //$NON-NLS-1$ 46 47 private static final String LANGUAGE = "BSFSampler.language"; //$NON-NLS-1$ 48 49 private static final String PARAMETERS = "BSFSampler.parameters"; //$NON-NLS-1$ 50 //- JMX file attributes 51 52 public BSFSampler() { 53 super(); 54 } 55 56 public String getFilename() { 57 return getPropertyAsString(FILENAME); 58 } 59 60 public void setFilename(String newFilename) { 61 this.setProperty(FILENAME, newFilename); 62 } 63 64 public String getScript() { 65 return this.getPropertyAsString(SCRIPT); 66 } 67 68 public void setScript(String newScript) { 69 this.setProperty(SCRIPT, newScript); 70 } 71 72 public String getParameters() { 73 return this.getPropertyAsString(PARAMETERS); 74 } 75 76 public void setParameters(String newScript) { 77 this.setProperty(PARAMETERS, newScript); 78 } 79 80 public String getScriptLanguage() { 81 return this.getPropertyAsString(LANGUAGE); 82 } 83 84 public void setScriptLanguage(String lang) { 85 this.setProperty(LANGUAGE, lang); 86 } 87 88 /** 89 * Returns a formatted string label describing this sampler 90 * 91 * @return a formatted string label describing this sampler 92 */ 93 94 public String getLabel() { 95 return getName(); 96 } 97 98 public SampleResult sample(Entry e)// Entry tends to be ignored ... 99 { 100 final String label = getLabel(); 101 final String request = getScript(); 102 final String fileName = getFilename(); 103 log.debug(label + " " + fileName); 104 SampleResult res = new SampleResult(); 105 res.setSampleLabel(label); 106 FileInputStream is = null; 107 BSFEngine bsfEngine = null; 108 // There's little point saving the manager between invocations 109 // as we need to reset most of the beans anyway 110 BSFManager mgr = new BSFManager(); 111 112 // TODO: find out how to retrieve these from the script 113 // At present the script has to use SampleResult methods to set them. 114 res.setResponseCode("200"); // $NON-NLS-1$ 115 res.setResponseMessage("OK"); // $NON-NLS-1$ 116 res.setSuccessful(true); 117 res.setDataType(SampleResult.TEXT); // Default (can be overridden by the script) 118 119 res.sampleStart(); 120 try { 121 initManager(mgr); 122 mgr.declareBean("SampleResult", res, res.getClass()); // $NON-NLS-1$ 123 124 // These are not useful yet, as have not found how to get updated values back 125 //mgr.declareBean("ResponseCode", "200", String.class); // $NON-NLS-1$ 126 //mgr.declareBean("ResponseMessage", "OK", String.class); // $NON-NLS-1$ 127 //mgr.declareBean("IsSuccess", Boolean.TRUE, Boolean.class); // $NON-NLS-1$ 128 129 // N.B. some engines (e.g. Javascript) cannot handle certain declareBean() calls 130 // after the engine has been initialised, so create the engine last 131 bsfEngine = mgr.loadScriptingEngine(getScriptLanguage()); 132 133 Object bsfOut = null; 134 if (fileName.length()>0) { 135 res.setSamplerData("File: "+fileName); 136 is = new FileInputStream(fileName); 137 bsfOut = bsfEngine.eval(fileName, 0, 0, IOUtils.toString(is)); 138 } else { 139 res.setSamplerData(request); 140 bsfOut = bsfEngine.eval("script", 0, 0, request); 141 } 142 143 if (bsfOut != null) { 144 res.setResponseData(bsfOut.toString().getBytes()); 145 } 146 } catch (BSFException ex) { 147 log.warn("BSF error", ex); 148 res.setSuccessful(false); 149 res.setResponseCode("500"); // $NON-NLS-1$ 150 res.setResponseMessage(ex.toString()); 151 } catch (Exception ex) {// Catch evaluation errors 152 log.warn("Problem evaluating the script", ex); 153 res.setSuccessful(false); 154 res.setResponseCode("500"); // $NON-NLS-1$ 155 res.setResponseMessage(ex.toString()); 156 } finally { 157 res.sampleEnd(); 158 IOUtils.closeQuietly(is); 159 // Will be done by mgr.terminate() anyway 160 // if (bsfEngine != null) { 161 // bsfEngine.terminate(); 162 // } 163 mgr.terminate(); 164 } 165 166 return res; 167 } 168 }