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
		return suite;
110
	}
111
	
112
	/**
113
	 * test the checksum creation
114
	 */
115
	public void testChecksum()
116
	{
117
	    try
118
	    {
119
	        CrudService cs = CrudService.getInstance();
120
	        AuthToken token = getToken();
121
	        System.out.println("token: " + token.getToken());
122
	        String doc = getTestDoc();
123
	        Identifier id = createDoc(token, doc);
124
	        System.out.println("ID: " + id.getValue());
125
            makeDocPublic(token, id, true);
126
	        String doc2 = getDoc(token, id);
127
            
128
	        String checksum = checksum(doc);
129
            Checksum checksum2 = cs.getChecksum(token, id, "MD5");
130
            System.out.println("doc: \"" + doc + "\"");
131
            System.out.println("doc2: \"" + doc2 + "\"");
132
            System.out.println("checksum1: " + checksum);
133
            System.out.println("checksum2: " + checksum2.getValue());
134
            assertTrue(checksum.equals(checksum2.getValue()));
135
            
136
	    }
137
	    catch(Exception e)
138
	    {
139
	        fail("Unexpected error in testChecksum: " + e.getMessage());
140
	    }
141
	    
142
	}
143
	
144
	/**
145
	 * insert an invalid document and make sure create fails and does not
146
	 * leave any artifacts behind
147
	 */
148
	public void testFailedCreate()
149
	{
150
	    try
151
	    {
152
	        String invalidDoc = "<xxx></yyy>";
153
	        System.out.println("trying to insert doc " + invalidDoc);
154
	        CrudService cs = CrudService.getInstance();
155
            AuthToken token = getToken();
156
            //run create
157
            try
158
            {
159
                Identifier id = createDoc(token, invalidDoc);
160
                fail("Should have thrown an exception.");
161
            }
162
            catch(Exception e)
163
            {
164
                //e.printStackTrace();
165
            }
166
            
167
	    }
168
	    catch(Exception e)
169
	    {
170
	        fail("unexpected exception in testFailedCreate: " + e.getMessage());
171
	    }
172
	}
173
	
174
	/**
175
	 * test to make sure that get and listObjects methods are publicly accessible
176
	 */
177
	public void testPublicAccess()
178
	{
179
	    try
180
	    {
181
	        AuthToken token = new AuthToken("public");
182
	        //AuthToken token = getToken();
183
	        CrudService cs = CrudService.getInstance();
184
	        ObjectList ol = cs.listObjects(token, null, null, null);
185
	        System.out.println("ol: " + ol.sizeObjectInfoList());
186
	        assertTrue(ol.sizeObjectInfoList() > 0);
187
	        
188
	        ObjectInfo oi = ol.getObjectInfo(0);
189
	        String s = getDoc(token, oi.getIdentifier());
190
	        assertNotNull(s);
191
	        
192
	        try
193
	        { //try a create with the public auth.  should fail
194
	            Identifier id = new Identifier();
195
	            String docid = generateDocumentId();
196
	            id.setValue(docid);
197
	            String testDoc = getTestDoc();
198
	            StringBufferInputStream sbis = new StringBufferInputStream(testDoc);
199
	            ObjectFormat of1 = ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0");
200
	            SystemMetadata sm = createSystemMetadata(id, testDoc, of1);
201
	            assertFalse(sm.getChecksum().getValue().startsWith("MD5"));
202
	            //create the doc
203
	            Identifier idC = cs.create(token, id, sbis, sm);
204
	            fail("Should have thrown an auth exception");
205
	        }
206
	        catch(Exception e)
207
	        {
208
	            
209
	        }
210
	        
211
	        //create a legit doc
212
	        token = getToken();
213
	        Identifier id = new Identifier();
214
            String docid = generateDocumentId();
215
            id.setValue(docid);
216
            String testDoc = getTestDoc();
217
            StringBufferInputStream sbis = new StringBufferInputStream(testDoc);
218
            ObjectFormat of1 = ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0");
219
            SystemMetadata sm = createSystemMetadata(id, testDoc, of1);
220
            assertFalse(sm.getChecksum().getValue().startsWith("MD5"));
221
            //create the doc
222
            Identifier idC = cs.create(token, id, sbis, sm);
223
            //make it public, then use a public token to try to get it
224
            InputStream data = null;
225
            try
226
            {
227
                AuthToken publicToken = new AuthToken("public");
228
                data = cs.get(publicToken, id);
229
                data.read();
230
                
231
                fail("should have thrown an exception");
232
            }
233
            catch(Exception e)
234
            {
235
                /*System.out.println("%%%%%%%%%%%%%%%%%%%%%%%getting result");
236
                Object o = ((InputStreamFromOutputStream)data).getResult();
237
                System.out.println("result: " + o);
238
                System.out.println("exception thrown!");
239
                System.out.println("exception thrown: " + e.getClass().getName());*/
240
            }
241
            
242
            
243
            
244
            makeDocPublic(token, id, true);
245
            token = new AuthToken("public");
246
	        data = cs.get(token, id);
247
	    }
248
	    catch(Exception e)
249
	    {
250
	        fail("Error in testPublicAccess: " + e.getMessage());
251
	    }
252
	    
253
	}
