View Javadoc

1   /*$Id: InstallationSelfCheck.java,v 1.7 2006/08/21 15:39:30 clq2 Exp $
2    * Created on 28-Nov-2003
3    *
4    * Copyright (C) AstroGrid. All rights reserved.
5    *
6    * This software is published under the terms of the AstroGrid
7    * Software License version 1.2, a copy of which has been included
8    * with this distribution in the LICENSE.txt file.
9    *
10   **/
11  package org.astrogrid.dataservice.service;
12  
13  
14  import java.io.ByteArrayInputStream;
15  import java.io.IOException;
16  import java.io.InputStream;
17  import java.io.StringWriter;
18  import java.lang.reflect.Constructor;
19  import java.security.Principal;
20  import javax.xml.parsers.ParserConfigurationException;
21  import junit.framework.TestCase;
22  import org.astrogrid.cfg.ConfigFactory;
23  import org.astrogrid.cfg.PropertyNotFoundException;
24  import org.astrogrid.dataservice.api.nvocone.NvoConeSearcher;
25  import org.astrogrid.dataservice.metadata.VoDescriptionServer;
26  import org.astrogrid.dataservice.queriers.QuerierPlugin;
27  import org.astrogrid.dataservice.queriers.QuerierPluginFactory;
28  import org.astrogrid.io.account.LoginAccount;
29  import org.astrogrid.query.Query;
30  import org.astrogrid.query.QueryException;
31  import org.astrogrid.query.SimpleQueryMaker;
32  import org.astrogrid.query.returns.ReturnTable;
33  import org.astrogrid.slinger.targets.NullTarget;
34  import org.astrogrid.slinger.targets.TargetIdentifier;
35  import org.astrogrid.slinger.targets.WriterTarget;
36  import org.astrogrid.xml.DomHelper;
37  import org.xml.sax.SAXException;
38  
39  // For validation
40  import org.w3c.dom.Document;
41  import org.astrogrid.test.AstrogridAssert;
42  import org.astrogrid.contracts.SchemaMap;
43  
44   // Just used in testCone debugging
45  import java.io.InputStreamReader;
46  import org.astrogrid.io.Piper;
47  /*
48  */
49  
50  
51  /*** Unit test for checking an installation - checks location of config files, etc.
52   * <p>
53   * not intended for use during development - hence the different naming convention.
54   * @author Noel Winstanley nw@jb.man.ac.uk 28-Nov-2003
55   *
56   * (MCH Dec ratpak - removed 'fails' so that original exceptions propogate nicely
57   * to nice web self-test page)
58   */
59  public class InstallationSelfCheck extends InstallationPropertiesCheck {
60     
61     private Principal testPrincipal = new LoginAccount("SelfTest", "localhost");
62     
63     /*** Checks we can create the various interfaces */
64     /*
65      *  Not supporting either of these interfaces now
66     public void testInstantiateServer() throws IOException {
67        new AxisDataService_v06();
68        new SkyNodeService();
69     }
70     */
71     
72     /*** Checks the characteristics of the plugin */
73     public void testPluginDefinition() throws Exception {
74        String pluginClass = ConfigFactory.getCommonConfig().getString(QuerierPluginFactory.QUERIER_PLUGIN_KEY);
75        assertNotNull(QuerierPluginFactory.QUERIER_PLUGIN_KEY + " is not defined",pluginClass);
76        // try to load plugin class.
77        Class plugin = null;
78  //      try {
79        plugin = Class.forName(pluginClass);
80        assertNotNull(QuerierPluginFactory.QUERIER_PLUGIN_KEY + " could not be found",plugin);
81        // check its type
82        assertTrue(QuerierPluginFactory.QUERIER_PLUGIN_KEY + " does not extend QuerierPlugin",QuerierPlugin.class.isAssignableFrom(plugin));
83        // we expect a contructor as follows
84        Constructor constr = plugin.getConstructor(new Class[]{  });
85        assertNotNull("Plugin class must provide constructor(String,Query)",constr);
86     }
87  
88     /***
89      * Creates a test query from properties, defaulting to cone(30,-80,0.1)
90      */
91     public Query makeTestQuery(TargetIdentifier target, String format) throws QueryException, ParserConfigurationException, IOException, SAXException {
92       /*
93        * REMOVED BY KEA, WE DON'T PROVIDE SQL TRANSLATION ANYMORE
94        String sql = ConfigFactory.getCommonConfig().getString("datacenter.testquery.sql", null);
95        if (sql != null) {
96           return SqlParser.makeQuery(sql, target, format);
97        }
98        */
99        //no sql given, make a cone searcher
100       //String ra = ConfigFactory.getCommonConfig().getString("datacenter.testquery.ra","30");
101       //String dec = ConfigFactory.getCommonConfig().getString("datacenter.testquery.dec","-80");
102       //String radius = ConfigFactory.getCommonConfig().getString("datacenter.testquery.radius","0.1");
103       //return SimpleQueryMaker.makeConeQuery(Double.parseDouble(ra),Double.parseDouble(dec),Double.parseDouble(radius), target, format);
104       //return new Query(Double.parseDouble(ra), Double.parseDouble(dec), Double.parseDouble(radius), new ReturnTable(target, format));
105       
106       // Make a standard test query, that's what it's for.
107       return SimpleQueryMaker.makeTestQuery(new ReturnTable(target, format));
108    }
109 
110    /*** Checks the querier/plugin operates - runs a test query that will exercise it
111     * direct to the data server - so
112     * this will also test the connection to the backend database, but not any of the
113     * public interfaces */
114    public void testQueryDirect() throws Throwable {
115       
116       StringWriter sw = new StringWriter(); //although we throw away the results
117       DataServer server = new DataServer();
118       server.askQuery(testPrincipal,makeTestQuery(new WriterTarget(sw), ReturnTable.VOTABLE), this);
119 
120       // Check that the VOTable response is schema-valid XML 
121       // NB: This doesn't actually test that the returned VOTable 
122       // contains real data rather than e.g. an error message
123       // or no data
124       Document doc = DomHelper.newDocument(sw.toString());
125       String rootElement = doc.getDocumentElement().getLocalName();
126       if(rootElement == null) {
127          rootElement = doc.getDocumentElement().getNodeName();
128       }
129       AstrogridAssert.assertSchemaValid(doc,rootElement,SchemaMap.ALL);
130    }
131 
132 
133    /*** Checks that we can a cone search, which only really applies to 
134     * sky services... 
135     *
136     * Also performs a rudimentary check to see if the search failed
137     * (any error message is returned in the stream - so a non-null stream
138     * *doesn't* mean a successful search necessarily).
139     */
140    public void testCone() throws Throwable {
141       
142       String endpoint;
143       String querierPlugin = ConfigFactory.getCommonConfig().getString(
144           "datacenter.querier.plugin","");
145       String coneEnabled = ConfigFactory.getCommonConfig().getString(
146           "datacenter.implements.conesearch","");
147       if (querierPlugin.equals(
148             "org.astrogrid.tableserver.test.SampleStarsPlugin")) {
149          // Doesn't run conesearch if using samplestars plugin;
150          // this is so that self-tests pass "out of the box" 
151          // without the user having to set the 'datacenter.url'
152          // property (this is reassuring).
153          //
154          // (NB: Tried to get the actual url stem of the installed webapp
155          // into this test, rather than use the datacenter.url property;
156          // However, the JUnitEE test infrastructure that runs the tests
157          // in this class swallows the HttpServletRequest which we might 
158          // have used to extract the installation URL.   After much pain 
159          // with reflection, classloaders and other java jewels, have 
160          // simply disabled this test in the default samplestars config.
161          // Bah.
162          return;
163       }
164       else if (coneEnabled.equals("false") || coneEnabled.equals("FALSE")) {
165         // Don't run conesearch test if conesearch switched off in config
166          return;
167       }
168       else {
169          // Otherwise, use context configured in properties file.
170          // this test is called as a servlet, so get url stem from 
171          // servlet context
172          endpoint = ServletHelper.getUrlStem()+"/SubmitCone";
173       }
174       NvoConeSearcher searcher = new NvoConeSearcher(endpoint);
175       
176       InputStream is = searcher.coneSearch(30, -80, 0.1);
177       assertNotNull(is);
178 
179       // Read first 1000 bytes to look for an error message
180       byte[] block = new byte[1000];
181       int ibytes = 0;
182       int imult = 1;
183       int read = is.read(block);
184       String s = new String(block);
185       //System.out.println("String is ");
186       //System.out.println(s);
187       if (s.indexOf("ASTROGRID DSA ERROR") != -1) {
188         // Got an error message in the stream
189         throw new QueryException(s);
190       }
191    }
192 
193    /*** Would check the CEA Interface, but the CEA stuff is very clever and so
194     completely obscure for all practical purposes  *
195    public void testCea() throws IOException {
196       new DatacenterApplication();
197    }
198     */
199 
200    /***
201     * Checks Metadoc file is schema-valid
202     */
203    public void testMetadocValidity() throws IOException, SAXException, ParserConfigurationException {
204       String vodesc = VoDescriptionServer.makeVoDescription();
205       Document doc = DomHelper.newDocument(vodesc);
206       String rootElement = doc.getDocumentElement().getLocalName();
207       if(rootElement == null) {
208          rootElement = doc.getDocumentElement().getNodeName();
209       }
210       AstrogridAssert.assertSchemaValid(doc,rootElement,SchemaMap.ALL);
211    }
212    /***
213     * Checks metadata is OK.
214     * NB This test will not pick up empty metadata 
215     */
216    public void testMetadata() throws IOException, SAXException, ParserConfigurationException {
217       String vodesc = VoDescriptionServer.makeVoDescription();
218       Document doc = DomHelper.newDocument(vodesc);
219       String rootElement = doc.getDocumentElement().getLocalName();
220       if(rootElement == null) {
221          rootElement = doc.getDocumentElement().getNodeName();
222       }
223       AstrogridAssert.assertSchemaValid(doc,rootElement,SchemaMap.ALL);
224    }
225    
226    /*** For running standalone, so it can be used from an IDE for quick tests against services 
227     * @TOFIX Put some kind of runtime test here? */
228    public static void main(String[] args) throws Exception {
229       /*
230       //temporary for testing SSA Image Plugin
231       ConfigFactory.getCommonConfig().setProperty(QuerierPluginFactory.QUERIER_PLUGIN_KEY, SssImagePlugin.class.getName());
232       ServletHelper.setUrlStem("http://localhost.roe.ac.uk:8080/pal-samples");
233       
234       junit.textui.TestRunner.run(InstallationSelfCheck.class);
235       */
236      throw new Exception("Main routine not defined in InstallationSelfCheck");
237    }
238 
239 
240 
241    /* ---------------------------------------------------------------------*/
242    /* LEGACY TESTS BELOW HERE, NO LONGER USED */
243 
244    /*** Checks that we can submit ADQL through the AxisDataService, again an internal check */
245    /*
246     * // No longer supported
247    public void testAxisServiceClassAdql() throws Throwable {
248       
249       AxisDataService_v06 server = new AxisDataService_v06();
250       Query testQuery = makeTestQuery(new NullTarget(), ReturnTable.VOTABLE);
251       //String adql = Adql074Writer.makeAdql(testQuery);
252       String adql = testQuery.getAdqlString();
253       String votable = server.askAdql(DomHelper.newDocument(adql).getDocumentElement(), ReturnTable.VOTABLE);
254       assertNotNull(votable);
255    }
256    */
257 
258    /*** Checks that we can submit a count query with ADQL through the AxisDataService c*/
259    /*
260     * // No longer supported
261    public void testAxisServiceClassCount() throws Throwable {
262       
263       AxisDataService_v06 server = new AxisDataService_v06();
264       Query testQuery = makeTestQuery(new NullTarget(), ReturnTable.VOTABLE);
265       //String adql = Adql074Writer.makeAdql(testQuery);
266       String adql = testQuery.getAdqlString();
267       long count = server.askCount(DomHelper.newDocument(adql).getDocumentElement());
268    }
269    */
270    /*** Checks that we can reach the SOAP service
271    public void testSoapv06() throws Throwable {
272       
273       //this test is called as a servlet, so get url stem from servlet context
274       String endpoint = ServletHelper.getUrlStem()+"/services/AxisDataService05";
275       
276       
277       InputStream is = new URL(endpoint).openStream();
278 
279       assertNotNull(is);
280    }
281    
282    /** Checks that the SkyNode interface works OK using the generated SkyNode
283     * binding *
284    public void testSkyNodeAxisBinding() throws Throwable {
285       
286       //this test is called as a servlet, so get url stem from servlet context
287       String endpoint = ServletHelper.getUrlStem()+"/services/SkyNode074";
288 
289       //make the query - a cone search around the south pole
290       if (ConfigFactory.getCommonConfig().getString(StdSqlWriter.CONE_SEARCH_DEC_COL_KEY, null) == null) {
291          fail("Would test using a search on DEC, but "+StdSqlWriter.CONE_SEARCH_DEC_COL_KEY+" and/or "+StdSqlWriter.CONE_SEARCH_TABLE_KEY+" is not set");
292       }
293       SelectType adql = new SelectType();
294       //select
295       adql.setSelectionList(new SelectionListType());
296       adql.getSelectionList().setItem(new SelectionItemType[] { new AllSelectionItemType() });
297       
298       //from
299       FromType from = new FromType();
300       TableType fromTable = new TableType();
301       fromTable.setName(ConfigFactory.getCommonConfig().getString(StdSqlWriter.CONE_SEARCH_TABLE_KEY));
302       fromTable.setAlias(ConfigFactory.getCommonConfig().getString(StdSqlWriter.CONE_SEARCH_TABLE_KEY));
303       from.setTable(new FromTableType[] { fromTable});
304       adql.setFrom(from);
305       
306          
307       adql.setWhere(new WhereType());
308       ComparisonPredType comp = new ComparisonPredType();
309       comp.setArg(new ScalarExpressionType[2]);
310       adql.getWhere().setCondition(comp);
311       ColumnReferenceType decCol = new ColumnReferenceType();
312       decCol.setName(ConfigFactory.getCommonConfig().getString(StdSqlWriter.CONE_SEARCH_DEC_COL_KEY));
313       decCol.setTable(ConfigFactory.getCommonConfig().getString(StdSqlWriter.CONE_SEARCH_TABLE_KEY));
314       comp.setArg(0, decCol);
315       AtomType decValue = new AtomType();
316       decValue.setLiteral(new RealType());
317       ((RealType) decValue.getLiteral()).setValue(-89.5);
318       comp.setArg(1, decValue);
319       comp.setComparison(ComparisonType.fromValue("<"));
320       
321       //construct SOAP client
322       SkyNodeSoap skyNodeClient = new SkyNodeLocator().getSkyNodeSoap(new URL(endpoint));
323 
324       //make call
325       VOData vodata = skyNodeClient.performQuery(adql, "VOTABLE");
326 
327       //check results
328       assertNotNull(vodata);
329    }
330     */
331 }