View Javadoc

1   /*
2    * $Id: DataServer.java,v 1.3 2005/03/21 18:45:55 mch 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.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        //botch, need a better way of plugging into initialisation stuff
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 //         if ( (query instanceof RawSqlQuery) && !ConfigFactory.getCommonConfig().getBoolean(SQL_PASSTHROUGH_ENABLED)) {
112 //            throw new UnsupportedOperationException("This service does not allow SQL to be directly submitted");
113 //         }
114    
115          querier = Querier.makeQuerier(user, query, source);
116          querierManager.askQuerier(querier);
117       }
118       catch (Throwable th) {
119          //if there's an error, log it, make sure the querier state is correct, and rethrow to
120          //be dealt with correctly up the tree
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) {} ; //ignore
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          //if there's an error, log it, make sure the querier state is correct, and rethrow to
159          //be dealt with correctly up the tree
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) {} ; //ignore
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          //if there's an error, log it, make sure the querier state is correct, and rethrow to
193          //be dealt with correctly up the tree
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) {} ; //ignore
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 //         if ( (querier.getQuery() instanceof RawSqlQuery) && !ConfigFactory.getCommonConfig().getBoolean(SQL_PASSTHROUGH_ENABLED)) {
217 //            throw new UnsupportedOperationException("This service does not allow SQL to be directly submitted");
218 //         }
219    
220          querierManager.submitQuerier(querier);
221          return querier.getId();
222       }
223       catch (Throwable th) {
224          //if there's an error, log it, make sure the querier state is correct, and rethrow to
225          //be dealt with correctly up the tree
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) {} ; //ignore
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 //         throw new DatacenterException("No Query found for ID="+queryId+" on this server");
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