Project

General

Profile

« Previous | Next » 

Revision 7849

add method for publishing existing object (usually assumed to be scimeta) with a DOI. https://projects.ecoinformatics.org/ecoinfo/issues/6014

View differences:

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