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.util.*;
29
import java.io.*;
30

    
31
import java.security.MessageDigest;
32

    
33
import edu.ucsb.nceas.MCTestCase;
34
import edu.ucsb.nceas.metacat.IdentifierManager;
35
import edu.ucsb.nceas.metacat.client.MetacatAuthException;
36
import edu.ucsb.nceas.metacat.client.MetacatException;
37
import edu.ucsb.nceas.metacat.client.MetacatInaccessibleException;
38
import edu.ucsb.nceas.metacat.dataone.CrudService;
39
import junit.framework.Test;
40
import junit.framework.TestSuite;
41

    
42
import org.apache.commons.io.IOUtils;
43
import org.apache.log.LogEvent;
44
import org.dataone.service.exceptions.InvalidRequest;
45
import org.dataone.service.exceptions.InvalidToken;
46
import org.dataone.service.exceptions.NotAuthorized;
47
import org.dataone.service.exceptions.NotImplemented;
48
import org.dataone.service.exceptions.ServiceFailure;
49
import org.dataone.service.types.*;
50

    
51
import edu.ucsb.nceas.metacat.properties.PropertyService;
52
import edu.ucsb.nceas.metacat.client.rest.MetacatRestClient;
53

    
54
import edu.ucsb.nceas.metacat.service.SessionService;
55
import edu.ucsb.nceas.metacat.util.SessionData;
56

    
57
import com.gc.iotools.stream.is.InputStreamFromOutputStream;
58

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

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

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

    
330
	        Identifier id = new Identifier();
331
	        String docid = "test." + new Date().getTime();
332
	        id.setValue(docid);
333

    
334
	        //create the system metadata then run the create method
335
	        String testDoc = getTestDoc();
336
	        StringBufferInputStream sbis = new StringBufferInputStream(testDoc);
337
	        SystemMetadata sm = createSystemMetadata(id, testDoc, of1);
338
	        assertFalse(sm.getChecksum().getValue().startsWith("MD5"));
339
	        //create the doc
340
	        Identifier idC = cs.create(token, id, sbis, sm);
341
	        makeDocPublic(token, id, true);
342
	        assertTrue(idC.getValue().equals(id.getValue()));
343
	        SystemMetadata smC = getSystemMetadata(token, idC);
344
	        assertFalse(smC.getChecksum().getValue().startsWith("MD5"));
345
	        
346
	        Date d2 = new Date(new Date().getTime() + 5000);
347
	        
348
	        ObjectList ol = cs.listObjects(token, d1, d2, of1);
349
	        assertTrue(ol.sizeObjectInfoList() > 0);
350
	        ObjectInfo oi = ol.getObjectInfo(0);
351
	        //this will fail if the error state exists.
352
	        assertFalse(oi.getChecksum().getValue().startsWith("MD5"));
353
	    }
354
	    catch(Exception e)
355
	    {
356
	        fail("Unexpected exception: " + e.getMessage());
357
	    }
358
        
359
	}
360
	
361
	/**
362
	 * test CrudService.getLogRecords
363
	 */
364
	public void testGetLogRecords()
365
	{
366
	    printTestHeader("testGetLogRecords");
367
	    try
368
	    {
369
	        CrudService cs = CrudService.getInstance();
370
	        AuthToken token = getToken();
371
	        Date fromDate = new Date();
372
	        Identifier id = createDoc(token, getTestDoc());
373
	        Date toDate = new Date();
374
	        Log lrs = cs.getLogRecords(token, fromDate, toDate, null);
375
	        assertNotNull(lrs);
376
	        assertTrue(lrs.sizeLogEntryList() == 1);
377
	        LogEntry lrLogEvent = lrs.getLogEntry(0);
378
	        assertTrue(lrLogEvent.getEvent().name().equals("CREATE"));
379
	        assertTrue(lrLogEvent.getIdentifier().getValue().equals(id.getValue()));
380
	    }
381
	    catch(Exception e)
382
	    {
383
	        e.printStackTrace();
384
	        fail("testGetLogRecords threw an unexpected exception: " + e.getMessage());
385
	    }
386
	}
387
	
388
	/**
389
	 * test the generation of system metadata for docs that don't already 
390
	 * have it.  This will be used for migration of existing object stores
391
	 * to dataone.
392
	 */
393
	public void testGenerateMissingSystemMetadata()
394
	{
395
	    printTestHeader("testGenerateMissingSystemMetadata");
396
	    try
397
	    {
398
	        CrudService cs = CrudService.getInstance();
399
	        AuthToken token = getToken();
400
	        //create a document with no system metadata
401
	        String testDoc = getTestDoc();
402
	        Identifier id = new Identifier();
403
	        String docid = generateDocumentId();
404
	        id.setValue(docid);
405
	        
406
	        cs.insertOrUpdateDocument(testDoc, id, cs.getSessionData(token), "insert", false); 
407
	        //try to get its system metadata, should fail
408
	        try
409
	        {
410
	            getSystemMetadata(token, id);
411
	            fail("call to getSystemMetadata should have failed.");
412
	        }
413
	        catch(Exception e)
414
	        {}
415
	        
416
	        //generate missing system metadata
417
	        cs.generateMissingSystemMetadata(token);
418
	        //try to get system metadata again, should succeed
419
	        getSystemMetadata(token, id);
420
	    }
421
	    catch(Exception e)
422
	    {
423
	        fail("Unexpected error generating missing system metadata: " + e.getMessage());
424
	    }
425
	}
426
	
427
	/**
428
	 * make sure that only valid sessions can update/delete
429
	 */
430
	public void testAccessControl()
431
	{
432
	    printTestHeader("testAccessControl");
433
        try
434
        {
435
            CrudService cs = CrudService.getInstance();
436
            AuthToken token = getToken();
437
            //create a doc
438
            Identifier id = createDoc(token, getTestDoc());
439
            
440
            //get the doc and sysmetadata
441
            String gotDoc = getDoc(token, id);
442
            SystemMetadata sm = getSystemMetadata(token, id);
443
            
444
            //break the session id
445
            String sessionid = "somefakesessionid";
446
            token = new AuthToken(sessionid);
447
            
448
            //update the doc
449
            gotDoc = gotDoc.replaceAll("XXX", "YYY");
450
            Identifier newid = new Identifier();
451
            newid.setValue(generateDocumentId());
452
            StringBufferInputStream sbis = new StringBufferInputStream(gotDoc);
453
            SystemMetadata newsm = createSystemMetadata(newid, gotDoc);
454
            Identifier updatedid = cs.update(token, newid, sbis, id, newsm);
455
            fail("exception should have been thrown.");
456
        }
457
        catch(Exception e)
458
        {
459
        }
460
        
461
        try
462
        {
463
            CrudService cs = CrudService.getInstance();
464
            AuthToken token = new AuthToken("somefakesessionid");
465
            //create a doc
466
            Identifier id = createDoc(token, getTestDoc());
467
            fail("exception should have been thrown.");
468
        }
469
        catch(Exception e)
470
        {
471
        }
472
	}
473
	
474
	/**
475
	 * public ObjectList listObjects(AuthToken token, Date startTime, Date endTime, 
476
     *     ObjectFormat objectFormat, boolean replicaStatus, int start, int count)
477
     *       throws NotAuthorized, InvalidRequest, NotImplemented, ServiceFailure, InvalidToken
478
	 */
479
	public void testListObjects()
480
	{
481
	    printTestHeader("testListObjects");
482
	    try
483
	    {
484
	        CrudService cs = CrudService.getInstance();
485
	        AuthToken token = getToken();
486
	        ObjectFormat of1 = ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0");
487
	        ObjectFormat of2 = ObjectFormat.convert("eml://ecoinformatics.org/eml-2.0.0");
488
	        //create docs at different times
489
	        Date d1 = new Date();
490
	        Identifier id1 = createDoc(token, getTestDoc(), of1);
491
            SystemMetadata sm1 = getSystemMetadata(token, id1);
492
            
493
            Date d2 = new Date();
494
            Identifier id2 = createDoc(token, getTestDoc(), of2);
495
            makeDocPublic(token, id2, true);
496
            SystemMetadata sm2 = getSystemMetadata(token, id2);
497
            
498
            Date d3 = new Date();
499
            Identifier id3 = createDoc(token, getTestDoc(), of1);
500
            makeDocPublic(token, id3, true);
501
            SystemMetadata sm3 = getSystemMetadata(token, id3);
502
              
503
            Date d4 = new Date();
504
            Identifier id4 = createDoc(token, getTestDoc(), of2);
505
            makeDocPublic(token, id4, true);
506
            SystemMetadata sm4 = getSystemMetadata(token, id4);
507
            
508
            Date d5 = new Date();
509
            Identifier id5 = createDoc(token, getTestDoc(), of1);
510
            makeDocPublic(token, id5, true);
511
            SystemMetadata sm5 = getSystemMetadata(token, id5);  
512
             
513
            Date d6 = new Date();
514
            
515
            //now get the objects for specific time ranges and test that it returns
516
            //the correct objects
517
            
518
            //ObjectList list = cs.listObjects(token, null, null, null);
519
            //System.out.println("list size: " + list.sizeObjectInfoList());
520
           
521
            //should return sm1 and sm2
522
            ObjectList list1 = cs.listObjects(token, d1, d3, null);
523
            assertTrue(list1.sizeObjectInfoList() == 2);
524
            assertTrue(idInObjectList(id1, list1));
525
            assertTrue(idInObjectList(id2, list1));
526
            
527
            ObjectInfo info = list1.getObjectInfo(0);
528
            
529
            
530
            //should only return sm1
531
            ObjectList list2 = cs.listObjects(token, d1, d3, of1);
532
            assertTrue(list2.sizeObjectInfoList() == 1);
533
            assertTrue(idInObjectList(id1, list2));
534
            
535
            //should return sm1-sm4
536
            ObjectList list3 = cs.listObjects(token, d1, d5, null);
537
            assertTrue(list3.sizeObjectInfoList() == 4);
538
            ObjectInfo oi4 = list3.getObjectInfo(0);
539
            assertTrue(idInObjectList(id1, list3));
540
            assertTrue(idInObjectList(id2, list3));
541
            assertTrue(idInObjectList(id3, list3));
542
            assertTrue(idInObjectList(id4, list3));
543
            
544
            //should only return sm2 and sm4
545
            ObjectList list4 = cs.listObjects(token, d1, d5, of2);
546
            assertTrue(list4.sizeObjectInfoList() == 2);
547
            assertTrue(idInObjectList(id2, list4));
548
            assertTrue(idInObjectList(id4, list4));
549
            
550
            //should return all
551
            ObjectList list5 = cs.listObjects(token, d1, d6, null);
552
            assertTrue(list5.sizeObjectInfoList() == 5);
553
            assertTrue(idInObjectList(id1, list5));
554
            assertTrue(idInObjectList(id2, list5));
555
            assertTrue(idInObjectList(id3, list5));
556
            assertTrue(idInObjectList(id4, list5));
557
            assertTrue(idInObjectList(id5, list5));
558
            
559
            //should return 1, 3, 5
560
            ObjectList list6 = cs.listObjects(token, d1, d6, of1);
561
            assertTrue(list6.sizeObjectInfoList() == 3);
562
            assertTrue(idInObjectList(id1, list6));
563
            assertTrue(idInObjectList(id3, list6));
564
            assertTrue(idInObjectList(id5, list6));
565
            
566
            //should return 4 (id1 is not public)
567
            token = new AuthToken("public");
568
            ObjectList list7 = cs.listObjects(token, d1, d6, null);
569
            //System.out.println("list7 size: " + list7.sizeObjectInfoList());
570
            assertTrue(list7.sizeObjectInfoList() == 4);
571
            
572
            //test paging
573
            ObjectList list8 = cs.listObjects(token, d1, d6, null, false, 2, 2);
574
            assertTrue(list8.getCount() == 2);
575
            assertTrue(list8.getStart() == 2);
576
            assertTrue(list8.getTotal() == 4);
577
            
578
	    }
579
	    catch(Exception e)
580
	    {
581
	        //e.printStackTrace();
582
	        fail("Error in listObjects: " + e.getMessage());
583
	    }
584
	}
585
	
586
	private boolean idInObjectList(Identifier id, ObjectList list)
587
	{
588
	    for(int i=0; i<list.sizeObjectInfoList(); i++)
589
	    {
590
	        ObjectInfo oi = list.getObjectInfo(i);
591
	        if(id.getValue().equals(oi.getIdentifier().getValue()))
592
	            return true;
593
	    }
594
	    return false;
595
	}
596
	
597
	/**
598
	 * public Identifier update(AuthToken token, Identifier guid, 
599
     *       InputStream object, Identifier obsoletedGuid, SystemMetadata sysmeta) 
600
     *         throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique, 
601
     *           UnsupportedType, InsufficientResources, NotFound, InvalidSystemMetadata, 
602
     *           NotImplemented
603
	 */
604
	public void testUpdate()
605
	{
606
	    printTestHeader("testUpdate");
607
	    try
608
	    {
609
	        CrudService cs = CrudService.getInstance();
610
	        AuthToken token = getToken();
611
            //create a doc
612
            Identifier id = createDoc(token, getTestDoc());
613
            
614
            //get the doc and sysmetadata
615
            String gotDoc = getDoc(token, id);
616
            SystemMetadata sm = getSystemMetadata(token, id);
617
            
618
            //update the doc
619
            gotDoc = gotDoc.replaceAll("XXX", "YYY");
620
            Identifier newid = new Identifier();
621
            newid.setValue(generateDocumentId());
622
            StringBufferInputStream sbis = new StringBufferInputStream(gotDoc);
623
            SystemMetadata newsm = createSystemMetadata(newid, gotDoc);
624
            Identifier updatedid = cs.update(token, newid, sbis, id, newsm);
625
            
626
            //get doc - check that it matches update
627
            String newdoc = getDoc(token, newid);
628
            assertTrue(gotDoc.equals(newdoc));
629
            
630
            //get sysmeta - check that ids and other fields are updated
631
            SystemMetadata newnewsm = getSystemMetadata(token, id);
632
            assertTrue(newnewsm.getObsoletedBy(0).getValue().equals(newid.getValue()));
633
            
634
            //get the new sysmeta and make sure the obsoletes field is set
635
            SystemMetadata newnewnewsm = getSystemMetadata(token, newid);
636
            assertTrue(newnewnewsm.getObsolete(0).getValue().equals(id.getValue()));
637
        }
638
        catch(Exception e)
639
        {
640
            e.printStackTrace();
641
            fail("Error in testUpdate: " + e.getMessage());
642
        }
643
	}
644
	
645
	/**
646
	 * public SystemMetadata getSystemMetadata(AuthToken token, Identifier guid)
647
     *       throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, 
648
     *       InvalidRequest, NotImplemented
649
	 */
650
	public void testGetSystemMetadata()
651
	{
652
	    printTestHeader("testGetSystemMetadata");
653
	    try
654
	    {
655
            CrudService cs = CrudService.getInstance();
656
            AuthToken token = getToken();
657
            //run create
658
            Identifier id = createDoc(token, getTestDoc());
659
            //get the systemMetadata and make sure it is the correct object for this testDoc
660
            SystemMetadata sm = getSystemMetadata(token, id);
661
            assertTrue(sm.getIdentifier().getValue().equals(id.getValue()));
662
            assertTrue(sm.getChecksum().getValue().equals(checksum(getTestDoc())));
663
            
664
            try
665
            {
666
                Identifier fakeid = new Identifier();
667
                fakeid.setValue("somethingfake.234234");
668
                getSystemMetadata(token, fakeid);
669
                fail("getSystemMetadata should have thrown an exception.");
670
            }
671
            catch(Exception e)
672
            {
673
                assertTrue(true);
674
            }
675
        }
676
        catch(Exception e)
677
        {
678
            e.printStackTrace();
679
            fail("Error testing system metadata: " + e.getMessage());
680
        }
681
	}
682
	
