Project

General

Profile

« Previous | Next » 

Revision 9340

Added by Jing Tao about 9 years ago

Add a flag on the systemMetadataChanged method. If it is true, the authoritative member node will only accepts the serial version and replica list; the replica node accepts everything. If it is false, it will accept everything.

View differences:

src/edu/ucsb/nceas/metacat/dataone/MNodeService.java
103 103
import org.dataone.service.types.v1.ObjectList;
104 104
import org.dataone.service.types.v1.Permission;
105 105
import org.dataone.service.types.v1.Ping;
106
import org.dataone.service.types.v1.Replica;
106 107
import org.dataone.service.types.v1.ReplicationStatus;
107 108
import org.dataone.service.types.v1.Schedule;
108 109
import org.dataone.service.types.v1.Service;
......
1345 1346

  
1346 1347
        return inputStream;
1347 1348
    }
1348

  
1349
    
1349 1350
    /**
1350 1351
     * A method to notify the Member Node that the authoritative copy of 
1351 1352
     * system metadata on the Coordinating Nodes has changed.
1352
     * 
1353
     *
1353 1354
     * @param session   Session information that contains the identity of the 
1354 1355
     *                  calling user as retrieved from the X.509 certificate 
1355 1356
     *                  which must be traceable to the CILogon service.
......
1365 1366
        long serialVersion, Date dateSysMetaLastModified) 
1366 1367
        throws NotImplemented, ServiceFailure, NotAuthorized, InvalidRequest,
1367 1368
        InvalidToken {
1369
        boolean needCheckAuthoriativeNode = true; 
1370
        return systemMetadataChanged(needCheckAuthoriativeNode, session, pid,serialVersion, dateSysMetaLastModified);
1371
    }
1372

  
1373
    /**
1374
     * A method to notify the Member Node that the authoritative copy of 
1375
     * system metadata on the Coordinating Nodes has changed.
1376
     * @param needCheckAuthoriativeNode  this is for the dataone version 2. In the
1377
     * version 2, there are two scenarios:
1378
     * 1. If the node is the authoritative node, it only accepts serial version and replica list.
1379
     * 2. If the node is a replica, it accepts everything.
1380
     * For the v1, api, the parameter should be false. 
1381
     * @param session   Session information that contains the identity of the 
1382
     *                  calling user as retrieved from the X.509 certificate 
1383
     *                  which must be traceable to the CILogon service.
1384
     * @param serialVersion   The serialVersion of the system metadata
1385
     * @param dateSysMetaLastModified  The time stamp for when the system metadata was changed
1386
     * @throws NotImplemented
1387
     * @throws ServiceFailure
1388
     * @throws NotAuthorized
1389
     * @throws InvalidRequest
1390
     * @throws InvalidToken
1391
     */
1392
    public boolean systemMetadataChanged(boolean needCheckAuthoriativeNode, Session session, Identifier pid,
1393
        long serialVersion, Date dateSysMetaLastModified) 
1394
        throws NotImplemented, ServiceFailure, NotAuthorized, InvalidRequest,
