Project

General

Profile

1 6177 cjones
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2000-2011 Regents of the University of California and the
4
 *              National Center for Ecological Analysis and Synthesis
5
 *
6
 *   '$Author:  $'
7
 *     '$Date:  $'
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 2 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22
 */
23
24
package edu.ucsb.nceas.metacat.dataone;
25
26 6569 cjones
import java.io.InputStream;
27 6567 cjones
import java.math.BigInteger;
28 6883 leinfelder
import java.util.ArrayList;
29 6567 cjones
import java.util.Calendar;
30 6177 cjones
import java.util.Date;
31 6220 leinfelder
import java.util.List;
32 6859 cjones
import java.util.concurrent.locks.Lock;
33 6177 cjones
34 6542 leinfelder
import javax.servlet.http.HttpServletRequest;
35
36 6178 cjones
import org.apache.log4j.Logger;
37 6484 cjones
import org.dataone.client.CNode;
38
import org.dataone.client.D1Client;
39 7073 cjones
import org.dataone.client.MNode;
40 6366 leinfelder
import org.dataone.service.cn.v1.CNAuthorization;
41
import org.dataone.service.cn.v1.CNCore;
42
import org.dataone.service.cn.v1.CNRead;
43
import org.dataone.service.cn.v1.CNReplication;
44 6792 cjones
import org.dataone.service.exceptions.BaseException;
45 6177 cjones
import org.dataone.service.exceptions.IdentifierNotUnique;
46
import org.dataone.service.exceptions.InsufficientResources;
47
import org.dataone.service.exceptions.InvalidRequest;
48
import org.dataone.service.exceptions.InvalidSystemMetadata;
49
import org.dataone.service.exceptions.InvalidToken;
50
import org.dataone.service.exceptions.NotAuthorized;
51
import org.dataone.service.exceptions.NotFound;
52
import org.dataone.service.exceptions.NotImplemented;
53
import org.dataone.service.exceptions.ServiceFailure;
54 6569 cjones
import org.dataone.service.exceptions.UnsupportedType;
55 6869 cjones
import org.dataone.service.exceptions.VersionMismatch;
56 6571 cjones
import org.dataone.service.types.v1.AccessPolicy;
57 6366 leinfelder
import org.dataone.service.types.v1.Checksum;
58 6803 leinfelder
import org.dataone.service.types.v1.ChecksumAlgorithmList;
59 7144 leinfelder
import org.dataone.service.types.v1.DescribeResponse;
60
import org.dataone.service.types.v1.Event;
61 6366 leinfelder
import org.dataone.service.types.v1.Identifier;
62 7144 leinfelder
import org.dataone.service.types.v1.Log;
63 6463 cjones
import org.dataone.service.types.v1.Node;
64 6366 leinfelder
import org.dataone.service.types.v1.NodeList;
65 6409 cjones
import org.dataone.service.types.v1.NodeReference;
66 6570 cjones
import org.dataone.service.types.v1.NodeType;
67 6366 leinfelder
import org.dataone.service.types.v1.ObjectFormat;
68
import org.dataone.service.types.v1.ObjectFormatIdentifier;
69
import org.dataone.service.types.v1.ObjectFormatList;
70
import org.dataone.service.types.v1.ObjectList;
71
import org.dataone.service.types.v1.ObjectLocationList;
72
import org.dataone.service.types.v1.Permission;
73
import org.dataone.service.types.v1.Replica;
74
import org.dataone.service.types.v1.ReplicationPolicy;
75
import org.dataone.service.types.v1.ReplicationStatus;
76
import org.dataone.service.types.v1.Session;
77
import org.dataone.service.types.v1.Subject;
78
import org.dataone.service.types.v1.SystemMetadata;
79 6881 leinfelder
import org.dataone.service.types.v1.util.ServiceMethodRestrictionUtil;
80 6177 cjones
81 6188 leinfelder
import edu.ucsb.nceas.metacat.EventLog;
82
import edu.ucsb.nceas.metacat.IdentifierManager;
83 6446 leinfelder
import edu.ucsb.nceas.metacat.dataone.hazelcast.HazelcastService;
84 6188 leinfelder
85 6177 cjones
/**
86
 * Represents Metacat's implementation of the DataONE Coordinating Node
87 6179 cjones
 * service API. Methods implement the various CN* interfaces, and methods common
88 6177 cjones
 * to both Member Node and Coordinating Node interfaces are found in the
89
 * D1NodeService super class.
90
 *
91
 */
