View Javadoc

1   /*$Id: RegistryToolLocator.java,v 1.11 2004/10/08 20:03:19 pah Exp $
2    * Created on 08-Mar-2004
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.jes.jobscheduler.locator;
12  
13  import org.astrogrid.component.descriptor.ComponentDescriptor;
14  import org.astrogrid.jes.JesException;
15  import org.astrogrid.jes.jobscheduler.Locator;
16  import org.astrogrid.registry.RegistryException;
17  import org.astrogrid.registry.beans.resource.IdentifierType;
18  import org.astrogrid.registry.client.RegistryDelegateFactory;
19  import org.astrogrid.registry.client.query.RegistryService;
20  import org.astrogrid.workflow.beans.v1.Step;
21  import org.astrogrid.workflow.beans.v1.Tool;
22  
23  import org.apache.axis.utils.XMLUtils;
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.exolab.castor.xml.CastorException;
27  import org.exolab.castor.xml.Unmarshaller;
28  import org.w3c.dom.Document;
29  import org.w3c.dom.NodeList;
30  
31  import java.io.StringWriter;
32  import java.net.URL;
33  
34  import junit.framework.Test;
35  
36  /*** Tool locator that resolves tools using the registry.
37   * @author Noel Winstanley nw@jb.man.ac.uk 08-Mar-2004
38   *
39   */
40  public class RegistryToolLocator implements Locator, ComponentDescriptor {
41      private static final Log logger = LogFactory.getLog(RegistryToolLocator.class);
42      /*** interface to configure registry with */
43      public interface RegistryEndpoint {
44          URL getURL();
45      }
46      
47      public RegistryToolLocator(RegistryEndpoint endpoint) {
48          url = endpoint.getURL();
49          delegate = RegistryDelegateFactory.createQuery(url);
50      }
51      
52      protected final URL url;
53      protected final RegistryService delegate;
54  
55      /***
56       * @see org.astrogrid.jes.jobscheduler.Locator#locateTool(org.astrogrid.workflow.beans.v1.Step)
57       */    
58      public String locateTool(Tool tool) throws JesException{
59              String name =tool.getName();
60              if (name == null ) {
61                  throw reportError("Unnamed tool - cannot locate it");
62              }
63              logger.debug("retreiving tool location for " +name);
64              Document toolDocument;
65              try {
66                  toolDocument = delegate.getResourceByIdentifier(name);
67                  if (logger.isDebugEnabled()) {
68                      StringWriter sw = new StringWriter();
69                      XMLUtils.PrettyDocumentToWriter(toolDocument,sw);
70                      logger.debug("ToolDocument\n" + sw.toString());
71                  }
72              }
73              catch (RegistryException e) {
74                  throw reportError("Could not get registry entry for tool " + name,e);
75              }            
76  
77          IdentifierType toolId = null;
78          try {            
79              IdentifierType[] toolIds = getIdentifiers(toolDocument);
80              if (toolIds.length == 0) {
81                  throw reportError("No identifiers in registry entry for tool" + name);
82              }           
83              toolId = toolIds[0];
84          } catch (CastorException e) {
85              throw reportError("Could not parse return document for tool" + name,e);
86          }            
87              logger.debug("found tool: " + toolId.getAuthorityID() + " / " + toolId.getResourceKey());
88               
89              // now query registry for all entries the provide this.
90              String queryString = buildQueryString(toolId);
91              logger.debug("Query to find services supporting this:" + queryString);
92              Document results = null;
93              try {
94                 results = delegate.submitQuery(queryString);
95                 if (logger.isDebugEnabled()) {
96                     StringWriter sw = new StringWriter();
97                     XMLUtils.PrettyDocumentToWriter(results,sw);
98                     logger.debug("Query Results\n" + sw.toString());
99                 }
100             } catch (RegistryException e) {
101                 throw reportError("Failed to query registry for services providing tool " + name,e);
102             }
103             // found identifiers
104             IdentifierType[] serviceIds = null;
105             try {
106                 serviceIds = getIdentifiers(results);
107                 logger.debug("Found " + serviceIds.length + " matching services");
108                 if (serviceIds.length == 0) {
109                     throw reportError("Tool " + name + " has no known service providers");
110                 }
111             } catch (CastorException e) {
112                 throw reportError("Failed to extract identifiers from query document",e);
113             }
114             
115             String endpoint = null;            
116             for (int i = 0; i < serviceIds.length && endpoint == null; i++) {
117                 String serviceName = serviceIds[i].getAuthorityID() + "/" + serviceIds[i].getResourceKey();
118                 try {
119                     endpoint = delegate.getEndPointByIdentifier(serviceName);
120                     logger.debug("Service " + serviceName + " resolved to endpoint " + endpoint);
121                 } catch (RegistryException e) {
122                     logger.warn("Query registry about " + serviceName + " failed",e);
123                 }
124             }
125                        
126             logger.debug("registry resolved to " + endpoint);
127             return endpoint;
128     }
129     
130     
131     private JesException reportError(String s, Exception e) {
132         logger.error(s,e);
133         return new JesException(s,e);
134     }
135     private JesException reportError(String s) {
136         logger.error(s);
137         return new JesException(s);
138     }    
139     
140     /***
141      * @param toolId
142      */
143     
144     private final static String PRE_QUERY= "<query><selectionSequence>" +
145         "<selection item='searchElements' itemOp='EQ' value='vr:Resource'/>" +
146         "<selectionOp op='$and$'/>" +
147         /* don't bother with this for now - not nice to search in xsi:type anyway
148         "<selection item='@*:type' itemOp='EQ' value='CeaServiceType'/>"  +
149         "<selectionOp op='AND'/>" +
150         */
151         "<selection item='cea:ManagedApplications/cea:ApplicationReference/vr:AuthorityID' itemOp='EQ' value='" ;
152     private final static String MID_QUERY = "'/>"  +
153         "<selectionOp op='AND'/>" +
154         "<selection item='cea:ManagedApplications/cea:ApplicationReference/vr:ResourceKey' itemOp='EQ' value='" ;
155     private final static String END_QUERY =  "'/>"  +                                           
156         /* don't think that we need these....
157          "<selectionOp op='OR'/>" +
158          "<selection item='@*:type' itemOp='EQ' value='CeaServiceType'/>"  +
159          */
160         "</selectionSequence></query>";   
161     
162     private String buildQueryString(IdentifierType toolId) {
163         StringBuffer sb = new StringBuffer(PRE_QUERY);
164         sb.append( toolId.getAuthorityID());
165         sb.append(MID_QUERY);
166         sb.append(toolId.getResourceKey());
167         sb.append(END_QUERY);
168         return sb.toString();
169  
170     }
171 
172     /***
173      queries registry to get tool entry, extract details from this.
174      */
175     private IdentifierType[] getIdentifiers(Document doc)throws CastorException  {
176             NodeList nl = doc.getElementsByTagNameNS("*","Identifier");
177             IdentifierType[] results = new IdentifierType[nl.getLength()];
178             for (int i = 0; i < nl.getLength(); i++) {
179                 results[i] = (IdentifierType)Unmarshaller.unmarshal(IdentifierType.class,nl.item(0));
180             }
181             return results;
182     }    
183         
184     /***
185      * @see org.astrogrid.jes.jobscheduler.Locator#getToolInterface(org.astrogrid.workflow.beans.v1.Step)
186      */
187     public String getToolInterface(Step js) throws JesException {
188         logger.error("Deprecated method, not used");
189         return null;
190     }
191     /***
192      * @see org.astrogrid.jes.component.ComponentDescriptor#getName()
193      */
194     public String getName() {
195         return "Registry Tool Locator";
196     }
197     /***
198      * @see org.astrogrid.jes.component.ComponentDescriptor#getDescription()
199      */
200     public String getDescription() {
201         return "Resolve Tool locations using an astrogrid registry" +
202             "\n Currently looking in registry at " + url.toString();
203     }
204     /*** @todo check we can resolve endpoint 
205      * @see org.astrogrid.jes.component.ComponentDescriptor#getInstallationTest()
206      */
207     public Test getInstallationTest() {
208         return null;
209     }
210 }
211 
212 
213 /* 
214 $Log: RegistryToolLocator.java,v $
215 Revision 1.11  2004/10/08 20:03:19  pah
216 optimize the tool query to use namespaces - better performance than using wildcard
217 
218 Revision 1.10  2004/09/16 21:48:28  nw
219 tried to optimize query bulding
220 
221 Revision 1.9  2004/08/25 11:42:12  KevinBenson
222 changed to use prefixes
223 
224 Revision 1.8  2004/08/03 16:31:25  nw
225 simplified interface to dispatcher and locator components.
226 removed redundant implementations.
227 
228 Revision 1.7  2004/07/01 21:15:00  nw
229 added results-listener interface to jes
230 
231 Revision 1.6  2004/04/21 10:05:51  nw
232 implemented correctly - passes integration testing
233 
234 Revision 1.5  2004/04/08 14:43:26  nw
235 added delete and abort job functionality
236 
237 Revision 1.4  2004/03/15 01:30:45  nw
238 factored component descriptor out into separate package
239 
240 Revision 1.3  2004/03/15 00:06:57  nw
241 removed SchedulerNotifier interface - replaced references to it by references to JobScheduler interface - identical
242 
243 Revision 1.2  2004/03/09 14:41:44  nw
244 updated to track changes to registry delegate
245 
246 Revision 1.1  2004/03/08 00:37:07  nw
247 preliminary implementation of registry tool locatr
248  
249 */