1 /* Copyright (c) 2009 Peter Troshin
\r
3 * JAva Bioinformatics Analysis Web Services (JABAWS) @version: 1.0
\r
5 * This library is free software; you can redistribute it and/or modify it under the terms of the
\r
6 * Apache License version 2 as published by the Apache Software Foundation
\r
8 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
\r
9 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Apache
\r
10 * License for more details.
\r
12 * A copy of the license is in apache_license.txt. It is also available here:
\r
13 * @see: http://www.apache.org/licenses/LICENSE-2.0.txt
\r
15 * Any republication or derived work distributed in source code form
\r
16 * must include this copyright and license notice.
\r
19 package compbio.ws.client;
\r
21 import static compbio.ws.client.Constraints.hostkey;
\r
22 import static compbio.ws.client.Constraints.pseparator;
\r
23 import static compbio.ws.client.Constraints.servicekey;
\r
25 import java.io.ByteArrayInputStream;
\r
26 import java.io.Closeable;
\r
27 import java.io.IOException;
\r
28 import java.io.PrintWriter;
\r
29 import java.util.Arrays;
\r
30 import java.util.List;
\r
32 import org.apache.log4j.Logger;
\r
34 import compbio.data.msa.JABAService;
\r
35 import compbio.data.msa.Metadata;
\r
36 import compbio.data.msa.MsaWS;
\r
37 import compbio.data.msa.SequenceAnnotation;
\r
38 import compbio.data.sequence.Alignment;
\r
39 import compbio.data.sequence.FastaSequence;
\r
40 import compbio.data.sequence.ScoreManager;
\r
41 import compbio.data.sequence.SequenceUtil;
\r
42 import compbio.metadata.JobStatus;
\r
43 import compbio.metadata.JobSubmissionException;
\r
44 import compbio.metadata.Limit;
\r
45 import compbio.metadata.LimitsManager;
\r
46 import compbio.metadata.Option;
\r
47 import compbio.metadata.Preset;
\r
48 import compbio.metadata.PresetManager;
\r
49 import compbio.metadata.ResultNotAvailableException;
\r
50 import compbio.metadata.RunnerConfig;
\r
51 import compbio.metadata.UnsupportedRuntimeException;
\r
52 import compbio.metadata.WrongParameterException;
\r
53 import compbio.util.FileUtil;
\r
54 import compbio.util.Util;
\r
57 * Class for testing web services
\r
61 * @version 1.0 February 2010
\r
63 public class WSTester {
\r
65 private static Logger log = Logger.getLogger(WSTester.class);
\r
67 * Sequences to be used as input for all WS
\r
69 static final String fastaInput = ">Foo\n"
\r
70 + "MTADGPRELLQLRAAVRHRPQDFVAWLMLADAELGMGDTTAGEMAVQRGLALHPGHPEAV"
\r
72 + "ASDAAPEHPGIALWLHALEDAGQAEAAAAYTRAHQLLPEEPYITAQLLNAVA";
\r
74 static final String fastaAlignment = ">Foo\r\n"
\r
75 + "MTADGPRELLQLRAAVRHRPQDFVAWLMLADAELGMGDTTAGEMAVQRGLALHPGHPEAV--------\r\n"
\r
77 + "ASDAAPEH------------PGIALWLHALE-DAGQAEAAA---AYTRAHQLLPEEPYITAQLLNAVA\r\n"
\r
80 static final List<FastaSequence> seqs = loadSeqs();
\r
82 private static final String FAILED = "FAILED";
\r
83 private static final String OK = "OK";
\r
85 private static final String UNSUPPORTED = "UNSUPPORTED";
\r
88 * Converting input to a form accepted by WS
\r
90 * @return List of FastaSequence records
\r
92 private static List<FastaSequence> loadSeqs() {
\r
94 return SequenceUtil.readFasta(new ByteArrayInputStream(fastaInput
\r
96 } catch (IOException ignored) {
\r
97 // Should not happen as a source is not a external stream
\r
98 ignored.printStackTrace();
\r
104 * Converting input to a form accepted by WS
\r
106 * @return List of FastaSequence records
\r
108 private static List<FastaSequence> loadAlignment() {
\r
110 return SequenceUtil.readFasta(new ByteArrayInputStream(
\r
111 fastaAlignment.getBytes()));
\r
112 } catch (IOException ignored) {
\r
113 // Should not happen as a source is not a external stream
\r
114 ignored.printStackTrace();
\r
119 private final PrintWriter writer;
\r
120 private final String hostname;
\r
122 public WSTester(String hostname, PrintWriter writer) {
\r
123 if (Util.isEmpty(hostname)) {
\r
124 throw new NullPointerException("Hostname must be provided!");
\r
126 this.hostname = hostname;
\r
127 this.writer = writer;
\r
133 static void printUsage() {
\r
134 System.out.println("Usage: <Class or Jar file name> " + hostkey
\r
135 + pseparator + "host_and_context " + "<" + servicekey
\r
136 + pseparator + "serviceName>");
\r
137 System.out.println();
\r
141 + "<host_and_context> - a full URL to the JABAWS web server including context path e.g. http://10.31.1.159:8080/ws");
\r
143 .println(servicekey
\r
145 + "<ServiceName> - optional if unspecified all services are tested otherwise one of "
\r
146 + Arrays.toString(Services.values()));
\r
147 System.out.println();
\r
152 * Calls alignment with preset
\r
157 * list of the Preset
\r
158 * @throws UnsupportedRuntimeException
\r
160 private <T> boolean presetAlign(MsaWS<T> msaws, List<Preset<T>> presets)
\r
161 throws UnsupportedRuntimeException {
\r
162 boolean succeed = false;
\r
163 for (Preset<T> preset : presets) {
\r
164 writer.print("Aligning with preset '" + preset.getName() + "'... ");
\r
165 Alignment al = null;
\r
167 String taskId = msaws.presetAlign(seqs, preset);
\r
168 al = msaws.getResult(taskId);
\r
170 writer.println(OK);
\r
173 } catch (UnsupportedRuntimeException e) {
\r
174 writer.println(FAILED);
\r
175 // If executable is not supported than none of the presets are
\r
177 throw new UnsupportedRuntimeException(e);
\r
178 } catch (JobSubmissionException e) {
\r
179 // TODO custom message
\r
180 writer.println(FAILED);
\r
182 writer.println(e.getLocalizedMessage());
\r
183 e.printStackTrace(writer);
\r
185 } catch (WrongParameterException e) {
\r
186 // TODO custom message
\r
187 writer.println(FAILED);
\r
189 writer.println(e.getLocalizedMessage());
\r
190 e.printStackTrace(writer);
\r
192 } catch (ResultNotAvailableException e) {
\r
193 // TODO custom message
\r
194 writer.println(FAILED);
\r
196 writer.println(e.getLocalizedMessage());
\r
197 e.printStackTrace(writer);
\r
204 private <T> boolean testMsaWS(MsaWS<T> msaws)
\r
205 throws UnsupportedRuntimeException {
\r
206 assert msaws != null;
\r
208 boolean succeed = testDefaultAlignment(msaws);
\r
209 // If exception above is thrown than the tests below is not run
\r
211 PresetManager<T> pmanager = msaws.getPresets();
\r
212 if (pmanager != null && pmanager.getPresets().size() > 0) {
\r
213 writer.println("Testing alignment with presets:");
\r
214 List<Preset<T>> plist = pmanager.getPresets();
\r
215 succeed = !succeed ? presetAlign(msaws, plist) : succeed;
\r
217 testMetadata(msaws);
\r
221 * Call most of web services functions and check the output
\r
226 * @throws UnsupportedRuntimeException
\r
227 * is thrown if the connection to a web service was made, but
\r
228 * the web service is not functional. e.g. when native
\r
229 * executable does not exists for a server platform
\r
231 @SuppressWarnings("unchecked")
\r
232 private <T> boolean checkService(JABAService wservice) {
\r
234 if (wservice == null) {
\r
235 throw new NullPointerException(
\r
236 "JABAService instance must be provided!");
\r
239 if (wservice instanceof MsaWS) {
\r
240 return testMsaWS((MsaWS<T>) wservice);
\r
241 } else if (wservice instanceof SequenceAnnotation) {
\r
242 return testSequenceAnnotationWS((SequenceAnnotation<T>) wservice);
\r
244 throw new UnsupportedOperationException("The service: "
\r
245 + wservice.getClass() + " is not supported! ");
\r
247 } catch (UnsupportedRuntimeException e) {
\r
248 writer.println(e.getLocalizedMessage());
\r
249 e.printStackTrace(writer);
\r
254 private <T> boolean testSequenceAnnotationWS(SequenceAnnotation<T> wservice)
\r
255 throws UnsupportedRuntimeException {
\r
256 writer.println("Calling analyse.........");
\r
257 boolean success = testDefaultAnalyse(loadAlignment(), wservice, null,
\r
260 PresetManager<T> presetman = wservice.getPresets();
\r
261 if (presetman != null) {
\r
262 List<Preset<T>> presets = presetman.getPresets();
\r
263 if (presets != null && !presets.isEmpty()) {
\r
264 Preset<T> preset = presets.get(0);
\r
265 writer.println("Calling analyse with Preset.........");
\r
266 success = testDefaultAnalyse(loadAlignment(), wservice, preset,
\r
270 testMetadata(wservice);
\r
274 private <T> boolean testDefaultAnalyse(List<FastaSequence> fastalist,
\r
275 SequenceAnnotation<T> wsproxy, Preset<T> preset,
\r
276 List<Option<T>> customOptions) throws UnsupportedRuntimeException {
\r
278 ScoreManager scores = null;
\r
280 String jobId = null;
\r
281 if (customOptions != null) {
\r
282 jobId = wsproxy.customAnalize(fastalist, customOptions);
\r
283 } else if (preset != null) {
\r
284 jobId = wsproxy.presetAnalize(fastalist, preset);
\r
286 jobId = wsproxy.analize(fastalist);
\r
288 Thread.sleep(1000);
\r
289 scores = wsproxy.getAnnotation(jobId);
\r
291 } catch (JobSubmissionException e) {
\r
292 writer.println("Exception while submitting job to a web server. "
\r
293 + "Exception details are below:");
\r
294 e.printStackTrace(writer);
\r
295 } catch (ResultNotAvailableException e) {
\r
296 writer.println("Exception while waiting for results. "
\r
297 + "Exception details are below:");
\r
298 e.printStackTrace(writer);
\r
299 } catch (InterruptedException e) {
\r
300 // ignore and propagate an interruption
\r
301 Thread.currentThread().interrupt();
\r
302 writer.println("Exception while waiting for results. "
\r
303 + "Exception details are below:");
\r
304 e.printStackTrace(writer);
\r
305 } catch (WrongParameterException e) {
\r
306 writer.println("Exception while parsing the web method input parameters. "
\r
307 + "Exception details are below:");
\r
308 e.printStackTrace(writer);
\r
310 return scores != null;
\r
313 private <T> void testMetadata(Metadata<T> msaws)
\r
314 throws UnsupportedRuntimeException {
\r
316 writer.print("Querying presets...");
\r
317 PresetManager<T> pmanager = msaws.getPresets();
\r
318 if (pmanager != null && pmanager.getPresets().size() > 0) {
\r
319 writer.println(OK);
\r
321 writer.println(UNSUPPORTED);
\r
324 writer.print("Querying Parameters...");
\r
325 RunnerConfig<T> options = msaws.getRunnerOptions();
\r
326 if (options != null && options.getArguments().size() > 0) {
\r
327 writer.println(OK);
\r
329 writer.println(UNSUPPORTED);
\r
332 writer.print("Querying Limits...");
\r
333 LimitsManager<T> limits = msaws.getLimits();
\r
334 if (limits != null && limits.getLimits().size() > 0) {
\r
335 writer.println(OK);
\r
337 writer.println(UNSUPPORTED);
\r
340 writer.print("Querying Local Engine Limits...");
\r
341 Limit<T> localLimit = msaws
\r
342 .getLimit(PresetManager.LOCAL_ENGINE_LIMIT_PRESET);
\r
343 if (localLimit != null) {
\r
344 writer.println(OK);
\r
346 writer.println(UNSUPPORTED);
\r
351 * Align using default settings
\r
355 * @throws UnsupportedRuntimeException
\r
357 private <T> boolean testDefaultAlignment(MsaWS<T> msaws)
\r
358 throws UnsupportedRuntimeException {
\r
359 writer.print("Testing alignment with default parameters:");
\r
360 Alignment al = null;
\r
361 boolean succeed = false;
\r
363 String taskId = msaws.align(seqs);
\r
364 writer.print("\nQuerying job status...");
\r
365 JobStatus status = msaws.getJobStatus(taskId);
\r
366 while (status != JobStatus.FINISHED) {
\r
367 Thread.sleep(1000);
\r
368 status = msaws.getJobStatus(taskId);
\r
370 writer.println(OK);
\r
371 writer.print("Retrieving results...");
\r
372 al = msaws.getResult(taskId);
\r
374 } catch (Exception e) {
\r
375 if (e instanceof UnsupportedRuntimeException) {
\r
376 throw (UnsupportedRuntimeException) e;
\r
378 writer.println(FAILED);
\r
379 writer.println(e.getLocalizedMessage());
\r
380 e.printStackTrace(writer);
\r
384 writer.println(OK);
\r
390 * Test JWS2 web services
\r
395 * -h=<Your web application server host name, port and JWS2
\r
398 * -s=<ServiceName> which is optional. If service name is not
\r
399 * provided then all known JWS2 web services are tested
\r
400 * @throws IOException
\r
402 public static <T> void main(String[] args) throws IOException {
\r
404 if (args == null || args.length < 1) {
\r
405 WSTester.printUsage();
\r
408 String host = CmdHelper.getHost(args);
\r
409 String serviceName = CmdHelper.getServiceName(args);
\r
410 if (!Jws2Client.validURL(host)) {
\r
412 .println("<host_and_context> parameter is not provided or is incorrect!");
\r
415 WSTester tester = new WSTester(host, new PrintWriter(System.out, true));
\r
417 if (serviceName != null) {
\r
418 Services service = Services.getService(serviceName);
\r
419 if (service == null) {
\r
420 tester.writer.println("Service '" + serviceName
\r
421 + "' is not supported. Valid values are: "
\r
422 + Arrays.toString(Services.values()));
\r
423 tester.writer.println();
\r
427 tester.checkService(service);
\r
432 .println("<ServiceName> is not provided checking all known services...");
\r
434 for (Services serv : Services.values()) {
\r
435 tester.writer.println();
\r
436 tester.checkService(serv);
\r
441 public boolean checkService(Services service) {
\r
442 JABAService ws = Jws2Client.connect(hostname, service);
\r
444 writer.println("Cannot estabilish the connection to host "
\r
445 + hostname + " with service " + service.toString());
\r
448 boolean succeed = false;
\r
450 writer.println("Checking service " + service.toString());
\r
451 succeed = checkService(ws);
\r
453 FileUtil.closeSilently(((Closeable) ws));
\r
455 reportResults(service, succeed);
\r
459 private void reportResults(Services serv, boolean succeed) {
\r
461 writer.println("Check is completed. The Service " + serv
\r
462 + " IS WORKING\n");
\r
464 writer.println("Check is completed. The Service " + serv
\r
465 + " HAS SOME PROBLEMS\n");
\r