92
public class CNodeService extends D1NodeService implements CNAuthorization,
93 6446 leinfelder
    CNCore, CNRead, CNReplication {
94 6177 cjones
95 6178 cjones
  /* the logger instance */
96
  private Logger logMetacat = null;
97 6177 cjones
98 6178 cjones
  /**
99
   * singleton accessor
100
   */
101 6542 leinfelder
  public static CNodeService getInstance(HttpServletRequest request) {
102
    return new CNodeService(request);
103 6178 cjones
  }
104
105
  /**
106
   * Constructor, private for singleton access
107
   */
108 6542 leinfelder
  private CNodeService(HttpServletRequest request) {
109
    super(request);
110 6178 cjones
    logMetacat = Logger.getLogger(CNodeService.class);
111
112
  }
113
114 6410 cjones
  /**
115
   * Set the replication policy for an object given the object identifier
116
   *
117
   * @param session - the Session object containing the credentials for the Subject
118
   * @param pid - the object identifier for the given object
119
   * @param policy - the replication policy to be applied
120
   *
121
   * @return true or false
122
   *
123
   * @throws NotImplemented
124
   * @throws NotAuthorized
125
   * @throws ServiceFailure
126
   * @throws InvalidRequest
127 6869 cjones
   * @throws VersionMismatch
128 6410 cjones
   *
129
   */
130 6471 jones
  @Override
131 6410 cjones
  public boolean setReplicationPolicy(Session session, Identifier pid,
132 6593 cjones
      ReplicationPolicy policy, long serialVersion)
133 6567 cjones
      throws NotImplemented, NotFound, NotAuthorized, ServiceFailure,
134 6869 cjones
      InvalidRequest, InvalidToken, VersionMismatch {
135 6567 cjones
136 6717 cjones
      // The lock to be used for this identifier
137 6859 cjones
      Lock lock = null;
138 6702 cjones
139 6567 cjones
      // get the subject
140
      Subject subject = session.getSubject();
141
142
      // are we allowed to do this?
143 7068 cjones
      if (!isAuthorized(session, pid, Permission.CHANGE_PERMISSION)) {
144
          throw new NotAuthorized("4881", Permission.CHANGE_PERMISSION
145
                  + " not allowed by " + subject.getValue() + " on "
146
                  + pid.getValue());
147
148 6869 cjones
      }
149
150
      SystemMetadata systemMetadata = null;
151 6567 cjones
      try {
152 6858 cjones
          lock = HazelcastService.getInstance().getLock(pid.getValue());
153
          lock.lock();
154 6867 cjones
          logMetacat.debug("Locked identifier " + pid.getValue());
155 6858 cjones
156
          try {
157
              if ( HazelcastService.getInstance().getSystemMetadataMap().containsKey(pid) ) {
158
                  systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
159
160
              }
161 6869 cjones
162
              // did we get it correctly?
163
              if ( systemMetadata == null ) {
164
                  throw new NotFound("4884", "Couldn't find an object identified by " + pid.getValue());
165
166
              }
167 6858 cjones
168
              // does the request have the most current system metadata?
169
              if ( systemMetadata.getSerialVersion().longValue() != serialVersion ) {
170
                 String msg = "The requested system metadata version number " +
171
                     serialVersion + " differs from the current version at " +
172
                     systemMetadata.getSerialVersion().longValue() +
173
                     ". Please get the latest copy in order to modify it.";
174 6869 cjones
                 throw new VersionMismatch("4886", msg);
175
176 6858 cjones
              }
177 6717 cjones
178 6869 cjones
          } catch (RuntimeException e) { // Catch is generic since HZ throws RuntimeException
179 6858 cjones
              throw new NotFound("4884", "No record found for: " + pid.getValue());
180
181 6717 cjones
          }
182 6858 cjones
183
          // set the new policy
184
          systemMetadata.setReplicationPolicy(policy);
185
186
          // update the metadata
187
          try {
188
              systemMetadata.setSerialVersion(systemMetadata.getSerialVersion().add(BigInteger.ONE));
189
              systemMetadata.setDateSysMetadataModified(Calendar.getInstance().getTime());
190
              HazelcastService.getInstance().getSystemMetadataMap().put(systemMetadata.getIdentifier(), systemMetadata);
191 7076 cjones
              notifyReplicaNodes(systemMetadata);
192
193 6869 cjones
          } catch (RuntimeException e) {
194 6858 cjones
              throw new ServiceFailure("4882", e.getMessage());
195
196 6593 cjones
          }
197
198 6869 cjones
      } catch (RuntimeException e) {
199
          throw new ServiceFailure("4882", e.getMessage());
200
201
      } finally {
202
          lock.unlock();
203
          logMetacat.debug("Unlocked identifier " + pid.getValue());
204
205
      }
206 6410 cjones
207 6567 cjones
      return true;
208 6410 cjones
  }
209 6177 cjones
210 6410 cjones
  /**
211 6881 leinfelder
   * Deletes the replica from the given Member Node
212
   * NOTE: MN.delete() may be an "archive" operation. TBD.
213
   * @param session
214
   * @param pid
215
   * @param nodeId
216
   * @param serialVersion
217
   * @return
218
   * @throws InvalidToken
219
   * @throws ServiceFailure
220
   * @throws NotAuthorized
221
   * @throws NotFound
222
   * @throws NotImplemented
223 6883 leinfelder
   * @throws VersionMismatch
224 6881 leinfelder
   */
225 6884 leinfelder
  @Override
226 6881 leinfelder
  public boolean deleteReplicationMetadata(Session session, Identifier pid, NodeReference nodeId, long serialVersion)
227 6883 leinfelder
  	throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented, VersionMismatch {
228 6881 leinfelder
229 6883 leinfelder
	  	// The lock to be used for this identifier
230
		Lock lock = null;
231
232
		// get the subject
233
		Subject subject = session.getSubject();
234
235
		// are we allowed to do this?
236 7068 cjones
		boolean isAuthorized = false;
237
		try {
238
			isAuthorized = isAuthorized(session, pid, Permission.WRITE);
239
		} catch (InvalidRequest e) {
240
			throw new ServiceFailure("4882", e.getDescription());
241
		}
242
		if (!isAuthorized) {
243
			throw new NotAuthorized("4881", Permission.WRITE
244
					+ " not allowed by " + subject.getValue() + " on "
245
					+ pid.getValue());
246 6883 leinfelder
247
		}
248
249
		SystemMetadata systemMetadata = null;
250
		try {
251
			lock = HazelcastService.getInstance().getLock(pid.getValue());
252
			lock.lock();
253
			logMetacat.debug("Locked identifier " + pid.getValue());
254
255
			try {
256
				if (HazelcastService.getInstance().getSystemMetadataMap().containsKey(pid)) {
257
					systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
258
				}
259
260
				// did we get it correctly?
261
				if (systemMetadata == null) {
262
					throw new NotFound("4884", "Couldn't find an object identified by " + pid.getValue());
263
				}
264
265
				// does the request have the most current system metadata?
266
				if (systemMetadata.getSerialVersion().longValue() != serialVersion) {
267
					String msg = "The requested system metadata version number "
268
							+ serialVersion
269
							+ " differs from the current version at "
270
							+ systemMetadata.getSerialVersion().longValue()
271
							+ ". Please get the latest copy in order to modify it.";
272
					throw new VersionMismatch("4886", msg);
273
274
				}
275
276
			} catch (RuntimeException e) { // Catch is generic since HZ throws RuntimeException
277
				throw new NotFound("4884", "No record found for: " + pid.getValue());
278
279
			}
280
281
			// check permissions
282
			// TODO: is this necessary?
283
			List<Node> nodeList = D1Client.getCN().listNodes().getNodeList();
284
			boolean isAllowed = ServiceMethodRestrictionUtil.isMethodAllowed(session.getSubject(), nodeList, "CNReplication", "deleteReplicationMetadata");
285 7218 cjones
			if (!isAllowed) {
286 6883 leinfelder
				throw new NotAuthorized("4881", "Caller is not authorized to deleteReplicationMetadata");
287
			}
288
289
			// delete the replica from the given node
290 7252 cjones
			// CSJ: use CN.delete() to truly delete a replica, semantically
291
			// deleteReplicaMetadata() only modifies the sytem metadata entry.
292 7251 cjones
			//D1Client.getMN(nodeId).delete(session, pid);
293 6883 leinfelder
294
			// reflect that change in the system metadata
295
			List<Replica> updatedReplicas = new ArrayList<Replica>(systemMetadata.getReplicaList());
296
			for (Replica r: systemMetadata.getReplicaList()) {
297
				  if (r.getReplicaMemberNode().equals(nodeId)) {
298
					  updatedReplicas.remove(r);
299
					  break;
300
				  }
301
			}
302
			systemMetadata.setReplicaList(updatedReplicas);
303
304
			// update the metadata
305
			try {
306
				systemMetadata.setSerialVersion(systemMetadata.getSerialVersion().add(BigInteger.ONE));
307
				systemMetadata.setDateSysMetadataModified(Calendar.getInstance().getTime());
308
				HazelcastService.getInstance().getSystemMetadataMap().put(systemMetadata.getIdentifier(), systemMetadata);
309
			} catch (RuntimeException e) {
310
				throw new ServiceFailure("4882", e.getMessage());
311
			}
312
313
		} catch (RuntimeException e) {
314
			throw new ServiceFailure("4882", e.getMessage());
315
		} finally {
316
			lock.unlock();
317
			logMetacat.debug("Unlocked identifier " + pid.getValue());
318
		}
319
320
		return true;
321 6881 leinfelder
322
  }
323
324 6883 leinfelder
  /**
325 7077 leinfelder
   * Deletes an object from the Coordinating Node, where the object is a
326
   * a science metadata object.
327
   *
328
   * @param session - the Session object containing the credentials for the Subject
329
   * @param pid - The object identifier to be deleted
330
   *
331
   * @return pid - the identifier of the object used for the deletion
332
   *
333
   * @throws InvalidToken
334
   * @throws ServiceFailure
335
   * @throws NotAuthorized
336
   * @throws NotFound
337
   * @throws NotImplemented
338
   * @throws InvalidRequest
339
   */
340
  @Override
341
  public Identifier delete(Session session, Identifier pid)
342
      throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented {
343
344 7078 leinfelder
	  // check that it is CN/admin
345 7142 leinfelder
	  boolean allowed = isAdminAuthorized(session);
346 7077 leinfelder
347 7078 leinfelder
	  if (!allowed) {
348
		  String msg = "The subject is not allowed to call delete() on a Coordinating Node.";
349
		  logMetacat.info(msg);
350
		  throw new NotAuthorized("1320", msg);
351
	  }
352
353 7077 leinfelder
	  // defer to superclass implementation
354 7147 leinfelder
	  Identifier retId =  super.delete(session, pid);
355
356
	  // notify the replicas
357
	  SystemMetadata systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
358
	  if (systemMetadata.getReplicaList() != null) {
359
		  for (Replica replica: systemMetadata.getReplicaList()) {
360
			  NodeReference replicaNode = replica.getReplicaMemberNode();
361
			  try {
362
				  Identifier mnRetId = D1Client.getMN(replicaNode).delete(null, pid);
363
			  } catch (Exception e) {
364
				  // all we can really do is log errors and carry on with life
365
				  logMetacat.error("Error deleting pid: " +  pid.getValue() + " from replica MN: " + replicaNode.getValue(), e);
366
			}
367
368
		  }
369
	  }
370
371
	  return retId;
372
373 7077 leinfelder
  }
374
375
  /**
376 7148 leinfelder
   * Deletes an object from the Coordinating Node, where the object is a
377
   * a science metadata object.
378
   *
379
   * @param session - the Session object containing the credentials for the Subject
380
   * @param pid - The object identifier to be deleted
381
   *
382
   * @return pid - the identifier of the object used for the deletion
383
   *
384
   * @throws InvalidToken
385
   * @throws ServiceFailure
386
   * @throws NotAuthorized
387
   * @throws NotFound
388
   * @throws NotImplemented
389
   * @throws InvalidRequest
390
   */
391
  @Override
392
  public Identifier archive(Session session, Identifier pid)
393
      throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented {
394
395
	  // check that it is CN/admin
396
	  boolean allowed = isAdminAuthorized(session);
397
398
	  if (!allowed) {
399
		  String msg = "The subject is not allowed to call delete() on a Coordinating Node.";
400
		  logMetacat.info(msg);
401
		  throw new NotAuthorized("1320", msg);
402
	  }
403
404
	  // defer to superclass implementation
405
	  Identifier retId =  super.archive(session, pid);
406
407
	  // notify the replicas
408
	  SystemMetadata systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
409
	  if (systemMetadata.getReplicaList() != null) {
410
		  for (Replica replica: systemMetadata.getReplicaList()) {
411
			  NodeReference replicaNode = replica.getReplicaMemberNode();
412
			  try {
413
				  // TODO: implement in the clients
414
				  //Identifier mnRetId = D1Client.getMN(replicaNode).archive(null, pid);
415
			  } catch (Exception e) {
416
				  // all we can really do is log errors and carry on with life
417
				  logMetacat.error("Error archiving pid: " +  pid.getValue() + " from replica MN: " + replicaNode.getValue(), e);
418
			}
419
420
		  }
421
	  }
422
423
	  return retId;
424
425
  }
426
427
  /**
428 6883 leinfelder
   * Set the obsoletedBy attribute in System Metadata
429
   * @param session
430
   * @param pid
431
   * @param obsoletedByPid
432
   * @param serialVersion
433
   * @return
434
   * @throws NotImplemented
435
   * @throws NotFound
436
   * @throws NotAuthorized
437
   * @throws ServiceFailure
438
   * @throws InvalidRequest
439
   * @throws InvalidToken
440
   * @throws VersionMismatch
441
   */
442 6884 leinfelder
  @Override
443 6883 leinfelder
  public boolean setObsoletedBy(Session session, Identifier pid,
444
			Identifier obsoletedByPid, long serialVersion)
445
			throws NotImplemented, NotFound, NotAuthorized, ServiceFailure,
446
			InvalidRequest, InvalidToken, VersionMismatch {
447
448
		// The lock to be used for this identifier
449
		Lock lock = null;
450
451
		// get the subject
452
		Subject subject = session.getSubject();
453
454
		// are we allowed to do this?
455 7068 cjones
		if (!isAuthorized(session, pid, Permission.WRITE)) {
456
			throw new NotAuthorized("4881", Permission.WRITE
457
					+ " not allowed by " + subject.getValue() + " on "
458
					+ pid.getValue());
459 6883 leinfelder
460
		}
461
462 7068 cjones
463 6883 leinfelder
		SystemMetadata systemMetadata = null;
464
		try {
465
			lock = HazelcastService.getInstance().getLock(pid.getValue());
466
			lock.lock();
467
			logMetacat.debug("Locked identifier " + pid.getValue());
468
469
			try {
470
				if (HazelcastService.getInstance().getSystemMetadataMap().containsKey(pid)) {
471
					systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
472
				}
473
474
				// did we get it correctly?
475
				if (systemMetadata == null) {
476
					throw new NotFound("4884", "Couldn't find an object identified by " + pid.getValue());
477
				}
478
479
				// does the request have the most current system metadata?
480
				if (systemMetadata.getSerialVersion().longValue() != serialVersion) {
481
					String msg = "The requested system metadata version number "
482
							+ serialVersion
483
							+ " differs from the current version at "
484
							+ systemMetadata.getSerialVersion().longValue()
485
							+ ". Please get the latest copy in order to modify it.";
486
					throw new VersionMismatch("4886", msg);
487
488
				}
489
490
			} catch (RuntimeException e) { // Catch is generic since HZ throws RuntimeException
491
				throw new NotFound("4884", "No record found for: " + pid.getValue());
492
493
			}
494
495
			// set the new policy
496
			systemMetadata.setObsoletedBy(obsoletedByPid);
497
498
			// update the metadata
499
			try {
500
				systemMetadata.setSerialVersion(systemMetadata.getSerialVersion().add(BigInteger.ONE));
501
				systemMetadata.setDateSysMetadataModified(Calendar.getInstance().getTime());
502
				HazelcastService.getInstance().getSystemMetadataMap().put(systemMetadata.getIdentifier(), systemMetadata);
503
			} catch (RuntimeException e) {
504
				throw new ServiceFailure("4882", e.getMessage());
505
			}
506
507
		} catch (RuntimeException e) {
508
			throw new ServiceFailure("4882", e.getMessage());
509
		} finally {
510
			lock.unlock();
511
			logMetacat.debug("Unlocked identifier " + pid.getValue());
512
		}
513
514
		return true;
515
	}
516 6881 leinfelder
517 6883 leinfelder
518 6881 leinfelder
  /**
519 6410 cjones
   * Set the replication status for an object given the object identifier
520
   *
521
   * @param session - the Session object containing the credentials for the Subject
522
   * @param pid - the object identifier for the given object
523
   * @param status - the replication status to be applied
524
   *
525
   * @return true or false
526
   *
527
   * @throws NotImplemented
528
   * @throws NotAuthorized
529
   * @throws ServiceFailure
530
   * @throws InvalidRequest
531
   * @throws InvalidToken
532
   * @throws NotFound
533
   *
534
   */
535 6471 jones
  @Override
536 6410 cjones
  public boolean setReplicationStatus(Session session, Identifier pid,
537 6792 cjones
      NodeReference targetNode, ReplicationStatus status, BaseException failure)
538 6644 cjones
      throws ServiceFailure, NotImplemented, InvalidToken, NotAuthorized,
539
      InvalidRequest, NotFound {
540 7066 leinfelder
541
	  // cannot be called by public
542
	  if (session == null) {
543
		  throw new NotAuthorized("4720", "Session cannot be null");
544
	  }
545 6644 cjones
546 6702 cjones
      // The lock to be used for this identifier
547 6859 cjones
      Lock lock = null;
548 6702 cjones
549 6644 cjones
      boolean allowed = false;
550
      int replicaEntryIndex = -1;
551
      List<Replica> replicas = null;
552
      // get the subject
553
      Subject subject = session.getSubject();
554 6676 cjones
      logMetacat.debug("ReplicationStatus for identifier " + pid.getValue() +
555
          " is " + status.toString());
556 6644 cjones
557
      SystemMetadata systemMetadata = null;
558 6858 cjones
559
      try {
560 6703 cjones
          lock = HazelcastService.getInstance().getLock(pid.getValue());
561 6702 cjones
          lock.lock();
562 6867 cjones
          logMetacat.debug("Locked identifier " + pid.getValue());
563
564 6858 cjones
          try {
565
              systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
566 6657 cjones
567 6869 cjones
              // did we get it correctly?
568 6858 cjones
              if ( systemMetadata == null ) {
569
                  logMetacat.debug("systemMetadata is null for " + pid.getValue());
570 6869 cjones
                  throw new NotFound("4740", "Couldn't find an object identified by " + pid.getValue());
571 6858 cjones
572
              }
573
              replicas = systemMetadata.getReplicaList();
574
              int count = 0;
575 6657 cjones
576 6876 cjones
              // was there a failure? log it
577
              if ( failure != null && status == ReplicationStatus.FAILED ) {
578
                 String msg = "The replication request of the object identified by " +
579
                     pid.getValue() + " failed.  The error message was " +
580
                     failure.getMessage() + ".";
581 6858 cjones
              }
582 6869 cjones
583 6876 cjones
              if (replicas.size() > 0 && replicas != null) {
584
                  // find the target replica index in the replica list
585
                  for (Replica replica : replicas) {
586
                      String replicaNodeStr = replica.getReplicaMemberNode()
587
                              .getValue();
588
                      String targetNodeStr = targetNode.getValue();
589
                      logMetacat.debug("Comparing " + replicaNodeStr + " to "
590
                              + targetNodeStr);
591 6869 cjones
592 6876 cjones
                      if (replicaNodeStr.equals(targetNodeStr)) {
593
                          replicaEntryIndex = count;
594
                          logMetacat.debug("replica entry index is: "
595
                                  + replicaEntryIndex);
596
                          break;
597
                      }
598
                      count++;
599 6858 cjones
600
                  }
601
              }
602
              // are we allowed to do this? only CNs and target MNs are allowed
603
              CNode cn = D1Client.getCN();
604
              List<Node> nodes = cn.listNodes().getNodeList();
605 6657 cjones
606 6858 cjones
              // find the node in the node list
607
              for ( Node node : nodes ) {
608
609
                  NodeReference nodeReference = node.getIdentifier();
610
                  logMetacat.debug("In setReplicationStatus(), Node reference is: " + nodeReference.getValue());
611
612 7074 cjones
                  // allow target MN certs
613
                  if (targetNode.getValue().equals(nodeReference.getValue()) &&
614 7071 cjones
                      node.getType() == NodeType.MN) {
615 6858 cjones
                      List<Subject> nodeSubjects = node.getSubjectList();
616
617
                      // check if the session subject is in the node subject list
618
                      for (Subject nodeSubject : nodeSubjects) {
619 7071 cjones
                          logMetacat.debug("In setReplicationStatus(), comparing subjects: " +
620
                                  nodeSubject.getValue() + " and " + subject.getValue());
621 7074 cjones
                          if ( nodeSubject.equals(subject) ) { // subject of session == target node subject
622 6858 cjones
623 7179 cjones
                              // lastly limit to COMPLETED, INVALIDATED,
624
                              // and FAILED status updates from MNs only
625 7086 cjones
                              if ( status == ReplicationStatus.COMPLETED ||
626 7179 cjones
                                   status == ReplicationStatus.INVALIDATED ||
627 7086 cjones
                                   status == ReplicationStatus.FAILED) {
628 7074 cjones
                                  allowed = true;
629
                                  break;
630
631
                              }
632 6858 cjones
                          }
633
                      }
634
                  }
635
              }
636 6657 cjones
637 7071 cjones
              if ( !allowed ) {
638
                  //check for CN admin access
639
                  allowed = isAuthorized(session, pid, Permission.WRITE);
640 6858 cjones
641 7071 cjones
              }
642
643
              if ( !allowed ) {
644
                  String msg = "The subject identified by "
645
                          + subject.getValue()
646
                          + " does not have permission to set the replication status for "
647
                          + "the replica identified by "
648
                          + targetNode.getValue() + ".";
649
                  logMetacat.info(msg);
650
                  throw new NotAuthorized("4720", msg);
651
652 6858 cjones
              }
653 6876 cjones
654 6858 cjones
          } catch (RuntimeException e) { // Catch is generic since HZ throws RuntimeException
655
            throw new NotFound("4740", "No record found for: " + pid.getValue() +
656
                " : " + e.getMessage());
657
658 6644 cjones
          }
659
660 6876 cjones
          Replica targetReplica = new Replica();
661 6858 cjones
          // set the status for the replica
662
          if ( replicaEntryIndex != -1 ) {
663 6876 cjones
              targetReplica = replicas.get(replicaEntryIndex);
664 7231 cjones
665
              // don't allow status to change from COMPLETED to anything other
666
              // than INVALIDATED: prevents overwrites from race conditions
667
              if ( targetReplica.getReplicationStatus() == ReplicationStatus.COMPLETED &&
668
            	   status != ReplicationStatus.INVALIDATED) {
669
            	  throw new InvalidRequest("4730", "Status state change from " +
670
            			  targetReplica.getReplicationStatus() + " to " +
671
            			  status.toString() + "is prohibited for identifier " +
672
            			  pid.getValue() + " and target node " +
673
            			  targetReplica.getReplicaMemberNode().getValue());
674
              }
675
676 6858 cjones
              targetReplica.setReplicationStatus(status);
677
              logMetacat.debug("Set the replication status for " +
678
                  targetReplica.getReplicaMemberNode().getValue() + " to " +
679 7231 cjones
                  targetReplica.getReplicationStatus() + " for identifier " +
680
                  pid.getValue());
681 6644 cjones
682 6858 cjones
          } else {
683 6876 cjones
              // this is a new entry, create it
684
              targetReplica.setReplicaMemberNode(targetNode);
685
              targetReplica.setReplicationStatus(status);
686
              targetReplica.setReplicaVerified(Calendar.getInstance().getTime());
687
              replicas.add(targetReplica);
688
689 6644 cjones
          }
690
691 6858 cjones
          systemMetadata.setReplicaList(replicas);
692
693
          // update the metadata
694
          try {
695
              systemMetadata.setSerialVersion(systemMetadata.getSerialVersion().add(BigInteger.ONE));
696
              systemMetadata.setDateSysMetadataModified(Calendar.getInstance().getTime());
697
              HazelcastService.getInstance().getSystemMetadataMap().put(systemMetadata.getIdentifier(), systemMetadata);
698 7179 cjones
699
              if ( status != ReplicationStatus.QUEUED && status != ReplicationStatus.REQUESTED) {
700
701
                logMetacat.trace("METRICS:\tREPLICATION:\tEND REQUEST:\tPID:\t" + pid.getValue() +
702
                          "\tNODE:\t" + targetNode.getValue() +
703
                          "\tSIZE:\t" + systemMetadata.getSize().intValue());
704
705
                logMetacat.trace("METRICS:\tREPLICATION:\t" + status.toString().toUpperCase() +
706
                          "\tPID:\t"  + pid.getValue() +
707
                          "\tNODE:\t" + targetNode.getValue() +
708
                          "\tSIZE:\t" + systemMetadata.getSize().intValue());
709
              }
710
711 6858 cjones
              if ( status == ReplicationStatus.FAILED && failure != null ) {
712
                  logMetacat.warn("Replication failed for identifier " + pid.getValue() +
713
                      " on target node " + targetNode + ". The exception was: " +
714
                      failure.getMessage());
715
              }
716 6869 cjones
          } catch (RuntimeException e) {
717 6858 cjones
              throw new ServiceFailure("4700", e.getMessage());
718
719 6644 cjones
          }
720
721 6867 cjones
    } catch (RuntimeException e) {
722
        String msg = "There was a RuntimeException getting the lock for " +
723
            pid.getValue();
724
        logMetacat.info(msg);
725
726
    } finally {
727 6858 cjones
        lock.unlock();
728
        logMetacat.debug("Unlocked identifier " + pid.getValue());
729 6593 cjones
730 6858 cjones
    }
731 6676 cjones
732 6644 cjones
      return true;
733 6410 cjones
  }
734
735
  /**
736
   * Return the checksum of the object given the identifier
737
   *
738
   * @param session - the Session object containing the credentials for the Subject
739
   * @param pid - the object identifier for the given object
740
   *
741
   * @return checksum - the checksum of the object
742
   *
743
   * @throws InvalidToken
744
   * @throws ServiceFailure
745
   * @throws NotAuthorized
746
   * @throws NotFound
747
   * @throws NotImplemented
748
   */
749 6471 jones
  @Override
750 6410 cjones
  public Checksum getChecksum(Session session, Identifier pid)
751
    throws InvalidToken, ServiceFailure, NotAuthorized, NotFound,
752 6622 leinfelder
    NotImplemented {
753 7029 leinfelder
754
	boolean isAuthorized = false;
755
	try {
756
		isAuthorized = isAuthorized(session, pid, Permission.READ);
757
	} catch (InvalidRequest e) {
758
		throw new ServiceFailure("1410", e.getDescription());
759
	}
760
    if (!isAuthorized) {
761 6568 cjones
        throw new NotAuthorized("1400", Permission.READ + " not allowed on " + pid.getValue());
762 6410 cjones
    }
763 6568 cjones
764 6410 cjones
    SystemMetadata systemMetadata = null;
765 6568 cjones
    Checksum checksum = null;
766
767 6410 cjones
    try {
768 6869 cjones
        systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
769
770
        if (systemMetadata == null ) {
771
            throw new NotFound("1420", "Couldn't find an object identified by " + pid.getValue());
772
        }
773 6568 cjones
        checksum = systemMetadata.getChecksum();
774 6869 cjones
775
    } catch (RuntimeException e) {
776 6568 cjones
        throw new ServiceFailure("1410", "An error occurred getting the checksum for " +
777
            pid.getValue() + ". The error message was: " + e.getMessage());
778
779 6410 cjones
    }
780
781
    return checksum;
782
  }
783 6177 cjones
784 6410 cjones
  /**
785
   * Resolve the location of a given object
786
   *
787
   * @param session - the Session object containing the credentials for the Subject
788
   * @param pid - the object identifier for the given object
789
   *
790
   * @return objectLocationList - the list of nodes known to contain the object
791
   *
792
   * @throws InvalidToken
793
   * @throws ServiceFailure
794
   * @throws NotAuthorized
795
   * @throws NotFound
796
   * @throws NotImplemented
797
   */
798 6471 jones
  @Override
799 6410 cjones
  public ObjectLocationList resolve(Session session, Identifier pid)
800 6622 leinfelder
    throws InvalidToken, ServiceFailure, NotAuthorized,
801 6410 cjones
    NotFound, NotImplemented {
802 6177 cjones
803 6410 cjones
    throw new NotImplemented("4131", "resolve not implemented");
804 6303 leinfelder
805 6410 cjones
  }
806 6177 cjones
807 6410 cjones
  /**
808
   * Search the metadata catalog for identifiers that match the criteria
809
   *
810
   * @param session - the Session object containing the credentials for the Subject
811
   * @param queryType - An identifier for the type of query expression
812
   *                    provided in the query
813
   * @param query -  The criteria for matching the characteristics of the
814
   *                 metadata objects of interest
815
   *
816
   * @return objectList - the list of objects matching the criteria
817
   *
818
   * @throws InvalidToken
819
   * @throws ServiceFailure
820
   * @throws NotAuthorized
821
   * @throws InvalidRequest
822
   * @throws NotImplemented
823
   */
824 6471 jones
  @Override
825 6410 cjones
  public ObjectList search(Session session, String queryType, String query)
826
    throws InvalidToken, ServiceFailure, NotAuthorized, InvalidRequest,
827
    NotImplemented {
828 6177 cjones
829 6410 cjones
    ObjectList objectList = null;
830
    try {
831
        objectList =
832
          IdentifierManager.getInstance().querySystemMetadata(
833
              null, //startTime,
834
              null, //endTime,
835
              null, //objectFormat,
836
              false, //replicaStatus,
837
              0, //start,
838
              -1 //count
839
              );
840
841
    } catch (Exception e) {
842
      throw new ServiceFailure("4310", "Error querying system metadata: " + e.getMessage());
843
    }
844 6300 leinfelder
845 6410 cjones
      return objectList;
846
847
    //throw new NotImplemented("4281", "search not implemented");
848
849
    // the code block below is from an older implementation
850
851
    /*  This block commented out because of the EcoGrid circular dependency.
852 6281 leinfelder
         *  For now, query will not be supported until the circularity can be
853
         *  resolved, probably by moving the ecogrid query syntax transformers
854
         *  directly into the Metacat codebase.  MBJ 2010-02-03
855
856
        try {
857
            EcogridQueryParser parser = new EcogridQueryParser(request
858
                    .getReader());
859
            parser.parseXML();
860
            QueryType queryType = parser.getEcogridQuery();
861
            EcogridJavaToMetacatJavaQueryTransformer queryTransformer =
862
                new EcogridJavaToMetacatJavaQueryTransformer();
863
            QuerySpecification metacatQuery = queryTransformer
864
                    .transform(queryType);
865 6223 leinfelder
866 6281 leinfelder
            DBQuery metacat = new DBQuery();
867
868
            boolean useXMLIndex = (new Boolean(PropertyService
869
                    .getProperty("database.usexmlindex"))).booleanValue();
870
            String xmlquery = "query"; // we don't care the query in resultset,
871
            // the query can be anything
872
            PrintWriter out = null; // we don't want metacat result, so set out null
873
874
            // parameter: queryspecification, user, group, usingIndexOrNot
875
            StringBuffer result = metacat.createResultDocument(xmlquery,
876
                    metacatQuery, out, username, groupNames, useXMLIndex);
877
878
            // create result set transfer
879
            String saxparser = PropertyService.getProperty("xml.saxparser");
880
            MetacatResultsetParser metacatResultsetParser = new MetacatResultsetParser(
881
                    new StringReader(result.toString()), saxparser, queryType
882
                            .getNamespace().get_value());
883
            ResultsetType records = metacatResultsetParser.getEcogridResult();
884
885
            System.out
886
                    .println(EcogridResultsetTransformer.toXMLString(records));
887
            response.setContentType("text/xml");
888
            out = response.getWriter();
889
            out.print(EcogridResultsetTransformer.toXMLString(records));
890
891
        } catch (Exception e) {
892
            e.printStackTrace();
893
        }*/
894 6410 cjones
895 6281 leinfelder
896 6410 cjones
  }
897
898
  /**
899
   * Returns the object format registered in the DataONE Object Format
900
   * Vocabulary for the given format identifier
901
   *
902
   * @param fmtid - the identifier of the format requested
903
   *
904
   * @return objectFormat - the object format requested
905
   *
906
   * @throws ServiceFailure
907
   * @throws NotFound
908
   * @throws InsufficientResources
909
   * @throws NotImplemented
910
   */
911 6471 jones
  @Override
912 6410 cjones
  public ObjectFormat getFormat(ObjectFormatIdentifier fmtid)
913 6803 leinfelder
    throws ServiceFailure, NotFound, NotImplemented {
914 6410 cjones
915
      return ObjectFormatService.getInstance().getFormat(fmtid);
916
917
  }
918 6177 cjones
919 6410 cjones
  /**
920 6177 cjones
   * Returns a list of all object formats registered in the DataONE Object
921
   * Format Vocabulary
922 6410 cjones
    *
923
   * @return objectFormatList - The list of object formats registered in
924
   *                            the DataONE Object Format Vocabulary
925
   *
926
   * @throws ServiceFailure
927
   * @throws NotImplemented
928
   * @throws InsufficientResources
929
   */
930 6471 jones
  @Override
931 6410 cjones
  public ObjectFormatList listFormats()
932 6803 leinfelder
    throws ServiceFailure, NotImplemented {
933 6177 cjones
934 6410 cjones
    return ObjectFormatService.getInstance().listFormats();
935
  }
936 6177 cjones
937 6410 cjones
  /**
938 6177 cjones
   * Returns a list of nodes that have been registered with the DataONE infrastructure
939 6410 cjones
    *
940
   * @return nodeList - List of nodes from the registry
941
   *
942
   * @throws ServiceFailure
943
   * @throws NotImplemented
944
   */
945 6471 jones
  @Override
946 6410 cjones
  public NodeList listNodes()
947
    throws NotImplemented, ServiceFailure {
948 6177 cjones
949 6410 cjones
    throw new NotImplemented("4800", "listNodes not implemented");
950
  }
951 6177 cjones
952 6410 cjones
  /**
953 6177 cjones
   * Provides a mechanism for adding system metadata independently of its
954
   * associated object, such as when adding system metadata for data objects.
955 6410 cjones
    *
956
   * @param session - the Session object containing the credentials for the Subject
957
   * @param pid - The identifier of the object to register the system metadata against
958
   * @param sysmeta - The system metadata to be registered
959
   *
960
   * @return true if the registration succeeds
961
   *
962
   * @throws NotImplemented
963
   * @throws NotAuthorized
964
   * @throws ServiceFailure
965
   * @throws InvalidRequest
966
   * @throws InvalidSystemMetadata
967
   */
968 6471 jones
  @Override
969 6575 cjones
  public Identifier registerSystemMetadata(Session session, Identifier pid,
970
      SystemMetadata sysmeta)
971
      throws NotImplemented, NotAuthorized, ServiceFailure, InvalidRequest,
972
      InvalidSystemMetadata {
973 6177 cjones
974 6702 cjones
      // The lock to be used for this identifier
975 6859 cjones
      Lock lock = null;
976 6702 cjones
977 6575 cjones
      // TODO: control who can call this?
978
      if (session == null) {
979
          //TODO: many of the thrown exceptions do not use the correct error codes
980
          //check these against the docs and correct them
981
          throw new NotAuthorized("4861", "No Session - could not authorize for registration." +
982
                  "  If you are not logged in, please do so and retry the request.");
983
      }
984
985
      // verify that guid == SystemMetadata.getIdentifier()
986
      logMetacat.debug("Comparing guid|sysmeta_guid: " + pid.getValue() +
987
          "|" + sysmeta.getIdentifier().getValue());
988
      if (!pid.getValue().equals(sysmeta.getIdentifier().getValue())) {
989
          throw new InvalidRequest("4863",
990
              "The identifier in method call (" + pid.getValue() +
991
              ") does not match identifier in system metadata (" +
992
              sysmeta.getIdentifier().getValue() + ").");
993
      }
994 6188 leinfelder
995 6575 cjones
      try {
996 6703 cjones
          lock = HazelcastService.getInstance().getLock(sysmeta.getIdentifier().getValue());
997 6863 cjones
          lock.lock();
998 6867 cjones
          logMetacat.debug("Locked identifier " + pid.getValue());
999 6863 cjones
          logMetacat.debug("Checking if identifier exists...");
1000
          // Check that the identifier does not already exist
1001
          if (HazelcastService.getInstance().getSystemMetadataMap().containsKey(pid)) {
1002
              throw new InvalidRequest("4863",
1003
                  "The identifier is already in use by an existing object.");
1004 6575 cjones
1005 6863 cjones
          }
1006
1007
          // insert the system metadata into the object store
1008
          logMetacat.debug("Starting to insert SystemMetadata...");
1009
          try {
1010
              sysmeta.setSerialVersion(BigInteger.ONE);
1011
              sysmeta.setDateSysMetadataModified(Calendar.getInstance().getTime());
1012
              HazelcastService.getInstance().getSystemMetadataMap().put(sysmeta.getIdentifier(), sysmeta);
1013
1014 6869 cjones
          } catch (RuntimeException e) {
1015 6863 cjones
            logMetacat.error("Problem registering system metadata: " + pid.getValue(), e);
1016
              throw new ServiceFailure("4862", "Error inserting system metadata: " +
1017
                  e.getClass() + ": " + e.getMessage());
1018
1019
          }
1020
1021 6869 cjones
      } catch (RuntimeException e) {
1022 6575 cjones
          throw new ServiceFailure("4862", "Error inserting system metadata: " +
1023 6863 cjones
                  e.getClass() + ": " + e.getMessage());
1024 6575 cjones
1025 6863 cjones
      }  finally {
1026
          lock.unlock();
1027
          logMetacat.debug("Unlocked identifier " + pid.getValue());
1028
1029
      }
1030 6466 cjones
1031 6575 cjones
1032
      logMetacat.debug("Returning from registerSystemMetadata");
1033
      EventLog.getInstance().log(request.getRemoteAddr(),
1034
          request.getHeader("User-Agent"), session.getSubject().getValue(),
1035
          pid.getValue(), "registerSystemMetadata");
1036
      return pid;
1037 6410 cjones
  }
1038
1039
  /**
1040 6177 cjones
   * Given an optional scope and format, reserves and returns an identifier
1041
   * within that scope and format that is unique and will not be
1042
   * used by any other sessions.
1043 6410 cjones
    *
1044
   * @param session - the Session object containing the credentials for the Subject
1045
   * @param pid - The identifier of the object to register the system metadata against
1046
   * @param scope - An optional string to be used to qualify the scope of
1047
   *                the identifier namespace, which is applied differently
1048
   *                depending on the format requested. If scope is not
1049
   *                supplied, a default scope will be used.
1050
   * @param format - The optional name of the identifier format to be used,
1051
   *                  drawn from a DataONE-specific vocabulary of identifier
1052
   *                 format names, including several common syntaxes such
1053
   *                 as DOI, LSID, UUID, and LSRN, among others. If the
1054
   *                 format is not supplied by the caller, the CN service
1055
   *                 will use a default identifier format, which may change
1056
   *                 over time.
1057
   *
1058
   * @return true if the registration succeeds
1059
   *
1060
   * @throws InvalidToken
1061
   * @throws ServiceFailure
1062
   * @throws NotAuthorized
1063
   * @throws IdentifierNotUnique
1064
   * @throws NotImplemented
1065
   */
1066 6471 jones
  @Override
1067 6622 leinfelder
  public Identifier reserveIdentifier(Session session, Identifier pid)
1068 6410 cjones
  throws InvalidToken, ServiceFailure,
1069 6378 leinfelder
        NotAuthorized, IdentifierNotUnique, NotImplemented, InvalidRequest {
1070 6177 cjones
1071 6410 cjones
    throw new NotImplemented("4191", "reserveIdentifier not implemented on this node");
1072
  }
1073
1074 6471 jones
  @Override
1075 6410 cjones
  public Identifier generateIdentifier(Session session, String scheme, String fragment)
1076
  throws InvalidToken, ServiceFailure,
1077 6378 leinfelder
        NotAuthorized, NotImplemented, InvalidRequest {
1078 6410 cjones
    throw new NotImplemented("4191", "generateIdentifier not implemented on this node");
1079
  }
1080
1081
  /**
1082
    * Checks whether the pid is reserved by the subject in the session param
1083
    * If the reservation is held on the pid by the subject, we return true.
1084
    *
1085
   * @param session - the Session object containing the Subject
1086
   * @param pid - The identifier to check
1087
   *
1088
   * @return true if the reservation exists for the subject/pid
1089
   *
1090
   * @throws InvalidToken
1091
   * @throws ServiceFailure
1092
   * @throws NotFound - when the pid is not found (in use or in reservation)
1093
   * @throws NotAuthorized - when the subject does not hold a reservation on the pid
1094
   * @throws IdentifierNotUnique - when the pid is in use
1095
   * @throws NotImplemented
1096
   */
1097 6177 cjones
1098 6471 jones
  @Override
1099 6934 leinfelder
  public boolean hasReservation(Session session, Subject subject, Identifier pid)
1100 6410 cjones
      throws InvalidToken, ServiceFailure, NotFound, NotAuthorized, IdentifierNotUnique,
1101
      NotImplemented, InvalidRequest {
1102
1103
      throw new NotImplemented("4191", "hasReservation not implemented on this node");
1104
  }
1105 6339 leinfelder
1106 6410 cjones
  /**
1107 6177 cjones
   * Changes ownership (RightsHolder) of the specified object to the
1108
   * subject specified by userId
1109 6410 cjones
    *
1110
   * @param session - the Session object containing the credentials for the Subject
1111
   * @param pid - Identifier of the object to be modified
1112
   * @param userId - The subject that will be taking ownership of the specified object.
1113
   *
1114
   * @return pid - the identifier of the modified object
1115
   *
1116
   * @throws ServiceFailure
1117
   * @throws InvalidToken
1118
   * @throws NotFound
1119
   * @throws NotAuthorized
1120
   * @throws NotImplemented
1121
   * @throws InvalidRequest
1122
   */
1123 6471 jones
  @Override
1124 6803 leinfelder
  public Identifier setRightsHolder(Session session, Identifier pid, Subject userId,
1125 6593 cjones
      long serialVersion)
1126
      throws InvalidToken, ServiceFailure, NotFound, NotAuthorized,
1127 6869 cjones
      NotImplemented, InvalidRequest, VersionMismatch {
1128 6593 cjones
1129 6702 cjones
      // The lock to be used for this identifier
1130 6859 cjones
      Lock lock = null;
1131 6702 cjones
1132 6593 cjones
      // get the subject
1133
      Subject subject = session.getSubject();
1134
1135
      // are we allowed to do this?
1136 7068 cjones
      if (!isAuthorized(session, pid, Permission.CHANGE_PERMISSION)) {
1137
          throw new NotAuthorized("4440", "not allowed by "
1138
                  + subject.getValue() + " on " + pid.getValue());
1139
1140 6869 cjones
      }
1141
1142
      SystemMetadata systemMetadata = null;
1143 6593 cjones
      try {
1144 6703 cjones
          lock = HazelcastService.getInstance().getLock(pid.getValue());
1145 6867 cjones
          logMetacat.debug("Locked identifier " + pid.getValue());
1146
1147 6858 cjones
          try {
1148
              systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
1149
1150
              // does the request have the most current system metadata?
1151
              if ( systemMetadata.getSerialVersion().longValue() != serialVersion ) {
1152
                 String msg = "The requested system metadata version number " +
1153
                     serialVersion + " differs from the current version at " +
1154
                     systemMetadata.getSerialVersion().longValue() +
1155
                     ". Please get the latest copy in order to modify it.";
1156 6869 cjones
                 throw new VersionMismatch("4443", msg);
1157 6858 cjones
              }
1158
1159 6869 cjones
          } catch (RuntimeException e) { // Catch is generic since HZ throws RuntimeException
1160 6858 cjones
              throw new NotFound("4460", "No record found for: " + pid.getValue());
1161
1162 6593 cjones
          }
1163 6858 cjones
1164
          // set the new rights holder
1165
          systemMetadata.setRightsHolder(userId);
1166 6593 cjones
1167 6858 cjones
          // update the metadata
1168
          try {
1169
              systemMetadata.setSerialVersion(systemMetadata.getSerialVersion().add(BigInteger.ONE));
1170
              systemMetadata.setDateSysMetadataModified(Calendar.getInstance().getTime());
1171
              HazelcastService.getInstance().getSystemMetadataMap().put(pid, systemMetadata);
1172 7076 cjones
              notifyReplicaNodes(systemMetadata);
1173 6858 cjones
1174 6869 cjones
          } catch (RuntimeException e) {
1175
              throw new ServiceFailure("4490", e.getMessage());
1176 6593 cjones
1177 6858 cjones
          }
1178 6593 cjones
1179 6869 cjones
      } catch (RuntimeException e) {
1180 6858 cjones
          throw new ServiceFailure("4490", e.getMessage());
1181 6644 cjones
1182
      } finally {
1183 6702 cjones
          lock.unlock();
1184 6717 cjones
          logMetacat.debug("Unlocked identifier " + pid.getValue());
1185 6858 cjones
1186 6644 cjones
      }
1187
1188 6869 cjones
      return pid;
1189 6410 cjones
  }
1190 6177 cjones
1191 6410 cjones
  /**
1192
   * Verify that a replication task is authorized by comparing the target node's
1193
   * Subject (from the X.509 certificate-derived Session) with the list of
1194
   * subjects in the known, pending replication tasks map.
1195
   *
1196
   * @param originatingNodeSession - Session information that contains the
1197
   *                                 identity of the calling user
1198
   * @param targetNodeSubject - Subject identifying the target node
1199
   * @param pid - the identifier of the object to be replicated
1200
   * @param replicatePermission - the execute permission to be granted
1201
   *
1202
   * @throws ServiceFailure
1203
   * @throws NotImplemented
1204
   * @throws InvalidToken
1205
   * @throws NotAuthorized
1206
   * @throws InvalidRequest
1207
   * @throws NotFound
1208
   */
1209 6471 jones
  @Override
1210 6409 cjones
  public boolean isNodeAuthorized(Session originatingNodeSession,
1211 6777 leinfelder
    Subject targetNodeSubject, Identifier pid)
1212 6410 cjones
    throws NotImplemented, NotAuthorized, InvalidToken, ServiceFailure,
1213
    NotFound, InvalidRequest {
1214 6702 cjones
1215 6644 cjones
    boolean isAllowed = false;
1216
    SystemMetadata sysmeta = null;
1217 6463 cjones
    NodeReference targetNode = null;
1218
1219 6644 cjones
    try {
1220
      // get the target node reference from the nodes list
1221
      CNode cn = D1Client.getCN();
1222
      List<Node> nodes = cn.listNodes().getNodeList();
1223 6665 cjones
1224 6657 cjones
      if ( nodes != null ) {
1225
        for (Node node : nodes) {
1226 6665 cjones
1227 7141 leinfelder
        	if (node.getSubjectList() != null) {
1228
1229
	            for (Subject nodeSubject : node.getSubjectList()) {
1230
1231
	                if ( nodeSubject.equals(targetNodeSubject) ) {
1232
	                    targetNode = node.getIdentifier();
1233
	                    logMetacat.debug("targetNode is : " + targetNode.getValue());
1234
	                    break;
1235
	                }
1236
	            }
1237
        	}
1238 6657 cjones
1239 6665 cjones
            if ( targetNode != null) { break; }
1240 6657 cjones
        }
1241
1242
      } else {
1243
          String msg = "Couldn't get the node list from the CN";
1244
          logMetacat.debug(msg);
1245
          throw new ServiceFailure("4872", msg);
1246
1247 6644 cjones
      }
1248 6757 cjones
1249
      // can't find a node listed with the given subject
1250
      if ( targetNode == null ) {
1251
          String msg = "There is no Member Node registered with a node subject " +
1252
              "matching " + targetNodeSubject.getValue();
1253
          logMetacat.info(msg);
1254 7062 leinfelder
          throw new NotAuthorized("4871", msg);
1255 6757 cjones
1256
      }
1257
1258 6657 cjones
      logMetacat.debug("Getting system metadata for identifier " + pid.getValue());
1259
1260 6644 cjones
      sysmeta = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
1261 6463 cjones
1262 6657 cjones
      if ( sysmeta != null ) {
1263
1264
          List<Replica> replicaList = sysmeta.getReplicaList();
1265
1266
          if ( replicaList != null ) {
1267
1268
              // find the replica with the status set to 'requested'
1269
              for (Replica replica : replicaList) {
1270
                  ReplicationStatus status = replica.getReplicationStatus();
1271
                  NodeReference listedNode = replica.getReplicaMemberNode();
1272 6757 cjones
                  if ( listedNode != null && targetNode != null ) {
1273
                      logMetacat.debug("Comparing " + listedNode.getValue()
1274
                              + " to " + targetNode.getValue());
1275
1276
                      if (listedNode.getValue().equals(targetNode.getValue())
1277
                              && status.equals(ReplicationStatus.REQUESTED)) {
1278
                          isAllowed = true;
1279
                          break;
1280 6657 cjones
1281 6757 cjones
                      }
1282 6657 cjones
                  }
1283
              }
1284 6568 cjones
          }
1285 6665 cjones
          logMetacat.debug("The " + targetNode.getValue() + " is allowed " +
1286
              "to replicate: " + isAllowed + " for " + pid.getValue());
1287
1288 6657 cjones
1289
      } else {
1290
          logMetacat.debug("System metadata for identifier " + pid.getValue() +
1291
          " is null.");
1292 6869 cjones
          throw new NotFound("4874", "Couldn't find an object identified by " + pid.getValue());
1293 6657 cjones
1294 6568 cjones
      }
1295 6484 cjones
1296 6662 cjones
    } catch (RuntimeException e) {
1297 6665 cjones
    	  ServiceFailure sf = new ServiceFailure("4872",
1298
                "Runtime Exception: Couldn't determine if node is allowed: " +
1299 7140 leinfelder
                e.getMessage());
1300 6665 cjones
    	  sf.initCause(e);
1301 6659 leinfelder
        throw sf;
1302 6636 cjones
1303 6644 cjones
    }
1304
1305
    return isAllowed;
1306 6410 cjones
1307 6384 cjones
  }
1308
1309 6569 cjones
  /**
1310 6570 cjones
   * Adds a new object to the Node, where the object is a science metadata object.
1311 6569 cjones
   *
1312
   * @param session - the Session object containing the credentials for the Subject
1313
   * @param pid - The object identifier to be created
1314
   * @param object - the object bytes
1315
   * @param sysmeta - the system metadata that describes the object
1316
   *
1317
   * @return pid - the object identifier created
1318
   *
1319
   * @throws InvalidToken
1320
   * @throws ServiceFailure
1321
   * @throws NotAuthorized
1322
   * @throws IdentifierNotUnique
1323
   * @throws UnsupportedType
1324
   * @throws InsufficientResources
1325
   * @throws InvalidSystemMetadata
1326
   * @throws NotImplemented
1327
   * @throws InvalidRequest
1328
   */
1329
  public Identifier create(Session session, Identifier pid, InputStream object,
1330
    SystemMetadata sysmeta)
1331
    throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique,
1332
    UnsupportedType, InsufficientResources, InvalidSystemMetadata,
1333
    NotImplemented, InvalidRequest {
1334 6917 cjones
1335 6702 cjones
      // The lock to be used for this identifier
1336 6859 cjones
      Lock lock = null;
1337 6917 cjones
1338 6570 cjones
      try {
1339 6869 cjones
          lock = HazelcastService.getInstance().getLock(pid.getValue());
1340
          // are we allowed?
1341 6570 cjones
          boolean isAllowed = false;
1342 7142 leinfelder
          isAllowed = isAdminAuthorized(session);
1343 6570 cjones
1344
          // proceed if we're called by a CN
1345
          if ( isAllowed ) {
1346
              // create the coordinating node version of the document
1347 6702 cjones
              lock.lock();
1348 6867 cjones
              logMetacat.debug("Locked identifier " + pid.getValue());
1349 6570 cjones
              sysmeta.setSerialVersion(BigInteger.ONE);
1350
              sysmeta.setDateSysMetadataModified(Calendar.getInstance().getTime());
1351 6917 cjones
              sysmeta.setArchived(false); // this is a create op, not update
1352
1353
              // the CN should have set the origin and authoritative member node fields
1354
              try {
1355
                  sysmeta.getOriginMemberNode().getValue();
1356
                  sysmeta.getAuthoritativeMemberNode().getValue();
1357
1358
              } catch (NullPointerException npe) {
1359
                  throw new InvalidSystemMetadata("4896",
1360
                      "Both the origin and authoritative member node identifiers need to be set.");
1361
1362
              }
1363 6570 cjones
              pid = super.create(session, pid, object, sysmeta);
1364
1365
          } else {
1366
              String msg = "The subject listed as " + session.getSubject().getValue() +
1367
                  " isn't allowed to call create() on a Coordinating Node.";
1368
              logMetacat.info(msg);
1369
              throw new NotAuthorized("1100", msg);
1370
          }
1371
1372 6676 cjones
      } catch (RuntimeException e) {
1373 6570 cjones
          // Convert Hazelcast runtime exceptions to service failures
1374
          String msg = "There was a problem creating the object identified by " +
1375
              pid.getValue() + ". There error message was: " + e.getMessage();
1376 6676 cjones
          throw new ServiceFailure("4893", msg);
1377 6570 cjones
1378
      } finally {
1379 6805 leinfelder
    	  if (lock != null) {
1380
	          lock.unlock();
1381
	          logMetacat.debug("Unlocked identifier " + pid.getValue());
1382
    	  }
1383 6570 cjones
      }
1384
1385 6569 cjones
      return pid;
1386
1387
  }
1388
1389 6571 cjones
  /**
1390
   * Set access for a given object using the object identifier and a Subject
1391
   * under a given Session.
1392
   *
1393
   * @param session - the Session object containing the credentials for the Subject
1394
   * @param pid - the object identifier for the given object to apply the policy
1395
   * @param policy - the access policy to be applied
1396
   *
1397
   * @return true if the application of the policy succeeds
1398
   * @throws InvalidToken
1399
   * @throws ServiceFailure
1400
   * @throws NotFound
1401
   * @throws NotAuthorized
1402
   * @throws NotImplemented
1403
   * @throws InvalidRequest
1404
   */
1405
  public boolean setAccessPolicy(Session session, Identifier pid,
1406 6593 cjones
      AccessPolicy accessPolicy, long serialVersion)
1407 6571 cjones
      throws InvalidToken, ServiceFailure, NotFound, NotAuthorized,
1408 6869 cjones
      NotImplemented, InvalidRequest, VersionMismatch {
1409 6571 cjones
1410 6702 cjones
      // The lock to be used for this identifier
1411 6859 cjones
      Lock lock = null;
1412 6869 cjones
      SystemMetadata systemMetadata = null;
1413 6702 cjones
1414 6571 cjones
      boolean success = false;
1415
1416
      // get the subject
1417
      Subject subject = session.getSubject();
1418
1419 7068 cjones
      // are we allowed to do this?
1420
      if (!isAuthorized(session, pid, Permission.CHANGE_PERMISSION)) {
1421
          throw new NotAuthorized("4420", "not allowed by "
1422
                  + subject.getValue() + " on " + pid.getValue());
1423 6571 cjones
      }
1424
1425
      try {
1426 6703 cjones
          lock = HazelcastService.getInstance().getLock(pid.getValue());
1427 6702 cjones
          lock.lock();
1428 6867 cjones
          logMetacat.debug("Locked identifier " + pid.getValue());
1429
1430 6858 cjones
          try {
1431
              systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
1432 6571 cjones
1433 6869 cjones
              if ( systemMetadata == null ) {
1434
                  throw new NotFound("4400", "Couldn't find an object identified by " + pid.getValue());
1435
1436
              }
1437 6858 cjones
              // does the request have the most current system metadata?
1438
              if ( systemMetadata.getSerialVersion().longValue() != serialVersion ) {
1439
                 String msg = "The requested system metadata version number " +
1440
                     serialVersion + " differs from the current version at " +
1441
                     systemMetadata.getSerialVersion().longValue() +
1442
                     ". Please get the latest copy in order to modify it.";
1443 6869 cjones
                 throw new VersionMismatch("4402", msg);
1444
1445 6858 cjones
              }
1446
1447 6869 cjones
          } catch (RuntimeException e) {
1448 6858 cjones
              // convert Hazelcast RuntimeException to NotFound
1449
              throw new NotFound("4400", "No record found for: " + pid);
1450
1451 6593 cjones
          }
1452 6858 cjones
1453
          // set the access policy
1454
          systemMetadata.setAccessPolicy(accessPolicy);
1455 6593 cjones
1456 6858 cjones
          // update the system metadata
1457
          try {
1458
              systemMetadata.setSerialVersion(systemMetadata.getSerialVersion().add(BigInteger.ONE));
1459
              systemMetadata.setDateSysMetadataModified(Calendar.getInstance().getTime());
1460
              HazelcastService.getInstance().getSystemMetadataMap().put(systemMetadata.getIdentifier(), systemMetadata);
1461 7076 cjones
              notifyReplicaNodes(systemMetadata);
1462
1463 6869 cjones
          } catch (RuntimeException e) {
1464 6858 cjones
              // convert Hazelcast RuntimeException to ServiceFailure
1465
              throw new ServiceFailure("4430", e.getMessage());
1466
1467
          }
1468 6571 cjones
1469 6869 cjones
      } catch (RuntimeException e) {
1470 6571 cjones
          throw new ServiceFailure("4430", e.getMessage());
1471 6858 cjones
1472 6571 cjones
      } finally {
1473 6702 cjones
          lock.unlock();
1474 6717 cjones
          logMetacat.debug("Unlocked identifier " + pid.getValue());
1475 6571 cjones
1476
      }
1477 6858 cjones
1478 6571 cjones
1479
    // TODO: how do we know if the map was persisted?
1480
    success = true;
1481
1482
    return success;
1483
  }
1484
1485 6578 cjones
  /**
1486
   * Full replacement of replication metadata in the system metadata for the
1487
   * specified object, changes date system metadata modified
1488
   *
1489
   * @param session - the Session object containing the credentials for the Subject
1490
   * @param pid - the object identifier for the given object to apply the policy
1491
   * @param replica - the replica to be updated
1492
   * @return
1493
   * @throws NotImplemented
1494
   * @throws NotAuthorized
1495
   * @throws ServiceFailure
1496
   * @throws InvalidRequest
1497
   * @throws NotFound
1498 6869 cjones
   * @throws VersionMismatch
1499 6578 cjones
   */
1500 6869 cjones
  @Override
1501 6578 cjones
  public boolean updateReplicationMetadata(Session session, Identifier pid,
1502 6593 cjones
      Replica replica, long serialVersion)
1503 6578 cjones
      throws NotImplemented, NotAuthorized, ServiceFailure, InvalidRequest,
1504 6869 cjones
      NotFound, VersionMismatch {
1505 6578 cjones
1506 6702 cjones
      // The lock to be used for this identifier
1507 6859 cjones
      Lock lock = null;
1508 6702 cjones
1509 6578 cjones
      // get the subject
1510
      Subject subject = session.getSubject();
1511
1512
      // are we allowed to do this?
1513
      try {
1514 7068 cjones
1515
          // what is the controlling permission?
1516
          if (!isAuthorized(session, pid, Permission.WRITE)) {
1517
              throw new NotAuthorized("4851", "not allowed by "
1518
                      + subject.getValue() + " on " + pid.getValue());
1519
          }
1520
1521 6578 cjones
1522
      } catch (InvalidToken e) {
1523
          throw new NotAuthorized("4851", "not allowed by " + subject.getValue() +
1524
                  " on " + pid.getValue());
1525
1526
      }
1527
1528
      SystemMetadata systemMetadata = null;
1529 6858 cjones
      try {
1530 6703 cjones
          lock = HazelcastService.getInstance().getLock(pid.getValue());
1531 6702 cjones
          lock.lock();
1532 6867 cjones
          logMetacat.debug("Locked identifier " + pid.getValue());
1533 6578 cjones
1534 6858 cjones
          try {
1535
              systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
1536
1537
              // does the request have the most current system metadata?
1538
              if ( systemMetadata.getSerialVersion().longValue() != serialVersion ) {
1539
                 String msg = "The requested system metadata version number " +
1540
                     serialVersion + " differs from the current version at " +
1541
                     systemMetadata.getSerialVersion().longValue() +
1542
                     ". Please get the latest copy in order to modify it.";
1543 6869 cjones
                 throw new VersionMismatch("4855", msg);
1544 6858 cjones
              }
1545
1546 6869 cjones
          } catch (RuntimeException e) { // Catch is generic since HZ throws RuntimeException
1547
              throw new NotFound("4854", "No record found for: " + pid.getValue() +
1548
                  " : " + e.getMessage());
1549 6858 cjones
1550 6593 cjones
          }
1551 6858 cjones
1552
          // set the status for the replica
1553
          List<Replica> replicas = systemMetadata.getReplicaList();
1554
          NodeReference replicaNode = replica.getReplicaMemberNode();
1555 7231 cjones
          ReplicationStatus replicaStatus = replica.getReplicationStatus();
1556 6858 cjones
          int index = 0;
1557
          for (Replica listedReplica: replicas) {
1558
1559
              // remove the replica that we are replacing
1560
              if ( replicaNode.getValue().equals(listedReplica.getReplicaMemberNode().getValue())) {
1561 7231 cjones
                      // don't allow status to change from COMPLETED to anything other
1562
                      // than INVALIDATED: prevents overwrites from race conditions
1563
                	  if ( listedReplica.getReplicationStatus() == ReplicationStatus.COMPLETED &&
1564
            		    replicaStatus != ReplicationStatus.INVALIDATED ) {
1565
                	  throw new InvalidRequest("4853", "Status state change from " +
1566
                			  listedReplica.getReplicationStatus() + " to " +
1567
                			  replicaStatus.toString() + "is prohibited for identifier " +
1568
                			  pid.getValue() + " and target node " +
1569
                			  listedReplica.getReplicaMemberNode().getValue());
1570
1571
            	  }
1572 6858 cjones
                  replicas.remove(index);
1573
                  break;
1574
1575
              }
1576
              index++;
1577
          }
1578 6593 cjones
1579 6858 cjones
          // add the new replica item
1580
          replicas.add(replica);
1581
          systemMetadata.setReplicaList(replicas);
1582 6578 cjones
1583 6858 cjones
          // update the metadata
1584
          try {
1585
              systemMetadata.setSerialVersion(systemMetadata.getSerialVersion().add(BigInteger.ONE));
1586
              systemMetadata.setDateSysMetadataModified(Calendar.getInstance().getTime());
1587
              HazelcastService.getInstance().getSystemMetadataMap().put(systemMetadata.getIdentifier(), systemMetadata);
1588
1589 6869 cjones
          } catch (RuntimeException e) {
1590
              logMetacat.info("Unknown RuntimeException thrown: " + e.getCause().getMessage());
1591 6858 cjones
              throw new ServiceFailure("4852", e.getMessage());
1592 6578 cjones
1593
          }
1594 6858 cjones
1595 6869 cjones
      } catch (RuntimeException e) {
1596
          logMetacat.info("Unknown RuntimeException thrown: " + e.getCause().getMessage());
1597
          throw new ServiceFailure("4852", e.getMessage());
1598
1599
      } finally {
1600
          lock.unlock();
1601
          logMetacat.debug("Unlocked identifier " + pid.getValue());
1602
1603
      }
1604 6578 cjones
1605
      return true;
1606
1607
  }
1608 6622 leinfelder
1609 6869 cjones
  /**
1610
   *
1611
   */
1612
  @Override
1613 6858 cjones
  public ObjectList listObjects(Session session, Date startTime,
1614
      Date endTime, ObjectFormatIdentifier formatid, Boolean replicaStatus,
1615
      Integer start, Integer count)
1616 6644 cjones
      throws InvalidRequest, InvalidToken, NotAuthorized, NotImplemented,
1617
      ServiceFailure {
1618
1619
      ObjectList objectList = null;
1620 6622 leinfelder
        try {
1621
            objectList = IdentifierManager.getInstance().querySystemMetadata(startTime, endTime, formatid, replicaStatus, start, count);
1622
        } catch (Exception e) {
1623
            throw new ServiceFailure("1580", "Error querying system metadata: " + e.getMessage());
1624
        }
1625
1626
        return objectList;
1627 6644 cjones
  }
1628 6803 leinfelder
1629 7012 cjones
1630
 	/**
1631
 	 * Returns a list of checksum algorithms that are supported by DataONE.
1632
 	 * @return cal  the list of checksum algorithms
1633
 	 *
1634
 	 * @throws ServiceFailure
1635
 	 * @throws NotImplemented
1636
 	 */
1637 6869 cjones
  @Override
1638 7012 cjones
  public ChecksumAlgorithmList listChecksumAlgorithms()
1639 6803 leinfelder
			throws ServiceFailure, NotImplemented {
1640
		ChecksumAlgorithmList cal = new ChecksumAlgorithmList();
1641
		cal.addAlgorithm("MD5");
1642
		cal.addAlgorithm("SHA-1");
1643 7012 cjones
		return cal;
1644
1645 6803 leinfelder
	}
1646 7073 cjones
1647
  /**
1648
   * Notify replica Member Nodes of system metadata changes for a given pid
1649
   *
1650
   * @param currentSystemMetadata - the up to date system metadata
1651
   */
1652
  public void notifyReplicaNodes(SystemMetadata currentSystemMetadata) {
1653
1654
      Session session = null;
1655
      List<Replica> replicaList = currentSystemMetadata.getReplicaList();
1656
      MNode mn = null;
1657
      NodeReference replicaNodeRef = null;
1658
      CNode cn = null;
1659
      NodeType nodeType = null;
1660
      List<Node> nodeList = null;
1661
1662
      try {
1663
          cn = D1Client.getCN();
1664
          nodeList = cn.listNodes().getNodeList();
1665
1666
      } catch (Exception e) { // handle BaseException and other I/O issues
1667
1668
          // swallow errors since the call is not critical
1669
          logMetacat.error("Can't inform MNs of system metadata changes due " +
1670
              "to communication issues with the CN: " + e.getMessage());
1671
1672
      }
1673
1674
      if ( replicaList != null ) {
1675
1676
          // iterate through the replicas and inform  MN replica nodes
1677
          for (Replica replica : replicaList) {
1678
1679
              replicaNodeRef = replica.getReplicaMemberNode();
1680
              try {
1681
                  if (nodeList != null) {
1682
                      // find the node type
1683
                      for (Node node : nodeList) {
1684
                          if (node.getIdentifier().getValue() ==
1685
                              replicaNodeRef.getValue()) {
1686
                              nodeType = node.getType();
1687
                              break;
1688
1689
                          }
1690
                      }
1691
                  }
1692
1693
                  // notify only MNs
1694
                  if (nodeType != null && nodeType == NodeType.MN) {
1695
                      mn = D1Client.getMN(replicaNodeRef);
1696
                      mn.systemMetadataChanged(session,
1697
                          currentSystemMetadata.getIdentifier(),
1698
                          currentSystemMetadata.getSerialVersion().longValue(),
1699
                          currentSystemMetadata.getDateSysMetadataModified());
1700
                  }
1701
1702
              } catch (Exception e) { // handle BaseException and other I/O issues
1703
1704
                  // swallow errors since the call is not critical
1705
                  logMetacat.error("Can't inform "
1706
                          + replicaNodeRef.getValue()
1707
                          + " of system metadata changes due "
1708
                          + "to communication issues with the CN: "
1709
                          + e.getMessage());
1710
1711
              }
1712
          }
1713
      }
1714
  }
1715 7144 leinfelder
1716
	@Override
1717
	public boolean isAuthorized(Identifier pid, Permission permission)
1718
			throws ServiceFailure, InvalidToken, NotFound, NotAuthorized,
1719
			NotImplemented, InvalidRequest {
1720
1721
		return isAuthorized(null, pid, permission);
1722
	}
1723
1724
	@Override
1725
	public boolean setAccessPolicy(Identifier pid, AccessPolicy accessPolicy, long serialVersion)
1726
			throws InvalidToken, NotFound, NotImplemented, NotAuthorized,
1727
			ServiceFailure, InvalidRequest, VersionMismatch {
1728
1729
		return setAccessPolicy(null, pid, accessPolicy, serialVersion);
1730
	}
1731
1732
	@Override
1733
	public Identifier setRightsHolder(Identifier pid, Subject userId, long serialVersion)
1734
			throws InvalidToken, ServiceFailure, NotFound, NotAuthorized,
1735
			NotImplemented, InvalidRequest, VersionMismatch {
1736
1737
		return setRightsHolder(null, pid, userId, serialVersion);
1738
	}
1739
1740
	@Override
1741
	public Identifier create(Identifier pid, InputStream object, SystemMetadata sysmeta)
1742
			throws InvalidToken, ServiceFailure, NotAuthorized,
1743
			IdentifierNotUnique, UnsupportedType, InsufficientResources,
1744
			InvalidSystemMetadata, NotImplemented, InvalidRequest {
1745
1746
		return create(null, pid, object, sysmeta);
1747
	}
1748
1749
	@Override
1750
	public Identifier delete(Identifier pid) throws InvalidToken, ServiceFailure,
1751 7171 leinfelder
			NotAuthorized, NotFound, NotImplemented {
1752 7144 leinfelder
1753
		return delete(null, pid);
1754
	}
1755
1756
	@Override
1757
	public Identifier generateIdentifier(String scheme, String fragment)
1758
			throws InvalidToken, ServiceFailure, NotAuthorized, NotImplemented,
1759
			InvalidRequest {
1760
1761
		return generateIdentifier(null, scheme, fragment);
1762
	}
1763
1764
	@Override
1765
	public Log getLogRecords(Date fromDate, Date toDate, Event event, String pidFilter,
1766
			Integer start, Integer count) throws InvalidToken, InvalidRequest,
1767
			ServiceFailure, NotAuthorized, NotImplemented, InsufficientResources {
1768
1769
		return getLogRecords(null, fromDate, toDate, event, pidFilter, start, count);
1770
	}
1771
1772
	@Override
1773
	public boolean hasReservation(Subject subject, Identifier pid)
1774
			throws InvalidToken, ServiceFailure, NotFound, NotAuthorized,
1775
			NotImplemented, InvalidRequest, IdentifierNotUnique {
1776
1777
		return hasReservation(null, subject, pid);
1778
	}
1779
1780
	@Override
1781
	public Identifier registerSystemMetadata(Identifier pid, SystemMetadata sysmeta)
1782
			throws NotImplemented, NotAuthorized, ServiceFailure, InvalidRequest,
1783
			InvalidSystemMetadata, InvalidToken {
1784
1785
		return registerSystemMetadata(null, pid, sysmeta);
1786
	}
1787
1788
	@Override
1789
	public Identifier reserveIdentifier(Identifier pid) throws InvalidToken,
1790
			ServiceFailure, NotAuthorized, IdentifierNotUnique, NotImplemented,
1791
			InvalidRequest {
1792
1793
		return reserveIdentifier(null, pid);
1794
	}
1795
1796
	@Override
1797
	public boolean setObsoletedBy(Identifier pid, Identifier obsoletedByPid, long serialVersion)
1798
			throws NotImplemented, NotFound, NotAuthorized, ServiceFailure,
1799
			InvalidRequest, InvalidToken, VersionMismatch {
1800
1801
		return setObsoletedBy(null, pid, obsoletedByPid, serialVersion);
1802
	}
1803
1804
	@Override
1805
	public DescribeResponse describe(Identifier pid) throws InvalidToken,
1806
			NotAuthorized, NotImplemented, ServiceFailure, NotFound {
1807
1808
		return describe(null, pid);
1809
	}
1810
1811
	@Override
1812
	public InputStream get(Identifier pid) throws InvalidToken, ServiceFailure,
1813
			NotAuthorized, NotFound, NotImplemented {
1814
1815
		return get(null, pid);
1816
	}
1817
1818
	@Override
1819
	public Checksum getChecksum(Identifier pid) throws InvalidToken,
1820
			ServiceFailure, NotAuthorized, NotFound, NotImplemented {
1821
1822
		return getChecksum(null, pid);
1823
	}
1824
1825
	@Override
1826
	public SystemMetadata getSystemMetadata(Identifier pid) throws InvalidToken,
1827
			ServiceFailure, NotAuthorized, NotFound, NotImplemented {
1828
1829
		return getSystemMetadata(null, pid);
1830
	}
1831
1832
	@Override
1833
	public ObjectList listObjects(Date startTime, Date endTime,
1834
			ObjectFormatIdentifier formatid, Boolean replicaStatus, Integer start, Integer count)
1835
			throws InvalidRequest, InvalidToken, NotAuthorized, NotImplemented,
1836
			ServiceFailure {
1837
1838
		return listObjects(null, startTime, endTime, formatid, replicaStatus, start, count);
1839
	}
1840
1841
	@Override
1842
	public ObjectLocationList resolve(Identifier pid) throws InvalidToken,
1843
			ServiceFailure, NotAuthorized, NotFound, NotImplemented {
1844
1845
		return resolve(null, pid);
1846
	}
1847
1848
	@Override
1849
	public ObjectList search(String queryType, String query) throws InvalidToken,
1850
			ServiceFailure, NotAuthorized, InvalidRequest, NotImplemented {
1851
1852
		return search(null, queryType, query);
1853
	}
1854
1855
	@Override
1856
	public boolean deleteReplicationMetadata(Identifier pid, NodeReference nodeId,
1857
			long serialVersion) throws InvalidToken, InvalidRequest, ServiceFailure,
1858
			NotAuthorized, NotFound, NotImplemented, VersionMismatch {
1859
1860
		return deleteReplicationMetadata(null, pid, nodeId, serialVersion);
1861
	}
1862
1863
	@Override
1864
	public boolean isNodeAuthorized(Subject targetNodeSubject, Identifier pid)
1865
			throws NotImplemented, NotAuthorized, InvalidToken, ServiceFailure,
1866
			NotFound, InvalidRequest {
1867
1868
		return isNodeAuthorized(null, targetNodeSubject, pid);
1869
	}
1870
1871
	@Override
1872
	public boolean setReplicationPolicy(Identifier pid, ReplicationPolicy policy,
1873
			long serialVersion) throws NotImplemented, NotFound, NotAuthorized,
1874
			ServiceFailure, InvalidRequest, InvalidToken, VersionMismatch {
1875
1876
		return setReplicationPolicy(null, pid, policy, serialVersion);
1877
	}
1878
1879
	@Override
1880
	public boolean setReplicationStatus(Identifier pid, NodeReference targetNode,
1881
			ReplicationStatus status, BaseException failure) throws ServiceFailure,
1882
			NotImplemented, InvalidToken, NotAuthorized, InvalidRequest, NotFound {
1883
1884
		return setReplicationStatus(null, pid, targetNode, status, failure);
1885
	}
1886
1887
	@Override
1888
	public boolean updateReplicationMetadata(Identifier pid, Replica replica,
1889
			long serialVersion) throws NotImplemented, NotAuthorized, ServiceFailure,
1890
			NotFound, InvalidRequest, InvalidToken, VersionMismatch {
1891
1892
		return updateReplicationMetadata(null, pid, replica, serialVersion);
1893
	}
1894 6177 cjones
}