683
	/**
684
	 * create(AuthToken token, Identifier guid, InputStream object, SystemMetadata sysmeta) 
685
     *   throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique, UnsupportedType, 
686
     *       InsufficientResources, InvalidSystemMetadata, NotImplemented
687
     *
688
     * public InputStream get(AuthToken token, Identifier guid)
689
     *       throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, 
690
     *       NotImplemented
691
	 */
692
	public void testCreateAndGet()
693
	{
694
	    printTestHeader("testCreateAndGet");
695
	    try
696
	    {
697
	        CrudService cs = CrudService.getInstance();
698
	        AuthToken token = getToken();
699
	        //run create
700
	        Identifier id = createDoc(token, getTestDoc());
701
	        //make these docs public for debugging purposes.
702
	        makeDocPublic(token, id, true);
703
            //compare the docs
704
            String gotDoc = getDoc(token, id);
705
            assertTrue(gotDoc.trim().equals(getTestDoc().trim()));
706
            
707
            try
708
            {
709
                Identifier fakeid = new Identifier();
710
                fakeid.setValue("somethingfake.234234");
711
                getDoc(token, fakeid);
712
                fail("testCreateAndGet should have thrown an exception.");
713
            }
714
            catch(Exception e)
715
            {
716
                assertTrue(true);
717
            }
718
        }
719
        catch(Exception e)
720
        {
721
            e.printStackTrace();
722
            fail("Error in testCreate: " + e.getMessage());
723
        }
724
	}
725

    
726
	/**
727
	 * getInstance()
728
	 */
729
	public void testSingletonAccessor()
730
	{
731
	    printTestHeader("testSingletonAccessor");
732
	    CrudService cs = CrudService.getInstance();
733
	    assertNotNull(cs);
734
	}
735
	
736
	/**
737
	 * Run an initial test that always passes to check that the test harness is
738
	 * working.
739
	 */
740
	public void initialize() 
741
	{
742
	    printTestHeader("initialize");
743
		assertTrue(1 == 1);
744
	}
745
	
746
	/**
747
	 * return the systemMetadata object for id
748
	 */
749
	private SystemMetadata getSystemMetadata(AuthToken token, Identifier id)
750
	  throws Exception
751
	{
752
	    CrudService cs = CrudService.getInstance();
753
	    return cs.getSystemMetadata(token, id);
754
	}
755
	
756
	/**
757
	 * get a doc from metacat using CrudService.get()
758
	 */
759
	private String getDoc(AuthToken token, Identifier id)
760
	  throws Exception
761
	{
762
	    CrudService cs = CrudService.getInstance();
763
        InputStream gotDocStream = cs.get(token, id);
764
        return IOUtils.toString(gotDocStream);
765
	}
766
	
767
	/**
768
	 * return a test document
769
	 */
770
	private String getTestDoc()
771
	{
772
	    return "<?xml version=\"1.0\"?><test><somecontent>This is some content XXX</somecontent></test>\n";
773
	}
774
	
775
	/**
776
	 * authenticate and return a token
777
	 */
778
	private AuthToken getToken()
779
	  throws Exception
780
	{
781
	    CrudService cs = CrudService.getInstance();
782
        //login and get a sessionid
783
        MetacatRestClient restClient = new MetacatRestClient(cs.getContextUrl());
784
        String username = PropertyService.getProperty("test.mcUser");
785
        String password = PropertyService.getProperty("test.mcPassword");
786
        String response = restClient.login(username, password);
787
        String sessionid = restClient.getSessionId();
788
        SessionService sessionService = SessionService.getInstance();
789
        sessionService.registerSession(new SessionData(sessionid, username, new String[0], password, "CrudServiceLogin"));
790
        AuthToken token = new AuthToken(sessionid);
791
        return token;
792
	}
793
	
794
	/**
795
	 * create a doc using CrudService.create() and return its id
796
	 */
797
	private Identifier createDoc(AuthToken token, String testDoc) throws Exception
