1
2
3
4
5
6
7
8 package net.kwfgrid.gwes.client;
9
10 import net.kwfgrid.gwes.WorkflowStatus;
11 import net.kwfgrid.gwes.Constants;
12 import net.kwfgrid.gwes.exception.*;
13 import net.kwfgrid.gwes.exception.DatabaseException;
14 import net.kwfgrid.gwes.exception.StateTransitionException;
15 import net.kwfgrid.gwes.exception.NoSuchWorkflowException;
16 import net.kwfgrid.gwes.exception.GWESException;
17 import net.kwfgrid.gwes.exception.WorkflowSecurityException;
18 import org.apache.log4j.Logger;
19 import org.apache.axis2.AxisFault;
20 import org.gridforum.jgss.ExtendedGSSCredential;
21 import org.gridforum.jgss.ExtendedGSSManager;
22 import org.ietf.jgss.GSSCredential;
23 import org.ietf.jgss.GSSException;
24
25 import java.io.BufferedReader;
26 import java.io.FileReader;
27 import java.io.IOException;
28 import java.net.MalformedURLException;
29 import java.net.URL;
30 import java.rmi.RemoteException;
31 import java.security.NoSuchAlgorithmException;
32 import java.security.KeyStoreException;
33 import java.security.KeyManagementException;
34 import java.security.cert.CertificateException;
35 import java.lang.*;
36
37
38
39
40
41
42 public class GWESClient {
43
44
45
46
47 static Logger logger = Logger.getLogger(GWESClient.class);
48
49 public final static int COMMAND_INITIATE = 1;
50 public final static int COMMAND_INITIATE_START = 2;
51 public final static int COMMAND_START = 3;
52 public final static int COMMAND_SUSPEND = 4;
53 public final static int COMMAND_RESUME = 5;
54 public final static int COMMAND_STORE = 6;
55 public final static int COMMAND_RESTORE = 7;
56 public final static int COMMAND_RESTART = 8;
57 public final static int COMMAND_ABORT = 9;
58 public final static int COMMAND_GET_WORKFLOW_DESCRIPTION = 10;
59 public final static int COMMAND_GET_STATUS = 11;
60 public final static int COMMAND_GET_WORKFLOW_IDS = 12;
61 public final static int COMMAND_GET_WORKFLOW_STATUS_ARRAY = 13;
62 public final static int COMMAND_GET_DATA = 14;
63 public final static int COMMAND_MONITOR = 15;
64 public final static int COMMAND_REMOVE = 16;
65 public final static int COMMAND_GET_WORKFLOW_PROPERTIES = 17;
66 public final static int COMMAND_SET_WORKFLOW_PROPERTY = 18;
67 public final static int COMMAND_GET_DESCRIPTION = 19;
68 public final static int COMMAND_SET_DESCRIPTION = 20;
69 public final static int COMMAND_GET_ACTIVITIES = 21;
70
71 public RemoteGWES gwes;
72 public String host;
73 public int port;
74
75 public String userID;
76
77
78
79 public GWESClient() throws MalformedURLException {
80 this(new URL(System.getProperty(Constants.PROP_SYSTEM_GWES_SERVICE_BASE_URL_EXTERNAL) + "/services/GWES"), System.getProperty("user.name", "nn"));
81 }
82
83 public GWESClient(URL gwesServiceUrl, String userID) {
84 if (gwesServiceUrl == null) {
85 logger.fatal("GWES service base URL not specified. Please set property \""+ Constants.PROP_SYSTEM_GWES_SERVICE_BASE_URL_EXTERNAL + "\" or input parameter \"-gwes\".");
86 usage();
87 System.exit(1);
88 }
89
90 this.userID = (userID == null) ? System.getProperty("user.name", "nn") : userID;
91
92 try {
93 logger.info("Trying to connect to " + gwesServiceUrl + "...");
94
95 logger.info("Setting up security...");
96 CertUtils.setDefaultSystemProperties();
97
98 host = gwesServiceUrl.getHost();
99 port = gwesServiceUrl.getPort();
100 gwes = RemoteGWES.getInstance(gwesServiceUrl.toExternalForm());
101 } catch (Exception e) {
102 logger.fatal("exception:"+ e.getMessage(), e);
103 }
104 }
105
106 public static void main(String args[]) {
107 GWESClient client = null;
108
109 int command = 0;
110 String gworkflowdl = null;
111 String workflowID = null;
112 String placeID = null;
113 String name = null;
114 String value = null;
115 int level = 0;
116 boolean monitor = false;
117 boolean useCredential = false;
118
119 try {
120 for (int i = 0; i < args.length; i++) {
121 if (args[i].startsWith("-D")) {
122 name = args[i].substring(2,args[i].indexOf('='));
123 value = args[i].substring(args[i].indexOf('=')+1);
124 System.setProperty(name,value);
125 } else if (args[i].toLowerCase().equals("-initiate") || args[i].toLowerCase().equals("-i")) {
126 command = COMMAND_INITIATE;
127 gworkflowdl = args[++i];
128 } else if (args[i].toLowerCase().equals("-initiatestart") || args[i].toLowerCase().equals("-is")) {
129 command = COMMAND_INITIATE_START;
130 gworkflowdl = args[++i];
131 } else if (args[i].toLowerCase().equals("-start") || args[i].toLowerCase().equals("-s")) {
132 command = COMMAND_START;
133 workflowID = args[++i];
134 } else if (args[i].toLowerCase().equals("-suspend")) {
135 command = COMMAND_SUSPEND;
136 workflowID = args[++i];
137 } else if (args[i].toLowerCase().equals("-resume")) {
138 command = COMMAND_RESUME;
139 workflowID = args[++i];
140 } else if (args[i].toLowerCase().equals("-store")) {
141 command = COMMAND_STORE;
142 workflowID = args[++i];
143 } else if (args[i].toLowerCase().equals("-remove") || args[i].toLowerCase().equals("-r")) {
144 command = COMMAND_REMOVE;
145 workflowID = args[++i];
146 level = Integer.parseInt(args[++i]);
147 } else if (args[i].toLowerCase().equals("-restore")) {
148 command = COMMAND_RESTORE;
149 workflowID = args[++i];
150 } else if (args[i].toLowerCase().equals("-restart")) {
151 command = COMMAND_RESTART;
152 workflowID = args[++i];
153 } else if (args[i].toLowerCase().equals("-abort") | args[i].toLowerCase().equals("-a")) {
154 command = COMMAND_ABORT;
155 workflowID = args[++i];
156 } else
157 if (args[i].toLowerCase().equals("-getworkflowdescription") || args[i].toLowerCase().equals("-gwd")) {
158 command = COMMAND_GET_WORKFLOW_DESCRIPTION;
159 workflowID = args[++i];
160 } else if (args[i].toLowerCase().equals("-getstatus") || args[i].toLowerCase().equals("-gws")) {
161 command = COMMAND_GET_STATUS;
162 workflowID = args[++i];
163 } else if (args[i].toLowerCase().equals("-getworkflowids") || args[i].toLowerCase().equals("-gwi")) {
164 command = COMMAND_GET_WORKFLOW_IDS;
165 level = Integer.parseInt(args[++i]);
166 } else if (args[i].toLowerCase().equals("-getworkflowstatusarray") || args[i].toLowerCase().equals("-gwa")) {
167 command = COMMAND_GET_WORKFLOW_STATUS_ARRAY;
168 level = Integer.parseInt(args[++i]);
169 } else if (args[i].toLowerCase().equals("-getworkflowactivities") || args[i].toLowerCase().equals("-gwc")) {
170 command = COMMAND_GET_ACTIVITIES;
171 workflowID = args[++i];
172 } else if (args[i].toLowerCase().equals("-getdata")) {
173 command = COMMAND_GET_DATA;
174 workflowID = args[++i];
175 placeID = args[++i];
176 } else if (args[i].toLowerCase().equals("-getworkflowproperties") || args[i].toLowerCase().equals("-gwp")) {
177 command = COMMAND_GET_WORKFLOW_PROPERTIES;
178 workflowID = args[++i];
179 } else if (args[i].toLowerCase().equals("-setworkflowproperty") || args[i].toLowerCase().equals("-swp")) {
180 command = COMMAND_SET_WORKFLOW_PROPERTY;
181 workflowID = args[++i];
182 name = args[++i];
183 value = args[++i];
184 } else if (args[i].toLowerCase().equals("-getdescription") || args[i].toLowerCase().equals("-gd")) {
185 command = COMMAND_GET_DESCRIPTION;
186 workflowID = args[++i];
187 } else if (args[i].toLowerCase().equals("-setdescription") || args[i].toLowerCase().equals("-sd")) {
188 command = COMMAND_SET_DESCRIPTION;
189 workflowID = args[++i];
190 StringBuffer buffer = new StringBuffer();
191 while (i < args.length -1) {
192 buffer.append(args[++i]);
193 buffer.append(" ");
194 }
195 value = buffer.toString().trim();
196 logger.info(value);
197 } else if (args[i].toLowerCase().equals("-monitor") || args[i].toLowerCase().equals("-m")) {
198 if (command == 0) {
199 command = COMMAND_MONITOR;
200 workflowID = args[++i];
201 }
202 monitor = true;
203 } else if (args[i].toLowerCase().equals("-gwes") || args[i].toLowerCase().equals("-g")) {
204 String baseUrl = args[++i];
205
206 int serviceIndex = baseUrl.indexOf("/services/GWES");
207 if (serviceIndex > 0) {
208 baseUrl = baseUrl.substring(0, serviceIndex);
209 }
210 System.setProperty("gwes.service.base.url.external", baseUrl);
211 } else if (args[i].toLowerCase().equals("-credential") || args[i].toLowerCase().equals("-c")) {
212 useCredential = true;
213 }
214 }
215 } catch (Exception e) {
216 logger.fatal("Error in command line parameter: " + e);
217 usage();
218 System.exit(1);
219 }
220
221 try {
222
223 client = new GWESClient();
224
225 if (useCredential) {
226 try {
227 client.userID = getUserIDWithCredential(client.userID);
228 } catch (GSSException e) {
229 logger.fatal("Could not load default Globus Toolkit credential proxy. Please check option \"-credential\" and file \"${HOME}/.globus/cog.properties\": "+e,e);
230 usage();
231 System.exit(1);
232 }
233 }
234
235 switch (command) {
236 case COMMAND_ABORT:
237 checkWorkflowID(workflowID);
238 client.gwes.abort(workflowID, client.userID);
239 break;
240 case COMMAND_GET_DATA:
241 checkWorkflowID(workflowID);
242 checkPlaceID(placeID);
243 String[] tokens = client.gwes.getData(workflowID, placeID, client.userID);
244 System.out.println("data = ");
245 for (String token : tokens) {
246 System.out.println(token);
247 }
248 break;
249 case COMMAND_GET_WORKFLOW_PROPERTIES:
250 checkWorkflowID(workflowID);
251 String[][] properties = client.gwes.getProperties(workflowID, client.userID);
252 for (String[] property : properties) {
253 System.out.println(property[0]+"=\""+property[1]+"\"");
254 }
255 break;
256 case COMMAND_SET_WORKFLOW_PROPERTY:
257 checkWorkflowID(workflowID);
258 checkString("name",name);
259 checkString("value",value);
260 client.gwes.setProperty(workflowID,name,value, client.userID);
261 break;
262 case COMMAND_GET_STATUS:
263 checkWorkflowID(workflowID);
264 int status = client.gwes.getStatus(workflowID, client.userID);
265 System.out.println("status = " + WorkflowStatus.getStatusAsString(status));
266 break;
267 case COMMAND_GET_DESCRIPTION:
268 checkWorkflowID(workflowID);
269 String description = client.gwes.getDescription(workflowID, client.userID);
270 System.out.println("description = " + description);
271 break;
272 case COMMAND_SET_DESCRIPTION:
273 checkWorkflowID(workflowID);
274 checkString("description", value);
275 client.gwes.setDescription(workflowID,value, client.userID);
276 break;
277 case COMMAND_GET_WORKFLOW_DESCRIPTION:
278 checkWorkflowID(workflowID);
279 String xml = client.gwes.getWorkflowDescription(workflowID, client.userID);
280 System.out.println("workflowDescription = \n" + xml);
281 break;
282 case COMMAND_GET_WORKFLOW_IDS:
283 checkLevel(level);
284 String[] ids = client.gwes.getWorkflowIDs(level, client.userID);
285 if (ids == null || ids.length == 0) {
286 System.out.println("No workflows available for level="+level);
287 } else {
288 System.out.println("workflowIDs = ");
289 for (String id : ids) {
290 System.out.println(id);
291 }
292 }
293 break;
294 case COMMAND_GET_WORKFLOW_STATUS_ARRAY:
295 checkLevel(level);
296 String[][] states = client.gwes.getWorkflowStatusArray(level, client.userID);
297 if (states == null || states.length == 0) {
298 System.out.println("No workflows available for level=" + level);
299 } else {
300 System.out.println("workflowStatusArray = ");
301 for (String[] statearray : states) {
302 for (String state : statearray) {
303 System.out.println(state);
304 }
305 System.out.println();
306 }
307 }
308 break;
309 case COMMAND_GET_ACTIVITIES:
310 checkWorkflowID(workflowID);
311 String[][] activities = client.gwes.getActivityStatusArray(workflowID, client.userID);
312 System.out.println("ActivityStatusArray = ");
313 for (String[] statearray : activities) {
314 for (String state : statearray) {
315 System.out.println(state);
316 }
317 System.out.println();
318 }
319 break;
320 case COMMAND_INITIATE:
321 checkGWorkflowDL(gworkflowdl);
322 workflowID = client.gwes.initiate(readFile(gworkflowdl), client.userID);
323 System.out.println("workflowID = " + workflowID);
324 break;
325 case COMMAND_INITIATE_START:
326 checkGWorkflowDL(gworkflowdl);
327 workflowID = client.gwes.initiate(readFile(gworkflowdl), client.userID);
328 System.out.println("workflowID = " + workflowID);
329 client.gwes.start(workflowID, client.userID);
330 if (monitor) monitor(client, workflowID);
331 break;
332 case COMMAND_MONITOR:
333 checkWorkflowID(workflowID);
334 monitor(client, workflowID);
335 break;
336 case COMMAND_REMOVE:
337 checkWorkflowID(workflowID);
338 checkLevel(level);
339
340 client.gwes.remove(workflowID, level, client.userID);
341 break;
342 case COMMAND_RESTORE:
343 checkWorkflowID(workflowID);
344
345 workflowID = client.gwes.restart(workflowID, client.userID);
346 System.out.println("workflowID = " + workflowID);
347 break;
348 case COMMAND_RESTART:
349 checkWorkflowID(workflowID);
350
351 workflowID = client.gwes.restart(workflowID, client.userID);
352 System.out.println("workflowID = " + workflowID);
353 if (monitor) monitor(client, workflowID);
354 break;
355 case COMMAND_RESUME:
356 checkWorkflowID(workflowID);
357 client.gwes.resume(workflowID, client.userID);
358 break;
359 case COMMAND_START:
360 checkWorkflowID(workflowID);
361 client.gwes.start(workflowID, client.userID);
362 if (monitor) monitor(client, workflowID);
363 break;
364 case COMMAND_STORE:
365 checkWorkflowID(workflowID);
366 System.out.println("dbPath = " + client.gwes.store(workflowID, client.userID));
367 break;
368 case COMMAND_SUSPEND:
369 checkWorkflowID(workflowID);
370 client.gwes.suspend(workflowID, client.userID);
371 break;
372 default:
373 logger.fatal("Command not supported.");
374 usage();
375 System.exit(1);
376 }
377 } catch (AxisFault e) {
378 logger.error("Axis Fault:", e);
379 if (
380
381 e.getMessage().indexOf("SSL")!=-1 ||
382 e.getMessage().indexOf("the trustAnchors parameter must be non-empty") != -1 ||
383 e.getMessage().indexOf("Received fatal alert: bad_certificate")!=-1
384 ){
385 try {
386 CertUtils.getInstance().installCert(client.host,client.port);
387 System.out.println("=========> Please restart GWESClient to consider changes in keystore and truststore <=========");
388 } catch (NoSuchAlgorithmException e1) {
389 logger.error("exception:\n" + e1, e1);
390 } catch (KeyStoreException e1) {
391 logger.error("exception:\n" + e1, e1);
392 } catch (IOException e1) {
393 logger.error("exception:\n" + e1, e1);
394 } catch (KeyManagementException e1) {
395 logger.error("exception:\n" + e1, e1);
396 } catch (CertificateException e1) {
397 logger.error("exception:\n" + e1, e1);
398 }
399 }
400 System.exit(1);
401 } catch (RemoteException e) {
402 logger.fatal("exception:", e);
403 System.exit(1);
404 } catch (InterruptedException e) {
405 logger.fatal("exception:", e);
406 System.exit(1);
407 } catch (MalformedURLException e) {
408 logger.fatal("Please provide a valid GWES service base URL (e.g. http://server:8080/gwes)", e);
409 usage();
410 System.exit(1);
411 } catch (net.kwfgrid.gworkflowdl.structure.WorkflowFormatException e) {
412 logger.error("exception:\n" + e, e);
413 } catch (net.kwfgrid.gwes.exception.NoSuchWorkflowException e) {
414 logger.error("exception:\n" + e, e);
415 } catch (DatabaseException e) {
416 logger.error("exception:\n" + e, e);
417 } catch (StateTransitionException e) {
418 logger.error("exception:\n" + e, e);
419 } catch (java.lang.InterruptedException e) {
420 logger.error("exception:\n" + e, e);
421 } catch (net.kwfgrid.gwes.exception.LoggingException e) {
422 logger.error("exception:\n" + e, e);
423 } catch (net.kwfgrid.gwes.exception.WorkflowSecurityException e) {
424 logger.error("exception:\n" + e, e);
425 } catch (net.kwfgrid.gwes.exception.GWESException e) {
426 logger.error("exception:\n" + e, e);
427 }
428 }
429
430 private static void monitor(GWESClient client, String workflowID) throws RemoteException, InterruptedException, NoSuchWorkflowException, DatabaseException, java.lang.InterruptedException, net.kwfgrid.gwes.exception.LoggingException, GWESException, WorkflowSecurityException {
431 int status;
432 int oldstatus;
433
434 status = client.gwes.getStatus(workflowID, client.userID);
435 System.out.print(WorkflowStatus.getStatusAsString(status));
436 while (status != WorkflowStatus.STATUS_COMPLETED && status != WorkflowStatus.STATUS_TERMINATED) {
437 Thread.sleep(1000L);
438 oldstatus = status;
439 status = client.gwes.getStatus(workflowID, client.userID);
440 if (status == oldstatus) {
441 System.out.print(".");
442 } else {
443 System.out.print("\n" + WorkflowStatus.getStatusAsString(status));
444 }
445 }
446 System.out.print("\n");
447 }
448
449 private static void checkGWorkflowDL(String gworkflowdl) {
450 if (gworkflowdl == null) {
451 logger.fatal("Error: GWorkflowDL not specified!");
452 usage();
453 System.exit(1);
454 }
455 }
456
457 private static void checkWorkflowID(String workflowID) {
458 if (workflowID == null) {
459 logger.fatal("Error: workflowID not specified!");
460 usage();
461 System.exit(1);
462 }
463 }
464
465 private static void checkPlaceID(String placeID) {
466 if (placeID == null) {
467 logger.fatal("Error: placeID not specified!");
468 usage();
469 System.exit(1);
470 }
471 }
472
473 private static void checkLevel(int level) {
474 if (level < 1 || level > 7) {
475 logger.fatal("Error: wrong level value. Must be between 1 and 7!");
476 usage();
477 System.exit(1);
478 }
479 }
480
481 private static void checkString(String name, String str) {
482 if (str == null) {
483 logger.fatal("Error: parameter \""+name+"\" is missing!");
484 usage();
485 System.exit(1);
486 }
487 }
488
489
490
491
492
493
494
495 public static String getUserIDWithCredential(String userName) throws GSSException {
496 if (userName.contains("|")) return userName;
497 ExtendedGSSManager manager = (ExtendedGSSManager) ExtendedGSSManager.getInstance();
498 ExtendedGSSCredential credential = (ExtendedGSSCredential) manager.createCredential(GSSCredential.INITIATE_AND_ACCEPT);
499 logger.info("Loading credential \""
500 + credential.getName().toString() + "\" with remaining lifetime="
501 + credential.getRemainingLifetime() + "s");
502 String credentialString = new String(credential.export(ExtendedGSSCredential.IMPEXP_OPAQUE));
503 return userName + '|' + credentialString;
504 }
505
506 public static void usage() {
507 System.out.println("\n");
508 System.out.println("-------------------------------------------------------------------------------");
509 System.out.println("Usage: java net.kwfgrid.gwes.GWESClient -gwes | -g <gwesURL>");
510 System.out.println(" -initiate | -i <GWorkflowDL>");
511 System.out.println(" -initiateStart | -is <GWorkflowDL> [-monitor]");
512 System.out.println(" -start | -s <workflowID> [-monitor]");
513 System.out.println(" -suspend <workflowID>");
514 System.out.println(" -resume <workflowID>");
515 System.out.println(" -store <workflowID>");
516 System.out.println(" -remove | -r <workflowID> <level>");
517 System.out.println(" -restore <workflowID>");
518 System.out.println(" -restart <workflowID> [-monitor]");
519 System.out.println(" -abort | -a <workflowID>");
520 System.out.println(" -getWorkflowDescription | -gwd <workflowID>");
521 System.out.println(" -getStatus | -gws <workflowID>");
522 System.out.println(" -getWorkflowIDs | -gwi <level>");
523 System.out.println(" -getWorkflowStatusArray | -gwa <level>");
524 System.out.println(" -getWorkflowProperties | -gwp <workflowID>");
525 System.out.println(" -getWorkflowActivities | -gwc <workflowID>");
526 System.out.println(" -getData <workflowID> <placeID>");
527 System.out.println(" -getDescription <workflowID> | -gd <workflowID>");
528 System.out.println(" -setDescription <workflowID> <description> | -sd <workflowID> <description>");
529 System.out.println(" -monitor | -m <workflowID>");
530 System.out.println(" -credential | -c");
531 System.out.println("-------------------------------------------------------------------------------");
532 System.out.println(" If you define several commands in one call, only the last one will be ");
533 System.out.println(" invoked!");
534 System.out.println(" <gwesURL> : The URL where the GWES is located, e.g.");
535 System.out.println(" http://server:8080/gwes");
536 System.out.println(" <GWorkflowDL> : The filename of the GWorkflowDL document containing the");
537 System.out.println(" workflow to enact");
538 System.out.println(" <workflowID> : The identifier of the workflow");
539 System.out.println(" <description> : The human-readable description of the workflow");
540 System.out.println(" <level> : The storage level: 1=memory, 2=database, 4=temporary workflow data");
541 System.out.println(" -monitor | -m : The GWESClient monitors the running job until it");
542 System.out.println(" terminates or completes");
543 System.out.println(" -credential | -c : delegate local GSS credential to GWES");
544 System.out.println("-------------------------------------------------------------------------------");
545 }
546
547
548
549
550
551
552
553 public static String readFile(String fileName) {
554 logger.info("Reading file " + fileName + "...");
555 StringBuffer buffer = new StringBuffer();
556 BufferedReader fileReader;
557 try {
558 fileReader
559 = new BufferedReader(new FileReader(fileName));
560 } catch (java.io.FileNotFoundException fnfe) {
561 logger.error("problem opening file [" + fnfe.getMessage() + "]", fnfe);
562 return null;
563 }
564
565 String line;
566 try {
567 line = fileReader.readLine();
568 while (line != null) {
569 buffer.append(line);
570 buffer.append('\n');
571 line = fileReader.readLine();
572 }
573 } catch (java.io.IOException ioe) {
574 logger.error("problem reading file [" + ioe.getMessage() + "]", ioe);
575 return null;
576 }
577 return buffer.toString();
578 }
579
580 }