1
2
3
4
5
6
7
8
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
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
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
148
149
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
157
158
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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249