Added command timeouts as requested in #16
This commit is contained in:
parent
9aa06f3380
commit
c297aba43e
|
|
@ -7,9 +7,9 @@ package examples;
|
||||||
public class Config {
|
public class Config {
|
||||||
|
|
||||||
|
|
||||||
public static final String HOST = "192.168.1.1";
|
public static final String HOST = "192.168.1.34";
|
||||||
public static final String USERNAME = "admin";
|
public static final String USERNAME = "gideon";
|
||||||
public static final String PASSWORD = "";
|
public static final String PASSWORD = "minapp";
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import me.legrange.mikrotik.ApiConnection;
|
||||||
abstract class Example {
|
abstract class Example {
|
||||||
|
|
||||||
protected void connect() throws Exception {
|
protected void connect() throws Exception {
|
||||||
con = ApiConnection.connect(Config.HOST);
|
con = ApiConnection.connect(Config.HOST, ApiConnection.DEFAULT_PORT, 2000);
|
||||||
con.login(Config.USERNAME, Config.PASSWORD);
|
con.login(Config.USERNAME, Config.PASSWORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ public class Example2 extends Example {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void test() throws MikrotikApiException {
|
private void test() throws MikrotikApiException {
|
||||||
|
con.setTimeout(50);
|
||||||
List<Map<String, String>> results = con.execute("/interface/print");
|
List<Map<String, String>> results = con.execute("/interface/print");
|
||||||
for (Map<String, String> result : results) {
|
for (Map<String, String> result : results) {
|
||||||
System.out.println(result);
|
System.out.println(result);
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,9 @@ public abstract class ApiConnection {
|
||||||
public static final int DEFAULT_TLS_PORT = 8729;
|
public static final int DEFAULT_TLS_PORT = 8729;
|
||||||
/** default connection timeout to use when opening the connection */
|
/** default connection timeout to use when opening the connection */
|
||||||
public static final int DEFAULT_CONNECTION_TIMEOUT = 60000;
|
public static final int DEFAULT_CONNECTION_TIMEOUT = 60000;
|
||||||
|
/** default command timeout used for synchronous commands */
|
||||||
|
public static final int DEFAULT_COMMAND_TIMEOUT = 60000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new API connection to the give device on the supplied port, using anonymous TLS for encryption.
|
* Create a new API connection to the give device on the supplied port, using anonymous TLS for encryption.
|
||||||
* @param host The host to which to connect.
|
* @param host The host to which to connect.
|
||||||
|
|
@ -130,5 +132,18 @@ public abstract class ApiConnection {
|
||||||
* @param tag The tag of the command to cancel
|
* @param tag The tag of the command to cancel
|
||||||
* @throws me.legrange.mikrotik.MikrotikApiException Thrown if there is a problem canceling the command */
|
* @throws me.legrange.mikrotik.MikrotikApiException Thrown if there is a problem canceling the command */
|
||||||
public abstract void cancel(String tag) throws MikrotikApiException;
|
public abstract void cancel(String tag) throws MikrotikApiException;
|
||||||
|
|
||||||
|
/** get the command timeout. The command timeout is used to time out API
|
||||||
|
* commands after a specific time.
|
||||||
|
* @return The time out in milliseconds.
|
||||||
|
*/
|
||||||
|
public abstract int getTimeout();
|
||||||
|
|
||||||
|
/** set the command timeout. The command timeout is used to time out API
|
||||||
|
* commands after a specific time.
|
||||||
|
* @param timeout The time out in milliseconds.
|
||||||
|
* @throws MikrotikApiException Thrown if the timeout specified is invalid.
|
||||||
|
*/
|
||||||
|
public abstract void setTimeout(int timeout) throws MikrotikApiException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -36,6 +36,7 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
* @param host The host to which to connect.
|
* @param host The host to which to connect.
|
||||||
* @param port The TCP port to use.
|
* @param port The TCP port to use.
|
||||||
* @param secure Is TLS required
|
* @param secure Is TLS required
|
||||||
|
* @param timeOut The connection timeout
|
||||||
* @return The ApiConnection
|
* @return The ApiConnection
|
||||||
* @throws me.legrange.mikrotik.ApiConnectionException Thrown if there is a
|
* @throws me.legrange.mikrotik.ApiConnectionException Thrown if there is a
|
||||||
* problem connecting
|
* problem connecting
|
||||||
|
|
@ -46,22 +47,11 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
return con;
|
return con;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check the state of connection.
|
|
||||||
*
|
|
||||||
* @return if connection is established to router it returns true.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isConnected() {
|
public boolean isConnected() {
|
||||||
return connected;
|
return connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Disconnect from the remote API
|
|
||||||
*
|
|
||||||
* @throws me.legrange.mikrotik.ApiConnectionException Thrown if there is a
|
|
||||||
* problem disconnecting
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void disconnect() throws ApiConnectionException {
|
public void disconnect() throws ApiConnectionException {
|
||||||
if (!connected) {
|
if (!connected) {
|
||||||
|
|
@ -77,14 +67,6 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Log in to the remote router.
|
|
||||||
*
|
|
||||||
* @param username - username of the user on the router
|
|
||||||
* @param password - password for the user
|
|
||||||
* @throws me.legrange.mikrotik.MikrotikApiException
|
|
||||||
* @throws java.lang.InterruptedException
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void login(String username, String password) throws MikrotikApiException, InterruptedException {
|
public void login(String username, String password) throws MikrotikApiException, InterruptedException {
|
||||||
if (username.trim().isEmpty()) {
|
if (username.trim().isEmpty()) {
|
||||||
|
|
@ -98,47 +80,40 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
execute("/login name=" + username + " response=00" + chal);
|
execute("/login name=" + username + " response=00" + chal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* execute a command and return a list of results.
|
|
||||||
*
|
|
||||||
* @param cmd Command to execute
|
|
||||||
* @return The list of results
|
|
||||||
* @throws me.legrange.mikrotik.MikrotikApiException
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public List<Map<String, String>> execute(String cmd) throws MikrotikApiException {
|
public List<Map<String, String>> execute(String cmd) throws MikrotikApiException {
|
||||||
return execute(Parser.parse(cmd));
|
return execute(Parser.parse(cmd), timeOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* execute a command and attach a result listener to receive it's results.
|
|
||||||
*
|
|
||||||
* @param cmd Command to execute
|
|
||||||
* @param lis ResultListener that will receive the results
|
|
||||||
* @return A command object that can be used to cancel the command.
|
|
||||||
* @throws MikrotikApiException
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String execute(String cmd, ResultListener lis) throws MikrotikApiException {
|
public String execute(String cmd, ResultListener lis) throws MikrotikApiException {
|
||||||
return execute(Parser.parse(cmd), lis);
|
return execute(Parser.parse(cmd), lis);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* cancel a command
|
|
||||||
*
|
|
||||||
* @param tag
|
|
||||||
* @throws me.legrange.mikrotik.MikrotikApiException Thrown if an error is
|
|
||||||
* experienced while canceling the
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void cancel(String tag) throws MikrotikApiException {
|
public void cancel(String tag) throws MikrotikApiException {
|
||||||
execute(String.format("/cancel tag=%s", tag));
|
execute(String.format("/cancel tag=%s", tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Map<String, String>> execute(Command cmd) throws MikrotikApiException {
|
@Override
|
||||||
|
public int getTimeout() {
|
||||||
|
return timeOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTimeout(int timeout) throws MikrotikApiException {
|
||||||
|
if (timeout >=0) {
|
||||||
|
timeOut = timeout;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new MikrotikApiException(String.format("Invalid timeout value '%d'; must be postive or 0", timeout));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Map<String, String>> execute(Command cmd, int timeOut) throws MikrotikApiException {
|
||||||
SyncListener l = new SyncListener();
|
SyncListener l = new SyncListener();
|
||||||
execute(cmd, l);
|
execute(cmd, l);
|
||||||
return l.getResults();
|
return l.getResults(timeOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String execute(Command cmd, ResultListener lis) throws MikrotikApiException {
|
private String execute(Command cmd, ResultListener lis) throws MikrotikApiException {
|
||||||
|
|
@ -226,6 +201,7 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
private Processor processor;
|
private Processor processor;
|
||||||
private final Map<String, ResultListener> listeners;
|
private final Map<String, ResultListener> listeners;
|
||||||
private Integer _tag = 0;
|
private Integer _tag = 0;
|
||||||
|
private int timeOut = ApiConnection.DEFAULT_COMMAND_TIMEOUT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* thread to read data from the socket and process it into Strings
|
* thread to read data from the socket and process it into Strings
|
||||||
|
|
@ -483,6 +459,7 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void completed() {
|
public synchronized void completed() {
|
||||||
|
complete = true;
|
||||||
notify();
|
notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -492,6 +469,7 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
res.put("ret", done.getHash());
|
res.put("ret", done.getHash());
|
||||||
results.add(res);
|
results.add(res);
|
||||||
}
|
}
|
||||||
|
complete = true;
|
||||||
notify();
|
notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -500,11 +478,17 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
results.add(result);
|
results.add(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Map<String, String>> getResults() throws MikrotikApiException {
|
private List<Map<String, String>> getResults(int timeOut) throws MikrotikApiException {
|
||||||
try {
|
try {
|
||||||
synchronized (this) { // don't wait if we already have a result.
|
synchronized (this) { // don't wait if we already have a result.
|
||||||
if ((err == null) && results.isEmpty()) {
|
int waitTime = timeOut;
|
||||||
wait();
|
while (!complete && (waitTime > 0)) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
wait(waitTime);
|
||||||
|
waitTime = waitTime - (int)(System.currentTimeMillis() - start);
|
||||||
|
if ((waitTime < 0) && !complete) {
|
||||||
|
err = new ApiConnectionException(String.format("Command timed out after %d ms", timeOut));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
|
|
@ -515,7 +499,9 @@ public final class ApiConnectionImpl extends ApiConnection {
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final List<Map<String, String>> results = new LinkedList<>();
|
private final List<Map<String, String>> results = new LinkedList<>();
|
||||||
private MikrotikApiException err;
|
private MikrotikApiException err;
|
||||||
|
private boolean complete = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue