All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xxdb.DBConnection Maven / Gradle / Ivy

Go to download

The messaging and data conversion protocol between Java and DolphinDB server

There is a newer version: 1.0.27
Show newest version
package com.xxdb;

import java.io.*;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.Socket;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;

import com.xxdb.data.*;
import com.xxdb.data.Void;
import com.xxdb.io.AbstractExtendedDataOutputStream;
import com.xxdb.io.BigEndianDataInputStream;
import com.xxdb.io.BigEndianDataOutputStream;
import com.xxdb.io.ExtendedDataInput;
import com.xxdb.io.ExtendedDataOutput;
import com.xxdb.io.LittleEndianDataInputStream;
import com.xxdb.io.LittleEndianDataOutputStream;
import com.xxdb.io.ProgressListener;

/**
 * Sets up a connection to DolphinDB server through TCP/IP protocol
 * Executes DolphinDB scripts
 * 

* Example: *

* import com.xxdb; * DBConnection conn = new DBConnection(); * boolean success = conn.connect("localhost", 8080); * conn.run("sum(1..100)"); */ public class DBConnection { private enum NotLeaderStatus { NEW_LEADER, WAIT, CONN_FAIL, OTHER_EXCEPTION } private static final int MAX_FORM_VALUE = Entity.DATA_FORM.values().length - 1; private static final int MAX_TYPE_VALUE = Entity.DATA_TYPE.values().length - 1; private static final int DEFAULT_PRIORITY = 4; private static final int DEFAULT_PARALLELISM = 2; private String ServerVersion = ""; private ReentrantLock mutex; private String sessionID; private Socket socket; private boolean remoteLittleEndian; private ExtendedDataOutput out; private ExtendedDataInput in; private EntityFactory factory; private String hostName; private int port; private String mainHostName; private int mainPort; private String userId; private String password; private String initialScript = null; private boolean encrypted; private String controllerHost = null; private int controllerPort; private boolean highAvailability; private String[] highAvailabilitySites = null; private boolean HAReconnect = false; private int connTimeout = 0; public DBConnection() { factory = new BasicEntityFactory(); mutex = new ReentrantLock(); sessionID = ""; } public boolean isBusy() { if (!mutex.tryLock()) return true; else { mutex.unlock(); return false; } } private int getVersionNumber(String ver) { try { String[] s = ver.split(" "); if (s.length >= 2) { String vernum = s[0].replace(".", ""); return Integer.parseInt(vernum); } } catch (Exception ex) {} return 0; } public boolean connect(String hostName, int port) throws IOException { return connect(hostName, port, "", "", null, false, null); } public boolean connect(String hostName, int port, int timeout) throws IOException { this.connTimeout = timeout; return connect(hostName, port, "", "", null, false, null); } public boolean connect(String hostName, int port, String initialScript) throws IOException { return connect(hostName, port, "", "", initialScript, false, null); } public boolean connect(String hostName, int port, String initialScript, boolean highAvailability) throws IOException { return connect(hostName, port, "", "", initialScript, highAvailability, null); } public boolean connect(String hostName, int port, boolean highAvailability) throws IOException { return connect(hostName, port, "", "", null, highAvailability, null); } public boolean connect(String hostName, int port, String[] highAvailabilitySites) throws IOException { return connect(hostName, port, "", "", null, true, highAvailabilitySites); } public boolean connect(String hostName, int port, String initialScript, String[] highAvailabilitySites) throws IOException { return connect(hostName, port, "", "", initialScript, true, highAvailabilitySites); } public boolean connect(String hostName, int port, String userId, String password) throws IOException { return connect(hostName, port, userId, password, null, false, null); } public boolean connect(String hostName, int port, String userId, String password, boolean highAvailability) throws IOException { return connect(hostName, port, userId, password, null, highAvailability, null); } public boolean connect(String hostName, int port, String userId, String password, String[] highAvailabilitySites) throws IOException { return connect(hostName, port, userId, password, null, true, highAvailabilitySites); } public boolean connect(String hostName, int port, String userId, String password, String initialScript) throws IOException { return connect(hostName, port, userId, password, initialScript, false, null); } public boolean connect(String hostName, int port, String userId, String password, String initialScript, boolean highAvailability) throws IOException { return connect(hostName, port, userId, password, initialScript, highAvailability, null); } public boolean connect(String hostName, int port, String userId, String password, String initialScript, String[] highAvailabilitySites) throws IOException { return connect(hostName, port, userId, password, initialScript, true, highAvailabilitySites); } public boolean connect(String hostName, int port, String userId, String password, String initialScript, boolean highAvailability, String[] highAvailabilitySites) throws IOException { mutex.lock(); try { if (!sessionID.isEmpty()) { mutex.unlock(); return true; } this.hostName = hostName; this.mainHostName = hostName; this.port = port; this.mainPort = port; this.userId = userId; this.password = password; this.encrypted = true; this.initialScript = initialScript; this.highAvailability = highAvailability; this.highAvailabilitySites = highAvailabilitySites; if (highAvailabilitySites != null) { for (String site : highAvailabilitySites) { String HASite[] = site.split(":"); if (HASite.length != 2) throw new IllegalArgumentException("The site '" + site + "' is invalid."); } } assert (highAvailabilitySites == null || highAvailability); return connect(); } finally { mutex.unlock(); } } private boolean connect() throws IOException { try { socket = new Socket(hostName, port); } catch (ConnectException ex) { if (HAReconnect) return false; if (switchToRandomAvailableSite()) return true; throw ex; } if (this.connTimeout > 0) { socket.setSoTimeout(this.connTimeout); } socket.setKeepAlive(true); socket.setTcpNoDelay(true); out = new LittleEndianDataOutputStream(new BufferedOutputStream(socket.getOutputStream())); @SuppressWarnings("resource") ExtendedDataInput input = new LittleEndianDataInputStream(new BufferedInputStream(socket.getInputStream())); String body = "connect\n"; out.writeBytes("API 0 "); out.writeBytes(String.valueOf(body.length())); out.writeByte('\n'); out.writeBytes(body); out.flush(); String line = input.readLine(); int endPos = line.indexOf(' '); if (endPos <= 0) { close(); if (switchToRandomAvailableSite()) return true; return false; } sessionID = line.substring(0, endPos); int startPos = endPos + 1; endPos = line.indexOf(' ', startPos); if (endPos != line.length() - 2) { close(); if (switchToRandomAvailableSite()) return true; return false; } if (line.charAt(endPos + 1) == '0') { remoteLittleEndian = false; out = new BigEndianDataOutputStream(new BufferedOutputStream(socket.getOutputStream())); } else remoteLittleEndian = true; in = remoteLittleEndian ? new LittleEndianDataInputStream(new BufferedInputStream(socket.getInputStream())) : new BigEndianDataInputStream(new BufferedInputStream(socket.getInputStream())); if (!userId.isEmpty() && !password.isEmpty()) login(); if (initialScript != null && initialScript.length() > 0) run(initialScript); if (highAvailability && highAvailabilitySites == null) { try { controllerHost = ((BasicString) run("rpc(getControllerAlias(), getNodeHost)")).getString(); controllerPort = ((BasicInt) run("rpc(getControllerAlias(), getNodePort)")).getInt(); } catch (Exception e) { } } return true; } public void login(String userId, String password, boolean enableEncryption) throws IOException { mutex.lock(); try { this.userId = userId; this.password = password; this.encrypted = enableEncryption; login(); } finally { mutex.unlock(); } } private void login() throws IOException { List args = new ArrayList<>(); if (encrypted) { BasicString keyCode = (BasicString) run("getDynamicPublicKey", new ArrayList()); PublicKey key = RSAUtils.getPublicKey(keyCode.getString()); byte[] usr = RSAUtils.encryptByPublicKey(userId.getBytes(), key); byte[] pass = RSAUtils.encryptByPublicKey(password.getBytes(), key); args.add(new BasicString(Base64.getMimeEncoder().encodeToString(usr))); args.add(new BasicString(Base64.getMimeEncoder().encodeToString(pass))); args.add(new BasicBoolean(true)); } else { args.add(new BasicString(userId)); args.add(new BasicString(password)); } run("login", args); } public boolean getRemoteLittleEndian() { return this.remoteLittleEndian; } private boolean switchToRandomAvailableSite() throws IOException { if (!highAvailability) return false; int tryCount = 0; while (true) { HAReconnect = true; if (highAvailabilitySites != null) { if (tryCount < 3) { hostName = mainHostName; port = mainPort; } else { int rnd = new Random().nextInt(highAvailabilitySites.length); String site[] = highAvailabilitySites[rnd].split(":"); hostName = site[0]; port = new Integer(site[1]); } tryCount++; } else { if (controllerHost == null) return false; DBConnection tmp = new DBConnection(); tmp.connect(controllerHost, controllerPort); BasicStringVector availableSites = (BasicStringVector) tmp.run("getClusterLiveDataNodes(false)"); tmp.close(); int size = availableSites.rows(); if (size <= 0) return false; String site[] = availableSites.getString(0).split(":"); hostName = site[0]; port = new Integer(site[1]); } try { System.out.println("Trying to reconnect to " + hostName + ":" + port); if (connect()) { HAReconnect = false; System.out.println("Successfully reconnected to " + hostName + ":" + port); return true; } } catch (Exception e) { } try { Thread.sleep(1000); } catch (Exception e) { } } } private NotLeaderStatus handleNotLeaderException(Exception ex, String function) { String errMsg = ex.getMessage(); if (ServerExceptionUtils.isNotLeader(errMsg)) { String newLeaderString = ServerExceptionUtils.newLeader(errMsg); String[] newLeader = newLeaderString.split(":"); String newHostName = newLeader[0]; int newPort = new Integer(newLeader[1]); if (hostName.equals(newHostName) && port == newPort) { System.out.println("Got NotLeader exception. Waiting for new leader."); try { Thread.sleep(1000); } catch (Exception e) { } return NotLeaderStatus.WAIT; } hostName = newHostName; port = newPort; try { System.out.println("Got NotLeader exception. Switching to " + hostName + ":" + port); if (connect()) return NotLeaderStatus.NEW_LEADER; else return NotLeaderStatus.CONN_FAIL; } catch (IOException e) { return NotLeaderStatus.CONN_FAIL; } } return NotLeaderStatus.OTHER_EXCEPTION; } public Entity tryRun(String script) throws IOException { return tryRun(script, DEFAULT_PRIORITY, DEFAULT_PARALLELISM); } public Entity tryRun(String script, int priority, int parallelism) throws IOException { return tryRun(script, priority, parallelism, 0); } public Entity tryRun(String script, int priority, int parallelism,int fetchSize) throws IOException { if (!mutex.tryLock()) return null; try { return run(script, (ProgressListener) null, priority, parallelism, fetchSize); } finally { mutex.unlock(); } } public Entity run(String script) throws IOException { return run(script, (ProgressListener) null, DEFAULT_PRIORITY, DEFAULT_PARALLELISM); } public Entity run(String script, int priority) throws IOException { return run(script, (ProgressListener) null, priority, DEFAULT_PARALLELISM); } public Entity run(String script, int priority, int parallelism) throws IOException { return run(script, (ProgressListener) null, priority, parallelism); } public Entity run(String script, ProgressListener listener) throws IOException { return run(script, listener, DEFAULT_PRIORITY, DEFAULT_PARALLELISM); } public Entity run(String script, ProgressListener listener, int priority, int parallelism) throws IOException { return run( script, listener, priority, parallelism, 0); } public Entity run(String script, ProgressListener listener, int priority, int parallelism, int fetchSize) throws IOException { if(fetchSize>0){ if(fetchSize<8192){ throw new IOException("fetchSize must be greater than 8192"); } } mutex.lock(); boolean isUrgentCancelJob = false; if (script.startsWith("cancelJob(") || script.startsWith("cancelConsoleJob(")) isUrgentCancelJob = true; try { boolean reconnect = false; InputStream is = null; if (socket == null || !socket.isConnected() || socket.isClosed()) { if (sessionID.isEmpty()) throw new IOException("Database connection is not established yet."); else { socket = new Socket(hostName, port); socket.setKeepAlive(true); socket.setTcpNoDelay(true); out = new LittleEndianDataOutputStream(new BufferedOutputStream(socket.getOutputStream())); is = socket.getInputStream(); BufferedInputStream bis = new BufferedInputStream(is); in = remoteLittleEndian ? new LittleEndianDataInputStream(bis) : new BigEndianDataInputStream(new BufferedInputStream(bis)); } } String body = "script\n" + script; String header = null; try { out.writeBytes((listener != null ? "API2 " : "API ") + sessionID + " "); out.writeBytes(String.valueOf(AbstractExtendedDataOutputStream.getUTFlength(body, 0, 0))); if (priority != DEFAULT_PRIORITY || parallelism != DEFAULT_PARALLELISM) { out.writeBytes(" / 0_1_" + String.valueOf(priority) + "_" + String.valueOf(parallelism)); } else if (isUrgentCancelJob) { out.writeBytes(" / 1_1_8_8"); } if(fetchSize>0){ out.writeBytes("__" + String.valueOf(fetchSize)); } out.writeByte('\n'); out.writeBytes(body); out.flush(); header = in.readLine(); } catch (IOException ex) { if (reconnect) { socket = null; throw ex; } NotLeaderStatus status = handleNotLeaderException(ex, null); if (status == NotLeaderStatus.NEW_LEADER) return run(script, listener, priority, parallelism); else if (status == NotLeaderStatus.WAIT) { if (!HAReconnect) { HAReconnect = true; while (true) { try { Entity re = run(script, listener, priority, parallelism); HAReconnect = false; return re; } catch (Exception e) { } } } throw ex; } try { connect(); out.writeBytes((listener != null ? "API2 " : "API ") + sessionID + " "); out.writeBytes(String.valueOf(AbstractExtendedDataOutputStream.getUTFlength(body, 0, 0))); if (priority != DEFAULT_PRIORITY || parallelism != DEFAULT_PARALLELISM) { out.writeBytes(" / 0_1_" + String.valueOf(priority) + "_" + String.valueOf(parallelism)); }else if (isUrgentCancelJob) { out.writeBytes(" / 1_1_8_8"); } if(fetchSize>0){ out.writeBytes("__" + String.valueOf(fetchSize)); } out.writeByte('\n'); out.writeBytes(body); out.flush(); header = in.readLine(); reconnect = true; } catch (Exception e) { socket = null; throw e; } } while (header.equals("MSG")) { //read intermediate message to indicate the progress String msg = in.readString(); if (listener != null) listener.progress(msg); header = in.readLine(); } String[] headers = header.split(" "); if (headers.length != 3) { socket = null; throw new IOException("Received invalid header: " + header); } if (reconnect) sessionID = headers[0]; int numObject = Integer.parseInt(headers[1]); String msg = in.readLine(); if (!msg.equals("OK")) { if (reconnect && ServerExceptionUtils.isNotLogin(msg)) { if (userId.length() > 0 && password.length() > 0) login(); } else { throw new IOException(msg); } } if (numObject == 0) return new Void(); try { short flag = in.readShort(); int form = flag >> 8; int type = flag & 0xff; if (form < 0 || form > MAX_FORM_VALUE) throw new IOException("Invalid form value: " + form); if (type < 0 || type > MAX_TYPE_VALUE) throw new IOException("Invalid type value: " + type); Entity.DATA_FORM df = Entity.DATA_FORM.values()[form]; Entity.DATA_TYPE dt = Entity.DATA_TYPE.values()[type]; if(fetchSize>0 && df == Entity.DATA_FORM.DF_VECTOR && dt == Entity.DATA_TYPE.DT_ANY){ return new EntityBlockReader(in); } return factory.createEntity(df, dt, in); } catch (IOException ex) { socket = null; throw ex; } } catch (Exception ex) { NotLeaderStatus status = handleNotLeaderException(ex, null); if (status == NotLeaderStatus.NEW_LEADER) return run(script, listener, priority, parallelism); else if (status == NotLeaderStatus.WAIT) { if (!HAReconnect) { HAReconnect = true; while (true) { try { Entity re = run(script, listener, priority, parallelism); HAReconnect = false; return re; } catch (Exception e) { } } } throw ex; } if (socket != null || !highAvailability) throw ex; if (switchToRandomAvailableSite()) return run(script, listener, priority, parallelism); else throw ex; } finally { mutex.unlock(); } } public Entity tryRun(String function, List arguments) throws IOException { return tryRun(function, arguments, DEFAULT_PRIORITY, DEFAULT_PARALLELISM); } public Entity tryRun(String function, List arguments, int priority, int parallelism) throws IOException { return tryRun(function, arguments, priority, parallelism,0); } public Entity tryRun(String function, List arguments, int priority, int parallelism, int fetchSize) throws IOException { if (!mutex.tryLock()) return null; try { return run(function, arguments, priority, parallelism, fetchSize); } finally { mutex.unlock(); } } public Entity run(String function, List arguments) throws IOException { return run(function, arguments, DEFAULT_PRIORITY, DEFAULT_PARALLELISM); } public Entity run(String function, List arguments, int priority) throws IOException { return run(function, arguments, priority, DEFAULT_PARALLELISM); } public Entity run(String function, List arguments, int priority, int parallelism) throws IOException { return run(function, arguments, priority, parallelism, 0); } public Entity run(String function, List arguments, int priority, int parallelism, int fetchSize) throws IOException { if(fetchSize>0){ if(fetchSize<8192){ throw new IOException("fetchSize must be greater than 8192"); } } mutex.lock(); try { boolean reconnect = false; if (socket == null || !socket.isConnected() || socket.isClosed()) { if (sessionID.isEmpty()) throw new IOException("Database connection is not established yet."); else { socket = new Socket(hostName, port); socket.setKeepAlive(true); socket.setTcpNoDelay(true); out = new LittleEndianDataOutputStream(new BufferedOutputStream(socket.getOutputStream())); in = remoteLittleEndian ? new LittleEndianDataInputStream(new BufferedInputStream(socket.getInputStream())) : new BigEndianDataInputStream(new BufferedInputStream(socket.getInputStream())); } } String body = "function\n" + function; body += ("\n" + arguments.size() + "\n"); body += remoteLittleEndian ? "1" : "0"; String[] headers = null; try { out.writeBytes("API " + sessionID + " "); out.writeBytes(String.valueOf(body.length())); if (priority != DEFAULT_PRIORITY || parallelism != DEFAULT_PARALLELISM) { out.writeBytes(" / 0_1_" + String.valueOf(priority) + "_" + String.valueOf(parallelism)); } if(fetchSize>0){ out.writeBytes("__" + String.valueOf(fetchSize)); } out.writeByte('\n'); out.writeBytes(body); for (int i = 0; i < arguments.size(); ++i) arguments.get(i).write(out); out.flush(); headers = in.readLine().split(" "); } catch (IOException ex) { if (reconnect) { socket = null; throw ex; } NotLeaderStatus status = handleNotLeaderException(ex, null); if (status == NotLeaderStatus.NEW_LEADER) return run(function, arguments, priority, parallelism); else if (status == NotLeaderStatus.WAIT) { if (!HAReconnect) { HAReconnect = true; while (true) { try { Entity re = run(function, arguments, priority, parallelism); HAReconnect = false; return re; } catch (Exception e) { } } } throw ex; } try { connect(); out = new LittleEndianDataOutputStream(new BufferedOutputStream(socket.getOutputStream())); out.writeBytes("API " + sessionID + " "); out.writeBytes(String.valueOf(body.length())); if (priority != DEFAULT_PRIORITY || parallelism != DEFAULT_PARALLELISM) { out.writeBytes(" / 0_1_" + String.valueOf(priority) + "_" + String.valueOf(parallelism)); } out.writeByte('\n'); out.writeBytes(body); for (int i = 0; i < arguments.size(); ++i) arguments.get(i).write(out); out.flush(); in = remoteLittleEndian ? new LittleEndianDataInputStream(new BufferedInputStream(socket.getInputStream())) : new BigEndianDataInputStream(new BufferedInputStream(socket.getInputStream())); headers = in.readLine().split(" "); reconnect = true; } catch (Exception e) { socket = null; throw e; } } if (headers.length != 3) { socket = null; throw new IOException("Received invalid header."); } if (reconnect) sessionID = headers[0]; int numObject = Integer.parseInt(headers[1]); String msg = in.readLine(); if (!msg.equals("OK")) throw new IOException(msg); if (numObject == 0) return new Void(); try { short flag = in.readShort(); int form = flag >> 8; int type = flag & 0xff; if (form < 0 || form > MAX_FORM_VALUE) throw new IOException("Invalid form value: " + form); if (type < 0 || type > MAX_TYPE_VALUE) throw new IOException("Invalid type value: " + type); Entity.DATA_FORM df = Entity.DATA_FORM.values()[form]; Entity.DATA_TYPE dt = Entity.DATA_TYPE.values()[type]; if(fetchSize>0 && df == Entity.DATA_FORM.DF_VECTOR && dt == Entity.DATA_TYPE.DT_ANY){ return new EntityBlockReader(in); } return factory.createEntity(df, dt, in); } catch (IOException ex) { socket = null; throw ex; } } catch (Exception ex) { NotLeaderStatus status = handleNotLeaderException(ex, null); if (status == NotLeaderStatus.NEW_LEADER) return run(function, arguments, priority, parallelism); else if (status == NotLeaderStatus.WAIT) { if (!HAReconnect) { HAReconnect = true; while (true) { try { Entity re = run(function, arguments, priority, parallelism); HAReconnect = false; return re; } catch (Exception e) { } } } throw ex; } if (socket != null || !highAvailability) throw ex; if (switchToRandomAvailableSite()) return run(function, arguments, priority, parallelism); else throw ex; } finally { mutex.unlock(); } } public void tryUpload(final Map variableObjectMap) throws IOException { if (!mutex.tryLock()) throw new IOException("The connection is in use."); try { upload(variableObjectMap); } finally { mutex.unlock(); } } public void upload(final Map variableObjectMap) throws IOException { if (variableObjectMap == null || variableObjectMap.isEmpty()) return; mutex.lock(); try { boolean reconnect = false; if (socket == null || !socket.isConnected() || socket.isClosed()) { if (sessionID.isEmpty()) throw new IOException("Database connection is not established yet."); else { reconnect = true; socket = new Socket(hostName, port); socket.setKeepAlive(true); socket.setTcpNoDelay(true); out = new LittleEndianDataOutputStream(new BufferedOutputStream(socket.getOutputStream())); in = remoteLittleEndian ? new LittleEndianDataInputStream(new BufferedInputStream(socket.getInputStream())) : new BigEndianDataInputStream(new BufferedInputStream(socket.getInputStream())); } } List objects = new ArrayList(); String body = "variable\n"; for (String key : variableObjectMap.keySet()) { if (!isVariableCandidate(key)) throw new IllegalArgumentException("'" + key + "' is not a good variable name."); body += key + ","; objects.add(variableObjectMap.get(key)); } body = body.substring(0, body.length() - 1); body += ("\n" + objects.size() + "\n"); body += remoteLittleEndian ? "1" : "0"; try { out.writeBytes("API " + sessionID + " "); out.writeBytes(String.valueOf(body.length())); out.writeByte('\n'); out.writeBytes(body); for (int i = 0; i < objects.size(); ++i) objects.get(i).write(out); out.flush(); } catch (IOException ex) { if (reconnect) { socket = null; throw ex; } try { socket = new Socket(hostName, port); socket.setKeepAlive(true); socket.setTcpNoDelay(true); out = new LittleEndianDataOutputStream(new BufferedOutputStream(socket.getOutputStream())); out.writeBytes("API " + sessionID + " "); out.writeBytes(String.valueOf(body.length())); out.writeByte('\n'); out.writeBytes(body); for (int i = 0; i < objects.size(); ++i) objects.get(i).write(out); out.flush(); reconnect = true; } catch (Exception e) { socket = null; throw e; } } String[] headers = in.readLine().split(" "); if (headers.length != 3) { socket = null; throw new IOException("Received invalid header."); } if (reconnect) sessionID = headers[0]; int numObject = Integer.parseInt(headers[1]); String msg = in.readLine(); if (!msg.equals("OK")) throw new IOException(msg); if (numObject > 0) { try { short flag = in.readShort(); int form = flag >> 8; int type = flag & 0xff; if (form < 0 || form > MAX_FORM_VALUE) throw new IOException("Invalid form value: " + form); if (type < 0 || type > MAX_TYPE_VALUE) throw new IOException("Invalid type value: " + type); Entity.DATA_FORM df = Entity.DATA_FORM.values()[form]; Entity.DATA_TYPE dt = Entity.DATA_TYPE.values()[type]; Entity re = factory.createEntity(df, dt, in); } catch (IOException ex) { socket = null; throw ex; } } } catch (Exception ex) { if (socket != null || !highAvailability) throw ex; if (switchToRandomAvailableSite()) { mutex.unlock(); upload(variableObjectMap); } else throw ex; } finally { mutex.unlock(); } } public void close() { mutex.lock(); try { if (socket != null) { socket.close(); sessionID = ""; socket = null; } } catch (Exception ex) { ex.printStackTrace(); } finally { mutex.unlock(); } } private boolean isVariableCandidate(String word) { char cur = word.charAt(0); if ((cur < 'a' || cur > 'z') && (cur < 'A' || cur > 'Z')) return false; for (int i = 1; i < word.length(); i++) { cur = word.charAt(i); if ((cur < 'a' || cur > 'z') && (cur < 'A' || cur > 'Z') && (cur < '0' || cur > '9') && cur != '_') return false; } return true; } public String getHostName() { return hostName; } public int getPort() { return port; } public String getSessionID() { return sessionID; } public InetAddress getLocalAddress() { return socket.getLocalAddress(); } public boolean isConnected() { return socket != null && socket.isConnected(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy