View Javadoc

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