Project

General

Profile

1
/**
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
import java.io.IOException;
27
import java.io.InputStream;
28
import java.security.NoSuchAlgorithmException;
29
import java.util.Date;
30

    
31
import org.apache.log4j.Logger;
32
import org.dataone.service.exceptions.IdentifierNotUnique;
33
import org.dataone.service.exceptions.InsufficientResources;
34
import org.dataone.service.exceptions.InvalidRequest;
35
import org.dataone.service.exceptions.InvalidSystemMetadata;
36
import org.dataone.service.exceptions.InvalidToken;
37
import org.dataone.service.exceptions.NotAuthorized;
38
import org.dataone.service.exceptions.NotFound;
39
import org.dataone.service.exceptions.NotImplemented;
40
import org.dataone.service.exceptions.ServiceFailure;
41
import org.dataone.service.exceptions.SynchronizationFailed;
42
import org.dataone.service.exceptions.UnsupportedType;
43
import org.dataone.service.mn.tier1.MNCore;
44
import org.dataone.service.mn.tier1.MNRead;
45
import org.dataone.service.mn.tier2.MNAuthorization;
46
import org.dataone.service.mn.tier3.MNStorage;
47
import org.dataone.service.mn.tier4.MNReplication;
48
import org.dataone.service.types.AccessPolicy;
49
import org.dataone.service.types.Checksum;
50
import org.dataone.service.types.ChecksumAlgorithm;
51
import org.dataone.service.types.DescribeResponse;
52
import org.dataone.service.types.Event;
53
import org.dataone.service.types.Identifier;
54
import org.dataone.service.types.Log;
55
import org.dataone.service.types.MonitorList;
56
import org.dataone.service.types.Node;
57
import org.dataone.service.types.NodeReference;
58
import org.dataone.service.types.ObjectFormat;
59
import org.dataone.service.types.ObjectList;
60
import org.dataone.service.types.Permission;
61
import org.dataone.service.types.Session;
62
import org.dataone.service.types.Subject;
63
import org.dataone.service.types.SystemMetadata;
64
import org.dataone.service.types.util.ServiceTypeUtil;
65

    
66
/**
67
 * Represents Metacat's implementation of the DataONE Member Node 
68
 * service API. Methods implement the various MN* interfaces, and methods common
69
 * to both Member Node and Coordinating Node interfaces are found in the
70
 * D1NodeService base class.
71
 */
