/******************************************************************************* * Copyright 2013-2015 alladin-IT GmbH * * 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 at.alladin.rmbt.client.v2.task; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.FilterInputStream; import java.io.FilterOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; import java.util.Locale; import at.alladin.rmbt.client.AbstractRMBTTest; import at.alladin.rmbt.client.QualityOfServiceTest; import at.alladin.rmbt.client.v2.task.result.QoSTestResult; import at.alladin.rmbt.client.v2.task.result.QoSTestResultEnum; import at.alladin.rmbt.client.v2.task.service.TestProgressListener.TestProgressEvent; /** * Superclass of all QoS tasks<br> * When creating a new task place a call to {@link AbstractQoSTask#onStart(QoSTestResult)} at the beginning of the test and a call to {@link AbstractQoSTask#onEnd(QoSTestResult)} at the absolute end of the test.<br> * @author lb * */ public abstract class AbstractQoSTask extends AbstractRMBTTest implements QoSTask { /** * timeout to establish a control connection for a test */ public final static int CONTROL_CONNECTION_TIMEOUT = 10000; public final static String QOS_SERVER_PROTOCOL_VERSION = "QoSSP0.1"; public final static String PARAM_QOS_TEST_OBJECTIVE_ID = "qos_test_uid"; public final static String PARAM_QOS_TEST_OBJECTIVE_PORT = "server_port"; public final static String PARAM_QOS_TEST_OBJECTIVE_ADDRESS = "server_addr"; public final static String PARAM_QOS_CONCURRENCY_GROUP = "concurrency_group"; public final static String PARAM_QOS_RESULT_START_TIME = "start_time_ns"; public final static String PARAM_QOS_RESULT_END_TIME = "end_time_ns"; public final static String PARAM_QOS_RESULT_DURATION_NS = "duration_ns"; /** * */ private final int priority; private final int serverPort; private final int concurrencyGroup; private final String serverAddress; private final long qoSTestObjectiveUid; private long testStartTimestampNs; private long testEndTimestampNs; private boolean hasFinished = false; private boolean hasStarted = false; /** * */ protected final TaskDesc taskDesc; protected final QualityOfServiceTest qoSTest; protected final int id; protected QoSControlConnection controlConnection; /** * this constructor set the priority to max * @param taskDesc */ public AbstractQoSTask(QualityOfServiceTest nnTest, TaskDesc taskDesc, int threadId, int id) { this(nnTest, taskDesc, threadId, id, Integer.MAX_VALUE); } /** * * @param taskDesc * @param priority the higher the value, the higher the priority */ public AbstractQoSTask(QualityOfServiceTest nnTest, TaskDesc taskDesc, int threadId, int id, int priority) { super(nnTest.getRMBTClient(), taskDesc, threadId); this.qoSTest = nnTest; this.taskDesc = taskDesc; this.priority = priority; this.id = id; String value = (String) taskDesc.getParams().get(PARAM_QOS_TEST_OBJECTIVE_ID); this.qoSTestObjectiveUid = value != null ? Long.valueOf(value) : null; value = (String) taskDesc.getParams().get(PARAM_QOS_TEST_OBJECTIVE_PORT); this.serverPort = value != null ? Integer.valueOf(value) : null; value = (String) taskDesc.getParams().get(PARAM_QOS_CONCURRENCY_GROUP); this.concurrencyGroup = value != null ? Integer.valueOf(value) : 0; value = (String) taskDesc.getParams().get(PARAM_QOS_TEST_OBJECTIVE_ADDRESS); this.serverAddress = value; } /** * */ public abstract void initTask(); /* * (non-Javadoc) * @see at.alladin.rmbt.client.v2.task.QoSTask#getPriority() */ public int getPriority() { return priority; } /* * (non-Javadoc) * @see at.alladin.rmbt.client.v2.task.QoSTask#getTestServerPort() */ public int getTestServerPort() { return serverPort; } /* * (non-Javadoc) * @see at.alladin.rmbt.client.v2.task.QoSTask#getTestServerAddr() */ public String getTestServerAddr() { return serverAddress; } /* * (non-Javadoc) * @see at.alladin.rmbt.client.v2.task.QoSTask#getQoSObjectiveTestId() */ public long getQoSObjectiveTestId() { return qoSTestObjectiveUid; } /* * (non-Javadoc) * @see at.alladin.rmbt.client.v2.task.QoSTask#getConcurrencyGroup() */ public int getConcurrencyGroup() { return concurrencyGroup; } /* * (non-Javadoc) * @see at.alladin.rmbt.client.v2.task.QoSTask#getTaskDesc() */ public TaskDesc getTaskDesc() { return taskDesc; } /* * (non-Javadoc) * @see java.lang.Comparable#compareTo(java.lang.Object) */ public int compareTo(QoSTask o) { return (Integer.valueOf(priority).compareTo(Integer.valueOf(o.getPriority()))); } /** * * @param socket * @param message * @throws IOException */ public void sendMessage(Socket socket, String message) throws IOException { FilterOutputStream fos = new FilterOutputStream(socket.getOutputStream()); String send; send = String.format(Locale.US, message); fos.write(send.getBytes("US-ASCII")); fos.flush(); } /** * * @param socket * @return * @throws IOException */ public String readLine(Socket socket) throws IOException { FilterInputStream fis = new BufferedInputStream(socket.getInputStream()); BufferedReader r = new BufferedReader(new InputStreamReader(fis, "US-ASCII"), 4096); return r.readLine(); } /** * * @param testType * @return */ public QoSTestResult initQoSTestResult(QoSTestResultEnum testType) { QoSTestResult nnResult = new QoSTestResult(testType, this); nnResult.getResultMap().put(PARAM_QOS_TEST_OBJECTIVE_ID, qoSTestObjectiveUid); return nnResult; } /** * * @return */ public QualityOfServiceTest getQoSTest() { return qoSTest; } /** * */ public void onStart(QoSTestResult result) { this.testStartTimestampNs = (System.nanoTime() - getQoSTest().getTestSettings().getStartTimeNs()); this.hasStarted = true; result.getResultMap().put(PARAM_QOS_RESULT_START_TIME, this.testStartTimestampNs); getQoSTest().getTestSettings().dispatchTestProgressEvent(TestProgressEvent.ON_START, this); } /** * */ public void onEnd(QoSTestResult result) { this.testEndTimestampNs = (System.nanoTime() - getQoSTest().getTestSettings().getStartTimeNs()); //result.getResultMap().put(PARAM_QOS_RESULT_END_TIME, this.testEndTimestampNs); result.getResultMap().put(PARAM_QOS_RESULT_DURATION_NS, (this.testEndTimestampNs - this.testStartTimestampNs)); this.hasFinished = true; getQoSTest().getTestSettings().dispatchTestProgressEvent(TestProgressEvent.ON_END, this); } /** * * @return */ public long getTestStartTimestampNs() { return this.testStartTimestampNs; } /** * * @return */ public long getTestEndTimestampNs() { return this.testEndTimestampNs; } /** * * @return */ public boolean hasFinished() { return this.hasFinished; } /** * * @return */ public boolean hasStarted() { return this.hasStarted; } /** * * @param timeStampNs * @return */ public long getRelativeDurationNs(long timeStampNs) { return ((timeStampNs - getQoSTest().getTestSettings().getStartTimeNs()) - this.testStartTimestampNs); } /** * * @return */ public QoSControlConnection getControlConnection() { return controlConnection; } /** * * @param controlConnection */ public void setControlConnection(QoSControlConnection controlConnection) { this.controlConnection = controlConnection; } /** * * @return */ public int getId() { return id; } /** * * @return */ public boolean hasConnectionError() { if (needsQoSControlConnection()) { return (getControlConnection() == null || getControlConnection().couldNotConnect.get()); } return false; } /** * * @param command * @param listener * @throws IOException */ public void sendCommand(String command, ControlConnectionResponseCallback callback) throws IOException { controlConnection.sendTaskCommand(this, command, callback); } }