4067 |
02 Sep 16 |
nicklas |
1 |
package net.sf.basedb.opengrid; |
4067 |
02 Sep 16 |
nicklas |
2 |
|
4257 |
30 Nov 16 |
nicklas |
3 |
import org.json.simple.JSONObject; |
4067 |
02 Sep 16 |
nicklas |
4 |
|
4067 |
02 Sep 16 |
nicklas |
5 |
import net.schmizz.sshj.SSHClient; |
4254 |
25 Nov 16 |
nicklas |
6 |
import net.sf.basedb.opengrid.config.ClusterConfig; |
4254 |
25 Nov 16 |
nicklas |
7 |
import net.sf.basedb.opengrid.config.ConnectionInfo; |
4257 |
30 Nov 16 |
nicklas |
8 |
import net.sf.basedb.opengrid.json.JSONOption; |
4257 |
30 Nov 16 |
nicklas |
9 |
import net.sf.basedb.opengrid.json.JSONOptions; |
4296 |
12 Jan 17 |
nicklas |
10 |
import net.sf.basedb.opengrid.service.OpenGridService; |
4067 |
02 Sep 16 |
nicklas |
11 |
|
4067 |
02 Sep 16 |
nicklas |
12 |
|
4067 |
02 Sep 16 |
nicklas |
13 |
/** |
4067 |
02 Sep 16 |
nicklas |
Represents a single Open Grid Scheduler cluster |
4067 |
02 Sep 16 |
nicklas |
together with login information for accessing it |
4301 |
13 Jan 17 |
nicklas |
via SSH. Use the {@link #connect(int)} method to create |
4067 |
02 Sep 16 |
nicklas |
a session for interacting with the cluster. This class |
4296 |
12 Jan 17 |
nicklas |
is thread-safe, but the {@link OpenGridSession} need |
4296 |
12 Jan 17 |
nicklas |
synchronization if used with multiple threads. |
4067 |
02 Sep 16 |
nicklas |
20 |
|
4296 |
12 Jan 17 |
nicklas |
Typically, instances of this class are created and managed |
4296 |
12 Jan 17 |
nicklas |
by the {@link OpenGridService}. It is possible to create ad-hoc, |
4296 |
12 Jan 17 |
nicklas |
unmanaged instances, but this is not recommended. |
4296 |
12 Jan 17 |
nicklas |
24 |
|
4067 |
02 Sep 16 |
nicklas |
@author nicklas |
4067 |
02 Sep 16 |
nicklas |
@since 1.0 |
4067 |
02 Sep 16 |
nicklas |
27 |
*/ |
4067 |
02 Sep 16 |
nicklas |
28 |
public class OpenGridCluster |
4278 |
20 Dec 16 |
nicklas |
29 |
extends AbstractHost<OpenGridSession> |
4067 |
02 Sep 16 |
nicklas |
30 |
{ |
4197 |
31 Oct 16 |
nicklas |
31 |
private final String id; |
4126 |
26 Sep 16 |
nicklas |
32 |
private final ClusterConfig config; |
4257 |
30 Nov 16 |
nicklas |
33 |
private Info info; |
4067 |
02 Sep 16 |
nicklas |
34 |
|
4067 |
02 Sep 16 |
nicklas |
35 |
/** |
4296 |
12 Jan 17 |
nicklas |
Creates a new Open Grid Cluster instance. Note that the |
4296 |
12 Jan 17 |
nicklas |
configurations will be locked as a result of calling this |
4296 |
12 Jan 17 |
nicklas |
method. |
4296 |
12 Jan 17 |
nicklas |
39 |
|
4296 |
12 Jan 17 |
nicklas |
@param ci Connection information to access the cluster |
4296 |
12 Jan 17 |
nicklas |
@param config Other configuration settings |
4067 |
02 Sep 16 |
nicklas |
42 |
*/ |
4126 |
26 Sep 16 |
nicklas |
43 |
public OpenGridCluster(ConnectionInfo ci, ClusterConfig config) |
4067 |
02 Sep 16 |
nicklas |
44 |
{ |
4278 |
20 Dec 16 |
nicklas |
45 |
super(ci); |
4126 |
26 Sep 16 |
nicklas |
46 |
this.config = config.lock(); |
4197 |
31 Oct 16 |
nicklas |
47 |
this.id = ci.getUser() + "@" + ci.getAddress() + ":" + ci.getPort(); |
4067 |
02 Sep 16 |
nicklas |
48 |
} |
4067 |
02 Sep 16 |
nicklas |
49 |
|
7380 |
18 Oct 23 |
nicklas |
50 |
@Override |
7380 |
18 Oct 23 |
nicklas |
51 |
public String toString() |
7380 |
18 Oct 23 |
nicklas |
52 |
{ |
7380 |
18 Oct 23 |
nicklas |
53 |
return config.getType()+"["+id+"]"; |
7380 |
18 Oct 23 |
nicklas |
54 |
} |
7380 |
18 Oct 23 |
nicklas |
55 |
|
4067 |
02 Sep 16 |
nicklas |
56 |
/** |
4197 |
31 Oct 16 |
nicklas |
Get the ID of this cluster. The ID is composed of the |
4197 |
31 Oct 16 |
nicklas |
username, address and port from the connection information. |
4254 |
25 Nov 16 |
nicklas |
The ID need to be unique among registered clusters. |
4197 |
31 Oct 16 |
nicklas |
60 |
*/ |
4197 |
31 Oct 16 |
nicklas |
61 |
public String getId() |
4197 |
31 Oct 16 |
nicklas |
62 |
{ |
4197 |
31 Oct 16 |
nicklas |
63 |
return id; |
4197 |
31 Oct 16 |
nicklas |
64 |
} |
4197 |
31 Oct 16 |
nicklas |
65 |
|
4197 |
31 Oct 16 |
nicklas |
66 |
/** |
4126 |
26 Sep 16 |
nicklas |
Get configuration settings for this cluster. |
4126 |
26 Sep 16 |
nicklas |
68 |
*/ |
4126 |
26 Sep 16 |
nicklas |
69 |
public ClusterConfig getConfig() |
4126 |
26 Sep 16 |
nicklas |
70 |
{ |
4126 |
26 Sep 16 |
nicklas |
71 |
return config; |
4126 |
26 Sep 16 |
nicklas |
72 |
} |
4126 |
26 Sep 16 |
nicklas |
73 |
|
4126 |
26 Sep 16 |
nicklas |
74 |
/** |
4270 |
16 Dec 16 |
nicklas |
Get the work folder for a job with the given name. |
4270 |
16 Dec 16 |
nicklas |
76 |
*/ |
4270 |
16 Dec 16 |
nicklas |
77 |
public String getWorkFolder(String jobName) |
4270 |
16 Dec 16 |
nicklas |
78 |
{ |
4270 |
16 Dec 16 |
nicklas |
79 |
return getConfig().getJobFolder() + "/" + jobName; |
4270 |
16 Dec 16 |
nicklas |
80 |
} |
4270 |
16 Dec 16 |
nicklas |
81 |
|
4270 |
16 Dec 16 |
nicklas |
82 |
/** |
4270 |
16 Dec 16 |
nicklas |
Get the tmp folder for a job with the given name. |
4270 |
16 Dec 16 |
nicklas |
84 |
*/ |
4270 |
16 Dec 16 |
nicklas |
85 |
public String getTmpFolder(String jobName, boolean debug) |
4270 |
16 Dec 16 |
nicklas |
86 |
{ |
4270 |
16 Dec 16 |
nicklas |
87 |
return getConfig().getTmpFolder(debug) + "/" + jobName; |
4270 |
16 Dec 16 |
nicklas |
88 |
} |
4270 |
16 Dec 16 |
nicklas |
89 |
|
4270 |
16 Dec 16 |
nicklas |
90 |
/** |
4257 |
30 Nov 16 |
nicklas |
Get information about the Open Grid cluster. This is a shortcut |
4257 |
30 Nov 16 |
nicklas |
for connecting to the cluster and exucuting a few commands on it: |
4257 |
30 Nov 16 |
nicklas |
{@link OpenGridSession#getHostInfo()}, {@link OpenGridSession#getOpenGridInfo()} |
4257 |
30 Nov 16 |
nicklas |
and {@link OpenGridSession#getTimeAdjustment()}. In addition, |
4257 |
30 Nov 16 |
nicklas |
the information is cached for up to 1 hour. |
4257 |
30 Nov 16 |
nicklas |
96 |
*/ |
4257 |
30 Nov 16 |
nicklas |
97 |
public Info getClusterInfo() |
4257 |
30 Nov 16 |
nicklas |
98 |
{ |
4257 |
30 Nov 16 |
nicklas |
99 |
long outdated = System.currentTimeMillis() - 3600000L; // 1 hour ago |
4257 |
30 Nov 16 |
nicklas |
100 |
if (info == null || info.created() < outdated) |
4257 |
30 Nov 16 |
nicklas |
101 |
{ |
4257 |
30 Nov 16 |
nicklas |
102 |
synchronized (this) |
4257 |
30 Nov 16 |
nicklas |
103 |
{ |
5980 |
03 Jul 20 |
nicklas |
104 |
OpenGridSession session = null; |
4257 |
30 Nov 16 |
nicklas |
105 |
try |
4257 |
30 Nov 16 |
nicklas |
106 |
{ |
5980 |
03 Jul 20 |
nicklas |
107 |
session = connect(5); |
4257 |
30 Nov 16 |
nicklas |
108 |
info = new Info(session); |
4257 |
30 Nov 16 |
nicklas |
109 |
} |
5980 |
03 Jul 20 |
nicklas |
110 |
catch (RuntimeException ex) |
5980 |
03 Jul 20 |
nicklas |
111 |
{ |
5980 |
03 Jul 20 |
nicklas |
112 |
info = new Info(getConfig(), ex); |
5980 |
03 Jul 20 |
nicklas |
113 |
} |
4257 |
30 Nov 16 |
nicklas |
114 |
finally |
4257 |
30 Nov 16 |
nicklas |
115 |
{ |
4257 |
30 Nov 16 |
nicklas |
116 |
OpenGrid.close(session); |
4257 |
30 Nov 16 |
nicklas |
117 |
} |
4257 |
30 Nov 16 |
nicklas |
118 |
} |
4257 |
30 Nov 16 |
nicklas |
119 |
} |
4257 |
30 Nov 16 |
nicklas |
120 |
return info; |
4257 |
30 Nov 16 |
nicklas |
121 |
} |
4257 |
30 Nov 16 |
nicklas |
122 |
|
4257 |
30 Nov 16 |
nicklas |
123 |
/** |
4067 |
02 Sep 16 |
nicklas |
Connect to the cluster. The returned session can |
4067 |
02 Sep 16 |
nicklas |
be used to send commands or transfer files to/from |
4067 |
02 Sep 16 |
nicklas |
the cluster. Do not forget to {@link OpenGridSession#close()} |
4067 |
02 Sep 16 |
nicklas |
the session after use. |
4067 |
02 Sep 16 |
nicklas |
128 |
|
4067 |
02 Sep 16 |
nicklas |
@param timeout Timeout in seconds for the connection to be established |
4067 |
02 Sep 16 |
nicklas |
130 |
*/ |
4278 |
20 Dec 16 |
nicklas |
131 |
@Override |
4067 |
02 Sep 16 |
nicklas |
132 |
public OpenGridSession connect(int timeout) |
4067 |
02 Sep 16 |
nicklas |
133 |
{ |
4278 |
20 Dec 16 |
nicklas |
134 |
SSHClient ssh = internalConnect(timeout); |
4067 |
02 Sep 16 |
nicklas |
135 |
return new OpenGridSession(this, ssh); |
4067 |
02 Sep 16 |
nicklas |
136 |
} |
4067 |
02 Sep 16 |
nicklas |
137 |
|
4067 |
02 Sep 16 |
nicklas |
138 |
|
4257 |
30 Nov 16 |
nicklas |
139 |
/** |
4257 |
30 Nov 16 |
nicklas |
Get the configuration information for this cluster as a JSON |
4257 |
30 Nov 16 |
nicklas |
object. The following attributes are set: |
4257 |
30 Nov 16 |
nicklas |
142 |
|
4257 |
30 Nov 16 |
nicklas |
id: {@link #getId()} |
4301 |
13 Jan 17 |
nicklas |
config: {@link #getConfig()}.{@link ClusterConfig#asJSONObject(JSONOptions)} |
4301 |
13 Jan 17 |
nicklas |
connection: {@link #getConnectionInfo()}.{@link ConnectionInfo#asJSONObject(JSONOptions)} |
4257 |
30 Nov 16 |
nicklas |
146 |
|
4257 |
30 Nov 16 |
nicklas |
Note that a new JSON object is created each time this method is |
4257 |
30 Nov 16 |
nicklas |
called. Clients should cache this information if they need to |
4257 |
30 Nov 16 |
nicklas |
re-used it. |
4257 |
30 Nov 16 |
nicklas |
150 |
|
4257 |
30 Nov 16 |
nicklas |
More information about the cluster is also available by calling |
4257 |
30 Nov 16 |
nicklas |
{@link #getClusterInfo()}. |
4257 |
30 Nov 16 |
nicklas |
153 |
*/ |
4257 |
30 Nov 16 |
nicklas |
154 |
public JSONObject asJSONObject(JSONOptions options) |
4257 |
30 Nov 16 |
nicklas |
155 |
{ |
4257 |
30 Nov 16 |
nicklas |
156 |
JSONObject json = new JSONObject(); |
4257 |
30 Nov 16 |
nicklas |
157 |
json.put("id", getId()); |
4257 |
30 Nov 16 |
nicklas |
158 |
json.put("config", getConfig().asJSONObject(options)); |
4257 |
30 Nov 16 |
nicklas |
159 |
json.put("connection", getConnectionInfo().asJSONObject(options)); |
4257 |
30 Nov 16 |
nicklas |
160 |
if (options.isEnabled(JSONOption.CLUSTER_INFO)) |
4257 |
30 Nov 16 |
nicklas |
161 |
{ |
4257 |
30 Nov 16 |
nicklas |
162 |
json.put("clusterInfo", getClusterInfo().asJSONObject(options)); |
4257 |
30 Nov 16 |
nicklas |
163 |
} |
4257 |
30 Nov 16 |
nicklas |
164 |
return json; |
4257 |
30 Nov 16 |
nicklas |
165 |
} |
4257 |
30 Nov 16 |
nicklas |
166 |
|
4257 |
30 Nov 16 |
nicklas |
167 |
/** |
4257 |
30 Nov 16 |
nicklas |
Holds information about the Open Grid cluster together with |
4257 |
30 Nov 16 |
nicklas |
a timestamp for caching purposes. |
4257 |
30 Nov 16 |
nicklas |
170 |
*/ |
4257 |
30 Nov 16 |
nicklas |
171 |
public static class Info |
4257 |
30 Nov 16 |
nicklas |
172 |
{ |
4257 |
30 Nov 16 |
nicklas |
173 |
private final long created; |
4257 |
30 Nov 16 |
nicklas |
174 |
private final CmdResult<String> hostInfo; |
4257 |
30 Nov 16 |
nicklas |
175 |
private final CmdResult<String> ogsInfo; |
4257 |
30 Nov 16 |
nicklas |
176 |
private final int timeAdjustment; |
4257 |
30 Nov 16 |
nicklas |
177 |
private final boolean error; |
5995 |
21 Aug 20 |
nicklas |
178 |
private final boolean connected; |
4257 |
30 Nov 16 |
nicklas |
179 |
|
4257 |
30 Nov 16 |
nicklas |
180 |
Info(OpenGridSession session) |
4257 |
30 Nov 16 |
nicklas |
181 |
{ |
4257 |
30 Nov 16 |
nicklas |
182 |
created = System.currentTimeMillis(); |
4257 |
30 Nov 16 |
nicklas |
183 |
hostInfo = session.getHostInfo(); |
4257 |
30 Nov 16 |
nicklas |
184 |
ogsInfo = session.getOpenGridInfo(); |
4257 |
30 Nov 16 |
nicklas |
185 |
timeAdjustment = session.getTimeAdjustment(); |
4257 |
30 Nov 16 |
nicklas |
186 |
error = hostInfo.getExitStatus() != 0 || ogsInfo.getExitStatus() != 0; |
5995 |
21 Aug 20 |
nicklas |
187 |
connected = true; |
4257 |
30 Nov 16 |
nicklas |
188 |
} |
4257 |
30 Nov 16 |
nicklas |
189 |
|
4257 |
30 Nov 16 |
nicklas |
190 |
/** |
5980 |
03 Jul 20 |
nicklas |
Constructor to use when connecting to the host fails. The |
5980 |
03 Jul 20 |
nicklas |
exception should be the exception thrown from the |
5980 |
03 Jul 20 |
nicklas |
{@link OpenGridCluster#connect(int)} method. |
5980 |
03 Jul 20 |
nicklas |
@since 1.4 |
5980 |
03 Jul 20 |
nicklas |
195 |
*/ |
5980 |
03 Jul 20 |
nicklas |
196 |
Info(ClusterConfig cfg, Exception ex) |
5980 |
03 Jul 20 |
nicklas |
197 |
{ |
5980 |
03 Jul 20 |
nicklas |
198 |
created = System.currentTimeMillis(); |
5980 |
03 Jul 20 |
nicklas |
199 |
hostInfo = new CmdResult<String>("Connect failed"); |
5980 |
03 Jul 20 |
nicklas |
200 |
hostInfo.setException(ex); |
5980 |
03 Jul 20 |
nicklas |
201 |
ogsInfo = new CmdResult<String>(cfg.getOpenGridInfoCommand()); |
5980 |
03 Jul 20 |
nicklas |
202 |
ogsInfo.setStdout("n/a"); |
5980 |
03 Jul 20 |
nicklas |
203 |
timeAdjustment = 0; |
5980 |
03 Jul 20 |
nicklas |
204 |
error = true; |
5995 |
21 Aug 20 |
nicklas |
205 |
connected = false; |
5980 |
03 Jul 20 |
nicklas |
206 |
} |
5980 |
03 Jul 20 |
nicklas |
207 |
|
5980 |
03 Jul 20 |
nicklas |
208 |
/** |
4257 |
30 Nov 16 |
nicklas |
The timestamp when this information was created. |
4257 |
30 Nov 16 |
nicklas |
210 |
*/ |
4257 |
30 Nov 16 |
nicklas |
211 |
public long created() |
4257 |
30 Nov 16 |
nicklas |
212 |
{ |
4257 |
30 Nov 16 |
nicklas |
213 |
return created; |
4257 |
30 Nov 16 |
nicklas |
214 |
} |
4257 |
30 Nov 16 |
nicklas |
215 |
|
4257 |
30 Nov 16 |
nicklas |
216 |
/** |
5995 |
21 Aug 20 |
nicklas |
TRUE if was possible to connect to the cluster, FALSE otherwise. |
5995 |
21 Aug 20 |
nicklas |
@since 1.4 |
5995 |
21 Aug 20 |
nicklas |
219 |
*/ |
5995 |
21 Aug 20 |
nicklas |
220 |
public boolean isConnected() |
5995 |
21 Aug 20 |
nicklas |
221 |
{ |
5995 |
21 Aug 20 |
nicklas |
222 |
return connected; |
5995 |
21 Aug 20 |
nicklas |
223 |
} |
5995 |
21 Aug 20 |
nicklas |
224 |
|
5995 |
21 Aug 20 |
nicklas |
225 |
/** |
4257 |
30 Nov 16 |
nicklas |
Get the cached result of the call to {@link OpenGridSession#getHostInfo()}. |
4257 |
30 Nov 16 |
nicklas |
227 |
*/ |
4257 |
30 Nov 16 |
nicklas |
228 |
public CmdResult<String> getHostInfo() |
4257 |
30 Nov 16 |
nicklas |
229 |
{ |
4257 |
30 Nov 16 |
nicklas |
230 |
return hostInfo; |
4257 |
30 Nov 16 |
nicklas |
231 |
} |
4257 |
30 Nov 16 |
nicklas |
232 |
|
4257 |
30 Nov 16 |
nicklas |
233 |
/** |
4257 |
30 Nov 16 |
nicklas |
Get the cached result of the call to {@link OpenGridSession#getOpenGridInfo()}. |
4257 |
30 Nov 16 |
nicklas |
235 |
*/ |
4257 |
30 Nov 16 |
nicklas |
236 |
public CmdResult<String> getOpenGridInfo() |
4257 |
30 Nov 16 |
nicklas |
237 |
{ |
4257 |
30 Nov 16 |
nicklas |
238 |
return ogsInfo; |
4257 |
30 Nov 16 |
nicklas |
239 |
} |
4257 |
30 Nov 16 |
nicklas |
240 |
|
4257 |
30 Nov 16 |
nicklas |
241 |
/** |
4257 |
30 Nov 16 |
nicklas |
Get the cached result of the call to {@link OpenGridSession#getTimeAdjustment()}. |
4257 |
30 Nov 16 |
nicklas |
243 |
*/ |
4257 |
30 Nov 16 |
nicklas |
244 |
public int getTimeAdjustment() |
4257 |
30 Nov 16 |
nicklas |
245 |
{ |
4257 |
30 Nov 16 |
nicklas |
246 |
return timeAdjustment; |
4257 |
30 Nov 16 |
nicklas |
247 |
} |
4257 |
30 Nov 16 |
nicklas |
248 |
|
4257 |
30 Nov 16 |
nicklas |
249 |
/** |
4257 |
30 Nov 16 |
nicklas |
Get the information as a JSON object. |
4257 |
30 Nov 16 |
nicklas |
251 |
*/ |
4257 |
30 Nov 16 |
nicklas |
252 |
public JSONObject asJSONObject(JSONOptions options) |
4257 |
30 Nov 16 |
nicklas |
253 |
{ |
4257 |
30 Nov 16 |
nicklas |
254 |
JSONObject json = new JSONObject(); |
4257 |
30 Nov 16 |
nicklas |
255 |
json.put("timeAdjustment", timeAdjustment); |
4258 |
01 Dec 16 |
nicklas |
256 |
json.put("hostInfo", hostInfo.asJSONObject(options)); |
4258 |
01 Dec 16 |
nicklas |
257 |
json.put("openGridInfo", ogsInfo.asJSONObject(options)); |
5995 |
21 Aug 20 |
nicklas |
258 |
json.put("connected", connected); |
4257 |
30 Nov 16 |
nicklas |
259 |
json.put("error", error); |
4257 |
30 Nov 16 |
nicklas |
260 |
return json; |
4257 |
30 Nov 16 |
nicklas |
261 |
} |
4257 |
30 Nov 16 |
nicklas |
262 |
|
4257 |
30 Nov 16 |
nicklas |
263 |
} |
4067 |
02 Sep 16 |
nicklas |
264 |
} |