Revision 8444
Added by Chris Jones almost 11 years ago
src/edu/ucsb/nceas/metacat/dataone/CNodeService.java | ||
---|---|---|
82 | 82 |
|
83 | 83 |
import edu.ucsb.nceas.metacat.EventLog; |
84 | 84 |
import edu.ucsb.nceas.metacat.IdentifierManager; |
85 |
import edu.ucsb.nceas.metacat.McdbDocNotFoundException; |
|
85 | 86 |
import edu.ucsb.nceas.metacat.dataone.hazelcast.HazelcastService; |
86 | 87 |
|
87 | 88 |
/** |
... | ... | |
324 | 325 |
} |
325 | 326 |
|
326 | 327 |
/** |
327 |
* Deletes an object from the Coordinating Node, where the object is a |
|
328 |
* a science metadata object. |
|
328 |
* Deletes an object from the Coordinating Node |
|
329 | 329 |
* |
330 | 330 |
* @param session - the Session object containing the credentials for the Subject |
331 | 331 |
* @param pid - The object identifier to be deleted |
... | ... | |
342 | 342 |
@Override |
343 | 343 |
public Identifier delete(Session session, Identifier pid) |
344 | 344 |
throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented { |
345 |
|
|
346 |
String localId = null; // The corresponding docid for this pid |
|
347 |
Lock lock = null; // The lock to be used for this identifier |
|
345 | 348 |
|
349 |
// check for a valid session |
|
350 |
if (session == null) { |
|
351 |
throw new InvalidToken("4963", "No session has been provided"); |
|
352 |
|
|
353 |
} |
|
354 |
|
|
355 |
// do we have a valid pid? |
|
356 |
if (pid == null || pid.getValue().trim().equals("")) { |
|
357 |
throw new ServiceFailure("4960", "The provided identifier was invalid."); |
|
358 |
|
|
359 |
} |
|
360 |
|
|
346 | 361 |
// check that it is CN/admin |
347 | 362 |
boolean allowed = isAdminAuthorized(session); |
348 | 363 |
|
349 | 364 |
// additional check if it is the authoritative node if it is not the admin |
350 | 365 |
if(!allowed) { |
351 | 366 |
allowed = isAuthoritativeMNodeAdmin(session, pid); |
367 |
|
|
352 | 368 |
} |
353 | 369 |
|
354 | 370 |
if (!allowed) { |
355 |
String msg = "The subject is not allowed to call delete() on a Coordinating Node."; |
|
371 |
String msg = "The subject " + session.getSubject().getValue() + |
|
372 |
" is not allowed to call delete() on a Coordinating Node."; |
|
356 | 373 |
logMetacat.info(msg); |
357 |
throw new NotAuthorized("1320", msg); |
|
374 |
throw new NotAuthorized("4960", msg); |
|
375 |
|
|
358 | 376 |
} |
359 | 377 |
|
360 |
// defer to superclass implementation |
|
361 |
Identifier retId = super.delete(session, pid); |
|
378 |
// Don't defer to superclass implementation without a locally registered identifier |
|
379 |
|
|
380 |
// Check for the existing identifier |
|
381 |
try { |
|
382 |
localId = IdentifierManager.getInstance().getLocalId(pid.getValue()); |
|
383 |
super.delete(session, pid); |
|
384 |
|
|
385 |
} catch (McdbDocNotFoundException e) { |
|
386 |
// This object is not registered in the identifier table. Assume it is of formatType DATA, |
|
387 |
// and set the archive flag. (i.e. the *object* doesn't exist on the CN) |
|
388 |
|
|
389 |
try { |
|
390 |
lock = HazelcastService.getInstance().getLock(pid.getValue()); |
|
391 |
lock.lock(); |
|
392 |
logMetacat.debug("Locked identifier " + pid.getValue()); |
|
393 |
|
|
394 |
SystemMetadata sysMeta = HazelcastService.getInstance().getSystemMetadataMap().get(pid); |
|
395 |
if ( sysMeta != null ) { |
|
396 |
sysMeta.setArchived(true); |
|
397 |
sysMeta.setDateSysMetadataModified(Calendar.getInstance().getTime()); |
|
398 |
HazelcastService.getInstance().getSystemMetadataMap().put(pid, sysMeta); |
|
399 |
|
|
400 |
} else { |
|
401 |
throw new ServiceFailure("4962", "Couldn't delete the object " + pid.getValue() + |
|
402 |
". Couldn't obtain the system metadata record."); |
|
403 |
|
|
404 |
} |
|
405 |
|
|
406 |
} catch (RuntimeException re) { |
|
407 |
throw new ServiceFailure("4962", "Couldn't delete " + pid.getValue() + |
|
408 |
". The error message was: " + re.getMessage()); |
|
409 |
|
|
410 |
} finally { |
|
411 |
lock.unlock(); |
|
412 |
logMetacat.debug("Unlocked identifier " + pid.getValue()); |
|
413 |
|
|
414 |
} |
|
415 |
|
|
416 |
// Log the delete |
|
417 |
EventLog.getInstance().log(request.getRemoteAddr(), |
|
418 |
request.getHeader("User-Agent"), session.getSubject().getValue(), |
|
419 |
pid.getValue(), Event.DELETE.xmlValue()); |
|
420 |
|
|
421 |
} |
|
422 |
|
|
362 | 423 |
|
363 | 424 |
// notify the replicas |
364 | 425 |
SystemMetadata systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid); |
... | ... | |
375 | 436 |
} |
376 | 437 |
} |
377 | 438 |
|
378 |
return retId;
|
|
439 |
return pid;
|
|
379 | 440 |
|
380 | 441 |
} |
381 | 442 |
|
382 | 443 |
/** |
383 |
* Deletes an object from the Coordinating Node, where the object is a |
|
384 |
* a science metadata object. |
|
444 |
* Archives an object from the Coordinating Node |
|
385 | 445 |
* |
386 | 446 |
* @param session - the Session object containing the credentials for the Subject |
387 | 447 |
* @param pid - The object identifier to be deleted |
... | ... | |
399 | 459 |
public Identifier archive(Session session, Identifier pid) |
400 | 460 |
throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented { |
401 | 461 |
|
462 |
String localId = null; // The corresponding docid for this pid |
|
463 |
Lock lock = null; // The lock to be used for this identifier |
|
464 |
|
|
465 |
// check for a valid session |
|
466 |
if (session == null) { |
|
467 |
throw new InvalidToken("4973", "No session has been provided"); |
|
468 |
|
|
469 |
} |
|
470 |
|
|
471 |
// do we have a valid pid? |
|
472 |
if (pid == null || pid.getValue().trim().equals("")) { |
|
473 |
throw new ServiceFailure("4972", "The provided identifier was invalid."); |
|
474 |
|
|
475 |
} |
|
476 |
|
|
402 | 477 |
// check that it is CN/admin |
403 | 478 |
boolean allowed = isAdminAuthorized(session); |
404 | 479 |
|
... | ... | |
408 | 483 |
} |
409 | 484 |
|
410 | 485 |
if (!allowed) { |
411 |
String msg = "The subject is not allowed to call archive() on a Coordinating Node."; |
|
486 |
String msg = "The subject " + session.getSubject().getValue() + |
|
487 |
" is not allowed to call archive() on a Coordinating Node."; |
|
412 | 488 |
logMetacat.info(msg); |
413 |
throw new NotAuthorized("1320", msg);
|
|
489 |
throw new NotAuthorized("4970", msg);
|
|
414 | 490 |
} |
415 | 491 |
|
416 |
// defer to superclass implementation |
|
417 |
Identifier retId = super.archive(session, pid); |
|
492 |
// Check for the existing identifier |
|
493 |
try { |
|
494 |
localId = IdentifierManager.getInstance().getLocalId(pid.getValue()); |
|
495 |
super.archive(session, pid); |
|
496 |
|
|
497 |
} catch (McdbDocNotFoundException e) { |
|
498 |
// This object is not registered in the identifier table. Assume it is of formatType DATA, |
|
499 |
// and set the archive flag. (i.e. the *object* doesn't exist on the CN) |
|
500 |
|
|
501 |
try { |
|
502 |
lock = HazelcastService.getInstance().getLock(pid.getValue()); |
|
503 |
lock.lock(); |
|
504 |
logMetacat.debug("Locked identifier " + pid.getValue()); |
|
505 |
|
|
506 |
SystemMetadata sysMeta = HazelcastService.getInstance().getSystemMetadataMap().get(pid); |
|
507 |
if ( sysMeta != null ) { |
|
508 |
sysMeta.setArchived(true); |
|
509 |
sysMeta.setDateSysMetadataModified(Calendar.getInstance().getTime()); |
|
510 |
HazelcastService.getInstance().getSystemMetadataMap().put(pid, sysMeta); |
|
511 |
|
|
512 |
} else { |
|
513 |
throw new ServiceFailure("4972", "Couldn't archive the object " + pid.getValue() + |
|
514 |
". Couldn't obtain the system metadata record."); |
|
515 |
|
|
516 |
} |
|
517 |
|
|
518 |
} catch (RuntimeException re) { |
|
519 |
throw new ServiceFailure("4972", "Couldn't archive " + pid.getValue() + |
|
520 |
". The error message was: " + re.getMessage()); |
|
521 |
|
|
522 |
} finally { |
|
523 |
lock.unlock(); |
|
524 |
logMetacat.debug("Unlocked identifier " + pid.getValue()); |
|
525 |
|
|
526 |
} |
|
527 |
|
|
528 |
// Log the archive |
|
529 |
EventLog.getInstance().log(request.getRemoteAddr(), |
|
530 |
request.getHeader("User-Agent"), session.getSubject().getValue(), |
|
531 |
pid.getValue(), Event.DELETE.xmlValue()); |
|
532 |
|
|
533 |
} |
|
418 | 534 |
|
419 | 535 |
// notify the replicas |
420 | 536 |
SystemMetadata systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid); |
... | ... | |
432 | 548 |
} |
433 | 549 |
} |
434 | 550 |
|
435 |
return retId;
|
|
551 |
return pid;
|
|
436 | 552 |
|
437 | 553 |
} |
438 | 554 |
|
Also available in: Unified diff
Update CNodeService.delete() and .archive() to handle situations where the pid is of formatType DATA, and therefore are not registered in the identifier table, and caused NotFound exceptions. For DATA objects, we just update the system metadata now, and for all other objects (METADATA, RESOURCE), we continue to use super.{delete()|archive()}. Also, log the delete/archive into the event log.
https://projects.ecoinformatics.org/ecoinfo/issues/6315
https://redmine.dataone.org/issues/4204