further work on registry & WSTester nearly there
[jabaws.git] / webservices / compbio / ws / server / RegistryWS.java
1 package compbio.ws.server;\r
2 \r
3 import java.io.PrintWriter;\r
4 import java.io.StringWriter;\r
5 import java.io.Writer;\r
6 import java.util.Date;\r
7 import java.util.Map;\r
8 import java.util.Set;\r
9 import java.util.concurrent.ConcurrentHashMap;\r
10 \r
11 import javax.annotation.Resource;\r
12 import javax.jws.WebService;\r
13 import javax.servlet.http.HttpServletRequest;\r
14 import javax.xml.ws.WebServiceContext;\r
15 import javax.xml.ws.handler.MessageContext;\r
16 \r
17 import org.apache.log4j.Logger;\r
18 \r
19 import compbio.data.msa.JABAService;\r
20 import compbio.ws.client.Services;\r
21 import compbio.ws.client.WSTester;\r
22 \r
23 /**\r
24  * JABAWS services registry\r
25  * \r
26  * @author pvtroshin\r
27  * \r
28  */\r
29 @WebService(endpointInterface = "compbio.data.msa.RegistryWS", targetNamespace = "http://msa.data.compbio/01/12/2010/", serviceName = "RegistryWS")\r
30 public class RegistryWS implements compbio.data.msa.RegistryWS, JABAService {\r
31 \r
32         // Ask for resource injection\r
33         @Resource\r
34         WebServiceContext wsContext;\r
35 \r
36         private static Logger log = Logger.getLogger(RegistryWS.class);\r
37 \r
38         private final static Map<Services, Date> operating = new ConcurrentHashMap<Services, Date>();\r
39 \r
40         @Override\r
41         public Set<Services> getSupportedServices() {\r
42                 init();\r
43                 return operating.keySet();\r
44         }\r
45 \r
46         private void init() {\r
47                 // This should not be run concurrently\r
48                 if (operating.isEmpty()) {\r
49                         synchronized (operating) {\r
50                                 if (operating.isEmpty()) {\r
51                                         testAllServices();\r
52                                 }\r
53                         }\r
54                 }\r
55         }\r
56 \r
57         @Override\r
58         public int getLastTested(Services service) {\r
59                 Date testedOn = getLastTestedOn(service);\r
60                 if (testedOn != null) {\r
61                         return (int) ((System.currentTimeMillis() - testedOn.getTime()) / 1000);\r
62                 }\r
63                 return 0;\r
64         }\r
65 \r
66         /**\r
67          * Can potentially return null if the service has not been tested yet.\r
68          */\r
69         @Override\r
70         public Date getLastTestedOn(Services service) {\r
71                 if (operating.containsKey(service)) {\r
72                         return operating.get(service);\r
73                 }\r
74                 return null;\r
75         }\r
76 \r
77         /**\r
78          * TODO improve reporting. stop testing service on unsupported runtime env\r
79          * exception\r
80          */\r
81         @Override\r
82         public String testAllServices() {\r
83                 Writer testlog = new StringWriter();\r
84                 PrintWriter writer = new PrintWriter(testlog, true);\r
85                 WSTester tester = new WSTester(getServicePath(), writer);\r
86                 // This is done deliberately to prevent malicious user from overloading\r
87                 // the server\r
88                 synchronized (operating) {\r
89                         for (Services service : Services.values()) {\r
90                                 if (tester.checkService(service)) {\r
91                                         operating.put(service, new Date());\r
92                                 }\r
93                         }\r
94                 }\r
95                 writer.close();\r
96                 return testlog.toString();\r
97         }\r
98 \r
99         private String getServicePath() {\r
100                 assert wsContext != null : "WS context injection failed!";\r
101                 MessageContext msContext = wsContext.getMessageContext();\r
102                 HttpServletRequest request = (HttpServletRequest) msContext\r
103                                 .get(MessageContext.SERVLET_REQUEST);\r
104 \r
105                 StringBuffer server = request.getRequestURL();\r
106                 server = server.delete(server.lastIndexOf("/"), server.length());\r
107                 return server.toString();\r
108         }\r
109 \r
110         @Override\r
111         public String testService(Services service) {\r
112                 String server = getServicePath();\r
113                 Writer testlog = new StringWriter();\r
114                 PrintWriter writer = new PrintWriter(testlog, true);\r
115                 WSTester tester = new WSTester(server, writer);\r
116                 try {\r
117                         synchronized (operating) {\r
118                                 boolean succeed = tester.checkService(service);\r
119                                 if (succeed) {\r
120                                         operating.put(service, new Date());\r
121                                 }\r
122                         }\r
123                 } finally {\r
124                         writer.close();\r
125                 }\r
126                 return testlog.toString();\r
127         }\r
128 \r
129         @Override\r
130         public boolean isOperating(Services service) {\r
131                 init();\r
132                 return operating.containsKey(service);\r
133         }\r
134 \r
135 }\r