Java tutorial
/** * Copyright 2009 - 2011 Sergio Bossa (sergio.bossa@gmail.com) * * Licensed 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 terrastore.metrics; import org.apache.commons.httpclient.HttpConnectionManager; import org.apache.commons.httpclient.params.HttpConnectionManagerParams; import java.io.StringWriter; import java.util.UUID; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PutMethod; import org.apache.commons.httpclient.methods.StringRequestEntity; import org.codehaus.jackson.map.ObjectMapper; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * @author Sergio Bossa */ public class PerformanceTest { private static final String HOST = "127.0.0.1"; private static final int NODE1_PORT = 8080; private static final int SETUP_TIME = 90000; private static final int CONCURRENCY = 25; private static final HttpClient HTTP_CLIENT = new HttpClient(); @BeforeClass public static void setUpClass() throws Exception { HTTP_CLIENT.setHttpConnectionManager(new MultiThreadedHttpConnectionManager()); System.err.println("Waiting " + SETUP_TIME + " millis for system to set up ..."); Thread.sleep(SETUP_TIME); // HttpConnectionManagerParams httpParams = new HttpConnectionManagerParams(); httpParams.setDefaultMaxConnectionsPerHost(100); httpParams.setMaxTotalConnections(100); HttpConnectionManager httpManager = new MultiThreadedHttpConnectionManager(); httpManager.setParams(httpParams); HTTP_CLIENT.setHttpConnectionManager(httpManager); } @Test public void writeOnly() throws Exception { final String bucket = UUID.randomUUID().toString(); int warmup = 1000; int writes = 1000; final ExecutorService threadPool = Executors.newFixedThreadPool(CONCURRENCY); final CountDownLatch termination = new CountDownLatch(writes); final String payload = getPayload(); warmUp(warmup, bucket, payload); System.err.println("Starting writeOnly performance test."); long start = System.currentTimeMillis(); for (int i = warmup; i < warmup + writes; i++) { final int index = i; threadPool.execute(new Runnable() { public void run() { try { PutMethod putValue = null; putValue = makePutMethod(NODE1_PORT, bucket + "/value" + index); putValue.setRequestEntity(new StringRequestEntity(payload, "application/json", null)); HTTP_CLIENT.executeMethod(putValue); assertEquals(HttpStatus.SC_NO_CONTENT, putValue.getStatusCode()); putValue.releaseConnection(); termination.countDown(); } catch (Exception ex) { throw new RuntimeException(ex); } } }); } threadPool.shutdown(); termination.await(Integer.MAX_VALUE, TimeUnit.SECONDS); long elapsed = System.currentTimeMillis() - start; System.err.println("Elapsed time in millis: " + elapsed); } @Test public void writeThenRead() throws Exception { final String bucket = UUID.randomUUID().toString(); final String payload = getPayload(); int warmup = 1000; int writes = 1000; warmUp(warmup, bucket, payload); System.err.println("Starting writeThenRead performance test."); ExecutorService threadPool = Executors.newFixedThreadPool(CONCURRENCY); long start = System.currentTimeMillis(); for (int i = warmup; i < warmup + writes; i++) { final int index = i; threadPool.execute(new Runnable() { public void run() { try { PutMethod putValue = null; putValue = makePutMethod(NODE1_PORT, bucket + "/value" + index); putValue.setRequestEntity(new StringRequestEntity(payload, "application/json", null)); HTTP_CLIENT.executeMethod(putValue); assertEquals(HttpStatus.SC_NO_CONTENT, putValue.getStatusCode()); putValue.releaseConnection(); } catch (Exception ex) { throw new RuntimeException(ex); } } }); } threadPool.shutdown(); threadPool.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); long elapsed = System.currentTimeMillis() - start; System.err.println("Elapsed write time in millis: " + elapsed); threadPool = Executors.newFixedThreadPool(CONCURRENCY); start = System.currentTimeMillis(); for (int i = warmup; i < warmup + writes; i++) { final int index = i; threadPool.execute(new Runnable() { public void run() { try { GetMethod getValue = null; getValue = makeGetMethod(NODE1_PORT, bucket + "/value" + index); HTTP_CLIENT.executeMethod(getValue); assertEquals(HttpStatus.SC_OK, getValue.getStatusCode()); getValue.releaseConnection(); } catch (Exception ex) { throw new RuntimeException(ex); } } }); } threadPool.shutdown(); threadPool.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); elapsed = System.currentTimeMillis() - start; System.err.println("Elapsed read time in millis: " + elapsed); } private String getPayload() throws Exception { final String payload = toJson(new TestValue("value", 1)); System.err.println("Payload bytes length: " + payload.getBytes().length); return payload; } private void warmUp(int warmup, String bucket, String payload) throws RuntimeException { System.err.println("Warming up..."); for (int i = 0; i < warmup; i++) { try { PutMethod putValue = null; putValue = makePutMethod(NODE1_PORT, bucket + "/value" + i); putValue.setRequestEntity(new StringRequestEntity(payload, "application/json", null)); HTTP_CLIENT.executeMethod(putValue); assertEquals(HttpStatus.SC_NO_CONTENT, putValue.getStatusCode()); putValue.releaseConnection(); } catch (Exception ex) { throw new RuntimeException(ex); } } } private PutMethod makePutMethod(int nodePort, String path) { PutMethod method = new PutMethod("http://" + HOST + ":" + nodePort + "/" + path); method.setRequestHeader("Content-Type", "application/json"); return method; } private GetMethod makeGetMethod(int nodePort, String path) { GetMethod method = new GetMethod("http://" + HOST + ":" + nodePort + "/" + path); method.setRequestHeader("Content-Type", "application/json"); return method; } private String toJson(TestValue value) throws Exception { ObjectMapper jsonMapper = new ObjectMapper(); StringWriter result = new StringWriter(); jsonMapper.writeValue(result, value); return result.toString(); } private static class TestValue { private String stringField; private int numField; private String[] constantArray = new String[] { "a", "b", "c" }; private InnerValue constantValue = new InnerValue("inner", 1); public TestValue(String stringField, int numField) { this.stringField = stringField; this.numField = numField; } protected TestValue() { } public String getStringField() { return stringField; } public int getNumField() { return numField; } public String[] getConstantArray() { return constantArray; } public InnerValue getConstantValue() { return constantValue; } private void setStringField(String stringField) { this.stringField = stringField; } private void setNumField(int numField) { this.numField = numField; } private void setConstantArray(String[] constantArray) { this.constantArray = constantArray; } private void setConstantValue(InnerValue constantValue) { this.constantValue = constantValue; } @Override public boolean equals(Object obj) { TestValue other = (TestValue) obj; return this.stringField.equals(other.stringField) && this.numField == other.numField; } @Override public int hashCode() { return stringField.hashCode() * numField; } private static class InnerValue { private String stringField; private int numField; private String[] constantArray = new String[] { "a", "b", "c" }; public InnerValue(String stringField, int numField) { this.stringField = stringField; this.numField = numField; } protected InnerValue() { } public String getStringField() { return stringField; } public int getNumField() { return numField; } public String[] getConstantArray() { return constantArray; } private void setStringField(String stringField) { this.stringField = stringField; } private void setNumField(int numField) { this.numField = numField; } private void setConstantArray(String[] constantArray) { this.constantArray = constantArray; } @Override public boolean equals(Object obj) { InnerValue other = (InnerValue) obj; return this.stringField.equals(other.stringField) && this.numField == other.numField; } @Override public int hashCode() { return stringField.hashCode() * numField; } } } }