Revision 7849
Added by ben leinfelder over 11 years ago
test/edu/ucsb/nceas/metacat/dataone/RegisterDOITest.java | ||
---|---|---|
93 | 93 |
suite.addTest(new RegisterDOITest("testCreateDOI")); |
94 | 94 |
suite.addTest(new RegisterDOITest("testMintAndCreateDOI")); |
95 | 95 |
suite.addTest(new RegisterDOITest("testMintAndCreateForEML")); |
96 |
|
|
97 |
// publish |
|
98 |
suite.addTest(new RegisterDOITest("testPublishDOI")); |
|
96 | 99 |
|
97 | 100 |
return suite; |
98 | 101 |
|
... | ... | |
232 | 235 |
fail("Unexpected error: " + e.getMessage()); |
233 | 236 |
} |
234 | 237 |
} |
238 |
|
|
239 |
/** |
|
240 |
* Test object publishing |
|
241 |
*/ |
|
242 |
public void testPublishDOI() { |
|
243 |
printTestHeader("testPublishDOI"); |
|
244 |
|
|
245 |
try { |
|
246 |
// get ezid config properties |
|
247 |
String ezidUsername = PropertyService.getProperty("guid.ezid.username"); |
|
248 |
String ezidPassword = PropertyService.getProperty("guid.ezid.password"); |
|
249 |
String ezidServiceBaseUrl = PropertyService.getProperty("guid.ezid.baseurl"); |
|
250 |
|
|
251 |
Session session = getTestSession(); |
|
252 |
Identifier guid = new Identifier(); |
|
253 |
guid.setValue("testPublishDOI." + System.currentTimeMillis()); |
|
254 |
|
|
255 |
// use EML to test |
|
256 |
// TODO: include an ORE to really exercise it |
|
257 |
String emlFile = "test/tao.14563.1.xml"; |
|
258 |
InputStream content = null; |
|
259 |
try { |
|
260 |
content = new FileInputStream(emlFile); |
|
261 |
} catch (FileNotFoundException e) { |
|
262 |
e.printStackTrace(); |
|
263 |
fail(e.getMessage()); |
|
264 |
} |
|
265 |
|
|
266 |
// create the initial version without DOI |
|
267 |
SystemMetadata sysmeta = createSystemMetadata(guid, session.getSubject(), null); |
|
268 |
sysmeta.setFormatId(ObjectFormatCache.getInstance().getFormat("eml://ecoinformatics.org/eml-2.1.0").getFormatId()); |
|
269 |
Identifier pid = MNodeService.getInstance(request).create(session, guid, content, sysmeta); |
|
270 |
assertEquals(guid.getValue(), pid.getValue()); |
|
271 |
|
|
272 |
// now publish it |
|
273 |
Identifier publishedIdentifier = MNodeService.getInstance(request).publish(session, pid); |
|
274 |
|
|
275 |
// check for the metadata explicitly, using ezid service |
|
276 |
EZIDService ezid = new EZIDService(ezidServiceBaseUrl); |
|
277 |
ezid.login(ezidUsername, ezidPassword); |
|
278 |
HashMap<String, String> metadata = ezid.getMetadata(publishedIdentifier.getValue()); |
|
279 |
assertNotNull(metadata); |
|
280 |
assertTrue(metadata.containsKey(DataCiteProfile.TITLE.toString())); |
|
281 |
|
|
282 |
} catch (Exception e) { |
|
283 |
e.printStackTrace(); |
|
284 |
fail("Unexpected error: " + e.getMessage()); |
|
285 |
} |
|
286 |
} |
|
235 | 287 |
} |
src/edu/ucsb/nceas/metacat/dataone/MNodeService.java | ||
---|---|---|
26 | 26 |
import java.io.ByteArrayInputStream; |
27 | 27 |
import java.io.IOException; |
28 | 28 |
import java.io.InputStream; |
29 |
import java.io.UnsupportedEncodingException; |
|
29 | 30 |
import java.math.BigInteger; |
31 |
import java.net.URISyntaxException; |
|
30 | 32 |
import java.security.NoSuchAlgorithmException; |
31 | 33 |
import java.util.ArrayList; |
32 | 34 |
import java.util.Calendar; |
33 | 35 |
import java.util.Date; |
34 | 36 |
import java.util.HashSet; |
35 | 37 |
import java.util.List; |
38 |
import java.util.Map; |
|
36 | 39 |
import java.util.Set; |
37 | 40 |
import java.util.Timer; |
38 | 41 |
import java.util.UUID; |
... | ... | |
42 | 45 |
|
43 | 46 |
import org.apache.commons.io.IOUtils; |
44 | 47 |
import org.apache.log4j.Logger; |
45 |
import org.apache.solr.client.solrj.SolrServerException; |
|
46 | 48 |
import org.dataone.client.CNode; |
47 | 49 |
import org.dataone.client.D1Client; |
48 | 50 |
import org.dataone.client.MNode; |
49 | 51 |
import org.dataone.client.auth.CertificateManager; |
50 | 52 |
import org.dataone.configuration.Settings; |
53 |
import org.dataone.ore.ResourceMapFactory; |
|
51 | 54 |
import org.dataone.service.exceptions.BaseException; |
52 | 55 |
import org.dataone.service.exceptions.IdentifierNotUnique; |
53 | 56 |
import org.dataone.service.exceptions.InsufficientResources; |
... | ... | |
97 | 100 |
import org.dataone.service.types.v1_1.QueryEngineList; |
98 | 101 |
import org.dataone.service.types.v1_1.QueryField; |
99 | 102 |
import org.dataone.service.util.Constants; |
103 |
import org.dspace.foresite.OREException; |
|
104 |
import org.dspace.foresite.OREParserException; |
|
105 |
import org.dspace.foresite.ORESerialiserException; |
|
106 |
import org.dspace.foresite.ResourceMap; |
|
100 | 107 |
|
101 | 108 |
import edu.ucsb.nceas.ezid.EZIDException; |
102 | 109 |
import edu.ucsb.nceas.metacat.DBQuery; |
... | ... | |
148 | 155 |
implements MNAuthorization, MNCore, MNRead, MNReplication, MNStorage, MNQuery { |
149 | 156 |
|
150 | 157 |
//private static final String PATHQUERY = "pathquery"; |
151 |
private static final String UUID_SCHEME = "UUID";
|
|
152 |
private static final String DOI_SCHEME = "DOI";
|
|
158 |
public static final String UUID_SCHEME = "UUID";
|
|
159 |
public static final String DOI_SCHEME = "DOI";
|
|
153 | 160 |
private static final String UUID_PREFIX = "urn:uuid:"; |
154 | 161 |
|
155 | 162 |
/* the logger instance */ |
... | ... | |
1521 | 1528 |
} |
1522 | 1529 |
return null; |
1523 | 1530 |
} |
1531 |
|
|
1532 |
/** |
|
1533 |
* Given an existing Science Metadata PID, this method mints a DOI |
|
1534 |
* and updates the original object "publishing" the update with the DOI. |
|
1535 |
* This includes updating the ORE map that describes the Science Metadata+data. |
|
1536 |
* TODO: ensure all referenced objects allow public read |
|
1537 |
* |
|
1538 |
* @see https://projects.ecoinformatics.org/ecoinfo/issues/6014 |
|
1539 |
* |
|
1540 |
* @param originalIdentifier |
|
1541 |
* @param request |
|
1542 |
* @throws InvalidRequest |
|
1543 |
* @throws EZIDException |
|
1544 |
* @throws InvalidToken |
|
1545 |
* @throws NotAuthorized |
|
1546 |
* @throws NotImplemented |
|
1547 |
* @throws ServiceFailure |
|
1548 |
* @throws NotFound |
|
1549 |
* @throws InsufficientResources |
|
1550 |
* @throws IdentifierNotUnique |
|
1551 |
* @throws InvalidSystemMetadata |
|
1552 |
* @throws UnsupportedType |
|
1553 |
* @throws McdbDocNotFoundException |
|
1554 |
* @throws OREParserException |
|
1555 |
* @throws URISyntaxException |
|
1556 |
* @throws OREException |
|
1557 |
* @throws UnsupportedEncodingException |
|
1558 |
* @throws ORESerialiserException |
|
1559 |
* @throws NoSuchAlgorithmException |
|
1560 |
*/ |
|
1561 |
public Identifier publish(Session session, Identifier originalIdentifier) throws InvalidRequest, EZIDException, InvalidToken, NotAuthorized, NotImplemented, ServiceFailure, NotFound, InsufficientResources, IdentifierNotUnique, InvalidSystemMetadata, UnsupportedType, McdbDocNotFoundException, UnsupportedEncodingException, OREException, URISyntaxException, OREParserException, ORESerialiserException, NoSuchAlgorithmException { |
|
1562 |
|
|
1563 |
// mint a DOI for the new revision |
|
1564 |
Identifier newIdentifier = this.generateIdentifier(session, MNodeService.DOI_SCHEME, null); |
|
1565 |
|
|
1566 |
// get the original SM and update the values |
|
1567 |
SystemMetadata sysmeta = this.getSystemMetadata(session, originalIdentifier); |
|
1568 |
sysmeta.setIdentifier(newIdentifier); |
|
1569 |
sysmeta.setObsoletes(originalIdentifier); |
|
1570 |
sysmeta.setObsoletedBy(null); |
|
1571 |
|
|
1572 |
// get the bytes |
|
1573 |
InputStream inputStream = this.get(session, originalIdentifier); |
|
1574 |
|
|
1575 |
// update the object |
|
1576 |
this.update(session, originalIdentifier, inputStream , newIdentifier, sysmeta); |
|
1577 |
|
|
1578 |
// TODO: update ORE that references the scimeta |
|
1579 |
String localId = IdentifierManager.getInstance().getLocalId(originalIdentifier.getValue()); |
|
1580 |
Identifier potentialOreIdentifier = new Identifier(); |
|
1581 |
potentialOreIdentifier.setValue(SystemMetadataFactory.RESOURCE_MAP_PREFIX + localId); |
|
1582 |
|
|
1583 |
InputStream oreInputStream = null; |
|
1584 |
try { |
|
1585 |
oreInputStream = this.get(session, potentialOreIdentifier); |
|
1586 |
} catch (NotFound nf) { |
|
1587 |
// this is probably okay for many sci meta data docs |
|
1588 |
logMetacat.warn("No potential ORE map found for: " + potentialOreIdentifier.getValue()); |
|
1589 |
} |
|
1590 |
if (oreInputStream != null) { |
|
1591 |
Identifier newOreIdentifier = MNodeService.getInstance(request).generateIdentifier(session, MNodeService.UUID_SCHEME, null); |
|
1592 |
|
|
1593 |
Map<Identifier, Map<Identifier, List<Identifier>>> resourceMapStructure = ResourceMapFactory.getInstance().parseResourceMap(oreInputStream); |
|
1594 |
Map<Identifier, List<Identifier>> sciMetaMap = resourceMapStructure.get(potentialOreIdentifier); |
|
1595 |
List<Identifier> dataIdentifiers = sciMetaMap.get(originalIdentifier); |
|
1596 |
|
|
1597 |
// TODO: ensure all data package objects allow public read |
|
1598 |
|
|
1599 |
// reconstruct the ORE with the new identifiers |
|
1600 |
sciMetaMap.remove(originalIdentifier); |
|
1601 |
sciMetaMap.put(newIdentifier, dataIdentifiers); |
|
1602 |
|
|
1603 |
ResourceMap resourceMap = ResourceMapFactory.getInstance().createResourceMap(newOreIdentifier, sciMetaMap); |
|
1604 |
String resourceMapString = ResourceMapFactory.getInstance().serializeResourceMap(resourceMap); |
|
1605 |
|
|
1606 |
// get the original ORE SM and update the values |
|
1607 |
SystemMetadata oreSysMeta = this.getSystemMetadata(session, potentialOreIdentifier); |
|
1608 |
oreSysMeta.setIdentifier(newOreIdentifier); |
|
1609 |
oreSysMeta.setObsoletes(potentialOreIdentifier); |
|
1610 |
oreSysMeta.setObsoletedBy(null); |
|
1611 |
oreSysMeta.setSize(BigInteger.valueOf(resourceMapString.getBytes("UTF-8").length)); |
|
1612 |
oreSysMeta.setChecksum(ChecksumUtil.checksum(resourceMapString.getBytes("UTF-8"), oreSysMeta.getChecksum().getAlgorithm())); |
|
1613 |
|
|
1614 |
// save the updated ORE |
|
1615 |
this.update( |
|
1616 |
session, |
|
1617 |
potentialOreIdentifier, |
|
1618 |
new ByteArrayInputStream(resourceMapString.getBytes("UTF-8")), |
|
1619 |
newOreIdentifier, |
|
1620 |
oreSysMeta); |
|
1621 |
|
|
1622 |
} |
|
1623 |
|
|
1624 |
return newIdentifier; |
|
1625 |
} |
|
1524 | 1626 |
|
1525 | 1627 |
} |
src/edu/ucsb/nceas/metacat/dataone/SystemMetadataFactory.java | ||
---|---|---|
96 | 96 |
|
97 | 97 |
public class SystemMetadataFactory { |
98 | 98 |
|
99 |
private static final String resourceMapPrefix = "resourceMap_";
|
|
99 |
public static final String RESOURCE_MAP_PREFIX = "resourceMap_";
|
|
100 | 100 |
private static Logger logMetacat = Logger.getLogger(SystemMetadataFactory.class); |
101 | 101 |
/** |
102 | 102 |
* use this flag if you want to update any existing system metadata values with generated content |
... | ... | |
522 | 522 |
// generate the ORE map for this datapackage |
523 | 523 |
Identifier resourceMapId = new Identifier(); |
524 | 524 |
// use the local id, not the guid in case we have DOIs for them already |
525 |
resourceMapId.setValue(resourceMapPrefix + localId);
|
|
525 |
resourceMapId.setValue(RESOURCE_MAP_PREFIX + localId);
|
|
526 | 526 |
idMap.put(sysMeta.getIdentifier(), dataIds); |
527 | 527 |
ResourceMap rm = ResourceMapFactory.getInstance().createResourceMap(resourceMapId, idMap); |
528 | 528 |
String resourceMapXML = ResourceMapFactory.getInstance().serializeResourceMap(rm); |
... | ... | |
544 | 544 |
// use the localId in case we have a DOI |
545 | 545 |
String obsoletesLocalId = IdentifierManager.getInstance().getLocalId(sysMeta.getObsoletes().getValue()); |
546 | 546 |
Identifier resourceMapObsoletes = new Identifier(); |
547 |
resourceMapObsoletes.setValue(resourceMapPrefix + obsoletesLocalId );
|
|
547 |
resourceMapObsoletes.setValue(RESOURCE_MAP_PREFIX + obsoletesLocalId );
|
|
548 | 548 |
resourceMapSysMeta.setObsoletes(resourceMapObsoletes); |
549 | 549 |
SystemMetadata resourceMapObsoletesSystemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(resourceMapObsoletes); |
550 | 550 |
if (resourceMapObsoletesSystemMetadata != null) { |
... | ... | |
558 | 558 |
// use the localId in case we have a DOI |
559 | 559 |
String obsoletedByLocalId = IdentifierManager.getInstance().getLocalId(sysMeta.getObsoletedBy().getValue()); |
560 | 560 |
Identifier resourceMapObsoletedBy = new Identifier(); |
561 |
resourceMapObsoletedBy.setValue(resourceMapPrefix + obsoletedByLocalId);
|
|
561 |
resourceMapObsoletedBy.setValue(RESOURCE_MAP_PREFIX + obsoletedByLocalId);
|
|
562 | 562 |
resourceMapSysMeta.setObsoletedBy(resourceMapObsoletedBy); |
563 | 563 |
resourceMapSysMeta.setArchived(true); |
564 | 564 |
SystemMetadata resourceMapObsoletedBySystemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(resourceMapObsoletedBy); |
Also available in: Unified diff
add method for publishing existing object (usually assumed to be scimeta) with a DOI. https://projects.ecoinformatics.org/ecoinfo/issues/6014