Project

General

Profile

« Previous | Next » 

Revision 8444

Added by Chris Jones over 10 years ago

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

View differences:

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