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

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

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