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: berkley $'
8
 *     '$Date: 2010-05-03 14:26:08 -0700 (Fri, 14 Aug 2009) $'
9
 * '$Revision: 5027 $'
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.InputStream;
29
import java.io.StringBufferInputStream;
30
import java.security.MessageDigest;
31
import java.util.Date;
32

    
33
import junit.framework.Test;
34
import junit.framework.TestSuite;
35

    
36
import org.apache.commons.io.IOUtils;
37
import org.dataone.service.exceptions.BaseException;
38
import org.dataone.service.exceptions.NotFound;
39
import org.dataone.service.types.AuthToken;
40
import org.dataone.service.types.Checksum;
41
import org.dataone.service.types.ChecksumAlgorithm;
42
import org.dataone.service.types.DescribeResponse;
43
import org.dataone.service.types.Identifier;
44
import org.dataone.service.types.Log;
45
import org.dataone.service.types.LogEntry;
46
import org.dataone.service.types.NodeReference;
47
import org.dataone.service.types.ObjectFormat;
48
import org.dataone.service.types.ObjectInfo;
49
import org.dataone.service.types.ObjectList;
50
import org.dataone.service.types.Principal;
51
import org.dataone.service.types.SystemMetadata;
52

    
53
import edu.ucsb.nceas.MCTestCase;
54
import edu.ucsb.nceas.metacat.MetaCatServlet;
55
import edu.ucsb.nceas.metacat.client.rest.MetacatRestClient;
56
import edu.ucsb.nceas.metacat.properties.PropertyService;
57
import edu.ucsb.nceas.metacat.service.SessionService;
58
import edu.ucsb.nceas.metacat.util.SessionData;
59

    
60
/**
61
 * A JUnit test for testing the dataone CrudService class
62
 */
