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;
|
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.