org.jmeterplugins.protocol.http.control.HttpSimpleTableServer Maven / Gradle / Ivy
Show all versions of jmeter-plugins-extras Show documentation
/*
* 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.jmeterplugins.protocol.http.control;
import org.apache.jmeter.gui.Stoppable;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
public class HttpSimpleTableServer extends NanoHTTPD implements Stoppable, KeyWaiter {
private static final Logger log = LoggingManager.getLoggerForClass();
public static final String ROOT = "/sts/";
public static final String ROOT2 = "/sts";
public static final String URI_INITFILE = "INITFILE";
public static final String URI_READ = "READ";
public static final String URI_ADD = "ADD";
public static final String URI_SAVE = "SAVE";
public static final String URI_LENGTH = "LENGTH";
public static final String URI_STATUS = "STATUS";
public static final String URI_RESET = "RESET";
public static final String URI_STOP = "STOP";
public static final String PARM_FILENAME = "FILENAME";
public static final String PARM_LINE = "LINE";
public static final String PARM_READ_MODE = "READ_MODE";
public static final String PARM_ADD_MODE = "ADD_MODE";
public static final String PARM_KEEP = "KEEP";
public static final String VAL_FIRST = "FIRST";
public static final String VAL_LAST = "LAST";
public static final String VAL_RANDOM = "RANDOM";
public static final String VAL_TRUE = "TRUE";
public static final String VAL_FALSE = "FALSE";
public static final String INDEX = "URL for the dataset "
+ "From a data file (default: <JMETER_HOME>/bin/[data_file])
"
+ "Load file in memory:
"
+ "http://hostname:port/sts/INITFILE?FILENAME=file.txt
"
+ "Get one line from list:
"
+ "http://hostname:port/sts/READ?READ_MODE=[FIRST,LAST,RANDOM]&KEEP=[TRUE,FALSE]&FILENAME=file.txt
"
+ "Return the number of remaining lines of a linked list:
"
+ "http://hostname:port/sts/LENGTH?FILENAME=file.txt
"
+ "Add a line into a file: (POST HTTP protocol)
"
+ "FILENAME=file.txt,LINE=D0001123,ADD_MODE=[FIRST,LAST]
"
+ "Save the specified linked list in a file to the default location:
"
+ "http://hostname:port/sts/SAVE?FILENAME=file.txt
"
+ "Display the list of loaded files and the number of remaining lines for each linked list:
"
+ "http://hostname:port/sts/STATUS
"
+ "Remove all of the elements from the specified list:
"
+ "http://hostname:port/sts/RESET?FILENAME=file.txt
"
+ "Shutdown the Simple Table Server:
"
+ "http://hostname:port/sts/STOP
";
private String myDataDirectory;
private boolean bTimestamp;
private Random myRandom;
// CRLF ou LF ou CR
public static String lineSeparator = System.getProperty("line.separator");
private Map> database = new HashMap>();
public HttpSimpleTableServer(int port, boolean timestamp, String dataDir) {
super(port);
myDataDirectory = dataDir;
bTimestamp = timestamp;
myRandom = new Random();
}
@Override
public Response serve(IHTTPSession session) {
Method method = session.getMethod();
String uri = session.getUri();
String msg = "KO " + lineSeparator
+ "Error : unknown command !" + lineSeparator
+ "";
Map files = new HashMap();
if (Method.POST.equals(method)) {
try {
session.parseBody(files);
} catch (IOException ioe) {
return new Response(Response.Status.INTERNAL_ERROR,
MIME_PLAINTEXT, "SERVER INTERNAL ERROR: IOException: "
+ ioe.getMessage());
} catch (ResponseException re) {
return new Response(re.getStatus(), MIME_PLAINTEXT,
re.getMessage());
}
}
Map parms = session.getParms();
if (uri.equals(ROOT) || uri.equals(ROOT2)) {
msg = INDEX;
} else {
msg = doAction(uri, method, parms);
}
return new NanoHTTPD.Response(msg);
}
protected synchronized String doAction(String uri, Method method,
Map parms) {
String msg = "KO " + lineSeparator
+ "Error : unknown command !" + lineSeparator
+ "";
if (uri.equals(ROOT + URI_INITFILE)) {
msg = initFile(parms.get(PARM_FILENAME));
}
if (uri.equals(ROOT + URI_READ)) {
msg = read(parms.get(PARM_READ_MODE), parms.get(PARM_KEEP),
parms.get(PARM_FILENAME));
}
if (uri.equals(ROOT + URI_ADD) && Method.POST.equals(method)) {
msg = add(parms.get(PARM_ADD_MODE), parms.get(PARM_LINE),
parms.get(PARM_FILENAME));
}
if (uri.equals(ROOT + URI_LENGTH)) {
msg = length(parms.get(PARM_FILENAME));
}
if (uri.equals(ROOT + URI_SAVE)) {
msg = save(parms.get(PARM_FILENAME));
}
if (uri.equals(ROOT + URI_STATUS)) {
msg = status();
}
if (uri.equals(ROOT + URI_RESET)) {
msg = reset(parms.get(PARM_FILENAME));
}
if (uri.equals(ROOT + URI_STOP)) {
stopServer();
}
return msg;
}
private String status() {
if (database.isEmpty()) {
return "KO " + lineSeparator
+ "Error : Database was empty !"
+ lineSeparator + "";
}
String msg = "";
for (String key : database.keySet()) {
msg += key + " = " + database.get(key).size() + "
"
+ lineSeparator;
}
return "OK " + lineSeparator + ""
+ lineSeparator + msg + "";
}
private String read(String readMode, String keepMode, String filename) {
if (null == filename) {
return "KO " + lineSeparator
+ "Error : FILENAME parameter was missing !"
+ lineSeparator + "";
}
if (!database.containsKey(filename)) {
return "KO " + lineSeparator + "Error : "
+ filename + " not loaded yet !" + lineSeparator
+ "";
}
if (database.get(filename).isEmpty()) {
return "KO " + lineSeparator
+ "Error : No more line !" + lineSeparator
+ "";
}
if (null == readMode) {
readMode = VAL_FIRST;
}
if (null == keepMode) {
keepMode = VAL_TRUE;
}
if (!VAL_FIRST.equals(readMode) && !VAL_LAST.equals(readMode)
&& !VAL_RANDOM.equals(readMode)) {
return "KO "
+ lineSeparator
+ "Error : READ_MODE value has to be FIRST, LAST or RANDOM !"
+ lineSeparator + "";
}
if (!VAL_TRUE.equals(keepMode) && !VAL_FALSE.equals(keepMode)) {
return "KO "
+ lineSeparator
+ "Error : KEEP value has to be TRUE or FALSE !"
+ lineSeparator + "";
}
String line;
int index = 0;
if (VAL_LAST.equals(readMode)) {
index = database.get(filename).size() - 1;
}
if (VAL_RANDOM.equals(readMode)) {
index = myRandom.nextInt(database.get(filename).size());
}
line = database.get(filename).remove(index);
if (VAL_TRUE.equals(keepMode)) {
database.get(filename).add(line);
}
return "OK " + lineSeparator + "" + line
+ "" + lineSeparator + "";
}
private String add(String addMode, String line, String filename) {
if (null == filename) {
return "KO " + lineSeparator
+ "Error : FILENAME parameter was missing !"
+ lineSeparator + "";
}
if (null == line) {
return "KO " + lineSeparator
+ "Error : LINE parameter was missing !"
+ lineSeparator + "";
}
if (!database.containsKey(filename)) {
database.put(filename, new LinkedList());
}
if (null == addMode) {
addMode = VAL_FIRST;
}
if (!VAL_FIRST.equals(addMode) && !VAL_LAST.equals(addMode)) {
return "KO "
+ lineSeparator
+ "Error : ADD_MODE value has to be FIRST or LAST !"
+ lineSeparator + "";
}
if (VAL_FIRST.equals(addMode)) {
database.get(filename).addFirst(line);
} else {
database.get(filename).add(line);
}
return "OK " + lineSeparator + ""
+ lineSeparator + "";
}
private String save(String filename) {
if (null == filename) {
return "KO " + lineSeparator
+ "Error : FILENAME parameter was missing !"
+ lineSeparator + "";
}
if (filename.matches(".*[\\\\/:].*") || filename.equals(".")
|| filename.equals("..")) {
return "KO " + lineSeparator
+ "Error : Illegal character found !"
+ lineSeparator + "";
}
if (filename.length() > 128) {
return "KO " + lineSeparator
+ "Error : Maximum size reached (128) !"
+ lineSeparator + "";
}
if (!database.containsKey(filename)) {
return "KO " + lineSeparator
+ "Error : LinkedList not found !"
+ lineSeparator + "";
}
BufferedWriter out = null;
String saveFilename = filename;
if (bTimestamp) {
Date dNow = new Date();
SimpleDateFormat ft = new SimpleDateFormat(
"yyyyMMdd'T'HH'h'mm'm'ss's.'");
saveFilename = ft.format(dNow) + filename;
}
try {
Iterator it = database.get(filename).iterator();
out = new BufferedWriter(new FileWriter(new File(myDataDirectory,
saveFilename)));
while (it.hasNext()) {
out.write(it.next());
out.write(lineSeparator);
}
} catch (FileNotFoundException e1) {
return "KO " + lineSeparator + "Error : "
+ e1.getMessage() + "" + lineSeparator + "";
} catch (IOException e2) {
return "KO " + lineSeparator + "Error : "
+ e2.getMessage() + "" + lineSeparator + "";
} finally {
if (null != out) {
try {
out.close();
} catch (IOException e3) {
return "KO " + lineSeparator
+ "Error : " + e3.getMessage() + ""
+ lineSeparator + "";
}
}
}
return "OK " + lineSeparator + ""
+ database.get(filename).size() + "" + lineSeparator
+ "";
}
private String length(String filename) {
if (null == filename) {
return "KO " + lineSeparator
+ "Error : FILENAME parameter was missing !"
+ lineSeparator + "";
}
if (!database.containsKey(filename)) {
return "KO " + lineSeparator + "Error : "
+ filename + " not loaded yet !" + lineSeparator
+ "";
}
return "OK " + lineSeparator + ""
+ database.get(filename).size() + "" + lineSeparator
+ "";
}
private String reset(String filename) {
if (null == filename) {
return "KO " + lineSeparator
+ "Error : FILENAME parameter was missing !"
+ lineSeparator + "";
}
if (database.containsKey(filename)) {
database.get(filename).clear();
}
return "OK " + lineSeparator + ""
+ lineSeparator + "";
}
private String initFile(String filename) {
if (null == filename) {
return "KO " + lineSeparator
+ "Error : FILENAME parameter was missing !"
+ lineSeparator + "";
}
LinkedList lines = new LinkedList();
BufferedReader bufferReader = null;
File f = new File(myDataDirectory, filename);
if (f.exists()) {
try {
bufferReader = new BufferedReader(new FileReader(f), 50 * 1024);
String line;
while ((line = bufferReader.readLine()) != null) {
lines.add(line);
}
} catch (FileNotFoundException e1) {
return "KO " + lineSeparator
+ "Error : " + e1.getMessage() + ""
+ lineSeparator + "";
} catch (IOException e2) {
return "KO " + lineSeparator
+ "Error : " + e2.getMessage() + ""
+ lineSeparator + "";
} finally {
if (null != bufferReader) {
try {
bufferReader.close();
} catch (IOException e3) {
return "KO " + lineSeparator
+ "Error : " + e3.getMessage()
+ "" + lineSeparator + "";
}
}
}
database.put(filename, lines);
return "OK " + lineSeparator + ""
+ lines.size() + "" + lineSeparator + "";
}
return "KO " + lineSeparator
+ "Error : file not found !" + lineSeparator
+ "";
}
@Override
public void stopServer() {
log.info("HTTP Simple Table Server is shutting down...");
stop();
}
public static void main(String args[]) {
JMeterUtils.loadJMeterProperties("jmeter.properties");
String dataset = JMeterUtils.getPropDefault(
"jmeterPlugin.sts.datasetDirectory",
HttpSimpleTableControl.DEFAULT_DATA_DIR);
int port = JMeterUtils.getPropDefault("jmeterPlugin.sts.port",
HttpSimpleTableControl.DEFAULT_PORT);
boolean timestamp = JMeterUtils.getPropDefault(
"jmeterPlugin.sts.addTimestamp",
HttpSimpleTableControl.DEFAULT_TIMESTAMP);
// default level
LoggingManager.setPriority("INFO");
// allow override by system properties
LoggingManager.setLoggingLevels(System.getProperties());
HttpSimpleTableServer serv = new HttpSimpleTableServer(port, timestamp,
dataset);
log.info("Creating HttpSimpleTable ...");
log.info("------------------------------");
log.info("SERVER_PORT : " + port);
log.info("DATASET_DIR : " + dataset);
log.info("TIMESTAMP : " + timestamp);
log.info("------------------------------");
ServerRunner.executeInstance(serv);
}
public void waitForKey() {
log.info("Hit Enter to stop");
try {
System.in.read();
} catch (Throwable ignored) {
}
}
}