254
	
255
	/**
256
	 * test for an error where the checksum algorithm gets appended onto the checksum.
257
	 */
258
	public void testChecksumError()
259
	{
260
	    printTestHeader("testChecksumError");
261
	    try
262
	    {
263
	        Date d1 = new Date(new Date().getTime() - 5000);
264
	        CrudService cs = CrudService.getInstance();
265
	        AuthToken token = getToken();
266
	        ObjectFormat of1 = ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0");
267
	        //create docs at different times
268

    
269
	        Identifier id = new Identifier();
270
	        String docid = "test." + new Date().getTime();
271
	        id.setValue(docid);
272

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

    
665
	/**
666
	 * getInstance()
667
	 */
668
	public void testSingletonAccessor()
669
	{
670
	    printTestHeader("testSingletonAccessor");
671
	    CrudService cs = CrudService.getInstance();
672
	    assertNotNull(cs);
673
	}
674
	
675
	/**
676
	 * Run an initial test that always passes to check that the test harness is
677
	 * working.
678
	 */
679
	public void initialize() 
680
	{
681
	    printTestHeader("initialize");
682
		assertTrue(1 == 1);
683
	}
684
	
685
	/**
686
	 * return the systemMetadata object for id
687
	 */
688
	private SystemMetadata getSystemMetadata(AuthToken token, Identifier id)
689
	  throws Exception
690
	{
691
	    CrudService cs = CrudService.getInstance();
692
	    return cs.getSystemMetadata(token, id);
693
	}
694
	
695
	/**
696
	 * get a doc from metacat using CrudService.get()
697
	 */
698
	private String getDoc(AuthToken token, Identifier id)
699
	  throws Exception
700
	{
701
	    CrudService cs = CrudService.getInstance();
702
        InputStream gotDocStream = cs.get(token, id);
703
        return IOUtils.toString(gotDocStream);
704
	}
705
	
706
	/**
707
	 * return a test document
708
	 */
709
	private String getTestDoc()
710
	{
711
	    return "<?xml version=\"1.0\"?><test><somecontent>This is some content XXX</somecontent></test>\n";
712
	}
713
	
714
	/**
715
	 * authenticate and return a token
716
	 */
717
	private AuthToken getToken()
718
	  throws Exception
719
	{
720
	    CrudService cs = CrudService.getInstance();
721
        //login and get a sessionid
722
        MetacatRestClient restClient = new MetacatRestClient(cs.getContextUrl());
723
        String username = PropertyService.getProperty("test.mcUser");
724
        String password = PropertyService.getProperty("test.mcPassword");
725
        String response = restClient.login(username, password);
726
        String sessionid = restClient.getSessionId();
727
        SessionService sessionService = SessionService.getInstance();
728
        sessionService.registerSession(new SessionData(sessionid, username, new String[0], password, "CrudServiceLogin"));
729
        AuthToken token = new AuthToken(sessionid);
730
        return token;
731
	}
732
	
733
	/**
734
	 * create a doc using CrudService.create() and return its id
735
	 */
736
	private Identifier createDoc(AuthToken token, String testDoc) throws Exception
737
	{
738
	    return createDoc(token, testDoc, ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0"));
739
	}
740
	
741
	/**
742
	 * create a doc using CrudService.create() and return its id
743
	 */
744
	private Identifier createDoc(AuthToken token, String testDoc, ObjectFormat format) throws Exception
745
	{
746
	    Identifier id;
747
        CrudService cs = CrudService.getInstance();
748
        
749
        id = new Identifier();
750
        String docid = generateDocumentId();
751
        id.setValue(docid);
752
        
753
        //create the system metadata then run the create method
754
        StringBufferInputStream sbis = new StringBufferInputStream(testDoc);
755
        SystemMetadata sm = createSystemMetadata(id, testDoc, format);
756
        //create the doc
757
        cs.create(token, id, sbis, sm);
758
        createCount++;
759
        return id;
760
	}
761
	
762
	/**
763
	 * create a generic SystemMetadata object for testing
764
	 */
765
	private SystemMetadata createSystemMetadata(Identifier id, String testDoc)
766
	  throws Exception
767
	{
768
	    return createSystemMetadata(id, testDoc, 
769
	            ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0"));
770
	}
771
	
772
	/**
773
	 * create system metadata with a specified id, doc and format
774
	 */
775
	private SystemMetadata createSystemMetadata(Identifier id, String testDoc, ObjectFormat format)
776
	  throws Exception
777
	{
778
	    SystemMetadata sm = new SystemMetadata();
779
        //set the id
780
        sm.setIdentifier(id);
781
        sm.setObjectFormat(format);
782
        //create the checksum
783
        String checksumS = checksum(testDoc);
784
        ChecksumAlgorithm ca = ChecksumAlgorithm.convert("MD5");
785
        Checksum checksum = new Checksum();
786
        checksum.setValue(checksumS);
787
        checksum.setAlgorithm(ca);
788
        sm.setChecksum(checksum);
789
        //set the size
790
        sm.setSize(testDoc.getBytes().length);
791
        //submitter
792
        Principal p = new Principal();
793
        p.setValue("joe");
794
        sm.setSubmitter(p);
795
        sm.setRightsHolder(p);
796
        sm.setDateUploaded(new Date());
797
        sm.setDateSysMetadataModified(new Date());
798
        NodeReference nr = new NodeReference();
799
        nr.setValue("metacat");
800
        sm.setOriginMemberNode(nr);
801
        sm.setAuthoritativeMemberNode(nr);
802
        return sm;
803
	}
804
	
805
	/**
806
	 *  make a document public in metacat by inserting an access document
807
	 * @param id
808
	 */
809
	private void makeDocPublic(AuthToken token, Identifier id, boolean systemMetadataToo)
810
	  throws Exception
811
	{
812
	    CrudService cs = CrudService.getInstance();
813
	    cs.setAccess(token, id, "public", "read", "allow", "allowFirst", systemMetadataToo);
814
	}
815
	
816
	/**
817
	 * print a header to start each test
818
	 */
819
	private void printTestHeader(String testName)
820
	{
821
	    System.out.println();
822
	    System.out.println("*************** " + testName + " ***************");
823
	}
824
  
825
	/**
826
	 * produce an md5 checksum for item
827
	 */
828
	private String checksum(String item)
829
	  throws Exception
830
	{
831
        StringBufferInputStream fis =  new StringBufferInputStream(item);
832
        
833
        byte[] buffer = new byte[1024];
834
        MessageDigest complete = MessageDigest.getInstance("MD5");
835
        int numRead;
836
        
837
        do 
838
        {
839
          numRead = fis.read(buffer);
840
          if (numRead > 0) 
841
          {
842
            complete.update(buffer, 0, numRead);
843
          }
844
        } while (numRead != -1);
845
        
846
        
847
        return getHex(complete.digest());
848
	}
849
	
850
	/**
851
	 * convert a byte array to a hex string
852
	 */
853
	private static String getHex( byte [] raw ) 
854
	{
855
	    final String HEXES = "0123456789ABCDEF";
856
        if ( raw == null ) {
857
          return null;
858
        }
859
        final StringBuilder hex = new StringBuilder( 2 * raw.length );
860
        for ( final byte b : raw ) {
861
          hex.append(HEXES.charAt((b & 0xF0) >> 4))
862
             .append(HEXES.charAt((b & 0x0F)));
863
        }
864
        return hex.toString();
865
    }
866
}
(1-1/3)