1395
        InvalidToken {
1368 1396
        
1369 1397
        // cannot be called by public
1370 1398
        if (session == null) {
......
1407 1435
            throw new NotAuthorized("1331", msg);
1408 1436
            
1409 1437
        }
1410
        
1411
        // compare what we have locally to what is sent in the change notification
1412 1438
        try {
1413
            currentLocalSysMeta = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
1414
             
1415
        } catch (RuntimeException e) {
1416
            String msg = "SystemMetadata for pid " + pid.getValue() +
1417
              " couldn't be updated because it couldn't be found locally: " +
1418
              e.getMessage();
1419
            logMetacat.error(msg);
1420
            ServiceFailure sf = new ServiceFailure("1333", msg);
1421
            sf.initCause(e);
1422
            throw sf; 
1423
        }
1439
            HazelcastService.getInstance().getSystemMetadataMap().lock(pid);
1424 1440
        
1425
        if(currentLocalSysMeta == null) {
1426
            throw new InvalidRequest("1334", "We can't find the system metadata in the node for the id "+pid.getValue());
1427
        }
1428
        if (currentLocalSysMeta.getSerialVersion().longValue() < serialVersion ) {
1441
            // compare what we have locally to what is sent in the change notification
1429 1442
            try {
1430
                newSysMeta = cn.getSystemMetadata(null, pid);
1431
            } catch (NotFound e) {
1432
                // huh? you just said you had it
1433
            	String msg = "On updating the local copy of system metadata " + 
1434
                "for pid " + pid.getValue() +", the CN reports it is not found." +
1435
                " The error message was: " + e.getMessage();
1443
                currentLocalSysMeta = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
1444
                 
1445
            } catch (RuntimeException e) {
1446
                String msg = "SystemMetadata for pid " + pid.getValue() +
1447
                  " couldn't be updated because it couldn't be found locally: " +
1448
                  e.getMessage();
1436 1449
                logMetacat.error(msg);
1437
                //ServiceFailure sf = new ServiceFailure("1333", msg);
1438
                InvalidRequest sf = new InvalidRequest("1334", msg);
1450
                ServiceFailure sf = new ServiceFailure("1333", msg);
1439 1451
                sf.initCause(e);
1440
                throw sf;
1452
                throw sf; 
1441 1453
            }
1442 1454
            
1443
            //check about the sid in the system metadata
1444
            Identifier newSID = newSysMeta.getSeriesId();
1445
            if(newSID != null) {
1446
                if (!isValidIdentifier(newSID)) {
1447
                    throw new InvalidRequest("1334", "The series identifier in the new system metadata is invalid.");
1455
            if(currentLocalSysMeta == null) {
1456
                throw new InvalidRequest("1334", "We can't find the system metadata in the node for the id "+pid.getValue());
1457
            }
1458
            if (currentLocalSysMeta.getSerialVersion().longValue() < serialVersion ) {
1459
                try {
1460
                    newSysMeta = cn.getSystemMetadata(null, pid);
1461
                } catch (NotFound e) {
1462
                    // huh? you just said you had it
1463
                	String msg = "On updating the local copy of system metadata " + 
1464
                    "for pid " + pid.getValue() +", the CN reports it is not found." +
1465
                    " The error message was: " + e.getMessage();
1466
                    logMetacat.error(msg);
1467
                    //ServiceFailure sf = new ServiceFailure("1333", msg);
1468
                    InvalidRequest sf = new InvalidRequest("1334", msg);
1469
                    sf.initCause(e);
1470
                    throw sf;
1448 1471
                }
1449
                Identifier currentSID = currentLocalSysMeta.getSeriesId();
1450
                if( currentSID != null && currentSID.getValue() != null) {
1451
                    if(!newSID.getValue().equals(currentSID.getValue())) {
1452
                        //newSID doesn't match the currentSID. The newSID shouldn't be used.
1472
                
1473
                //check about the sid in the system metadata
1474
                Identifier newSID = newSysMeta.getSeriesId();
1475
                if(newSID != null) {
1476
                    if (!isValidIdentifier(newSID)) {
1477
                        throw new InvalidRequest("1334", "The series identifier in the new system metadata is invalid.");
1478
                    }
1479
                    Identifier currentSID = currentLocalSysMeta.getSeriesId();
1480
                    if( currentSID != null && currentSID.getValue() != null) {
1481
                        if(!newSID.getValue().equals(currentSID.getValue())) {
1482
                            //newSID doesn't match the currentSID. The newSID shouldn't be used.
1483
                            try {
1484
                                if(IdentifierManager.getInstance().identifierExists(newSID.getValue())) {
1485
                                    throw new InvalidRequest("1334", "The series identifier "+newSID.getValue()+" in the new system metadata has been used by another object.");
1486
                                }
1487
                            } catch (SQLException sql) {
1488
                                throw new ServiceFailure("1333", "Couldn't determine if the SID "+newSID.getValue()+" in the system metadata exists in the node since "+sql.getMessage());
1489
                            }
1490
                            
1491
                        }
1492
                    } else {
1493
                        //newSID shouldn't be used
1453 1494
                        try {
1454 1495
                            if(IdentifierManager.getInstance().identifierExists(newSID.getValue())) {
1455 1496
                                throw new InvalidRequest("1334", "The series identifier "+newSID.getValue()+" in the new system metadata has been used by another object.");
......
1457 1498
                        } catch (SQLException sql) {
1458 1499
                            throw new ServiceFailure("1333", "Couldn't determine if the SID "+newSID.getValue()+" in the system metadata exists in the node since "+sql.getMessage());
1459 1500
                        }
1460
                        
1461 1501
                    }
1462
                } else {
1463
                    //newSID shouldn't be used
1464
                    try {
1465
                        if(IdentifierManager.getInstance().identifierExists(newSID.getValue())) {
1466
                            throw new InvalidRequest("1334", "The series identifier "+newSID.getValue()+" in the new system metadata has been used by another object.");
1502
                }
1503
                // update the local copy of system metadata for the pid
1504
                try {
1505
                    if(needCheckAuthoriativeNode) {
1506
                        //this is for the v2 api.
1507
                        if(isAuthoritativeNode(pid)) {
1508
                            //this is the authoritative node, so we only accept replica and serial version
1509
                            List<Replica> replicas = newSysMeta.getReplicaList();
1510
                            newSysMeta = currentLocalSysMeta;
1511
                            newSysMeta.setSerialVersion(new BigInteger((new Long(serialVersion)).toString()));
1512
                            newSysMeta.setReplicaList(replicas);
1467 1513
                        }
1468
                    } catch (SQLException sql) {
1469
                        throw new ServiceFailure("1333", "Couldn't determine if the SID "+newSID.getValue()+" in the system metadata exists in the node since "+sql.getMessage());
1470 1514
                    }
1515
                    HazelcastService.getInstance().getSystemMetadataMap().put(newSysMeta.getIdentifier(), newSysMeta);
1516
                    logMetacat.info("Updated local copy of system metadata for pid " +
1517
                        pid.getValue() + " after change notification from the CN.");
1518
                    
1519
                    // TODO: consider inspecting the change for archive
1520
                    // see: https://projects.ecoinformatics.org/ecoinfo/issues/6417
1521
    //                if (newSysMeta.getArchived() != null && newSysMeta.getArchived().booleanValue()) {
1522
    //                	try {
1523
    //						this.archive(session, newSysMeta.getIdentifier());
1524
    //					} catch (NotFound e) {
1525
    //						// do we care? nothing to do about it now
1526
    //						logMetacat.error(e.getMessage(), e);
1527
    //					}
1528
    //                }
1529
                    
1530
                } catch (RuntimeException e) {
1531
                    String msg = "SystemMetadata for pid " + pid.getValue() +
1532
                      " couldn't be updated: " +
1533
                      e.getMessage();
1534
                    logMetacat.error(msg);
1535
                    ServiceFailure sf = new ServiceFailure("1333", msg);
1536
                    sf.initCause(e);
1537
                    throw sf;
1471 1538
                }
1472
            }
1473
            // update the local copy of system metadata for the pid
1474
            try {
1475
                HazelcastService.getInstance().getSystemMetadataMap().put(newSysMeta.getIdentifier(), newSysMeta);
1476
                logMetacat.info("Updated local copy of system metadata for pid " +
1477
                    pid.getValue() + " after change notification from the CN.");
1478 1539
                
1479
                // TODO: consider inspecting the change for archive
1480
                // see: https://projects.ecoinformatics.org/ecoinfo/issues/6417
1481
//                if (newSysMeta.getArchived() != null && newSysMeta.getArchived().booleanValue()) {
1482
//                	try {
1483
//						this.archive(session, newSysMeta.getIdentifier());
1484
//					} catch (NotFound e) {
1485
//						// do we care? nothing to do about it now
1486
//						logMetacat.error(e.getMessage(), e);
1487
//					}
1488
//                }
1489
                
1490
            } catch (RuntimeException e) {
1491
                String msg = "SystemMetadata for pid " + pid.getValue() +
1492
                  " couldn't be updated: " +
1493
                  e.getMessage();
1494
                logMetacat.error(msg);
1495
                ServiceFailure sf = new ServiceFailure("1333", msg);
1496
                sf.initCause(e);
1497
                throw sf;
1540
               
1498 1541
            }
1499
            
1542
        } finally {
1543
            HazelcastService.getInstance().getSystemMetadataMap().unlock(pid);
1544
        }
1545
        
1546
        if (currentLocalSysMeta.getSerialVersion().longValue() < serialVersion ) {
1500 1547
            // attempt to re-register the identifier (it checks if it is a doi)
1501 1548
            try {
1502
    			DOIService.getInstance().registerDOI(newSysMeta);
1503
    		} catch (Exception e) {
1504
    			logMetacat.warn("Could not [re]register DOI: " + e.getMessage(), e);
1505
    		}
1549
                DOIService.getInstance().registerDOI(newSysMeta);
1550
            } catch (Exception e) {
1551
                logMetacat.warn("Could not [re]register DOI: " + e.getMessage(), e);
1552
            }
1506 1553
            
1507 1554
            // submit for indexing
1508 1555
            try {
1509
				MetacatSolrIndex.getInstance().submit(newSysMeta.getIdentifier(), newSysMeta, null, true);
1510
			} catch (Exception e) {
1556
                MetacatSolrIndex.getInstance().submit(newSysMeta.getIdentifier(), newSysMeta, null, true);
1557
            } catch (Exception e) {
1511 1558
                logMetacat.error("Could not submit changed systemMetadata for indexing, pid: " + newSysMeta.getIdentifier().getValue(), e);
1512
			}
1559
            }
1513 1560
        }
1514 1561
        
1515 1562
        return true;
src/edu/ucsb/nceas/metacat/dataone/v1/MNodeService.java
518 518
        } catch (NotFound e) {
519 519
            throw new ServiceFailure(serviceFailure, e.getMessage());
520 520
        }
521
		return impl.systemMetadataChanged(null, pid, serialVersion, dateSysMetaLastModified);
521
        boolean needCheckAuthoriativeNode = false; 
522
		return impl.systemMetadataChanged(needCheckAuthoriativeNode, null, pid, serialVersion, dateSysMetaLastModified);
522 523

  
523 524
	}
524 525

  
......
535 536
        } catch (NotFound e) {
536 537
            throw new ServiceFailure(serviceFailure, e.getMessage());
537 538
        }
538
		return impl.systemMetadataChanged(session, pid, serialVersion, dateSysMetaLastModified);
539
        boolean needCheckAuthoriativeNode = false; 
540
		return impl.systemMetadataChanged(needCheckAuthoriativeNode,session, pid, serialVersion, dateSysMetaLastModified);
539 541
	}
540 542
    
541 543
	// methods not defined in v1, but implemented in metacat pre-v2 release

Also available in: Unified diff