798
	{
799
	    return createDoc(token, testDoc, ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0"));
800
	}
801
	
802
	/**
803
	 * create a doc using CrudService.create() and return its id
804
	 */
805
	private Identifier createDoc(AuthToken token, String testDoc, ObjectFormat format) throws Exception
806
	{
807
	    Identifier id;
808
        CrudService cs = CrudService.getInstance();
809
        
810
        id = new Identifier();
811
        String docid = generateDocumentId();
812
        id.setValue(docid);
813
        
814
        //create the system metadata then run the create method
815
        StringBufferInputStream sbis = new StringBufferInputStream(testDoc);
816
        SystemMetadata sm = createSystemMetadata(id, testDoc, format);
817
        //create the doc
818
        cs.create(token, id, sbis, sm);
819
        createCount++;
820
        return id;
821
	}
822
	
823
	/**
824
	 * create a generic SystemMetadata object for testing
825
	 */
826
	private SystemMetadata createSystemMetadata(Identifier id, String testDoc)
827
	  throws Exception
828
	{
829
	    return createSystemMetadata(id, testDoc, 
830
	            ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0"));
831
	}
832
	
833
	/**
834
	 * create system metadata with a specified id, doc and format
835
	 */
836
	private SystemMetadata createSystemMetadata(Identifier id, String testDoc, ObjectFormat format)
837
	  throws Exception
838
	{
839
	    SystemMetadata sm = new SystemMetadata();
840
        //set the id
841
        sm.setIdentifier(id);
842
        sm.setObjectFormat(format);
843
        //create the checksum
844
        String checksumS = checksum(testDoc);
845
        ChecksumAlgorithm ca = ChecksumAlgorithm.convert("MD5");
846
        Checksum checksum = new Checksum();
847
        checksum.setValue(checksumS);
848
        checksum.setAlgorithm(ca);
849
        sm.setChecksum(checksum);
850
        //set the size
851
        sm.setSize(testDoc.getBytes().length);
852
        //submitter
853
        Principal p = new Principal();
854
        p.setValue("joe");
855
        sm.setSubmitter(p);
856
        sm.setRightsHolder(p);
857
        sm.setDateUploaded(new Date());
858
        sm.setDateSysMetadataModified(new Date());
859
        NodeReference nr = new NodeReference();
860
        nr.setValue("metacat");
861
        sm.setOriginMemberNode(nr);
862
        sm.setAuthoritativeMemberNode(nr);
863
        return sm;
864
	}
865
	
866
	/**
867
	 *  make a document public in metacat by inserting an access document
868
	 * @param id
869
	 */
870
	private void makeDocPublic(AuthToken token, Identifier id, boolean systemMetadataToo)
871
	  throws Exception
872
	{
873
	    CrudService cs = CrudService.getInstance();
874
	    cs.setAccess(token, id, "public", "read", "allow", "allowFirst", systemMetadataToo);
875
	}
876
	
877
	/**
878
	 * print a header to start each test
879
	 */
880
	private void printTestHeader(String testName)
881
	{
882
	    System.out.println();
883
	    System.out.println("*************** " + testName + " ***************");
884
	}
885
  
886
	/**
887
	 * produce an md5 checksum for item
888
	 */
889
	private String checksum(String item)
890
	  throws Exception
891
	{
892
        StringBufferInputStream fis =  new StringBufferInputStream(item);
893
        
894
        byte[] buffer = new byte[1024];
895
        MessageDigest complete = MessageDigest.getInstance("MD5");
896
        int numRead;
897
        
898
        do 
899
        {
900
          numRead = fis.read(buffer);
901
          if (numRead > 0) 
902
          {
903
            complete.update(buffer, 0, numRead);
904
          }
905
        } while (numRead != -1);
906
        
907
        
908
        return getHex(complete.digest());
909
	}
910
	
911
	/**
912
	 * convert a byte array to a hex string
913
	 */
914
	private static String getHex( byte [] raw ) 
915
	{
916
	    final String HEXES = "0123456789ABCDEF";
917
        if ( raw == null ) {
918
          return null;
919
        }
920
        final StringBuilder hex = new StringBuilder( 2 * raw.length );
921
        for ( final byte b : raw ) {
922
          hex.append(HEXES.charAt((b & 0xF0) >> 4))
923
             .append(HEXES.charAt((b & 0x0F)));
924
        }
925
        return hex.toString();
926
    }
927
}
(1-1/3)