Revision 6226
Added by Chris Jones over 13 years ago
src/edu/ucsb/nceas/metacat/dataone/D1NodeService.java | ||
---|---|---|
23 | 23 |
|
24 | 24 |
package edu.ucsb.nceas.metacat.dataone; |
25 | 25 |
|
26 |
import java.io.File; |
|
27 |
import java.io.FileInputStream; |
|
28 |
import java.io.FileNotFoundException; |
|
29 |
import java.io.FileOutputStream; |
|
30 |
import java.io.IOException; |
|
26 | 31 |
import java.io.InputStream; |
32 |
import java.sql.SQLException; |
|
27 | 33 |
import java.util.ArrayList; |
28 | 34 |
import java.util.Calendar; |
29 | 35 |
import java.util.Date; |
36 |
import java.util.Enumeration; |
|
37 |
import java.util.Hashtable; |
|
30 | 38 |
import java.util.List; |
39 |
import java.util.Timer; |
|
40 |
import java.util.TimerTask; |
|
31 | 41 |
import java.util.Vector; |
32 | 42 |
|
43 |
import javax.servlet.http.HttpServletRequest; |
|
44 |
|
|
33 | 45 |
import org.apache.log4j.Logger; |
34 | 46 |
import org.dataone.service.exceptions.InvalidRequest; |
35 | 47 |
import org.dataone.service.exceptions.InvalidToken; |
... | ... | |
54 | 66 |
import edu.ucsb.nceas.metacat.EventLog; |
55 | 67 |
import edu.ucsb.nceas.metacat.IdentifierManager; |
56 | 68 |
import edu.ucsb.nceas.metacat.McdbDocNotFoundException; |
69 |
import edu.ucsb.nceas.metacat.McdbException; |
|
70 |
import edu.ucsb.nceas.metacat.MetacatHandler; |
|
71 |
import edu.ucsb.nceas.metacat.client.InsufficientKarmaException; |
|
72 |
import edu.ucsb.nceas.metacat.properties.PropertyService; |
|
73 |
import edu.ucsb.nceas.utilities.ParseLSIDException; |
|
74 |
import edu.ucsb.nceas.utilities.PropertyNotFoundException; |
|
57 | 75 |
|
58 | 76 |
public abstract class D1NodeService { |
59 | 77 |
|
60 |
private static Logger logMetacat = Logger.getLogger(D1NodeService.class);
|
|
78 |
private static Logger logMetacat = Logger.getLogger(D1NodeService.class); |
|
61 | 79 |
|
80 |
/* reference to the metacat handler */ |
|
81 |
private MetacatHandler handler; |
|
62 | 82 |
|
83 |
/* parameters set in the incoming request */ |
|
84 |
private Hashtable<String, String[]> params; |
|
85 |
|
|
63 | 86 |
/* Methods common to CNCore and MNCore APIs */ |
64 | 87 |
|
65 | 88 |
/** |
... | ... | |
204 | 227 |
* @param session - the Session object containing the credentials for the Subject |
205 | 228 |
* @param pid - the object identifier for the given object |
206 | 229 |
* |
230 |
* TODO: The D1 Authorization API doesn't provide information on which |
|
231 |
* authentication system the Subject belongs to, and so it's not possible to |
|
232 |
* discern which Person or Group is a valid KNB LDAP DN. Fix this. |
|
233 |
* |
|
207 | 234 |
* @return inputStream - the input stream of the given object |
208 | 235 |
* |
209 | 236 |
* @throws InvalidToken |
... | ... | |
215 | 242 |
public InputStream get(Session session, Identifier pid) |
216 | 243 |
throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, |
217 | 244 |
NotImplemented, InvalidRequest { |
245 |
|
|
246 |
InputStream inputStream = null; // bytes to be returned |
|
247 |
handler = new MetacatHandler(new Timer()); |
|
248 |
boolean allowed = false; |
|
249 |
String localId; // the metacat docid for the pid |
|
250 |
Subject subject = session.getSubject(); // the requesting user |
|
251 |
List<Group> groupList; // the user's groups |
|
252 |
|
|
253 |
// set the public user as a fallback |
|
254 |
if ( subject == null ) { |
|
255 |
subject.setValue("Public"); |
|
256 |
session.setSubject(subject); |
|
257 |
|
|
258 |
} |
|
259 |
|
|
260 |
// convert groups to a string array (for handler) |
|
261 |
groupList = session.getSubjectList().getGroupList(); |
|
262 |
String[] groups = new String[groupList.size()]; |
|
263 |
|
|
264 |
// get the local docid from Metacat |
|
265 |
try { |
|
266 |
localId = IdentifierManager.getInstance().getLocalId(pid.getValue()); |
|
267 |
|
|
268 |
} catch (McdbDocNotFoundException e) { |
|
269 |
throw new NotFound("1020", "The object specified by " + |
|
270 |
pid.getValue() + |
|
271 |
"does not exist at this node."); |
|
272 |
} |
|
273 |
|
|
274 |
// check for authorization |
|
275 |
allowed = isAuthorized(session, pid, Permission.READ); |
|
276 |
|
|
277 |
// if the person is authorized, perform the read |
|
278 |
if ( allowed ) { |
|
279 |
|
|
280 |
for ( int i = 0; i > groupList.size(); i++ ) { |
|
281 |
groups[i] = groupList.get(i).getGroupName(); |
|
282 |
|
|
283 |
} |
|
284 |
|
|
285 |
// get the object bytes |
|
286 |
// TODO: stream to file to stream conversion throughout Metacat needs to |
|
287 |
// be resolved |
|
288 |
File tmpDir; |
|
289 |
try |
|
290 |
{ |
|
291 |
tmpDir = new File(PropertyService.getProperty("application.tempDir")); |
|
292 |
} |
|
293 |
catch(PropertyNotFoundException pnfe) |
|
294 |
{ |
|
295 |
logMetacat.error("D1NodeService.get(): " + |
|
296 |
"application.tmpDir not found. Using /tmp instead."); |
|
297 |
tmpDir = new File("/tmp"); |
|
298 |
} |
|
299 |
|
|
300 |
Date d = new Date(); |
|
301 |
final File outputFile = new File(tmpDir, "metacat.output." + d.getTime()); |
|
302 |
FileOutputStream dataSink; |
|
303 |
try { |
|
304 |
dataSink = new FileOutputStream(outputFile); |
|
305 |
handler.readFromMetacat(localId, null, |
|
306 |
dataSink, localId, "xml", |
|
307 |
subject.getValue(), |
|
308 |
groups, true, params); |
|
218 | 309 |
|
219 |
return null; |
|
310 |
} catch (FileNotFoundException e) { |
|
311 |
throw new ServiceFailure("1020", "The object specified by " + |
|
312 |
pid.getValue() + |
|
313 |
"could not be returned due to a file read error: " + |
|
314 |
e.getMessage()); |
|
315 |
|
|
316 |
} catch (PropertyNotFoundException e) { |
|
317 |
throw new ServiceFailure("1020", "The object specified by " + |
|
318 |
pid.getValue() + |
|
319 |
"could not be returned due to an internal error: " + |
|
320 |
e.getMessage()); |
|
321 |
|
|
322 |
} catch (ClassNotFoundException e) { |
|
323 |
throw new ServiceFailure("1020", "The object specified by " + |
|
324 |
pid.getValue() + |
|
325 |
"could not be returned due to an internal error: " + |
|
326 |
e.getMessage()); |
|
327 |
|
|
328 |
} catch (IOException e) { |
|
329 |
throw new ServiceFailure("1020", "The object specified by " + |
|
330 |
pid.getValue() + |
|
331 |
"could not be returned due to a file read error: " + |
|
332 |
e.getMessage()); |
|
333 |
|
|
334 |
} catch (SQLException e) { |
|
335 |
throw new ServiceFailure("1020", "The object specified by " + |
|
336 |
pid.getValue() + |
|
337 |
"could not be returned due to a database error: " + |
|
338 |
e.getMessage()); |
|
339 |
|
|
340 |
} catch (McdbException e) { |
|
341 |
throw new ServiceFailure("1020", "The object specified by " + |
|
342 |
pid.getValue() + |
|
343 |
"could not be returned due to database error: " + |
|
344 |
e.getMessage()); |
|
345 |
|
|
346 |
} catch (ParseLSIDException e) { |
|
347 |
throw new ServiceFailure("1020", "The object specified by " + |
|
348 |
pid.getValue() + |
|
349 |
"could not be returned due to a parse error: " + |
|
350 |
e.getMessage()); |
|
351 |
|
|
352 |
} catch (InsufficientKarmaException e) { |
|
353 |
// TODO Auto-generated catch block |
|
354 |
e.printStackTrace(); |
|
355 |
} |
|
356 |
|
|
357 |
//set a timer to clean up the temp files |
|
358 |
Timer t = new Timer(); |
|
359 |
TimerTask tt = new TimerTask() { |
|
360 |
@Override |
|
361 |
public void run() |
|
362 |
{ |
|
363 |
outputFile.delete(); |
|
364 |
} |
|
365 |
}; |
|
366 |
t.schedule(tt, 20000); //schedule after 20 secs |
|
367 |
|
|
368 |
try { |
|
369 |
inputStream = new FileInputStream(outputFile); |
|
370 |
} catch (FileNotFoundException e) { |
|
371 |
throw new ServiceFailure("1020", "The object specified by " + |
|
372 |
pid.getValue() + |
|
373 |
"could not be returned due to a file read error: " + |
|
374 |
e.getMessage()); |
|
375 |
|
|
376 |
} |
|
377 |
|
|
378 |
} |
|
379 |
|
|
380 |
// if we fail to set the input stream |
|
381 |
if ( inputStream == null ) { |
|
382 |
throw new NotFound("1020", "The object specified by " + |
|
383 |
pid.getValue() + |
|
384 |
"does not exist at this node."); |
|
385 |
} |
|
386 |
|
|
387 |
return inputStream; |
|
220 | 388 |
} |
221 | 389 |
|
222 | 390 |
/** |
... | ... | |
389 | 557 |
return s; |
390 | 558 |
} |
391 | 559 |
|
560 |
/** |
|
561 |
* set the params for this service from an HttpServletRequest param list |
|
562 |
*/ |
|
563 |
public void setParamsFromRequest(HttpServletRequest request) { |
|
564 |
|
|
565 |
@SuppressWarnings("unchecked") |
|
566 |
Enumeration<String> paramlist = request.getParameterNames(); |
|
567 |
while (paramlist.hasMoreElements()) { |
|
568 |
String name = (String) paramlist.nextElement(); |
|
569 |
String[] value = (String[])request.getParameterValues(name); |
|
570 |
params.put(name, value); |
|
571 |
|
|
572 |
} |
|
573 |
} |
|
574 |
|
|
575 |
|
|
392 | 576 |
} |
Also available in: Unified diff
Implement [MN|CN]Read.get() in D1NodeService. Added setParamsFromRequest() to pass through parameters from the request object. Since the D1 Authorization API doesn't specify which authentication system a subject belongs to, we don't know if the subject listed is a KNB LDAP DN. isAuthorized() may return true for a mapped identity, but we don't know the DN of the KNB identity per se. This needs to be tested.