1
2
3
4
5
6
7 package org.astrogrid.dataservice.service;
8
9 import java.io.IOException;
10 import java.security.Principal;
11 import org.apache.commons.logging.Log;
12 import org.apache.commons.logging.LogFactory;
13 import org.astrogrid.cfg.ConfigFactory;
14 import org.astrogrid.dataservice.metadata.VoDescriptionServer;
15 import org.astrogrid.dataservice.queriers.Querier;
16 import org.astrogrid.dataservice.queriers.QuerierManager;
17 import org.astrogrid.dataservice.queriers.QuerierPluginException;
18 import org.astrogrid.dataservice.queriers.QuerierPluginFactory;
19 import org.astrogrid.dataservice.queriers.status.QuerierError;
20 import org.astrogrid.dataservice.queriers.status.QuerierStatus;
21 import org.astrogrid.tableserver.test.SampleStarsPlugin;
22 import org.astrogrid.dataservice.DatacenterException;
23 import org.astrogrid.query.Query;
24 import org.astrogrid.query.condition.Condition;
25 import org.astrogrid.query.returns.ReturnSpec;
26 import org.astrogrid.xml.DomHelper;
27
28 /***
29 * Framework for managing a datacenter.
30 *
31 * Interface bindings do the necessary conversions on their parameters and then
32 * call the 'standard' methods on this class.
33 * Therefore we can have several interfaces on the one datacenter (for example,
34 * a SkyNode one as well as the usual AstroGrid one, and several versions of
35 * each).
36 * It should however be able to report a status on a querier no matter
37 * which interface was used to create it
38 *
39 * Subclasses from this might implement
40 * an axis/http server, or a socket-server, or a grid/ogsa server, etc.
41 *
42 * Managing the Queriers (each one of which rrepresents one query performed
43 * on the database) is delegated to the QuerierManager
44 * <p>
45 * @todo Not happy with this being a mix of static and instance methods. Probably
46 * need a factory/singleton
47 *
48 * @author M Hill
49 */
50
51 public class DataServer
52 {
53 protected static Log log = LogFactory.getLog(DataServer.class);
54
55 /*** Singleton that manages the queriers for the application. By using a singleton,
56 * we can access the same queriers through different interfaces; eg start a querier
57 * using the AxisDataServer, but then watch its progress using a browser
58 */
59 protected final static QuerierManager querierManager = QuerierManager.getManager("DataServer");
60
61 /*** Start Time for status info */
62 public final static DataServiceStatus status = new DataServiceStatus();
63
64 /*** Configuration setting used to mark whether raw sql is allowed */
65 public final static String SQL_PASSTHROUGH_ENABLED = "datacenter.sql.passthrough.enabled";
66
67 /*** Returns the name of this datacenter if it is configured, and 'AstroGrid
68 * Datacenter Installation' by default.
69 */
70 public static String getDatacenterName() {
71 return ConfigFactory.getCommonConfig().getString("datacenter.name","Unnamed AstroGrid Datacenter");
72 }
73
74
75 /***
76 * Does all the things that need to be done on startup initialisation (as opposed
77 * to one-off in lifetime of data initialisation)
78 */
79 public static void startUp() {
80 log.info("Startup");
81
82
83 if (ConfigFactory.getCommonConfig().getString(QuerierPluginFactory.QUERIER_PLUGIN_KEY).equals("org.astrogrid.datacenter.queriers.test.SampleStarsPlugin")) {
84 SampleStarsPlugin.initConfig();
85 }
86 }
87
88 /***
89 * Expose the log for convenience to JSPs etc */
90 public Log getLog() {
91 return log;
92 }
93
94 /***
95 * Does all the things that need to be done on shutdown
96 */
97 public static void shutDown() {
98 log.info("Shutdown");
99 querierManager.shutDown();
100 }
101
102
103 /***
104 * Runs a (blocking) ADQL/XML/OM query, outputting the results as votable to the stream given
105 * in query.resultsSpec. Source indicates what interface is requesting the query (optional)
106 */
107 public void askQuery(Principal user, Query query, Object source) throws Throwable {
108
109 Querier querier = null;
110 try {
111
112
113
114
115 querier = Querier.makeQuerier(user, query, source);
116 querierManager.askQuerier(querier);
117 }
118 catch (Throwable th) {
119
120
121 if (querier != null) {
122 try {
123 if (!(querier.getStatus() instanceof QuerierError)) {
124 querier.setStatus(new QuerierError(querier.getStatus(), "",th));
125 }
126 } catch (Throwable th2) {} ;
127 }
128 log.error("askQuery("+user+", "+query+")", th);
129 throw th;
130 }
131 }
132
133 /***
134 * @deprecated convenience method
135 */
136 public void askQuery(Principal user, Condition condition, ReturnSpec returns) throws Throwable {
137 askQuery(user, new Query(condition, returns), null);
138 }
139
140 /***
141 * Returns the status object */
142 public static DataServiceStatus getStatus() {
143 return status;
144 }
145
146 /***
147 * Submits a (non-blocking) ADQL/XML/OM query, returning the query's external
148 * reference id. Results will be output to given Agsl. Source indicates
149 * which interface is submitting
150 */
151 public String submitQuery(Principal user, Query query, Object source) throws Throwable {
152
153 Querier querier = null;
154 try {
155 querier = Querier.makeQuerier(user, query, source);
156 }
157 catch (Throwable th) {
158
159
160 if (querier != null) {
161 try {
162 if (!(querier.getStatus() instanceof QuerierError)) {
163 querier.setStatus(new QuerierError(querier.getStatus(), "",th));
164 }
165 } catch (Throwable th2) {} ;
166 }
167 log.error("submitQuery("+user+", "+query+")", th);
168 throw th;
169 }
170
171 return submitQuerier(querier);
172 }
173
174 /***
175 * @deprecated convenience method
176 */
177 public String submitQuery(Principal user, Condition condition, ReturnSpec returns) throws Throwable {
178 return submitQuery(user, new Query(condition, returns), null);
179 }
180
181 /***
182 * Returns the number of matches of the given query condition. Source indicates which
183 * interface is requesting the count
184 */
185 public long askCount(Principal user, Query query, Object source) throws Throwable {
186 Querier querier = null;
187 try {
188 querier = Querier.makeQuerier(user, query, source);
189 return querierManager.askCount(querier);
190 }
191 catch (Throwable th) {
192
193
194 if (querier != null) {
195 try {
196 if (!(querier.getStatus() instanceof QuerierError)) {
197 querier.setStatus(new QuerierError(querier.getStatus(), "",th));
198 }
199 } catch (Throwable th2) {} ;
200 }
201 log.error("submitQuerier("+querier+")", th);
202 throw th;
203 }
204 }
205
206
207 /***
208 * Submits a (non-blocking) ADQL/XML/OM query, returning the query's external
209 * reference id. Results will be output to given Agsl
210 */
211 public String submitQuerier(Querier querier) throws Throwable {
212
213 assert(querier != null);
214
215 try {
216
217
218
219
220 querierManager.submitQuerier(querier);
221 return querier.getId();
222 }
223 catch (Throwable th) {
224
225
226 if (querier != null) {
227 try {
228 if (!(querier.getStatus() instanceof QuerierError)) {
229 querier.setStatus(new QuerierError(querier.getStatus(), "",th));
230 }
231 } catch (Throwable th2) {} ;
232 }
233 log.error("submitQuerier("+querier+")", th);
234 throw th;
235 }
236 }
237
238 /***
239 * Returns the querier corresponding to the given id
240 */
241 public Querier getQuerier(String queryId) {
242 return querierManager.getQuerier(queryId);
243 }
244
245 /***
246 * Returns status of a query. NB the id given is the *datacenter's* id
247 */
248 public QuerierStatus getQueryStatus(Principal user, String queryId) throws IOException
249 {
250 Querier querier = querierManager.getQuerier(queryId);
251 if (querier == null) {
252
253 return null;
254 }
255
256 return querier.getStatus();
257 }
258
259 /***
260 * Request to stop a query. This might not be successful - depends on the
261 * back end. NB the id given is the *datacenters* id.
262 */
263 public QuerierStatus abortQuery(Principal user, String queryId) throws IOException {
264 Querier querier = querierManager.getQuerier(queryId);
265 if (querier == null) {
266 throw new DatacenterException("No Query found for ID="+queryId+" on this server");
267 }
268
269 log.warn(user+" is aborting query "+queryId);
270 return querier.abort();
271 }
272
273 /***
274 * Returns the metadata file as a string
275 */
276 public String getMetadata() throws IOException {
277 return DomHelper.DocumentToString(VoDescriptionServer.getVoDescription());
278 }
279
280 /*** Returns the valid formats for this service as an array of strings */
281 public static String[] getFormats() throws QuerierPluginException {
282 return QuerierPluginFactory.createPlugin(null).getFormats();
283 }
284
285 }
286
287
288
289
290
291
292