72
public class MNodeService extends D1NodeService implements MNAuthorization,
73
  MNCore, MNRead, MNReplication, MNStorage {
74

    
75
	/* the instance of the MNodeService object */
76
  private static MNodeService instance = null;
77
  
78
  /* the logger instance */
79
  private Logger logMetacat = null;
80

    
81
  /**
82
   * singleton accessor
83
   */
84
  public static MNodeService getInstance() 
85
  {
86
    if (instance == null) {
87
      instance = new MNodeService();
88
    }
89
    
90
    return instance;
91
  }
92
  
93
  /**
94
   * Constructor, private for singleton access
95
   */
96
  private MNodeService() {
97
  	super();
98
    logMetacat = Logger.getLogger(MNodeService.class);
99
        
100
  }
101
    
102
	/**
103
	 * Adds a new object to the Member Node, where the object is either a data 
104
	 * object or a science metadata object. This method is called by clients 
105
	 * to create new data objects on Member Nodes
106
	 * 
107
	 * @param session - the Session object containing the credentials for the Subject
108
	 * @param pid - The object identifier to be created
109
	 * @param object - the object bytes
110
	 * @param sysmeta - the system metadata that describes the object  
111
	 * 
112
	 * @return pid - the object identifier created
113
	 * 
114
	 * @throws InvalidToken
115
	 * @throws ServiceFailure
116
	 * @throws NotAuthorized
117
	 * @throws IdentifierNotUnique
118
	 * @throws UnsupportedType
119
	 * @throws InsufficientResources
120
	 * @throws InvalidSystemMetadata
121
	 * @throws NotImplemented
122
	 * @throws InvalidRequest
123
	 */
124
  @Override
125
	public Identifier create(Session session, Identifier pid, InputStream object,
126
	  SystemMetadata sysmeta) 
127
    throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique, 
128
    UnsupportedType, InsufficientResources, InvalidSystemMetadata, 
129
    NotImplemented, InvalidRequest {
130

    
131
		return null;
132
	}
133

    
134
	/**
135
	 * Deletes an object from the Member Node, where the object is either a 
136
	 * data object or a science metadata object.
137
	 * 
138
	 * @param session - the Session object containing the credentials for the Subject
139
	 * @param pid - The object identifier to be deleted
140
	 * 
141
	 * @return pid - the identifier of the object used for the deletion
142
	 * 
143
	 * @throws InvalidToken
144
	 * @throws ServiceFailure
145
	 * @throws NotAuthorized
146
	 * @throws NotFound
147
	 * @throws NotImplemented
148
	 * @throws InvalidRequest
149
	 */
150
  @Override
151
	public Identifier delete(Session session, Identifier pid) 
152
    throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, 
153
    NotImplemented, InvalidRequest {
154

    
155
		return null;
156
	}
157

    
158
  /**
159
   * Updates an existing object by creating a new object identified by 
160
   * newPid on the Member Node which explicitly obsoletes the object 
161
   * identified by pid through appropriate changes to the SystemMetadata 
162
   * of pid and newPid
163
   * 
164
	 * @param session - the Session object containing the credentials for the Subject
165
	 * @param pid - The identifier of the object to be updated
166
	 * @param object - the new object bytes
167
	 * @param sysmeta - the new system metadata describing the object
168
	 * 
169
	 * @return newPid - the identifier of the new object
170
	 * 
171
	 * @throws InvalidToken
172
	 * @throws ServiceFailure
173
	 * @throws NotAuthorized
174
	 * @throws NotFound
175
	 * @throws NotImplemented
176
	 * @throws IdentifierNotUnique
177
	 * @throws UnsupportedType
178
	 * @throws InsufficientResources
179
	 * @throws InvalidSystemMetadata
180
	 * @throws InvalidRequest
181
   */
182
  @Override
183
	public Identifier update(Session session, Identifier pid, InputStream object,
184
	  Identifier newPid, SystemMetadata sysmeta) 
185
    throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique, 
186
    UnsupportedType, InsufficientResources, NotFound, InvalidSystemMetadata, 
187
    NotImplemented, InvalidRequest {
188

    
189
		return null;
190
	}
191

    
192
  /**
193
   * Called by a Coordinating Node to request that the Member Node create a 
194
   * copy of the specified object by retrieving it from another Member 
195
   * Node and storing it locally so that it can be made accessible to 
196
   * the DataONE system.
197
   * 
198
	 * @param session - the Session object containing the credentials for the Subject
199
	 * @param sysmeta - Copy of the CN held system metadata for the object
200
	 * @param sourceNode - A reference to node from which the content should be 
201
	 *                     retrieved. The reference should be resolved by 
202
	 *                     checking the CN node registry.
203
	 * 
204
	 * @return true if the replication succeeds
205
	 * 
206
	 * @throws ServiceFailure
207
	 * @throws NotAuthorized
208
	 * @throws NotImplemented
209
	 * @throws UnsupportedType
210
	 * @throws InsufficientResources
211
	 * @throws InvalidRequest
212
   */
213
  @Override
214
	public boolean replicate(Session session, SystemMetadata sysmeta, 
215
	  NodeReference sourceNode)
216
	  throws NotImplemented, ServiceFailure, NotAuthorized, InvalidRequest,
217
	  InsufficientResources, UnsupportedType {
218

    
219
		return false;
220
	}
221

    
222
  /**
223
   * This method provides a lighter weight mechanism than 
224
   * MN_read.getSystemMetadata() for a client to determine basic 
225
   * properties of the referenced object.
226
   * 
227
	 * @param session - the Session object containing the credentials for the Subject
228
	 * @param pid - the identifier of the object to be described
229
	 * 
230
	 * @return describeResponse - A set of values providing a basic description 
231
	 *                            of the object.
232
	 * 
233
	 * @throws InvalidToken
234
	 * @throws ServiceFailure
235
	 * @throws NotAuthorized
236
	 * @throws NotFound
237
	 * @throws NotImplemented
238
	 * @throws InvalidRequest
239
   */
240
  @Override
241
	public DescribeResponse describe(Session session, Identifier pid)
242
	  throws InvalidToken, ServiceFailure, NotAuthorized, NotFound,
243
	  NotImplemented, InvalidRequest {
244
    
245
  	if(session == null) {
246
      throw new InvalidToken("1370", "The session object is null");
247
      
248
    }
249
    
250
    if(pid == null || pid.getValue().trim().equals(""))
251
    {
252
      throw new InvalidRequest("1362", "The object identifier is null. " +
253
        "A valid identifier is required.");
254
        
255
    }
256
    
257
    SystemMetadata sysmeta = getSystemMetadata(session, pid);
258
    DescribeResponse describeResponse = 
259
    	new DescribeResponse(sysmeta.getObjectFormat(), 
260
      sysmeta.getSize(), sysmeta.getDateSysMetadataModified(), sysmeta.getChecksum());
261
    
262
    return describeResponse;
263

    
264
	}
265

    
266
	/**
267
	 * Return the object identified by the given object identifier
268
	 * 
269
	 * @param session - the Session object containing the credentials for the Subject
270
	 * @param pid - the object identifier for the given object
271
	 * 
272
	 * @return inputStream - the input stream of the given object
273
	 * 
274
	 * @throws InvalidToken
275
	 * @throws ServiceFailure
276
	 * @throws NotAuthorized
277
	 * @throws InvalidRequest
278
	 * @throws NotImplemented
279
	 */
280
  @Override
281
	public InputStream get(Session session, Identifier pid) 
282
	  throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, 
283
	  NotImplemented, InvalidRequest {
284
  	
285
		return super.get(session, pid);
286
		
287
	}
288

    
289
	/**
290
	 * Returns a Checksum for the specified object using an accepted hashing algorithm
291
	 * 
292
	 * @param session - the Session object containing the credentials for the Subject
293
	 * @param pid - the object identifier for the given object
294
	 * @param algorithm -  the name of an algorithm that will be used to compute 
295
	 *                     a checksum of the bytes of the object
296
	 * 
297
	 * @return checksum - the checksum of the given object
298
	 * 
299
	 * @throws InvalidToken
300
	 * @throws ServiceFailure
301
	 * @throws NotAuthorized
302
	 * @throws NotFound
303
	 * @throws InvalidRequest
304
	 * @throws NotImplemented
305
	 */
306
  @Override
307
	public Checksum getChecksum(Session session, Identifier pid, String algorithm)
308
	  throws InvalidToken, ServiceFailure, NotAuthorized, NotFound,
309
	  InvalidRequest, NotImplemented {
310

    
311
  	Checksum checksum = null;
312
  	
313
  	InputStream inputStream = get(session, pid);
314
  	
315
  	try {
316
	    checksum = 
317
	    	ServiceTypeUtil.checksum(inputStream, ChecksumAlgorithm.convert(algorithm));
318
    
319
  	} catch (NoSuchAlgorithmException e) {
320
      throw new ServiceFailure("1410", "The checksum for the object specified by " + 
321
        pid.getValue() +
322
        "could not be returned due to an internal error: " +
323
        e.getMessage());
324
      
325
    } catch (IOException e) {
326
      throw new ServiceFailure("1410", "The checksum for the object specified by " + 
327
        pid.getValue() +
328
        "could not be returned due to an internal error: " +
329
        e.getMessage());
330
      
331
    }
332
  	
333
    if ( checksum == null ) {
334
      throw new ServiceFailure("1410", "The checksum for the object specified by " + 
335
        pid.getValue() +
336
        "could not be returned.");
337
      
338
    }
339
    
340
		return checksum;
341
	}
342

    
343
	/**
344
	 * Return the system metadata for a given object
345
	 * 
346
	 * @param session - the Session object containing the credentials for the Subject
347
	 * @param pid - the object identifier for the given object
348
	 * 
349
	 * @return inputStream - the input stream of the given system metadata object
350
	 * 
351
	 * @throws InvalidToken
352
	 * @throws ServiceFailure
353
	 * @throws NotAuthorized
354
	 * @throws NotFound
355
	 * @throws InvalidRequest
356
	 * @throws NotImplemented
357
	 */
358
  @Override
359
	public SystemMetadata getSystemMetadata(Session session, Identifier pid)
360
	    throws InvalidToken, ServiceFailure, NotAuthorized, NotFound,
361
	    InvalidRequest, NotImplemented {
362

    
363
		return super.getSystemMetadata(session, pid);
364
	}
365

    
366
	/**
367
	 * Retrieve the list of objects present on the MN that match the calling parameters
368
	 * 
369
	 * @param session - the Session object containing the credentials for the Subject
370
	 * @param startTime - Specifies the beginning of the time range from which 
371
	 *                    to return object (>=)
372
	 * @param endTime - Specifies the beginning of the time range from which 
373
	 *                  to return object (>=)
374
	 * @param objectFormat - Restrict results to the specified object format
375
	 * @param replicaStatus - Indicates if replicated objects should be returned in the list
376
	 * @param start - The zero-based index of the first value, relative to the 
377
	 *                first record of the resultset that matches the parameters.
378
	 * @param count - The maximum number of entries that should be returned in 
379
	 *                the response. The Member Node may return less entries 
380
	 *                than specified in this value.
381
	 * 
382
	 * @return objectList - the list of objects matching the criteria
383
	 * 
384
	 * @throws InvalidToken
385
	 * @throws ServiceFailure
386
	 * @throws NotAuthorized
387
	 * @throws InvalidRequest
388
	 * @throws NotImplemented
389
	 */
390
  @Override
391
	public ObjectList listObjects(Session session, Date startTime, Date endTime,
392
	  ObjectFormat objectFormat, Boolean replicaStatus, Integer start, Integer count)
393
	  throws NotAuthorized, InvalidRequest, NotImplemented, ServiceFailure,
394
	  InvalidToken {
395

    
396
		return null;
397
	}
398

    
399
	/**
400
	 * Retrieve the list of objects present on the MN that match the calling parameters
401
	 * 
402
	 * @return node - the technical capabilities of the Member Node
403
	 * 
404
	 * @throws ServiceFailure
405
	 * @throws NotAuthorized
406
	 * @throws InvalidRequest
407
	 * @throws NotImplemented
408
	 */
409
  @Override
410
	public Node getCapabilities() throws NotImplemented, NotAuthorized,
411
	    ServiceFailure, InvalidRequest {
412

    
413
		return null;
414
	}
415

    
416
	/**
417
	 * Returns the number of operations that have been serviced by the node 
418
	 * over time periods of one and 24 hours.
419
	 * 
420
	 * @param session - the Session object containing the credentials for the Subject
421
	 * @param period - An ISO8601 compatible DateTime range specifying the time 
422
	 *                 range for which to return operation statistics.
423
	 * @param requestor - Limit to operations performed by given requestor identity.
424
	 * @param event -  Enumerated value indicating the type of event being examined
425
	 * @param format - Limit to events involving objects of the specified format
426
	 * 
427
	 * @return the desired log records
428
	 * 
429
	 * @throws InvalidToken
430
	 * @throws ServiceFailure
431
	 * @throws NotAuthorized
432
	 * @throws InvalidRequest
433
	 * @throws NotImplemented
434
	 */
435
  @Override
436
	public MonitorList getOperationStatistics(Session session, Integer period,
437
	  Subject requestor, Event event, ObjectFormat format) 
438
    throws NotImplemented, ServiceFailure, NotAuthorized, InvalidRequest, 
439
    InsufficientResources, UnsupportedType {
440

    
441
		return null;
442
	}
443

    
444
  /**
445
   * Low level “are you alive” operation. A valid ping response is 
446
   * indicated by a HTTP status of 200.
447
   * 
448
   * @return true if the service is alive
449
   * 
450
	 * @throws InvalidToken
451
	 * @throws ServiceFailure
452
	 * @throws NotAuthorized
453
	 * @throws InvalidRequest
454
	 * @throws NotImplemented
455
   */
456
	@Override
457
	public boolean ping() 
458
	  throws NotImplemented, ServiceFailure, NotAuthorized, InvalidRequest, 
459
	  InsufficientResources, UnsupportedType {
460

    
461
		return false;
462
	}
463

    
464
  /**
465
   * A callback method used by a CN to indicate to a MN that it cannot 
466
   * complete synchronization of the science metadata identified by pid
467
   * 
468
   * @param session
469
   * @param syncFailed
470
	 * 
471
	 * @throws ServiceFailure
472
	 * @throws NotAuthorized
473
	 * @throws InvalidRequest
474
	 * @throws NotImplemented
475
   */
476
	@Override
477
  public void synchronizationFailed(Session session, SynchronizationFailed syncFailed)
478
      throws NotImplemented, ServiceFailure, NotAuthorized, InvalidRequest {
479

    
480
		
481
  }
482

    
483
}
(5-5/8)