Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2010 Regents of the University of California and the
4
 *              National Center for Ecological Analysis and Synthesis
5
 *  Purpose: To test the Access Controls in metacat by JUnit
6
 *
7
 *   '$Author: leinfelder $'
8
 *     '$Date: 2011-07-07 13:09:49 -0700 (Thu, 07 Jul 2011) $'
9
 * '$Revision: 6315 $'
10
 *
11
 * This program is free software; you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation; either version 2 of the License, or
14
 * (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program; if not, write to the Free Software
23
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
 */
25

    
26
package edu.ucsb.nceas.metacat.dataone;
27

    
28
import java.io.ByteArrayInputStream;
29
import java.io.ByteArrayOutputStream;
30
import java.io.InputStream;
31
import java.io.InputStreamReader;
32
import java.io.Reader;
33
import java.util.Date;
34

    
35
import junit.framework.Test;
36
import junit.framework.TestSuite;
37

    
38
import org.apache.commons.io.IOUtils;
39
import org.dataone.client.ObjectFormatCache;
40
import org.dataone.service.Constants;
41
import org.dataone.service.exceptions.InsufficientResources;
42
import org.dataone.service.exceptions.InvalidRequest;
43
import org.dataone.service.exceptions.NotFound;
44
import org.dataone.service.exceptions.NotImplemented;
45
import org.dataone.service.exceptions.ServiceFailure;
46
import org.dataone.service.impl.ObjectFormatServiceImpl;
47
import org.dataone.service.types.AccessPolicy;
48
import org.dataone.service.types.AccessRule;
49
import org.dataone.service.types.Checksum;
50
import org.dataone.service.types.ChecksumAlgorithm;
51
import org.dataone.service.types.Identifier;
52
import org.dataone.service.types.NodeReference;
53
import org.dataone.service.types.ObjectFormat;
54
import org.dataone.service.types.ObjectFormatIdentifier;
55
import org.dataone.service.types.ObjectFormatList;
56
import org.dataone.service.types.ObjectInfo;
57
import org.dataone.service.types.ObjectList;
58
import org.dataone.service.types.Permission;
59
import org.dataone.service.types.Replica;
60
import org.dataone.service.types.ReplicationPolicy;
61
import org.dataone.service.types.ReplicationStatus;
62
import org.dataone.service.types.Session;
63
import org.dataone.service.types.Subject;
64
import org.dataone.service.types.SystemMetadata;
65
import org.dataone.service.types.util.ServiceTypeUtil;
66

    
67
import edu.ucsb.nceas.MCTestCase;
68
import edu.ucsb.nceas.metacat.client.Metacat;
69
import edu.ucsb.nceas.metacat.client.MetacatFactory;
70

    
71
/**
72
 * A JUnit test for testing the dataone CNCore implementation
73
 */
74
public class CNodeServiceTest extends MCTestCase {   
75
    
76
    /**
77
    * constructor for the test
78
    */
79
    public CNodeServiceTest(String name)
80
    {
81
        super(name);
82
    }
83
  
84
    /**
85
	 * Establish a testing framework by initializing appropriate objects
86
	 */
87
	public void setUp() throws Exception 
88
	{
89
		super.setUp();
90
	}
91

    
92
	/**
93
	 * Release any objects after tests are complete
94
	 */
95
	public void tearDown() 
96
	{
97
	}
98

    
99
	/**
100
	 * Create a suite of tests to be run together
101
	 */
102
	public static Test suite() 
103
	{
104
		TestSuite suite = new TestSuite();
105
		suite.addTest(new CNodeServiceTest("initialize"));
106
		
107
		suite.addTest(new CNodeServiceTest("testAssertRelation"));
108
		suite.addTest(new CNodeServiceTest("testChecksum"));
109
		suite.addTest(new CNodeServiceTest("testCreate"));
110
		suite.addTest(new CNodeServiceTest("testGet"));
111
		suite.addTest(new CNodeServiceTest("testGetFormat"));
112
		suite.addTest(new CNodeServiceTest("testListFormats"));
113
		suite.addTest(new CNodeServiceTest("testListNodes"));
114
		suite.addTest(new CNodeServiceTest("testObjectFormatNotFoundException"));
115
		suite.addTest(new CNodeServiceTest("testRegisterSystemMetadata"));
116
		suite.addTest(new CNodeServiceTest("testReplicationPolicy"));
117
		suite.addTest(new CNodeServiceTest("testReplicationStatus"));
118
		suite.addTest(new CNodeServiceTest("testReserveIdentifier"));
119
		suite.addTest(new CNodeServiceTest("testSearch"));
120
		suite.addTest(new CNodeServiceTest("testSetOwner"));
121
	
122
		return suite;
123
	}
124
	
125
	/**
126
	 * constructs a "fake" session with a test subject
127
	 * @return
128
	 */
129
	private Session getTestSession() {
130
		Session session = new Session();
131
        Subject subject = new Subject();
132
        subject.setValue("cn=test,dc=dataone,dc=org");
133
        session.setSubject(subject);
134
        return session;
135
	}
136
	
137
	/**
138
	 * test for registering standalone system metadata
139
	 */
140
	public void testRegisterSystemMetadata() {
141
	    printTestHeader("testRegisterSystemMetadata");
142

    
143
	    try {
144
            Session session = getTestSession();
145
			Identifier guid = new Identifier();
146
			guid.setValue("testRegisterSystemMetadata." + System.currentTimeMillis());
147
			SystemMetadata sysmeta = createSystemMetadata(guid, session.getSubject());
148
			boolean result = CNodeService.getInstance().registerSystemMetadata(session, guid, sysmeta);
149
			assertTrue(result);
150
        } catch(Exception e) {
151
            fail("Unexpected error: " + e.getMessage());
152
        }
153
	}
154
	
155
	public void testCreate() {
156
	    printTestHeader("testCreate");
157

    
158
	    try {
159
            Session session = getTestSession();
160
			Identifier guid = new Identifier();
161
			guid.setValue("testCreate." + System.currentTimeMillis());
162
			SystemMetadata sysmeta = createSystemMetadata(guid, session.getSubject());
163
			InputStream object = new ByteArrayInputStream("test".getBytes("UTF-8"));
164
			Identifier pid = CNodeService.getInstance().create(session, guid, object, sysmeta);
165
			assertEquals(guid, pid);
166
        } catch(Exception e) {
167
        	e.printStackTrace();
168
            fail("Unexpected error: " + e.getMessage());
169
        }
170
	}
171
	
172
	public void testGet() {
173
	    printTestHeader("testGet");
174

    
175
	    try {
176
            Session session = getTestSession();
177
			Identifier guid = new Identifier();
178
			guid.setValue("testGet." + System.currentTimeMillis());
179
			SystemMetadata sysmeta = createSystemMetadata(guid, session.getSubject());
180
			InputStream object = new ByteArrayInputStream("test".getBytes("UTF-8"));
181
			Identifier pid = CNodeService.getInstance().create(session, guid, object, sysmeta);
182
			assertEquals(guid, pid);
183
			// get it
184
			InputStream retObject = CNodeService.getInstance().get(session, pid);
185
			// check it
186
			assertTrue(IOUtils.contentEquals(object, retObject));
187
        } catch(Exception e) {
188
        	e.printStackTrace();
189
            fail("Unexpected error: " + e.getMessage());
190
        }
191
	}
192
	
193
	public void testAssertRelation() {
194
	    printTestHeader("testAssertRelation");
195

    
196
	    try {
197
            Session session = getTestSession();
198
			Identifier guid = new Identifier();
199
			guid.setValue("testAssertRelation." + System.currentTimeMillis());
200
			SystemMetadata sysmeta = createSystemMetadata(guid, session.getSubject());
201
			Identifier describePid = new Identifier();
202
			describePid.setValue("describePid." + System.currentTimeMillis());
203
			sysmeta.addDescribe(describePid);
204
			// save it
205
			boolean result = CNodeService.getInstance().registerSystemMetadata(session, guid, sysmeta);
206
			assertTrue(result);
207
			// save the other
208
			SystemMetadata describeSysmeta = createSystemMetadata(describePid, session.getSubject());
209
			result = CNodeService.getInstance().registerSystemMetadata(session, describePid, describeSysmeta);
210
			assertTrue(result);
211
			// check it
212
			result = CNodeService.getInstance().assertRelation(session, guid, "describes", describePid);
213
			assertTrue(result);
214
        } catch(Exception e) {
215
        	e.printStackTrace();
216
            fail("Unexpected error: " + e.getMessage());
217
        }
218
	}
219
	
220
	public void testChecksum() {
221
	    printTestHeader("testChecksum");
222

    
223
	    try {
224
            Session session = getTestSession();
225
			Identifier guid = new Identifier();
226
			guid.setValue("testChecksum." + System.currentTimeMillis());
227
			SystemMetadata sysmeta = createSystemMetadata(guid, session.getSubject());
228
			// save it
229
			boolean result = CNodeService.getInstance().registerSystemMetadata(session, guid, sysmeta);
230
			assertTrue(result);
231
			// check it
232
			Checksum checksum = CNodeService.getInstance().getChecksum(session, guid);
233
			assertEquals(sysmeta.getChecksum().getValue(), checksum.getValue());
234
        } catch(Exception e) {
235
            fail("Unexpected error: " + e.getMessage());
236
        }
237
	}
238
	
239
	public void testListNodes() {
240
	    printTestHeader("testListNodes");
241

    
242
	    try {
243
	    	CNodeService.getInstance().listNodes();
244
        } catch(NotImplemented e) {
245
        	// expecting not implemented
246
            assertTrue(true);
247
        } catch(Exception e) {
248
            fail("Unexpected error: " + e.getMessage());
249
        }
250
	}
251
	
252
	public void testReserveIdentifier() {
253
	    printTestHeader("testReserveIdentifier");
254

    
255
	    try {
256
            Session session = getTestSession();
257
			Identifier guid = new Identifier();
258
			guid.setValue("testReserveIdentifier." + System.currentTimeMillis());
259
			// reserve it
260
			Identifier retPid = CNodeService.getInstance().reserveIdentifier(session, guid, null, null);
261
			assertEquals(guid, retPid);
262
        } catch(Exception e) {
263
        	e.printStackTrace();
264
            fail("Unexpected error: " + e.getMessage());
265
        }
266
	}
267
	
268
	public void testSearch() {
269
	    printTestHeader("testSearch");
270

    
271
	    try {
272
            Session session = getTestSession();
273
			Identifier guid = new Identifier();
274
			guid.setValue("testSearch." + System.currentTimeMillis());
275
			SystemMetadata sysmeta = createSystemMetadata(guid, session.getSubject());
276
			
277
			// save it
278
			boolean result = CNodeService.getInstance().registerSystemMetadata(session, guid, sysmeta);
279
			assertTrue(result);
280
			// search for it
281
			ObjectList objectList = CNodeService.getInstance().search(session, null, null);
282
			// check it
283
			assertNotNull(objectList);
284
			result = false;
285
			for (ObjectInfo objectInfo: objectList.getObjectInfoList()) {
286
				Identifier pid = objectInfo.getIdentifier();
287
				if (pid.getValue().equals(guid.getValue())) {
288
					result = true;
289
					break;
290
				}
291
			}
292
			assertTrue(result);
293
        } catch(Exception e) {
294
            fail("Unexpected error: " + e.getMessage());
295
        }
296
	}
297
	
298
	public void testSetOwner() {
299
	    printTestHeader("testSetOwner");
300

    
301
	    try {
302
            Session session = getTestSession();
303
			Identifier guid = new Identifier();
304
			guid.setValue("testSetOwner." + System.currentTimeMillis());
305
			SystemMetadata sysmeta = createSystemMetadata(guid, session.getSubject());
306
			// save it
307
			boolean result = CNodeService.getInstance().registerSystemMetadata(session, guid, sysmeta);
308
			assertTrue(result);
309
			Subject rightsHolder = new Subject();
310
			rightsHolder.setValue("newUser");
311
			// set it
312
			Identifier retPid = CNodeService.getInstance().setOwner(session, guid, rightsHolder);
313
			assertEquals(guid, retPid);
314
			// get it
315
			sysmeta = CNodeService.getInstance().getSystemMetadata(session, guid);
316
			assertNotNull(sysmeta);
317
			// check it
318
			assertEquals(rightsHolder.getValue(), sysmeta.getRightsHolder().getValue());
319
			
320
        } catch(Exception e) {
321
            fail("Unexpected error: " + e.getMessage());
322
        }
323
	}
324
	
325
	public void testReplicationPolicy() {
326
	    printTestHeader("testReplicationPolicy");
327

    
328
	    try {
329
            Session session = getTestSession();
330
			Identifier guid = new Identifier();
331
			guid.setValue("testReplicationPolicy." + System.currentTimeMillis());
332
			SystemMetadata sysmeta = createSystemMetadata(guid, session.getSubject());
333
			// save it
334
			boolean result = CNodeService.getInstance().registerSystemMetadata(session, guid, sysmeta);
335
			assertTrue(result);
336
			
337
			ReplicationPolicy policy = new ReplicationPolicy();
338
			NodeReference node = new NodeReference();
339
			node.setValue("testNode");
340
			policy.addPreferredMemberNode(node );
341
			// set it
342
			result = CNodeService.getInstance().setReplicationPolicy(session, guid, policy);
343
			assertTrue(result);
344
			// get it
345
			sysmeta = CNodeService.getInstance().getSystemMetadata(session, guid);
346
			assertNotNull(sysmeta);
347
			// check it
348
			assertEquals(policy.getPreferredMemberNode(0).getValue(), sysmeta.getReplicationPolicy().getPreferredMemberNode(0).getValue());
349
			
350
        } catch(Exception e) {
351
            fail("Unexpected error: " + e.getMessage());
352
        }
353
	}
354
	
355
	public void testReplicationStatus() {
356
	    printTestHeader("testReplicationStatus");
357

    
358
	    try {
359
            Session session = getTestSession();
360
			Identifier guid = new Identifier();
361
			guid.setValue("testReplicationStatus." + System.currentTimeMillis());
362
			SystemMetadata sysmeta = createSystemMetadata(guid, session.getSubject());
363
			Replica replica = new Replica();
364
			NodeReference replicaMemberNode = new NodeReference();
365
			replicaMemberNode.setValue("testNode");
366
			replica.setReplicationStatus(ReplicationStatus.REQUESTED);
367
			replica.setReplicaMemberNode(replicaMemberNode);
368
			replica.setReplicaVerified(new Date());
369
			sysmeta.addReplica(replica );
370
			// save it
371
			boolean result = CNodeService.getInstance().registerSystemMetadata(session, guid, sysmeta);
372
			assertTrue(result);
373
			// set it
374
			ReplicationStatus status = ReplicationStatus.COMPLETED;
375
			result = CNodeService.getInstance().setReplicationStatus(session, guid, status);
376
			assertTrue(result);
377
			// get it
378
			sysmeta = CNodeService.getInstance().getSystemMetadata(session, guid);
379
			assertNotNull(sysmeta);
380
			// check it
381
			assertEquals(status, sysmeta.getReplica(0).getReplicationStatus());
382
			
383
        } catch(Exception e) {
384
            fail("Unexpected error: " + e.getMessage());
385
        }
386
	}
387
	
388
	/**
389
	 * Run an initial test that always passes to check that the test harness is
390
	 * working.
391
	 */
392
	public void initialize() 
393
	{
394
	    printTestHeader("initialize");
395
		assertTrue(1 == 1);
396
	}
397
		
398
	/**
399
	 * create system metadata with a specified id
400
	 */
401
	private SystemMetadata createSystemMetadata(Identifier id, Subject owner)
402
	  throws Exception
403
	{
404
	    SystemMetadata sm = new SystemMetadata();
405
        // set the id
406
        sm.setIdentifier(id);
407
        sm.setObjectFormat(ObjectFormatCache.getInstance().getFormat("application/octet-stream"));
408
        // create the checksum
409
        String checksumS = "test";
410
        ChecksumAlgorithm ca = ChecksumAlgorithm.convert("MD5");
411
        Checksum checksum = new Checksum();
412
        checksum.setValue(checksumS);
413
        checksum.setAlgorithm(ca);
414
        sm.setChecksum(checksum);
415
        // set the size
416
        sm.setSize(0);
417
        sm.setSubmitter(owner);
418
        sm.setRightsHolder(owner);
419
        sm.setDateUploaded(new Date());
420
        sm.setDateSysMetadataModified(new Date());
421
        NodeReference nr = new NodeReference();
422
        nr.setValue("metacat");
423
        sm.setOriginMemberNode(nr);
424
        sm.setAuthoritativeMemberNode(nr);
425
		// set the access to public read
426
        AccessPolicy accessPolicy = new AccessPolicy();
427
        AccessRule allow = new AccessRule();
428
        allow.addPermission(Permission.READ);
429
        Subject publicSubject = new Subject();
430
        publicSubject.setValue(Constants.PUBLIC_SUBJECT);
431
		allow.addSubject(publicSubject);
432
		accessPolicy.addAllow(allow);
433
        sm.setAccessPolicy(accessPolicy);
434
        
435
        return sm;
436
	}
437
	
438
	/**
439
	 * For fresh Metacat installations without the Object Format List
440
	 * we insert the default version from d1_common.jar
441
	 */
442
	private void setUpFormats() {
443
		try {
444
			Metacat m = MetacatFactory.createMetacatConnection(metacatUrl);
445
			m.login(username, password);
446
			// check if it exists already
447
			InputStream is = null;
448
			try {
449
				is = m.read(ObjectFormatService.OBJECT_FORMAT_DOCID);
450
			} catch (Exception e) {
451
				// probably missing the doc
452
			}
453
			if (is == null) {
454
				ObjectFormatList formats = ObjectFormatServiceImpl.getInstance().listFormats();
455
				ByteArrayOutputStream out = new ByteArrayOutputStream();
456
				ServiceTypeUtil.serializeServiceType(ObjectFormatList.class, formats, out);
457
				Reader xmlDocument = new InputStreamReader(new ByteArrayInputStream(out.toByteArray()));
458
				m.insert(ObjectFormatService.OBJECT_FORMAT_DOCID + ".1", xmlDocument, null);
459
			}
460
			m.logout();
461
		} catch (Exception e) {
462
			// any number of things could go wrong
463
			e.printStackTrace();
464
		}
465
	}
466

    
467
	/**
468
	 * test to list the object formats registered in metacat
469
	 */
470
	public void testListFormats() {
471
		
472
    printTestHeader("testListFormats");
473
    
474
    // make sure we are set up
475
    setUpFormats();
476
    
477
    // there should be at least 59 formats in the list
478
  	int formatsCount = 59;
479
  	ObjectFormatList objectFormatList;
480
  	
481
  	try {
482
	    objectFormatList = CNodeService.getInstance().listFormats();
483
	  	assertTrue(objectFormatList.getTotal() >= formatsCount);
484
  	
485
  	} catch (InvalidRequest e) {
486
  		fail("Could not get the object format list: " + e.getMessage());
487
    
488
  	} catch (ServiceFailure e) {
489
  		fail("Could not get the object format list: " + e.getMessage());
490

    
491
    } catch (NotFound e) {
492
  		fail("Could not get the object format list: " + e.getMessage());
493

    
494
    } catch (InsufficientResources e) {
495
  		fail("Could not get the object format list: " + e.getMessage());
496

    
497
    } catch (NotImplemented e) {
498
  		fail("Could not get the object format list: " + e.getMessage());
499

    
500
    }
501
    
502
	}
503
	
504
  /**
505
   * Test getting a single object format from the registered list
506
   */
507
  public void testGetFormat() {
508
  	
509
    printTestHeader("testGetFormat");
510

    
511
    // make sure we are set up
512
    setUpFormats();
513
    
514
    String knownFormat = "text/plain";
515
    ObjectFormatIdentifier fmtid = new ObjectFormatIdentifier();
516
    fmtid.setValue(knownFormat);
517
  	
518
    try {
519
	    
520
			String result = 
521
				CNodeService.getInstance().getFormat(fmtid).getFmtid().getValue();
522
	  	System.out.println("Expected result: " + knownFormat);
523
	  	System.out.println("Found    result: " + result);
524
	  	assertTrue(result.equals(knownFormat));
525
  
526
    } catch (NullPointerException npe) {	  
527
	    fail("The returned format was null: " + npe.getMessage());
528
    
529
    } catch (NotFound nfe) {     
530
    	fail("The format " + knownFormat + " was not found: " + nfe.getMessage());
531
    	
532
    } catch (InvalidRequest ire) {
533
    	fail("The format " + knownFormat + " was not found: " + ire.getMessage());
534

    
535
    } catch (ServiceFailure sfe) {
536
    	fail("The format " + knownFormat + " was not found: " + sfe.getMessage());
537

    
538
    } catch (InsufficientResources ise) {
539
    	fail("The format " + knownFormat + " was not found: " + ise.getMessage());
540
 
541
    } catch (NotImplemented nie) {
542
    	fail("The getFormat() method has not been implemented: " + nie.getMessage());
543

    
544
    }
545
  	
546
  }
547
	
548
  /**
549
   * Test getting a non-existent object format, returning NotFound
550
   */
551
  public void testObjectFormatNotFoundException() {
552
  
553
    printTestHeader("testObjectFormatNotFoundException");
554

    
555
    ObjectFormatIdentifier fmtid = new ObjectFormatIdentifier();
556
  	String badFormat = "text/bad-format";
557
  	fmtid.setValue(badFormat);
558
  	
559
  	try {
560
  		
561
	    ObjectFormat objectFormat = 
562
	    	CNodeService.getInstance().getFormat(fmtid);
563
      
564
  	} catch (Exception e) {
565
	    
566
  		assertTrue(e instanceof NotFound);
567
  	}
568
  	
569
  }
570
	
571
	/**
572
	 * print a header to start each test
573
	 */
574
	private void printTestHeader(String testName)
575
	{
576
	    System.out.println();
577
	    System.out.println("*************** " + testName + " ***************");
578
	}
579
 
580
}
(1-1/5)