63
public class CrudServiceTest extends MCTestCase 
64
{   
65
    private int createCount = 0;
66
    
67
    /**
68
    * consstructor for the test
69
    */
70
    public CrudServiceTest(String name)
71
    {
72
        super(name);
73
    }
74
  
75
    /**
76
	 * Establish a testing framework by initializing appropriate objects
77
	 */
78
	public void setUp() throws Exception 
79
	{
80
		super.setUp();
81
	}
82

    
83
	/**
84
	 * Release any objects after tests are complete
85
	 */
86
	public void tearDown() 
87
	{
88
	    System.out.println(createCount + " docs created in this test session.");
89
	}
90

    
91
	/**
92
	 * Create a suite of tests to be run together
93
	 */
94
	public static Test suite() 
95
	{
96
		TestSuite suite = new TestSuite();
97
		suite.addTest(new CrudServiceTest("initialize"));
98
		
99
		suite.addTest(new CrudServiceTest("testSingletonAccessor"));
100
		suite.addTest(new CrudServiceTest("testCreateAndGet"));
101
		suite.addTest(new CrudServiceTest("testGetSystemMetadata"));
102
		suite.addTest(new CrudServiceTest("testUpdate"));
103
		suite.addTest(new CrudServiceTest("testListObjects"));
104
		suite.addTest(new CrudServiceTest("testAccessControl"));
105
		suite.addTest(new CrudServiceTest("testGetLogRecords"));
106
		suite.addTest(new CrudServiceTest("testChecksumError"));
107
		suite.addTest(new CrudServiceTest("testPublicAccess"));
108
		suite.addTest(new CrudServiceTest("testFailedCreate"));
109
		suite.addTest(new CrudServiceTest("testChecksum"));
110
		suite.addTest(new CrudServiceTest("testDescribe"));
111
		suite.addTest(new CrudServiceTest("testDelete"));
112
		suite.addTest(new CrudServiceTest("testSemiColonsInIdentifiers"));
113
		suite.addTest(new CrudServiceTest("testGenerateMissingSystemMetadata"));
114
		return suite;
115
	}
116
	
117
	/**
118
	 * test for the use of semi colons in identifiers
119
	 * in response to https://redmine.dataone.org/issues/1143
120
	 */
121
	public void testSemiColonsInIdentifiers()
122
	{
123
	    try
124
        {
125
            CrudService cs = CrudService.getInstance();
126
            AuthToken token = getToken();
127
            String testDoc = getTestDoc();
128
            
129
            Identifier id = new Identifier();
130
            id.setValue("someid;id;with;semi;colons;in;it." + new Date().getTime());
131
            String docid = generateDocumentId();
132
            
133
            //create the system metadata then run the create method
134
            StringBufferInputStream sbis = new StringBufferInputStream(testDoc);
135
            SystemMetadata sm = createSystemMetadata(id, testDoc, 
136
                    ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0"));
137
            //create the doc
138
            Identifier rGuid = cs.create(token, id, sbis, sm);
139
            
140
            System.out.println("ID: " + rGuid.getValue());
141
            assertTrue(rGuid.toString().equals(id.toString())); 
142
            System.out.println("created doc with id " + id.getValue());
143
        }
144
        catch(Exception e)
145
        {
146
            fail("Unexpected error in testDescribe: " + e.getMessage());
147
        }
148
	}
149
	
150
	/**
151
	 * test the delete function
152
	 */
153
	public void testDelete()
154
	{
155
	    try
156
        {
157
            CrudService cs = CrudService.getInstance();
158
            AuthToken token = getToken();
159
            String doc = getTestDoc();
160
            Identifier id = createDoc(token, doc);
161
            System.out.println("ID: " + id.getValue());
162
            makeDocPublic(token, id, true);
163
            cs.get(token, id);
164
            cs.delete(token, id);
165
            //there should be a try/catch around the next statement
166
            //to make sure that the document is no longer readable,
167
            //but because the data is output in a 2nd thread, the
168
            //exception does not get caught here.  See 
169
            //https://redmine.dataone.org/issues/1079
170
            //cs.get(token, id);
171
        }
172
        catch(Exception e)
173
        {
174
            fail("Unexpected error in testDescribe: " + e.getMessage());
175
        }
176
	}
177
	
178
	/**
179
	 * test the describe crud function
180
	 */
181
	public void testDescribe()
182
	{
183
	    try
184
	    {
185
	        CrudService cs = CrudService.getInstance();
186
	        AuthToken token = getToken();
187
	        
188
	        String doc = getTestDoc();
189
	        Identifier id = createDoc(token, doc);
190
	        System.out.println("ID: " + id.getValue());
191
	        makeDocPublic(token, id, true);
192
	        
193
	        SystemMetadata sm = cs.getSystemMetadata(token, id);
194
	        
195
	        DescribeResponse dr = cs.describe(token, id);
196
	        
197
	        assertTrue(dr.getDataONE_Checksum().getValue().equals(sm.getChecksum().getValue()));
198
	        assertTrue(dr.getDataONE_ObjectFormat().toString().equals(sm.getObjectFormat().toString()));
199
	        assertTrue(dr.getLast_Modified().getTime() == sm.getDateSysMetadataModified().getTime());
200
	        assertTrue(dr.getContent_Length() == sm.getSize());
201
	    }
202
	    catch(Exception e)
203
	    {
204
	        fail("Unexpected error in testDescribe: " + e.getMessage());
205
	    }
206
	}
207
	
208
	/**
209
	 * test the checksum creation
210
	 */
211
	public void testChecksum()
212
	{
213
	    try
214
	    {
215
	        CrudService cs = CrudService.getInstance();
216
	        AuthToken token = getToken();
217
	        System.out.println("token: " + token.getToken());
218
	        String doc = getTestDoc();
219
	        Identifier id = createDoc(token, doc);
220
	        System.out.println("ID: " + id.getValue());
221
            makeDocPublic(token, id, true);
222
	        String doc2 = getDoc(token, id);
223
            
224
	        String checksum = checksum(doc);
225
            Checksum checksum2 = cs.getChecksum(token, id, "MD5");
226
            System.out.println("doc: \"" + doc + "\"");
227
            System.out.println("doc2: \"" + doc2 + "\"");
228
            System.out.println("checksum1: " + checksum);
229
            System.out.println("checksum2: " + checksum2.getValue());
230
            assertTrue(checksum.equals(checksum2.getValue()));
231
            
232
	    }
233
	    catch(Exception e)
234
	    {
235
	        fail("Unexpected error in testChecksum: " + e.getMessage());
236
	    }
237
	    
238
	}
239
	
240
	/**
241
	 * insert an invalid document and make sure create fails and does not
242
	 * leave any artifacts behind
243
	 */
244
	public void testFailedCreate()
245
	{
246
	    try
247
	    {
248
	        String invalidDoc = "<xxx></yyy>";
249
	        System.out.println("trying to insert doc " + invalidDoc);
250
	        CrudService cs = CrudService.getInstance();
251
            AuthToken token = getToken();
252
            //run create
253
            try
254
            {
255
                Identifier id = createDoc(token, invalidDoc);
256
                fail("Should have thrown an exception.");
257
            }
258
            catch(Exception e)
259
            {
260
                //e.printStackTrace();
261
            }
262
            
263
	    }
264
	    catch(Exception e)
265
	    {
266
	        fail("unexpected exception in testFailedCreate: " + e.getMessage());
267
	    }
268
	}
269
	
270
	/**
271
	 * test to make sure that get and listObjects methods are publicly accessible
272
	 */
273
	public void testPublicAccess()
274
	{
275
	    try
276
	    {
277
	        System.out.println("********************* testPublicAccess *********************");
278
	        AuthToken token = new AuthToken("public");
279
	        //AuthToken token = getToken();
280
	        CrudService cs = CrudService.getInstance();
281
	        ObjectList ol = cs.listObjects(token, null, null, null);
282
	        System.out.println("ol: " + ol.sizeObjectInfoList());
283
	        assertTrue(ol.sizeObjectInfoList() > 0);
284
	        
285
	        ObjectInfo oi = ol.getObjectInfo(0);
286
	        String s = getDoc(token, oi.getIdentifier());
287
	        assertNotNull(s);
288
	        
289
	        try
290
	        { //try a create with the public auth.  should fail
291
	            Identifier id = new Identifier();
292
	            String docid = generateDocumentId();
293
	            id.setValue(docid);
294
	            String testDoc = getTestDoc();
295
	            StringBufferInputStream sbis = new StringBufferInputStream(testDoc);
296
	            ObjectFormat of1 = ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0");
297
	            SystemMetadata sm = createSystemMetadata(id, testDoc, of1);
298
	            assertFalse(sm.getChecksum().getValue().startsWith("MD5"));
299
	            //create the doc
300
	            Identifier idC = cs.create(token, id, sbis, sm);
301
	            fail("Should have thrown an auth exception");
302
	        }
303
	        catch(Exception e)
304
	        {
305
	            
306
	        }
307
	        
308
	        //create a legit doc
309
	        token = getToken();
310
	        Identifier id = new Identifier();
311
            String docid = generateDocumentId();
312
            id.setValue(docid);
313
            String testDoc = getTestDoc();
314
            StringBufferInputStream sbis = new StringBufferInputStream(testDoc);
315
            ObjectFormat of1 = ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0");
316
            SystemMetadata sm = createSystemMetadata(id, testDoc, of1);
317
            assertFalse(sm.getChecksum().getValue().startsWith("MD5"));
318
            //create the doc
319
            Identifier idC = cs.create(token, id, sbis, sm);
320
            //make it public, then use a public token to try to get it
321
            InputStream data = null;
322
            try
323
            {
324
                AuthToken publicToken = new AuthToken("public");
325
                data = cs.get(publicToken, id);
326
                data.read();
327
                
328
                fail("should have thrown an exception");
329
            }
330
            catch(Exception e)
331
            {
332
                /*System.out.println("%%%%%%%%%%%%%%%%%%%%%%%getting result");
333
                Object o = ((InputStreamFromOutputStream)data).getResult();
334
                System.out.println("result: " + o);
335
                System.out.println("exception thrown!");
336
                System.out.println("exception thrown: " + e.getClass().getName());*/
337
            }
338
            
339
            
340
            
341
            makeDocPublic(token, id, true);
342
            token = new AuthToken("public");
343
	        data = cs.get(token, id);
344
	    }
345
	    catch(Exception e)
346
	    {
347
	        fail("Error in testPublicAccess: " + e.getMessage());
348
	    }
349
	    
350
	}
351
	
352
	/**
353
	 * test for an error where the checksum algorithm gets appended onto the checksum.
354
	 */
355
	public void testChecksumError()
356
	{
357
	    printTestHeader("testChecksumError");
358
	    try
359
	    {
360
	        Date d1 = new Date(new Date().getTime() - 5000);
361
	        CrudService cs = CrudService.getInstance();
362
	        AuthToken token = getToken();
363
	        ObjectFormat of1 = ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0");
364
	        //create docs at different times
365

    
366
	        Identifier id = new Identifier();
367
	        String docid = "test." + new Date().getTime();
368
	        id.setValue(docid);
369

    
370
	        //create the system metadata then run the create method
371
	        String testDoc = getTestDoc();
372
	        StringBufferInputStream sbis = new StringBufferInputStream(testDoc);
373
	        SystemMetadata sm = createSystemMetadata(id, testDoc, of1);
374
	        assertFalse(sm.getChecksum().getValue().startsWith("MD5"));
375
	        //create the doc
376
	        Identifier idC = cs.create(token, id, sbis, sm);
377
	        makeDocPublic(token, id, true);
378
	        assertTrue(idC.getValue().equals(id.getValue()));
379
	        SystemMetadata smC = getSystemMetadata(token, idC);
380
	        assertFalse(smC.getChecksum().getValue().startsWith("MD5"));
381
	        
382
	        Date d2 = new Date(new Date().getTime() + 5000);
383
	        
384
	        ObjectList ol = cs.listObjects(token, d1, d2, of1);
385
	        assertTrue(ol.sizeObjectInfoList() > 0);
386
	        ObjectInfo oi = ol.getObjectInfo(0);
387
	        //this will fail if the error state exists.
388
	        assertFalse(oi.getChecksum().getValue().startsWith("MD5"));
389
	    }
390
	    catch(Exception e)
391
	    {
392
	        fail("Unexpected exception: " + e.getMessage());
393
	    }
394
        
395
	}
396
	
397
	/**
398
	 * test CrudService.getLogRecords
399
	 */
400
	public void testGetLogRecords()
401
	{
402
	    printTestHeader("testGetLogRecords");
403
	    try
404
	    {
405
	        CrudService cs = CrudService.getInstance();
406
	        AuthToken token = getToken();
407
	        Date fromDate = new Date();
408
	        Identifier id = createDoc(token, getTestDoc());
409
	        Date toDate = new Date();
410
	        Log lrs = cs.getLogRecords(token, fromDate, toDate, null);
411
	        assertNotNull(lrs);
412
	        System.out.println("log entry size: " + lrs.sizeLogEntryList());
413
	        assertTrue(lrs.sizeLogEntryList() == 1);
414
	        LogEntry lrLogEvent = lrs.getLogEntry(0);
415
	        assertTrue(lrLogEvent.getEvent().name().equals("CREATE"));
416
	        assertTrue(lrLogEvent.getIdentifier().getValue().equals(id.getValue()));
417
	    }
418
	    catch(Exception e)
419
	    {
420
	        e.printStackTrace();
421
	        fail("testGetLogRecords threw an unexpected exception: " + e.getMessage());
422
	    }
423
	}
424
	
425
	/**
426
	 * test the generation of system metadata for docs that don't already 
427
	 * have it.  This will be used for migration of existing object stores
428
	 * to dataone.
429
	 */
430
	public void testGenerateMissingSystemMetadata()
431
	{
432
	    printTestHeader("testGenerateMissingSystemMetadata");
433
	    try
434
	    {
435
	        
436
	        CrudService cs = CrudService.getInstance();
437
	        AuthToken token = getToken();
438
	        //create a document with no system metadata
439
	        String testDoc = getTestDoc();
440
	        Identifier id = new Identifier();
441
	        String docid = generateDocumentId();
442
	        id.setValue(docid);
443
	        
444
	        cs.insertOrUpdateDocument(testDoc, id, cs.getSessionData(token), "insert", false); 
445
	        //try to get its system metadata, should fail
446
	        try
447
	        {
448
	            getSystemMetadata(token, id);
449
	            fail("call to getSystemMetadata should have failed.");
450
	        }
451
	        catch(org.dataone.service.exceptions.NotFound e)
452
	        {
453
	        	// expect an exception of this type
454
	        }
455
	        
456
	        //generate missing system metadata
457
	        cs.generateMissingSystemMetadata(token);
458
	        //try to get system metadata again, should succeed
459
	        SystemMetadata smd = getSystemMetadata(token, id);
460
	        assertTrue("SystemMetadata should not be null", smd != null);
461
	    }
462
	    catch(Exception e)
463
	    {
464
	    	System.out.println("testGenerateSystemMetadata  ***  exception trace:");
465
	    	e.printStackTrace();
466
	    	fail("Unexpected error generating missing system metadata: " + e.getClass() + ": " + e.getMessage());
467
	    }
468
	}
469
	
470
	/**
471
	 * make sure that only valid sessions can update/delete
472
	 */
473
	public void testAccessControl()
474
	{
475
	    printTestHeader("testAccessControl");
476
        try
477
        {
478
            CrudService cs = CrudService.getInstance();
479
            AuthToken token = getToken();
480
            //create a doc
481
            Identifier id = createDoc(token, getTestDoc());
482
            
483
            //get the doc and sysmetadata
484
            String gotDoc = getDoc(token, id);
485
            SystemMetadata sm = getSystemMetadata(token, id);
486
            
487
            //break the session id
488
            String sessionid = "somefakesessionid";
489
            token = new AuthToken(sessionid);
490
            
491
            //update the doc
492
            gotDoc = gotDoc.replaceAll("XXX", "YYY");
493
            Identifier newid = new Identifier();
494
            newid.setValue(generateDocumentId());
495
            StringBufferInputStream sbis = new StringBufferInputStream(gotDoc);
496
            SystemMetadata newsm = createSystemMetadata(newid, gotDoc);
497
            Identifier updatedid = cs.update(token, newid, sbis, id, newsm);
498
            fail("exception should have been thrown.");
499
        }
500
        catch(Exception e)
501
        {
502
        }
503
        
504
        try
505
        {
506
            CrudService cs = CrudService.getInstance();
507
            AuthToken token = new AuthToken("somefakesessionid");
508
            //create a doc
509
            Identifier id = createDoc(token, getTestDoc());
510
            fail("exception should have been thrown.");
511
        }
512
        catch(Exception e)
513
        {
514
        }
515
	}
516
	
517
	/**
518
	 * public ObjectList listObjects(AuthToken token, Date startTime, Date endTime, 
519
     *     ObjectFormat objectFormat, boolean replicaStatus, int start, int count)
520
     *       throws NotAuthorized, InvalidRequest, NotImplemented, ServiceFailure, InvalidToken
521
	 */
522
	public void testListObjects()
523
	{
524
	    printTestHeader("testListObjects");
525
	    try
526
	    {
527
	        CrudService cs = CrudService.getInstance();
528
	        AuthToken token = getToken();
529
	        ObjectFormat of1 = ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0");
530
	        ObjectFormat of2 = ObjectFormat.convert("eml://ecoinformatics.org/eml-2.0.0");
531
	        //create docs at different times
532
	        Date d1 = new Date();
533
	        Identifier id1 = createDoc(token, getTestDoc(EML2_1_0), of1);
534
            SystemMetadata sm1 = getSystemMetadata(token, id1);
535
            
536
            Date d2 = new Date();
537
            Identifier id2 = createDoc(token, getTestDoc(EML2_0_0), of2);
538
            makeDocPublic(token, id2, true);
539
            SystemMetadata sm2 = getSystemMetadata(token, id2);
540
            
541
            Date d3 = new Date();
542
            Identifier id3 = createDoc(token, getTestDoc(EML2_1_0), of1);
543
            makeDocPublic(token, id3, true);
544
            SystemMetadata sm3 = getSystemMetadata(token, id3);
545
              
546
            Date d4 = new Date();
547
            Identifier id4 = createDoc(token, getTestDoc(EML2_0_0), of2);
548
            makeDocPublic(token, id4, true);
549
            SystemMetadata sm4 = getSystemMetadata(token, id4);
550
            
551
            Date d5 = new Date();
552
            Identifier id5 = createDoc(token, getTestDoc(EML2_1_0), of1);
553
            makeDocPublic(token, id5, true);
554
            SystemMetadata sm5 = getSystemMetadata(token, id5);  
555
             
556
            Date d6 = new Date();
557
            
558
            //now get the objects for specific time ranges and test that it returns
559
            //the correct objects
560
            
561
            //ObjectList list = cs.listObjects(token, null, null, null);
562
            //System.out.println("list size: " + list.sizeObjectInfoList());
563
           
564
            //should return sm1 and sm2
565
            ObjectList list1 = cs.listObjects(token, d1, d3, null);
566
            assertTrue(list1.sizeObjectInfoList() == 2);
567
            assertTrue(idInObjectList(id1, list1));
568
            assertTrue(idInObjectList(id2, list1));
569
            
570
            ObjectInfo info = list1.getObjectInfo(0);
571
            
572
            
573
            //should only return sm1
574
            ObjectList list2 = cs.listObjects(token, d1, d3, of1);
575
            assertTrue(list2.sizeObjectInfoList() == 1);
576
            assertTrue(idInObjectList(id1, list2));
577
            
578
            //should return sm1-sm4
579
            ObjectList list3 = cs.listObjects(token, d1, d5, null);
580
            assertTrue(list3.sizeObjectInfoList() == 4);
581
            ObjectInfo oi4 = list3.getObjectInfo(0);
582
            assertTrue(idInObjectList(id1, list3));
583
            assertTrue(idInObjectList(id2, list3));
584
            assertTrue(idInObjectList(id3, list3));
585
            assertTrue(idInObjectList(id4, list3));
586
            
587
            //should only return sm2 and sm4
588
            ObjectList list4 = cs.listObjects(token, d1, d5, of2);
589
            assertTrue(list4.sizeObjectInfoList() == 2);
590
            assertTrue(idInObjectList(id2, list4));
591
            assertTrue(idInObjectList(id4, list4));
592
            
593
            //should return all
594
            ObjectList list5 = cs.listObjects(token, d1, d6, null);
595
            assertTrue(list5.sizeObjectInfoList() == 5);
596
            assertTrue(idInObjectList(id1, list5));
597
            assertTrue(idInObjectList(id2, list5));
598
            assertTrue(idInObjectList(id3, list5));
599
            assertTrue(idInObjectList(id4, list5));
600
            assertTrue(idInObjectList(id5, list5));
601
            
602
            //should return 1, 3, 5
603
            ObjectList list6 = cs.listObjects(token, d1, d6, of1);
604
            assertTrue(list6.sizeObjectInfoList() == 3);
605
            assertTrue(idInObjectList(id1, list6));
606
            assertTrue(idInObjectList(id3, list6));
607
            assertTrue(idInObjectList(id5, list6));
608
            
609
            //should return 4 (id1 is not public)
610
            token = new AuthToken("public");
611
            ObjectList list7 = cs.listObjects(token, d1, d6, null);
612
            //System.out.println("list7 size: " + list7.sizeObjectInfoList());
613
            assertTrue(list7.sizeObjectInfoList() == 5);
614
            
615
            //test paging
616
            ObjectList list8 = cs.listObjects(token, d1, d6, null, false, 2, 2);
617
            assertTrue(list8.getCount() == 2);
618
            assertTrue(list8.getStart() == 2);
619
            assertTrue(list8.getTotal() == 5);
620
            
621
            
622
	    }
623
	    catch(Exception e)
624
	    {
625
	        //e.printStackTrace();
626
	        fail("Error in listObjects: " + e.getMessage());
627
	    }
628
	}
629
	
630
	private boolean idInObjectList(Identifier id, ObjectList list)
631
	{
632
	    for(int i=0; i<list.sizeObjectInfoList(); i++)
633
	    {
634
	        ObjectInfo oi = list.getObjectInfo(i);
635
	        if(id.getValue().equals(oi.getIdentifier().getValue()))
636
	            return true;
637
	    }
638
	    return false;
639
	}
640
	
641
	/**
642
	 * public Identifier update(AuthToken token, Identifier guid, 
643
     *       InputStream object, Identifier obsoletedGuid, SystemMetadata sysmeta) 
644
     *         throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique, 
645
     *           UnsupportedType, InsufficientResources, NotFound, InvalidSystemMetadata, 
646
     *           NotImplemented
647
	 */
648
	public void testUpdate()
649
	{
650
	    printTestHeader("testUpdate");
651
	    try
652
	    {
653
	        CrudService cs = CrudService.getInstance();
654
	        AuthToken token = getToken();
655
            //create a doc
656
            Identifier id = createDoc(token, getTestDoc());
657
            
658
            //get the doc and sysmetadata
659
            String gotDoc = getDoc(token, id);
660
            SystemMetadata sm = getSystemMetadata(token, id);
661
            
662
            //update the doc
663
            gotDoc = gotDoc.replaceAll("XXX", "YYY");
664
            Identifier newid = new Identifier();
665
            newid.setValue(generateDocumentId());
666
            StringBufferInputStream sbis = new StringBufferInputStream(gotDoc);
667
            SystemMetadata newsm = createSystemMetadata(newid, gotDoc);
668
            Identifier updatedid = cs.update(token, newid, sbis, id, newsm);
669
            
670
            //get doc - check that it matches update
671
            String newdoc = getDoc(token, newid);
672
            assertTrue(gotDoc.equals(newdoc));
673
            
674
            //get sysmeta - check that ids and other fields are updated
675
            SystemMetadata newnewsm = getSystemMetadata(token, id);
676
            assertTrue(newnewsm.getObsoletedBy(0).getValue().equals(newid.getValue()));
677
            
678
            //get the new sysmeta and make sure the obsoletes field is set
679
            SystemMetadata newnewnewsm = getSystemMetadata(token, newid);
680
            assertTrue(newnewnewsm.getObsolete(0).getValue().equals(id.getValue()));
681
        }
682
        catch(Exception e)
683
        {
684
            e.printStackTrace();
685
            fail("Error in testUpdate: " + e.getMessage());
686
        }
687
	}
688
	
689
	/**
690
	 * public SystemMetadata getSystemMetadata(AuthToken token, Identifier guid)
691
     *       throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, 
692
     *       InvalidRequest, NotImplemented
693
	 */
694
	public void testGetSystemMetadata()
695
	{
696
	    printTestHeader("testGetSystemMetadata");
697
	    try
698
	    {
699
            CrudService cs = CrudService.getInstance();
700
            AuthToken token = getToken();
701
            //run create
702
            Identifier id = createDoc(token, getTestDoc());
703
            //get the systemMetadata and make sure it is the correct object for this testDoc
704
            SystemMetadata sm = getSystemMetadata(token, id);
705
            assertTrue(sm.getIdentifier().getValue().equals(id.getValue()));
706
            assertTrue(sm.getChecksum().getValue().equals(checksum(getTestDoc())));
707
            
708
            try
709
            {
710
                Identifier fakeid = new Identifier();
711
                fakeid.setValue("somethingfake.234234");
712
                getSystemMetadata(token, fakeid);
713
                fail("getSystemMetadata should have thrown an exception.");
714
            }
715
            catch(Exception e)
716
            {
717
                assertTrue(true);
718
            }
719
        }
720
        catch(Exception e)
721
        {
722
            e.printStackTrace();
723
            fail("Error testing system metadata: " + e.getMessage());
724
        }
725
	}
726
	
727
	/**
728
	 * create(AuthToken token, Identifier guid, InputStream object, SystemMetadata sysmeta) 
729
   *   throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique, UnsupportedType, 
730
   *       InsufficientResources, InvalidSystemMetadata, NotImplemented
731
   *
732
   * public InputStream get(AuthToken token, Identifier guid)
733
   *       throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, 
734
   *       NotImplemented
735
	 */
736
	public void testCreateAndGet()
737
	{
738
	    printTestHeader("testCreateAndGet");
739
	    try
740
	    {
741
	        CrudService cs = CrudService.getInstance();
742
	        AuthToken token = getToken();
743
	        //run create
744
	        Identifier id = createDoc(token, getTestDoc());
745
	        //make these docs public for debugging purposes.
746
	        makeDocPublic(token, id, true);
747
            //compare the docs
748
            String gotDoc = getDoc(token, id);
749
            assertTrue(gotDoc.trim().equals(getTestDoc().trim()));
750
            
751
            try
752
            {
753
                Identifier fakeid = new Identifier();
754
                fakeid.setValue("somethingfake.234234");
755
                getDoc(token, fakeid);
756
                fail("testCreateAndGet should have thrown an exception.");
757
            }
758
            catch(Exception e)
759
            {
760
                assertTrue(true);
761
            }
762
        }
763
        catch(Exception e)
764
        {
765
            e.printStackTrace();
766
            fail("Error in testCreate: " + e.getMessage());
767
        }
768
	}
769
	
770
	/**
771
	 * getInstance()
772
	 */
773
	public void testSingletonAccessor()
774
	{
775
	    printTestHeader("testSingletonAccessor");
776
	    CrudService cs = CrudService.getInstance();
777
	    assertNotNull(cs);
778
	}
779
	
780
	/**
781
	 * Run an initial test that always passes to check that the test harness is
782
	 * working.
783
	 */
784
	public void initialize() 
785
	{
786
	    printTestHeader("initialize");
787
		assertTrue(1 == 1);
788
	}
789
	
790
	/**
791
	 * return the systemMetadata object for id
792
	 */
793
	private SystemMetadata getSystemMetadata(AuthToken token, Identifier id)
794
	  throws BaseException
795
	{
796
	    CrudService cs = CrudService.getInstance();
797
	    return cs.getSystemMetadata(token, id);
798
	}
799
	
800
	/**
801
	 * get a doc from metacat using CrudService.get()
802
	 */
803
	private String getDoc(AuthToken token, Identifier id)
804
	  throws Exception
805
	{
806
	    CrudService cs = CrudService.getInstance();
807
        InputStream gotDocStream = cs.get(token, id);
808
        return IOUtils.toString(gotDocStream);
809
	}
810
	
811
	public String getTestDoc()
812
	{
813
	    return getTestDoc(null);
814
	}
815
	
816
	/**
817
	 * return a test document.  objectFormat should come from MCTestCase
818
	 */
819
	public String getTestDoc(String objectFormat)
820
	{
821
	    if(objectFormat == null)
822
	    {
823
	        return "<?xml version=\"1.0\"?><test><somecontent>This is some content XXX</somecontent></test>\n";
824
	    }
825
	    
826
	    String accessBlock = getAccessBlock("public", true, true,
827
                false, false, false);
828
	    
829
	    
830
	    return getTestEmlDoc("Test identifier manager", objectFormat, null,
831
	                null, "http://fake.example.com/somedata", null,
832
	                accessBlock, null, null,
833
	                null, null);
834
	}
835
	
836
	/**
837
	 * authenticate and return a token
838
	 * use the test.mcUser and test.mcPassword username/password combo
839
	 */
840
	public AuthToken getToken()
841
	  throws Exception
842
	{
843
        String username = PropertyService.getProperty("test.mcUser");
844
        String password = PropertyService.getProperty("test.mcPassword");
845
        return getToken(username, password);
846
	}
847
	
848
	/**
849
	 * authenticate and return a token using the given credentials
850
	 */
851
	public AuthToken getToken(String username, String password)
852
	  throws Exception
853
	{
854
	    CrudService cs = CrudService.getInstance();
855
        //login and get a sessionid
856
        MetacatRestClient restClient = new MetacatRestClient(cs.getContextUrl());
857
        String response = restClient.login(username, password);
858
        String sessionid = restClient.getSessionId();
859
        SessionService sessionService = SessionService.getInstance();
860
        sessionService.registerSession(new SessionData(sessionid, username, new String[0], password, "CrudServiceLogin"));
861
        AuthToken token = new AuthToken(sessionid);
862
        return token;
863
	}
864
	
865
	/**
866
	 * create a doc using CrudService.create() and return its id
867
	 */
868
	public Identifier createDoc(AuthToken token, String testDoc) throws Exception
869
	{
870
	    return createDoc(token, testDoc, ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0"));
871
	}
872
	
873
	/**
874
	 * create a doc using CrudService.create() and return its id
875
	 */
876
	public Identifier createDoc(AuthToken token, String testDoc, ObjectFormat format) throws Exception
877
	{
878
	    Identifier id;
879
        CrudService cs = CrudService.getInstance();
880
        
881
        id = new Identifier();
882
        String docid = generateDocumentId();
883
        id.setValue(docid);
884
        
885
        //create the system metadata then run the create method
886
        StringBufferInputStream sbis = new StringBufferInputStream(testDoc);
887
        SystemMetadata sm = createSystemMetadata(id, testDoc, format);
888
        //create the doc
889
        cs.create(token, id, sbis, sm);
890
        createCount++;
891
        return id;
892
	}
893
	
894
	/**
895
	 * create a generic SystemMetadata object for testing
896
	 */
897
	private SystemMetadata createSystemMetadata(Identifier id, String testDoc)
898
	  throws Exception
899
	{
900
	    return createSystemMetadata(id, testDoc, 
901
	            ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0"));
902
	}
903
	
904
	/**
905
	 * create system metadata with a specified id, doc and format
906
	 */
907
	private SystemMetadata createSystemMetadata(Identifier id, String testDoc, ObjectFormat format)
908
	  throws Exception
909
	{
910
	    SystemMetadata sm = new SystemMetadata();
911
        //set the id
912
        sm.setIdentifier(id);
913
        sm.setObjectFormat(format);
914
        //create the checksum
915
        String checksumS = checksum(testDoc);
916
        ChecksumAlgorithm ca = ChecksumAlgorithm.convert("MD5");
917
        Checksum checksum = new Checksum();
918
        checksum.setValue(checksumS);
919
        checksum.setAlgorithm(ca);
920
        sm.setChecksum(checksum);
921
        //set the size
922
        sm.setSize(testDoc.getBytes(MetaCatServlet.DEFAULT_ENCODING).length);
923
        //submitter
924
        Principal p = new Principal();
925
        p.setValue("joe");
926
        sm.setSubmitter(p);
927
        sm.setRightsHolder(p);
928
        sm.setDateUploaded(new Date());
929
        sm.setDateSysMetadataModified(new Date());
930
        NodeReference nr = new NodeReference();
931
        nr.setValue("metacat");
932
        sm.setOriginMemberNode(nr);
933
        sm.setAuthoritativeMemberNode(nr);
934
        return sm;
935
	}
936
	
937
	/**
938
	 *  make a document public in metacat by inserting an access document
939
	 * @param id
940
	 */
941
	private void makeDocPublic(AuthToken token, Identifier id, boolean systemMetadataToo)
942
	  throws Exception
943
	{
944
	    CrudService cs = CrudService.getInstance();
945
	    cs.setAccess(token, id, "public", "read", "allow", "allowFirst", systemMetadataToo);
946
	}
947
	
948
	/**
949
	 * print a header to start each test
950
	 */
951
	private void printTestHeader(String testName)
952
	{
953
	    System.out.println();
954
	    System.out.println("*************** " + testName + " ***************");
955
	}
956
  
957
	/**
958
	 * produce an md5 checksum for item
959
	 */
960
	private String checksum(String item)
961
	  throws Exception
962
	{
963
        StringBufferInputStream fis =  new StringBufferInputStream(item);
964
        
965
        byte[] buffer = new byte[1024];
966
        MessageDigest complete = MessageDigest.getInstance("MD5");
967
        int numRead;
968
        
969
        do 
970
        {
971
          numRead = fis.read(buffer);
972
          if (numRead > 0) 
973
          {
974
            complete.update(buffer, 0, numRead);
975
          }
976
        } while (numRead != -1);
977
        
978
        
979
        return getHex(complete.digest());
980
	}
981
	
982
	/**
983
	 * convert a byte array to a hex string
984
	 */
985
	private static String getHex( byte [] raw ) 
986
	{
987
	    final String HEXES = "0123456789ABCDEF";
988
        if ( raw == null ) {
989
          return null;
990
        }
991
        final StringBuilder hex = new StringBuilder( 2 * raw.length );
992
        for ( final byte b : raw ) {
993
          hex.append(HEXES.charAt((b & 0xF0) >> 4))
994
             .append(HEXES.charAt((b & 0x0F)));
995
        }
996
        return hex.toString();
997
  }
998
}
(1-1/3)