Project

General

Profile

« Previous | Next » 

Revision 7855

include GET /package/{pid} endpoint in MN service. https://projects.ecoinformatics.org/ecoinfo/issues/6027

View differences:

src/edu/ucsb/nceas/metacat/restservice/MNResourceHandler.java
139 139
    protected static final String RESOURCE_ERROR = "error";
140 140
    protected static final String RESOURCE_META_CHANGED = "dirtySystemMetadata";
141 141
    protected static final String RESOURCE_GENERATE_ID = "generate";
142
    protected static final String RESOURCE_PACKAGE = "package";
142 143

  
143 144
    
144 145
    // shared executor
......
369 370
                        generateIdentifier();
370 371
                        status = true;
371 372
                    }
372
                }
373
                } else if (resource.startsWith(RESOURCE_PACKAGE)) {
374
                    logMetacat.debug("Using resource: " + RESOURCE_PACKAGE);
375
                    // get
376
                    if (httpVerb == GET) {
377
                    	// after the command
378
                        extra = parseTrailing(resource, RESOURCE_META);
379
                        getPackage(extra);
380
                        status = true;
381
                    }
382
                    
383
                } 
373 384
                
374 385
                if (!status) {
375 386
                	throw new ServiceFailure("0000", "Unknown error, status = " + status);
......
1173 1184
    
1174 1185

  
1175 1186
    /**
1187
     * Retrieve data package as Bagit zip
1188
     * @param pid
1189
     * @throws NotImplemented 
1190
     * @throws NotFound 
1191
     * @throws NotAuthorized 
1192
     * @throws ServiceFailure 
1193
     * @throws InvalidToken 
1194
     * @throws IOException 
1195
     */
1196
    protected void getPackage(String pid) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented, IOException {
1197

  
1198
        Identifier id = new Identifier();
1199
        id.setValue(pid);
1200
        InputStream is = MNodeService.getInstance(request).getPackage(session, id);
1201
        
1202
        response.setContentType("application/zip");
1203
        response.setStatus(200);
1204
        OutputStream out = response.getOutputStream();
1205
        
1206
        // write it to the output stream
1207
        IOUtils.copyLarge(is, out);
1208
   }
1209
    
1210
    /**
1176 1211
     * Retrieve System Metadata
1177 1212
     * @param pid
1178 1213
     * @throws InvalidToken
src/edu/ucsb/nceas/metacat/dataone/MNodeService.java
1635 1635
	/**
1636 1636
	 * Packages the given package in a Bagit collection for download
1637 1637
	 * @param pid
1638
	 * @throws IOException 
1639 1638
	 * @throws NotImplemented 
1640 1639
	 * @throws NotFound 
1641 1640
	 * @throws NotAuthorized 
1642 1641
	 * @throws ServiceFailure 
1643 1642
	 * @throws InvalidToken 
1644
	 * @throws OREParserException 
1645
	 * @throws URISyntaxException 
1646
	 * @throws OREException 
1647 1643
	 */
1648
	public InputStream getPackage(Session session, Identifier pid) throws IOException, InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented, OREException, URISyntaxException, OREParserException {
1644
	public InputStream getPackage(Session session, Identifier pid) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented {
1645
		
1649 1646
		InputStream bagInputStream = null;
1650 1647
		BagFactory bagFactory = new BagFactory();
1651 1648
		Bag bag = bagFactory.createBag();
......
1656 1653
		// the pids to include in the package
1657 1654
		List<Identifier> packagePids = new ArrayList<Identifier>();
1658 1655
		
1659
		// find the package contents
1660
		SystemMetadata sysMeta = this.getSystemMetadata(session, pid);
1661
		if (ObjectFormatService.getInstance().getFormat(sysMeta.getFormatId()).getFormatType().equals("RESOURCE")) {
1662
			InputStream oreInputStream = this.get(session, pid);
1663
			Map<Identifier, Map<Identifier, List<Identifier>>> resourceMapStructure = ResourceMapFactory.getInstance().parseResourceMap(oreInputStream);
1664
			packagePids.addAll(resourceMapStructure.keySet());
1665
			for (Map<Identifier, List<Identifier>> entries: resourceMapStructure.values()) {
1666
				packagePids.addAll(entries.keySet());
1667
				for (List<Identifier> dataPids: entries.values()) {
1668
					packagePids.addAll(dataPids);
1656
		// catch non-D1 service errors and throw as ServiceFailures
1657
		try {
1658
			
1659
			// find the package contents
1660
			SystemMetadata sysMeta = this.getSystemMetadata(session, pid);
1661
			if (ObjectFormatService.getInstance().getFormat(sysMeta.getFormatId()).getFormatType().equals("RESOURCE")) {
1662
				InputStream oreInputStream = this.get(session, pid);
1663
				Map<Identifier, Map<Identifier, List<Identifier>>> resourceMapStructure = ResourceMapFactory.getInstance().parseResourceMap(oreInputStream);
1664
				packagePids.addAll(resourceMapStructure.keySet());
1665
				for (Map<Identifier, List<Identifier>> entries: resourceMapStructure.values()) {
1666
					packagePids.addAll(entries.keySet());
1667
					for (List<Identifier> dataPids: entries.values()) {
1668
						packagePids.addAll(dataPids);
1669
					}
1669 1670
				}
1671
			} else {
1672
				// just the lone pid in this package
1673
				packagePids.add(pid);
1670 1674
			}
1671
		} else {
1672
			// just the lone pid in this package
1673
			packagePids.add(pid);
1675
	
1676
			// track the pid-to-file mapping
1677
			StringBuffer pidMapping = new StringBuffer();
1678
			// loop through the package contents
1679
			for (Identifier entryPid: packagePids) {
1680
				SystemMetadata entrySysMeta = this.getSystemMetadata(session, entryPid);
1681
				String extension = ObjectFormatInfo.instance().getExtension(entrySysMeta.getFormatId().getValue());
1682
		        String prefix = entryPid.getValue();
1683
		        prefix = "entry";
1684
				File tempFile = File.createTempFile(prefix + ".", extension);
1685
				tempFiles.add(tempFile);
1686
				InputStream entryInputStream = this.get(session, entryPid);
1687
				IOUtils.copy(entryInputStream, new FileOutputStream(tempFile));
1688
				bag.addFileToPayload(tempFile);
1689
				pidMapping.append(entryPid.getValue() + "\t" + "data/" + tempFile.getName() + "\n");
1690
			}
1691
			
1692
			//add the the pid to data file map
1693
			File pidMappingFile = File.createTempFile("pid-mapping.", ".txt");
1694
			IOUtils.write(pidMapping.toString(), new FileOutputStream(pidMappingFile));
1695
			bag.addFileAsTag(pidMappingFile);
1696
	
1697
			bag = bag.makeComplete();
1698
			File bagFile = File.createTempFile("bag.", ".zip");
1699
			// TODO: delete more confidently
1700
			bagFile.deleteOnExit();
1701
			bag.setFile(bagFile);
1702
			Writer zipWriter = new ZipWriter(bagFactory);
1703
			bag.write(zipWriter, bagFile);
1704
			bagFile = bag.getFile();
1705
			bagInputStream = new FileInputStream(bagFile);
1706
			
1707
			// clean up temp entry files
1708
			for (File tf: tempFiles) {
1709
				tf.delete();
1710
			}
1711
		} catch (IOException e) {
1712
			// report as service failure
1713
			ServiceFailure sf = new ServiceFailure("1030", e.getMessage());
1714
			sf.initCause(e);
1715
			throw sf;
1716
		} catch (OREException e) {
1717
			// report as service failure
1718
			ServiceFailure sf = new ServiceFailure("1030", e.getMessage());
1719
			sf.initCause(e);
1720
			throw sf;
1721
		} catch (URISyntaxException e) {
1722
			// report as service failure
1723
			ServiceFailure sf = new ServiceFailure("1030", e.getMessage());
1724
			sf.initCause(e);
1725
			throw sf;
1726
		} catch (OREParserException e) {
1727
			// report as service failure
1728
			ServiceFailure sf = new ServiceFailure("1030", e.getMessage());
1729
			sf.initCause(e);
1730
			throw sf;
1674 1731
		}
1675

  
1676
		// track the pid-to-file mapping
1677
		StringBuffer pidMapping = new StringBuffer();
1678
		// loop through the package contents
1679
		for (Identifier entryPid: packagePids) {
1680
			SystemMetadata entrySysMeta = this.getSystemMetadata(session, entryPid);
1681
			String extension = ObjectFormatInfo.instance().getExtension(entrySysMeta.getFormatId().getValue());
1682
	        String prefix = entryPid.getValue();
1683
	        prefix = "entry";
1684
			File tempFile = File.createTempFile(prefix + ".", extension);
1685
			tempFiles.add(tempFile);
1686
			InputStream entryInputStream = this.get(session, entryPid);
1687
			IOUtils.copy(entryInputStream, new FileOutputStream(tempFile));
1688
			bag.addFileToPayload(tempFile);
1689
			pidMapping.append(entryPid.getValue() + "\t" + "data/" + tempFile.getName() + "\n");
1690
		}
1691 1732
		
1692
		//add the the pid to data file map
1693
		File pidMappingFile = File.createTempFile("pid-mapping.", ".txt");
1694
		IOUtils.write(pidMapping.toString(), new FileOutputStream(pidMappingFile));
1695
		bag.addFileAsTag(pidMappingFile);
1696

  
1697
		bag = bag.makeComplete();
1698
		File bagFile = File.createTempFile("bag.", ".zip");
1699
		// TODO: delete more confidently
1700
		bagFile.deleteOnExit();
1701
		bag.setFile(bagFile);
1702
		Writer zipWriter = new ZipWriter(bagFactory);
1703
		bag.write(zipWriter, bagFile);
1704
		bagFile = bag.getFile();
1705
		bagInputStream = new FileInputStream(bagFile);
1706
		
1707
		// clean up temp entry files
1708
		for (File tf: tempFiles) {
1709
			tf.delete();
1710
		}
1711
		
1712 1733
		return bagInputStream;
1713 1734

  
1714 1735
	}

Also available in: Unified diff