Project

General

Profile

Revision 9781

Added by Chris Jones over 4 years ago

Merge in changes from the 2.6.0 release.

View differences:

src/edu/ucsb/nceas/metacat/dataone/D1NodeService.java
448 448
      	//String objectAsXML = "";
449 449
        try {
450 450
	        //objectAsXML = IOUtils.toString(object, "UTF-8");
451
            String formatId = null;
452
            if(sysmeta.getFormatId() != null)  {
453
                formatId = sysmeta.getFormatId().getValue();
454
            }
455
	        localId = insertOrUpdateDocument(object,"UTF-8", pid, session, "insert", formatId);
451
	        localId = insertOrUpdateDocument(object,"UTF-8", pid, session, "insert");
456 452
	        //localId = im.getLocalId(pid.getValue());
457 453

  
458 454
        } catch (IOException e) {
......
1274 1270
          " is science metadata: " + e.getMessage());*/
1275 1271
    
1276 1272
    } catch (NotFound e) {
1277
      logMetacat.warn("There was a problem determining if the object identified by" + 
1273
      logMetacat.debug("There was a problem determining if the object identified by" + 
1278 1274
          sysmeta.getIdentifier().getValue() + 
1279 1275
          " is science metadata: " + e.getMessage());
1280 1276
    
......
1307 1303
   * @return localId - the resulting docid of the document created or updated
1308 1304
   * 
1309 1305
   */
1310
  public String insertOrUpdateDocument(InputStream xmlStream, String encoding,  Identifier pid, 
1311
    Session session, String insertOrUpdate, String formatId) 
1306
  public String insertOrUpdateDocument(InputStream xml, String encoding,  Identifier pid, 
1307
    Session session, String insertOrUpdate) 
1312 1308
    throws ServiceFailure, IOException {
1313 1309
    
1314 1310
  	logMetacat.debug("Starting to insert xml document...");
......
1316 1312

  
1317 1313
    // generate pid/localId pair for sysmeta
1318 1314
    String localId = null;
1319
    byte[] xmlBytes  = IOUtils.toByteArray(xmlStream);
1320
    IOUtils.closeQuietly(xmlStream);
1315
    byte[] xmlBytes  = IOUtils.toByteArray(xml);
1321 1316
    String xmlStr = new String(xmlBytes, encoding);
1322 1317
    if(insertOrUpdate.equals("insert")) {
1323 1318
      localId = im.generateLocalId(pid.getValue(), 1);
......
1383 1378
    // do the insert or update action
1384 1379
    handler = new MetacatHandler(new Timer());
1385 1380
    String result = handler.handleInsertOrUpdateAction(request.getRemoteAddr(), request.getHeader("User-Agent"), null, 
1386
                        null, params, username, groupnames, false, false, xmlBytes, formatId);
1381
                        null, params, username, groupnames, false, false, xmlBytes);
1387 1382
    
1388 1383
    if(result.indexOf("<error>") != -1) {
1389 1384
    	String detailCode = "";
......
1407 1402
  /**
1408 1403
   * Insert a data document
1409 1404
   * 
1410
   * @param object
-   * @param pid
-   * @param sessionData
-   * @throws ServiceFailure
-   * @returns localId of the data object inserted
-   */
-  public String insertDataObject(InputStream object, Identifier pid, 
-          Session session) throws ServiceFailure {
-      
+   * @param object
1405
   * @param pid
1406
   * @param sessionData
1407
   * @throws ServiceFailure
1408
   * @returns localId of the data object inserted
1409
   */
1410
  public String insertDataObject(InputStream object, Identifier pid, 
1411
          Session session) throws ServiceFailure {
1412
      
1411 1413
    String username = Constants.SUBJECT_PUBLIC;
1412 1414
    String[] groupnames = null;
1413 1415
    if (session != null ) {
1414 1416
    	username = session.getSubject().getValue();
1415
    	Set<Subject> otherSubjects = AuthUtils.authorizedClientSubjects(session);
1416
    	if (otherSubjects != null) {    		
1417
			groupnames = new String[otherSubjects.size()];
1418
			int i = 0;
1419
			Iterator<Subject> iter = otherSubjects.iterator();
1420
			while (iter.hasNext()) {
1421
				groupnames[i] = iter.next().getValue();
1422
				i++;
1423
			}
1417
    	if (session.getSubjectInfo() != null) {
1418
    		List<Group> groupList = session.getSubjectInfo().getGroupList();
1419
    		if (groupList != null) {
1420
    			groupnames = new String[groupList.size()];
1421
    			for (int i = 0; i < groupList.size(); i++ ) {
1422
    				groupnames[i] = groupList.get(i).getSubject().getValue();
1423
    			}
1424
    		}
1424 1425
    	}
1425 1426
    }
1426
  
-    // generate pid/localId pair for object
-    logMetacat.debug("Generating a pid/localId mapping");
-    IdentifierManager im = IdentifierManager.getInstance();
-    String localId = im.generateLocalId(pid.getValue(), 1);
   
1427
    // generate pid/localId pair for object
1428
    logMetacat.debug("Generating a pid/localId mapping");
1429
    IdentifierManager im = IdentifierManager.getInstance();
1430
    String localId = im.generateLocalId(pid.getValue(), 1);
1431
  
1427 1432
    // Save the data file to disk using "localId" as the name
1428 1433
    String datafilepath = null;
1429 1434
	try {
......
1445 1439
		ServiceFailure sf = new ServiceFailure("1190", "Lookup data file path" + e.getMessage());
1446 1440
		sf.initCause(e);
1447 1441
		throw sf;
1448
	}
+	}
1449 1442
    boolean locked = false;
1450 1443
	try {
1451 1444
		locked = DocumentImpl.getDataFileLockGrant(localId);
......
1454 1448
		sf.initCause(e);
1455 1449
		throw sf;
1456 1450
	}
1457
-    logMetacat.debug("Case DATA: starting to write to disk.");
-	if (locked) {
-
-          File dataDirectory = new File(datafilepath);
-          dataDirectory.mkdirs();
-  
-          File newFile = writeStreamToFile(dataDirectory, localId, object);
-  
-          // TODO: Check that the file size matches SystemMetadata
-          // long size = newFile.length();
-          // if (size == 0) {
-          //     throw new IOException("Uploaded file is 0 bytes!");
-          // }
-  
-          // Register the file in the database (which generates an exception
-          // if the localId is not acceptable or other untoward things happen
-          try {
-            logMetacat.debug("Registering document...");
-            DocumentImpl.registerDocument(localId, "BIN", localId,
-                    username, groupnames);
+
1451
    logMetacat.debug("Case DATA: starting to write to disk.");
1452
	if (locked) {
1453

  
1454
          File dataDirectory = new File(datafilepath);
1455
          dataDirectory.mkdirs();
1456
  
1457
          File newFile = writeStreamToFile(dataDirectory, localId, object);
1458
  
1459
          // TODO: Check that the file size matches SystemMetadata
1460
          // long size = newFile.length();
1461
          // if (size == 0) {
1462
          //     throw new IOException("Uploaded file is 0 bytes!");
1463
          // }
1464
  
1465
          // Register the file in the database (which generates an exception
1466
          // if the localId is not acceptable or other untoward things happen
1467
          try {
1468
            logMetacat.debug("Registering document...");
1469
            DocumentImpl.registerDocument(localId, "BIN", localId,
1470
                    username, groupnames);
1458 1471
            logMetacat.debug("Registration step completed.");
1459
            
-          } catch (SQLException e) {
-            //newFile.delete();
-            logMetacat.debug("SQLE: " + e.getMessage());
-            e.printStackTrace(System.out);
+            
1472
          } catch (SQLException e) {
1473
            //newFile.delete();
1474
            logMetacat.debug("SQLE: " + e.getMessage());
1475
            e.printStackTrace(System.out);
1460 1476
            throw new ServiceFailure("1190", "Registration failed: " + 
1461 1477
            		e.getMessage());
1462
            
-          } catch (AccessionNumberException e) {
-            //newFile.delete();
-            logMetacat.debug("ANE: " + e.getMessage());
-            e.printStackTrace(System.out);
+            
1478
          } catch (AccessionNumberException e) {
1479
            //newFile.delete();
1480
            logMetacat.debug("ANE: " + e.getMessage());
1481
            e.printStackTrace(System.out);
1463 1482
            throw new ServiceFailure("1190", "Registration failed: " + 
1464 1483
            	e.getMessage());
1465
            
-          } catch (Exception e) {
-            //newFile.delete();
-            logMetacat.debug("Exception: " + e.getMessage());
-            e.printStackTrace(System.out);
+            
1484
          } catch (Exception e) {
1485
            //newFile.delete();
1486
            logMetacat.debug("Exception: " + e.getMessage());
1487
            e.printStackTrace(System.out);
1466 1488
            throw new ServiceFailure("1190", "Registration failed: " + 
1467
            	e.getMessage());
-          }
-  
-          logMetacat.debug("Logging the creation event.");
-          EventLog.getInstance().log(request.getRemoteAddr(), request.getHeader("User-Agent"), username, localId, "create");
-  
-          // Schedule replication for this data file, the "insert" action is important here!
-          logMetacat.debug("Scheduling replication.");
-          ForceReplicationHandler frh = new ForceReplicationHandler(localId, "insert", false, null);
+            	e.getMessage());
1489
          }
1490
  
1491
          logMetacat.debug("Logging the creation event.");
1492
          EventLog.getInstance().log(request.getRemoteAddr(), request.getHeader("User-Agent"), username, localId, "create");
1493
  
1494
          // Schedule replication for this data file, the "insert" action is important here!
1495
          logMetacat.debug("Scheduling replication.");
1496
          ForceReplicationHandler frh = new ForceReplicationHandler(localId, "insert", false, null);
1468 1497
      }
1469
      
+      
1470 1498
      return localId;
1471
    
-  }
1499
    
1500
  }
1472 1501

  
1473 1502
  /**
1474 1503
   * Insert a systemMetadata document and return its localId
......
1876 1870
   * 
1877 1871
   * @throws ServiceFailure
1878 1872
   */
1879
  private File writeStreamToFile(File dir, String fileName, InputStream dataStream) 
1873
  private File writeStreamToFile(File dir, String fileName, InputStream data) 
1880 1874
    throws ServiceFailure {
1881 1875
    
1882 1876
    File newFile = new File(dir, fileName);
......
1886 1880
        if (newFile.createNewFile()) {
1887 1881
          // write data stream to desired file
1888 1882
          OutputStream os = new FileOutputStream(newFile);
1889
          long length = IOUtils.copyLarge(dataStream, os);
1883
          long length = IOUtils.copyLarge(data, os);
1890 1884
          os.flush();
1891 1885
          os.close();
1892 1886
        } else {
......
1901 1895
      logMetacat.debug("IOE: " + e.getMessage());
1902 1896
      throw new ServiceFailure("1190", "File was not written: " + fileName 
1903 1897
                + " " + e.getMessage());
1904
    } finally {
1905
        IOUtils.closeQuietly(dataStream);
1906 1898
    }
1907 1899

  
1908 1900
    return newFile;
......
2393 2385
      return guid;
2394 2386
      
2395 2387
  }
2396
}
+}
2397 2388

  
src/edu/ucsb/nceas/metacat/dataone/MNodeService.java
309 309
        throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique, 
310 310
        UnsupportedType, InsufficientResources, NotFound, 
311 311
        InvalidSystemMetadata, NotImplemented, InvalidRequest {
312
        
313
        if(isReadOnlyMode()) {
314
            throw new ServiceFailure("1310", ReadOnlyChecker.DATAONEERROR);
315
        }
316

  
317
        //transform a sid to a pid if it is applicable
318
        String serviceFailureCode = "1310";
319
        Identifier sid = getPIDForSID(pid, serviceFailureCode);
320
        if(sid != null) {
321
            pid = sid;
322
        }
323
        
324
        String localId = null;
325
        boolean allowed = false;
326
        boolean isScienceMetadata = false;
327
        
328
        if (session == null) {
329
        	throw new InvalidToken("1210", "No session has been provided");
330
        }
331
        Subject subject = session.getSubject();
332

  
333
        // verify the pid is valid format
334
        if (!isValidIdentifier(pid)) {
335
        	throw new InvalidRequest("1202", "The provided identifier is invalid.");
336
        }
337
        
338
        // verify the new pid is valid format
339
        if (!isValidIdentifier(newPid)) {
340
            throw new InvalidRequest("1202", "The provided identifier is invalid.");
341
        }
342
        
343
        // make sure that the newPid doesn't exists
344
        boolean idExists = true;
312 345
        try {
313
            if(isReadOnlyMode()) {
314
                throw new ServiceFailure("1310", ReadOnlyChecker.DATAONEERROR);
315
            }
316
    
317
            //transform a sid to a pid if it is applicable
318
            String serviceFailureCode = "1310";
319
            Identifier sid = getPIDForSID(pid, serviceFailureCode);
320
            if(sid != null) {
321
                pid = sid;
322
            }
346
            idExists = IdentifierManager.getInstance().identifierExists(newPid.getValue());
347
        } catch (SQLException e) {
348
            throw new ServiceFailure("1310", 
349
                                    "The requested identifier " + newPid.getValue() +
350
                                    " couldn't be determined if it is unique since : "+e.getMessage());
351
        }
352
        if (idExists) {
353
                throw new IdentifierNotUnique("1220", 
354
                          "The requested identifier " + newPid.getValue() +
355
                          " is already used by another object and" +
356
                          "therefore can not be used for this object. Clients should choose" +
357
                          "a new identifier that is unique and retry the operation or " +
358
                          "use CN.reserveIdentifier() to reserve one.");
323 359
            
324
            String localId = null;
325
            boolean allowed = false;
326
            boolean isScienceMetadata = false;
360
        }
361
        
362
       
363

  
364
        // check for the existing identifier
365
        try {
366
            localId = IdentifierManager.getInstance().getLocalId(pid.getValue());
327 367
            
328
            if (session == null) {
329
            	throw new InvalidToken("1210", "No session has been provided");
330
            }
331
            Subject subject = session.getSubject();
332
    
333
            // verify the pid is valid format
334
            if (!isValidIdentifier(pid)) {
335
            	throw new InvalidRequest("1202", "The provided identifier is invalid.");
336
            }
368
        } catch (McdbDocNotFoundException e) {
369
            throw new InvalidRequest("1202", "The object with the provided " + 
370
                "identifier was not found.");
337 371
            
338
            // verify the new pid is valid format
339
            if (!isValidIdentifier(newPid)) {
340
                throw new InvalidRequest("1202", "The provided identifier is invalid.");
372
        } catch (SQLException ee) {
373
            throw new ServiceFailure("1310", "The object with the provided " + 
374
                    "identifier "+pid.getValue()+" can't be identified since - "+ee.getMessage());
375
        }
376
        
377
        // set the originating node
378
        NodeReference originMemberNode = this.getCapabilities().getIdentifier();
379
        sysmeta.setOriginMemberNode(originMemberNode);
380
        
381
        // set the submitter to match the certificate
382
        sysmeta.setSubmitter(subject);
383
        // set the dates
384
        Date now = Calendar.getInstance().getTime();
385
        sysmeta.setDateSysMetadataModified(now);
386
        sysmeta.setDateUploaded(now);
387
        
388
        // make sure serial version is set to something
389
        BigInteger serialVersion = sysmeta.getSerialVersion();
390
        if (serialVersion == null) {
391
        	sysmeta.setSerialVersion(BigInteger.ZERO);
392
        }
393

  
394
        // does the subject have WRITE ( == update) priveleges on the pid?
395
        //allowed = isAuthorized(session, pid, Permission.WRITE);
396
        //CN having the permission is allowed; user with the write permission and calling on the authoritative node is allowed.
397
        allowed = allowUpdating(session, pid, Permission.WRITE);
398
        if (allowed) {
399
        	
400
        	// check quality of SM
401
        	if (sysmeta.getObsoletedBy() != null) {
402
        		throw new InvalidSystemMetadata("1300", "Cannot include obsoletedBy when updating object");
403
        	}
404
        	if (sysmeta.getObsoletes() != null && !sysmeta.getObsoletes().getValue().equals(pid.getValue())) {
405
        		throw new InvalidSystemMetadata("1300", "The identifier provided in obsoletes does not match old Identifier");
406
        	}
407

  
408
            // get the existing system metadata for the object
409
            SystemMetadata existingSysMeta = getSystemMetadata(session, pid);
410
            //System.out.println("the archive is "+existingSysMeta.getArchived());
411
            //Base on documentation, we can't update an archived object:
412
            //The update operation MUST fail with Exceptions.InvalidRequest on objects that have the Types.SystemMetadata.archived property set to true.
413
            if(existingSysMeta.getArchived() != null && existingSysMeta.getArchived()) {
414
                throw new InvalidRequest("1202","An archived object"+pid.getValue()+" can't be updated");
341 415
            }
342
            
343
            // make sure that the newPid doesn't exists
344
            boolean idExists = true;
345
            try {
346
                idExists = IdentifierManager.getInstance().identifierExists(newPid.getValue());
347
            } catch (SQLException e) {
348
                throw new ServiceFailure("1310", 
349
                                        "The requested identifier " + newPid.getValue() +
350
                                        " couldn't be determined if it is unique since : "+e.getMessage());
416

  
417
            // check for previous update
418
            // see: https://redmine.dataone.org/issues/3336
419
            Identifier existingObsoletedBy = existingSysMeta.getObsoletedBy();
420
            if (existingObsoletedBy != null) {
421
            	throw new InvalidRequest("1202", 
422
            			"The previous identifier has already been made obsolete by: " + existingObsoletedBy.getValue());
351 423
            }
352
            if (idExists) {
353
                    throw new IdentifierNotUnique("1220", 
354
                              "The requested identifier " + newPid.getValue() +
355
                              " is already used by another object and" +
356
                              "therefore can not be used for this object. Clients should choose" +
357
                              "a new identifier that is unique and retry the operation or " +
358
                              "use CN.reserveIdentifier() to reserve one.");
359
                
360
            }
361
            
362
           
363
    
364
            // check for the existing identifier
365
            try {
366
                localId = IdentifierManager.getInstance().getLocalId(pid.getValue());
367
                
368
            } catch (McdbDocNotFoundException e) {
369
                throw new InvalidRequest("1202", "The object with the provided " + 
370
                    "identifier was not found.");
371
                
372
            } catch (SQLException ee) {
373
                throw new ServiceFailure("1310", "The object with the provided " + 
374
                        "identifier "+pid.getValue()+" can't be identified since - "+ee.getMessage());
375
            }
376
            
377
            // set the originating node
378
            NodeReference originMemberNode = this.getCapabilities().getIdentifier();
379
            sysmeta.setOriginMemberNode(originMemberNode);
380
            
381
            // set the submitter to match the certificate
382
            sysmeta.setSubmitter(subject);
383
            // set the dates
384
            Date now = Calendar.getInstance().getTime();
385
            sysmeta.setDateSysMetadataModified(now);
386
            sysmeta.setDateUploaded(now);
387
            
388
            // make sure serial version is set to something
389
            BigInteger serialVersion = sysmeta.getSerialVersion();
390
            if (serialVersion == null) {
391
            	sysmeta.setSerialVersion(BigInteger.ZERO);
392
            }
393
    
394
            // does the subject have WRITE ( == update) priveleges on the pid?
395
            //allowed = isAuthorized(session, pid, Permission.WRITE);
396
            //CN having the permission is allowed; user with the write permission and calling on the authoritative node is allowed.
397
            allowed = allowUpdating(session, pid, Permission.WRITE);
398
            if (allowed) {
399
            	
400
            	// check quality of SM
401
            	if (sysmeta.getObsoletedBy() != null) {
402
            		throw new InvalidSystemMetadata("1300", "Cannot include obsoletedBy when updating object");
403
            	}
404
            	if (sysmeta.getObsoletes() != null && !sysmeta.getObsoletes().getValue().equals(pid.getValue())) {
405
            		throw new InvalidSystemMetadata("1300", "The identifier provided in obsoletes does not match old Identifier");
406
            	}
407
    
408
                // get the existing system metadata for the object
409
                SystemMetadata existingSysMeta = getSystemMetadata(session, pid);
410
                //System.out.println("the archive is "+existingSysMeta.getArchived());
411
                //Base on documentation, we can't update an archived object:
412
                //The update operation MUST fail with Exceptions.InvalidRequest on objects that have the Types.SystemMetadata.archived property set to true.
413
                if(existingSysMeta.getArchived() != null && existingSysMeta.getArchived()) {
414
                    throw new InvalidRequest("1202","An archived object"+pid.getValue()+" can't be updated");
424
            //check the sid in the system metadata. If it exists, it should be non-exist or match the old sid in the previous system metadata.
425
            Identifier sidInSys = sysmeta.getSeriesId();
426
            if(sidInSys != null) {
427
                if (!isValidIdentifier(sidInSys)) {
428
                    throw new InvalidSystemMetadata("1300", "The provided series id in the system metadata is invalid.");
415 429
                }
416
    
417
                // check for previous update
418
                // see: https://redmine.dataone.org/issues/3336
419
                Identifier existingObsoletedBy = existingSysMeta.getObsoletedBy();
420
                if (existingObsoletedBy != null) {
421
                	throw new InvalidRequest("1202", 
422
                			"The previous identifier has already been made obsolete by: " + existingObsoletedBy.getValue());
423
                }
424
                //check the sid in the system metadata. If it exists, it should be non-exist or match the old sid in the previous system metadata.
425
                Identifier sidInSys = sysmeta.getSeriesId();
426
                if(sidInSys != null) {
427
                    if (!isValidIdentifier(sidInSys)) {
428
                        throw new InvalidSystemMetadata("1300", "The provided series id in the system metadata is invalid.");
429
                    }
430
                    Identifier previousSid = existingSysMeta.getSeriesId();
431
                    if(previousSid != null) {
432
                        // there is a previous sid, if the new sid doesn't match it, the new sid should be non-existing.
433
                        if(!sidInSys.getValue().equals(previousSid.getValue())) {
434
                            try {
435
                                idExists = IdentifierManager.getInstance().identifierExists(sidInSys.getValue());
436
                            } catch (SQLException e) {
437
                                throw new ServiceFailure("1310", 
438
                                                        "The requested identifier " + sidInSys.getValue() +
439
                                                        " couldn't be determined if it is unique since : "+e.getMessage());
440
                            }
441
                            if(idExists) {
442
                                throw new InvalidSystemMetadata("1300", "The series id "+sidInSys.getValue()+" in the system metadata doesn't match the previous series id "
443
                                                                +previousSid.getValue()+", so it should NOT exist. However, it was used by another object.");
444
                            }
445
                        }
446
                    } else {
447
                        // there is no previous sid, the new sid should be non-existing.
430
                Identifier previousSid = existingSysMeta.getSeriesId();
431
                if(previousSid != null) {
432
                    // there is a previous sid, if the new sid doesn't match it, the new sid should be non-existing.
433
                    if(!sidInSys.getValue().equals(previousSid.getValue())) {
448 434
                        try {
449 435
                            idExists = IdentifierManager.getInstance().identifierExists(sidInSys.getValue());
450 436
                        } catch (SQLException e) {
......
453 439
                                                    " couldn't be determined if it is unique since : "+e.getMessage());
454 440
                        }
455 441
                        if(idExists) {
456
                            throw new InvalidSystemMetadata("1300", "The series id "+sidInSys.getValue()+" in the system metadata should NOT exist since the previous series id is null."
457
                                                            +"However, it was used by another object.");
442
                            throw new InvalidSystemMetadata("1300", "The series id "+sidInSys.getValue()+" in the system metadata doesn't match the previous series id "
443
                                                            +previousSid.getValue()+", so it should NOT exist. However, it was used by another object.");
458 444
                        }
459 445
                    }
460
                    //the series id equals the pid (new pid hasn't been registered in the system, so IdentifierManager.getInstance().identifierExists method can't exclude this scenario)
461
                    if(sidInSys.getValue().equals(newPid.getValue())) {
462
                        throw new InvalidSystemMetadata("1300", "The series id "+sidInSys.getValue()+" in the system metadata shouldn't have the same value of the pid.");
446
                } else {
447
                    // there is no previous sid, the new sid should be non-existing.
448
                    try {
449
                        idExists = IdentifierManager.getInstance().identifierExists(sidInSys.getValue());
450
                    } catch (SQLException e) {
451
                        throw new ServiceFailure("1310", 
452
                                                "The requested identifier " + sidInSys.getValue() +
453
                                                " couldn't be determined if it is unique since : "+e.getMessage());
463 454
                    }
455
                    if(idExists) {
456
                        throw new InvalidSystemMetadata("1300", "The series id "+sidInSys.getValue()+" in the system metadata should NOT exist since the previous series id is null."
457
                                                        +"However, it was used by another object.");
458
                    }
464 459
                }
465
    
466
                isScienceMetadata = isScienceMetadata(sysmeta);
467
    
468
                // do we have XML metadata or a data object?
469
                if (isScienceMetadata) {
470
    
471
                    // update the science metadata XML document
472
                    // TODO: handle non-XML metadata/data documents (like netCDF)
473
                    // TODO: don't put objects into memory using stream to string
474
                    //String objectAsXML = "";
475
                    try {
476
                        //objectAsXML = IOUtils.toString(object, "UTF-8");
477
                    	String formatId = null;
478
                    	if(sysmeta.getFormatId() != null) {
479
                    	    formatId = sysmeta.getFormatId().getValue();
480
                    	}
481
                        localId = insertOrUpdateDocument(object, "UTF-8", pid, session, "update", formatId);
482
                        
483
                        // register the newPid and the generated localId
484
                        if (newPid != null) {
485
                            IdentifierManager.getInstance().createMapping(newPid.getValue(), localId);
486
                        }
487
    
488
                    } catch (IOException e) {
489
                        String msg = "The Node is unable to create the object. " + "There was a problem converting the object to XML";
490
                        logMetacat.info(msg);
491
                        throw new ServiceFailure("1310", msg + ": " + e.getMessage());
492
    
460
                //the series id equals the pid (new pid hasn't been registered in the system, so IdentifierManager.getInstance().identifierExists method can't exclude this scenario)
461
                if(sidInSys.getValue().equals(newPid.getValue())) {
462
                    throw new InvalidSystemMetadata("1300", "The series id "+sidInSys.getValue()+" in the system metadata shouldn't have the same value of the pid.");
463
                }
464
            }
465

  
466
            isScienceMetadata = isScienceMetadata(sysmeta);
467

  
468
            // do we have XML metadata or a data object?
469
            if (isScienceMetadata) {
470

  
471
                // update the science metadata XML document
472
                // TODO: handle non-XML metadata/data documents (like netCDF)
473
                // TODO: don't put objects into memory using stream to string
474
                //String objectAsXML = "";
475
                try {
476
                    //objectAsXML = IOUtils.toString(object, "UTF-8");
477
                	
478
                    localId = insertOrUpdateDocument(object, "UTF-8", pid, session, "update");
479
                    
480
                    // register the newPid and the generated localId
481
                    if (newPid != null) {
482
                        IdentifierManager.getInstance().createMapping(newPid.getValue(), localId);
493 483
                    }
494
    
495
                } else {
496
    
497
                    // update the data object
498
                    localId = insertDataObject(object, newPid, session);
499
    
484

  
485
                } catch (IOException e) {
486
                    String msg = "The Node is unable to create the object. " + "There was a problem converting the object to XML";
487
                    logMetacat.info(msg);
488
                    throw new ServiceFailure("1310", msg + ": " + e.getMessage());
489

  
500 490
                }
501
                
502
                // add the newPid to the obsoletedBy list for the existing sysmeta
503
                existingSysMeta.setObsoletedBy(newPid);
504
                //increase version
505
                BigInteger current = existingSysMeta.getSerialVersion();
506
                //System.out.println("the current version is "+current);
507
                current = current.add(BigInteger.ONE);
508
                //System.out.println("the new current version is "+current);
509
                existingSysMeta.setSerialVersion(current);
510
                // then update the existing system metadata
511
                updateSystemMetadata(existingSysMeta);
512
    
513
                // prep the new system metadata, add pid to the affected lists
514
                sysmeta.setObsoletes(pid);
515
                //sysmeta.addDerivedFrom(pid);
516
    
517
                // and insert the new system metadata
518
                insertSystemMetadata(sysmeta);
519
    
520
                // log the update event
521
                EventLog.getInstance().log(request.getRemoteAddr(), request.getHeader("User-Agent"), subject.getValue(), localId, Event.UPDATE.toString());
522
                
523
                // attempt to register the identifier - it checks if it is a doi
524
                try {
525
        			DOIService.getInstance().registerDOI(sysmeta);
526
        		} catch (Exception e) {
527
                    throw new ServiceFailure("1190", "Could not register DOI: " + e.getMessage());
528
        		}
529
    
491

  
530 492
            } else {
531
                throw new NotAuthorized("1200", "The provided identity does not have " + "permission to UPDATE the object identified by " + pid.getValue()
532
                        + " on the Member Node.");
493

  
494
                // update the data object
495
                localId = insertDataObject(object, newPid, session);
496

  
533 497
            }
534
        } finally {
535
            IOUtils.closeQuietly(object);
498
            
499
            // add the newPid to the obsoletedBy list for the existing sysmeta
500
            existingSysMeta.setObsoletedBy(newPid);
501
            //increase version
502
            BigInteger current = existingSysMeta.getSerialVersion();
503
            //System.out.println("the current version is "+current);
504
            current = current.add(BigInteger.ONE);
505
            //System.out.println("the new current version is "+current);
506
            existingSysMeta.setSerialVersion(current);
507
            // then update the existing system metadata
508
            updateSystemMetadata(existingSysMeta);
509

  
510
            // prep the new system metadata, add pid to the affected lists
511
            sysmeta.setObsoletes(pid);
512
            //sysmeta.addDerivedFrom(pid);
513

  
514
            // and insert the new system metadata
515
            insertSystemMetadata(sysmeta);
516

  
517
            // log the update event
518
            EventLog.getInstance().log(request.getRemoteAddr(), request.getHeader("User-Agent"), subject.getValue(), localId, Event.UPDATE.toString());
519
            
520
            // attempt to register the identifier - it checks if it is a doi
521
            try {
522
    			DOIService.getInstance().registerDOI(sysmeta);
523
    		} catch (Exception e) {
524
                throw new ServiceFailure("1190", "Could not register DOI: " + e.getMessage());
525
    		}
526

  
527
        } else {
528
            throw new NotAuthorized("1200", "The provided identity does not have " + "permission to UPDATE the object identified by " + pid.getValue()
529
                    + " on the Member Node.");
536 530
        }
531

  
537 532
        return newPid;
538 533
    }
539 534

  
540 535
    public Identifier create(Session session, Identifier pid, InputStream object, SystemMetadata sysmeta) throws InvalidToken, ServiceFailure, NotAuthorized,
541 536
            IdentifierNotUnique, UnsupportedType, InsufficientResources, InvalidSystemMetadata, NotImplemented, InvalidRequest {
542
        Identifier resultPid = null;
543
        try {
544
            if(isReadOnlyMode()) {
545
                throw new ServiceFailure("1190", ReadOnlyChecker.DATAONEERROR);
537

  
538
        if(isReadOnlyMode()) {
539
            throw new ServiceFailure("1190", ReadOnlyChecker.DATAONEERROR);
540
        }
541
        // check for null session
542
        if (session == null) {
543
          throw new InvalidToken("1110", "Session is required to WRITE to the Node.");
544
        }
545
        // verify the pid is valid format
546
        if (!isValidIdentifier(pid)) {
547
            throw new InvalidRequest("1102", "The provided identifier is invalid.");
548
        }
549
        // set the submitter to match the certificate
550
        sysmeta.setSubmitter(session.getSubject());
551
        // set the originating node
552
        NodeReference originMemberNode = this.getCapabilities().getIdentifier();
553
        sysmeta.setOriginMemberNode(originMemberNode);
554
        
555
        // if no authoritative MN, set it to the same
556
        if (sysmeta.getAuthoritativeMemberNode() == null) {
557
        	sysmeta.setAuthoritativeMemberNode(originMemberNode);
558
        }
559
        
560
        sysmeta.setArchived(false);
561

  
562
        // set the dates
563
        Date now = Calendar.getInstance().getTime();
564
        sysmeta.setDateSysMetadataModified(now);
565
        sysmeta.setDateUploaded(now);
566
        
567
        // set the serial version
568
        sysmeta.setSerialVersion(BigInteger.ZERO);
569

  
570
        // check that we are not attempting to subvert versioning
571
        if (sysmeta.getObsoletes() != null && sysmeta.getObsoletes().getValue() != null) {
572
            throw new InvalidSystemMetadata("1180", 
573
              "The supplied system metadata is invalid. " +
574
              "The obsoletes field cannot have a value when creating entries.");
575
        }
576
        
577
        if (sysmeta.getObsoletedBy() != null && sysmeta.getObsoletedBy().getValue() != null) {
578
            throw new InvalidSystemMetadata("1180", 
579
              "The supplied system metadata is invalid. " +
580
              "The obsoletedBy field cannot have a value when creating entries.");
581
        }
582
        
583
        // verify the sid in the system metadata
584
        Identifier sid = sysmeta.getSeriesId();
585
        boolean idExists = false;
586
        if(sid != null) {
587
            if (!isValidIdentifier(sid)) {
588
                throw new InvalidSystemMetadata("1180", "The provided series id is invalid.");
546 589
            }
547
            // check for null session
548
            if (session == null) {
549
              throw new InvalidToken("1110", "Session is required to WRITE to the Node.");
590
            try {
591
                idExists = IdentifierManager.getInstance().identifierExists(sid.getValue());
592
            } catch (SQLException e) {
593
                throw new ServiceFailure("1190", 
594
                                        "The series identifier " + sid.getValue() +
595
                                        " in the system metadata couldn't be determined if it is unique since : "+e.getMessage());
550 596
            }
551
            // verify the pid is valid format
552
            if (!isValidIdentifier(pid)) {
553
                throw new InvalidRequest("1102", "The provided identifier is invalid.");
597
            if (idExists) {
598
                    throw new InvalidSystemMetadata("1180", 
599
                              "The series identifier " + sid.getValue() +
600
                              " is already used by another object and" +
601
                              "therefore can not be used for this object. Clients should choose" +
602
                              "a new identifier that is unique and retry the operation or " +
603
                              "use CN.reserveIdentifier() to reserve one.");
604
                
554 605
            }
555
            // set the submitter to match the certificate
556
            sysmeta.setSubmitter(session.getSubject());
557
            // set the originating node
558
            NodeReference originMemberNode = this.getCapabilities().getIdentifier();
559
            sysmeta.setOriginMemberNode(originMemberNode);
560
            
561
            // if no authoritative MN, set it to the same
562
            if (sysmeta.getAuthoritativeMemberNode() == null) {
563
            	sysmeta.setAuthoritativeMemberNode(originMemberNode);
606
            //the series id equals the pid (new pid hasn't been registered in the system, so IdentifierManager.getInstance().identifierExists method can't exclude this scenario )
607
            if(sid.getValue().equals(pid.getValue())) {
608
                throw new InvalidSystemMetadata("1180", "The series id "+sid.getValue()+" in the system metadata shouldn't have the same value of the pid.");
564 609
            }
565
            
566
            sysmeta.setArchived(false);
567
    
568
            // set the dates
569
            Date now = Calendar.getInstance().getTime();
570
            sysmeta.setDateSysMetadataModified(now);
571
            sysmeta.setDateUploaded(now);
572
            
573
            // set the serial version
574
            sysmeta.setSerialVersion(BigInteger.ZERO);
575
    
576
            // check that we are not attempting to subvert versioning
577
            if (sysmeta.getObsoletes() != null && sysmeta.getObsoletes().getValue() != null) {
578
                throw new InvalidSystemMetadata("1180", 
579
                  "The supplied system metadata is invalid. " +
580
                  "The obsoletes field cannot have a value when creating entries.");
581
            }
582
            
583
            if (sysmeta.getObsoletedBy() != null && sysmeta.getObsoletedBy().getValue() != null) {
584
                throw new InvalidSystemMetadata("1180", 
585
                  "The supplied system metadata is invalid. " +
586
                  "The obsoletedBy field cannot have a value when creating entries.");
587
            }
588
            
589
            // verify the sid in the system metadata
590
            Identifier sid = sysmeta.getSeriesId();
591
            boolean idExists = false;
592
            if(sid != null) {
593
                if (!isValidIdentifier(sid)) {
594
                    throw new InvalidSystemMetadata("1180", "The provided series id is invalid.");
595
                }
596
                try {
597
                    idExists = IdentifierManager.getInstance().identifierExists(sid.getValue());
598
                } catch (SQLException e) {
599
                    throw new ServiceFailure("1190", 
600
                                            "The series identifier " + sid.getValue() +
601
                                            " in the system metadata couldn't be determined if it is unique since : "+e.getMessage());
602
                }
603
                if (idExists) {
604
                        throw new InvalidSystemMetadata("1180", 
605
                                  "The series identifier " + sid.getValue() +
606
                                  " is already used by another object and" +
607
                                  "therefore can not be used for this object. Clients should choose" +
608
                                  "a new identifier that is unique and retry the operation or " +
609
                                  "use CN.reserveIdentifier() to reserve one.");
610
                    
611
                }
612
                //the series id equals the pid (new pid hasn't been registered in the system, so IdentifierManager.getInstance().identifierExists method can't exclude this scenario )
613
                if(sid.getValue().equals(pid.getValue())) {
614
                    throw new InvalidSystemMetadata("1180", "The series id "+sid.getValue()+" in the system metadata shouldn't have the same value of the pid.");
615
                }
616
            }
617
    
618
            // call the shared impl
619
            resultPid = super.create(session, pid, object, sysmeta);
620
            
621
            // attempt to register the identifier - it checks if it is a doi
622
            try {
623
    			DOIService.getInstance().registerDOI(sysmeta);
624
    		} catch (Exception e) {
625
    			ServiceFailure sf = new ServiceFailure("1190", "Could not register DOI: " + e.getMessage());
626
    			sf.initCause(e);
627
                throw sf;
628
    		}
629
        } finally {
630
            IOUtils.closeQuietly(object);
631 610
        }
611

  
612
        // call the shared impl
613
        Identifier resultPid = super.create(session, pid, object, sysmeta);
614
        
615
        // attempt to register the identifier - it checks if it is a doi
616
        try {
617
			DOIService.getInstance().registerDOI(sysmeta);
618
		} catch (Exception e) {
619
			ServiceFailure sf = new ServiceFailure("1190", "Could not register DOI: " + e.getMessage());
620
			sf.initCause(e);
621
            throw sf;
622
		}
623
        
632 624
        // return 
633 625
		return resultPid ;
634 626
    }
......
2687 2679
     */
2688 2680
    private boolean allowUpdating(Session session, Identifier pid, Permission permission) throws NotAuthorized, NotFound, InvalidRequest {
2689 2681
        boolean allow = false;
2682
        
2690 2683
        if( isCNAdmin (session) ) {
2691 2684
            allow = true;
2692 2685
            
2693 2686
        } else {
2694 2687
            if( isAuthoritativeNode(pid) ) {
2695 2688
            	
2689
            	// Check for admin authorization
2696 2690
            	try {
2697
					return isNodeAdmin(session);
2691
					allow = isNodeAdmin(session);
2698 2692
					
2699 2693
				} catch (NotImplemented e) {
2700 2694
					logMetacat.debug("Failed to authorize the Member Node Admin Subject: " + e.getMessage());
......
2704 2698
					
2705 2699
				}
2706 2700
            	
2707
            	if ( userHasPermission(session, pid, permission) ) {
2708
                    allow = true;
2701
            	// Check for user authorization
2702
            	if ( !allow ) {
2703
                    allow = userHasPermission(session, pid, permission);
2709 2704
                    
2710
                } else {
2711
                    allow = false;
2705
            	}
2712 2706
                    
2713
                }
2714 2707
            } else {
2715 2708
                throw new NotAuthorized("4861", "Client can only call the request on the authoritative memember node.");
2716 2709
                
2717 2710

  

Also available in: Unified diff