+/* Copyright (c) 2011 Peter Troshin\r
+ * \r
+ * JAva Bioinformatics Analysis Web Services (JABAWS) @version: 2.0 \r
+ * \r
+ * This library is free software; you can redistribute it and/or modify it under the terms of the\r
+ * Apache License version 2 as published by the Apache Software Foundation\r
+ * \r
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\r
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Apache \r
+ * License for more details.\r
+ * \r
+ * A copy of the license is in apache_license.txt. It is also available here:\r
+ * @see: http://www.apache.org/licenses/LICENSE-2.0.txt\r
+ * \r
+ * Any republication or derived work distributed in source code form\r
+ * must include this copyright and license notice.\r
+ */\r
package compbio.ws.server;\r
\r
import java.io.PrintWriter;\r
import org.apache.log4j.Logger;\r
\r
import compbio.data.msa.JABAService;\r
-import compbio.ws.client.Jws2Client;\r
import compbio.ws.client.Services;\r
import compbio.ws.client.WSTester;\r
\r
/**\r
- * TODO\r
+ * JABAWS services registry\r
* \r
* @author pvtroshin\r
* \r
*/\r
-@WebService(endpointInterface = "compbio.data.msa.RegistryWS", targetNamespace = "http://msa.data.compbio/01/12/2010/", serviceName = "RegistryWS")\r
+@WebService(endpointInterface = "compbio.data.msa.RegistryWS", targetNamespace = JABAService.V2_SERVICE_NAMESPACE, serviceName = "RegistryWS")\r
public class RegistryWS implements compbio.data.msa.RegistryWS, JABAService {\r
\r
// Ask for resource injection\r
@Resource\r
WebServiceContext wsContext;\r
\r
- private static Logger statLog = Logger.getLogger("RegistryWS-stats");\r
private static Logger log = Logger.getLogger(RegistryWS.class);\r
\r
+ /**\r
+ * Stores tested and passed (the test) services and their testing time\r
+ */\r
private final static Map<Services, Date> operating = new ConcurrentHashMap<Services, Date>();\r
\r
/**\r
- * 1) Check that the actual executable is configured\r
- * \r
- * 2) Check whether the service is enabled?\r
- * \r
- * 3) Attempt to execute?\r
- * \r
- * @return\r
+ * Indicate whether the services were tested at all\r
*/\r
+ private static boolean allTested = false;\r
+\r
@Override\r
public Set<Services> getSupportedServices() {\r
init();\r
}\r
\r
private void init() {\r
- // This can be run concurrently\r
- if (operating.isEmpty()) {\r
- testAllServices();\r
+ // Do not allow tests to run concurrently\r
+ if (timeToTest()) {\r
+ synchronized (operating) {\r
+ if (timeToTest()) {\r
+ testAllServices();\r
+ allTested = true;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ private boolean timeToTest() {\r
+ if (!allTested) {\r
+ return true;\r
+ }\r
+ // 24 h\r
+ if (getLongestUntestedServiceTime() > 3600 * 24) {\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Return time in seconds for the test for the oldest unchecked service\r
+ * \r
+ * @return\r
+ */\r
+ private int getLongestUntestedServiceTime() {\r
+ int timePassed = 0;\r
+ for (Services serv : operating.keySet()) {\r
+ int lasttimepassed = getLastTested(serv);\r
+ if (timePassed < lasttimepassed) {\r
+ timePassed = lasttimepassed;\r
+ }\r
}\r
+ return timePassed;\r
}\r
+\r
+ @Override\r
+ public int getLastTested(Services service) {\r
+ Date testedOn = getLastTestedOn(service);\r
+ if (testedOn != null) {\r
+ return (int) ((System.currentTimeMillis() - testedOn.getTime()) / 1000);\r
+ }\r
+ return 0;\r
+ }\r
+\r
+ /**\r
+ * Can potentially return null if the service has not been tested yet.\r
+ */\r
@Override\r
public Date getLastTestedOn(Services service) {\r
- return operating.get(service);\r
+ if (operating.containsKey(service)) {\r
+ return operating.get(service);\r
+ }\r
+ return null;\r
}\r
\r
+ /**\r
+ * TODO improve reporting. stop testing service on unsupported runtime env\r
+ * exception\r
+ */\r
@Override\r
public String testAllServices() {\r
Writer testlog = new StringWriter();\r
PrintWriter writer = new PrintWriter(testlog, true);\r
- WSTester tester = new WSTester(writer);\r
-\r
- for (Services service : Services.values()) {\r
- JABAService ws = Jws2Client.connect(getServicePath(), service);\r
- if (tester.checkService(ws)) {\r
- operating.put(service, new Date());\r
+ WSTester tester = new WSTester(getServicePath(), writer);\r
+ // This is done deliberately to prevent malicious user from overloading\r
+ // the server\r
+ synchronized (operating) {\r
+ for (Services service : Services.values()) {\r
+ try {\r
+ if (tester.checkService(service)) {\r
+ operating.put(service, new Date());\r
+ }\r
+ } catch (Exception e) {\r
+ log.info(e, e.getCause());\r
+ writer.println("Fails to connect to a web service: "\r
+ + service + " With " + e.getLocalizedMessage()\r
+ + "\nDetails: ");\r
+ e.printStackTrace(writer);\r
+ }\r
}\r
}\r
+ writer.close();\r
return testlog.toString();\r
}\r
\r
String server = getServicePath();\r
Writer testlog = new StringWriter();\r
PrintWriter writer = new PrintWriter(testlog, true);\r
- WSTester tester = new WSTester(writer);\r
- writer.println("Attempting to connect to the service " + service\r
- + " on the server " + server + "...");\r
- JABAService ws = Jws2Client.connect(server, service);\r
- writer.println("Connected successfully!");\r
+ WSTester tester = new WSTester(server, writer);\r
try {\r
- boolean succeed = tester.checkService(ws);\r
- if (succeed) {\r
- // TODO extract messages (see WSTester main)\r
- writer.println("Check is completed. The Service "\r
- + service.toString() + " IS WORKING");\r
- operating.put(service, new Date());\r
- } else {\r
- writer.println("Check is completed. The Service "\r
- + service.toString() + " HAS SOME PROBLEMS");\r
+ synchronized (operating) {\r
+ boolean succeed = tester.checkService(service);\r
+ if (succeed) {\r
+ operating.put(service, new Date());\r
+ }\r
}\r
+ } catch (Exception e) {\r
+ log.info(e, e.getCause());\r
+ writer.println("Fails to connect to a web service: " + service\r
+ + " With " + e.getLocalizedMessage() + "\nDetails: ");\r
+ e.printStackTrace(writer);\r
} finally {\r
writer.close();\r
}\r
return operating.containsKey(service);\r
}\r
\r
+ @Override\r
+ public String getServiceDescription(Services service) {\r
+ return service.getServiceInfo();\r
+ }\r
+\r
+ @Override\r
+ public Set<Category> getServiceCategories() {\r
+ return Category.getCategories();\r
+ }\r
+\r
}\r