Project

General

Profile

1 5335 berkley
/**
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 5337 berkley
import java.security.MessageDigest;
32
33 5335 berkley
import edu.ucsb.nceas.MCTestCase;
34 5362 berkley
import edu.ucsb.nceas.metacat.IdentifierManager;
35 5760 leinfelder
import edu.ucsb.nceas.metacat.MetaCatServlet;
36 5335 berkley
import edu.ucsb.nceas.metacat.client.MetacatAuthException;
37
import edu.ucsb.nceas.metacat.client.MetacatException;
38
import edu.ucsb.nceas.metacat.client.MetacatInaccessibleException;
39
import edu.ucsb.nceas.metacat.dataone.CrudService;
40
import junit.framework.Test;
41
import junit.framework.TestSuite;
42
43 5620 berkley
import org.apache.commons.io.IOUtils;
44 5389 berkley
import org.apache.log.LogEvent;
45 5359 berkley
import org.dataone.service.exceptions.InvalidRequest;
46
import org.dataone.service.exceptions.InvalidToken;
47
import org.dataone.service.exceptions.NotAuthorized;
48
import org.dataone.service.exceptions.NotImplemented;
49
import org.dataone.service.exceptions.ServiceFailure;
50 5337 berkley
import org.dataone.service.types.*;
51
52
import edu.ucsb.nceas.metacat.properties.PropertyService;
53
import edu.ucsb.nceas.metacat.client.rest.MetacatRestClient;
54
55
import edu.ucsb.nceas.metacat.service.SessionService;
56
import edu.ucsb.nceas.metacat.util.SessionData;
57
58 5428 berkley
import com.gc.iotools.stream.is.InputStreamFromOutputStream;
59
60 5335 berkley
/**
61
 * A JUnit test for testing the dataone CrudService class
62
 */
63
public class CrudServiceTest extends MCTestCase
64 5340 berkley
{
65 5611 berkley
    private int createCount = 0;
66
67 5340 berkley
    /**
68
    * consstructor for the test
69
    */
70
    public CrudServiceTest(String name)
71
    {
72
        super(name);
73
    }
74 5335 berkley
75 5340 berkley
    /**
76 5335 berkley
	 * 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 5611 berkley
	    System.out.println(createCount + " docs created in this test session.");
89 5335 berkley
	}
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 5798 berkley
		/*suite.addTest(new CrudServiceTest("initialize"));
98 5797 berkley
		suite.addTest(new CrudServiceTest("testSingletonAccessor"));
99
		suite.addTest(new CrudServiceTest("testCreateAndGet"));
100
		suite.addTest(new CrudServiceTest("testGetSystemMetadata"));
101
		suite.addTest(new CrudServiceTest("testUpdate"));
102
		suite.addTest(new CrudServiceTest("testListObjects"));
103 5798 berkley
		suite.addTest(new CrudServiceTest("testAccessControl"));*/
104 5797 berkley
		suite.addTest(new CrudServiceTest("testGenerateMissingSystemMetadata"));
105 5798 berkley
		/*suite.addTest(new CrudServiceTest("testGetLogRecords"));
106 5797 berkley
		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 5798 berkley
		suite.addTest(new CrudServiceTest("testSemiColonsInIdentifiers"));*/
113 5335 berkley
		return suite;
114
	}
115 5337 berkley
116
	/**
117 5746 berkley
	 * 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 5748 berkley
            id.setValue("someid;id;with;semi;colons;in;it." + new Date().getTime());
130 5746 berkley
            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
                    ObjectFormat.convert("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 5654 berkley
	 * 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 5657 berkley
            //cs.get(token, id);
170 5654 berkley
        }
171
        catch(Exception e)
172
        {
173
            fail("Unexpected error in testDescribe: " + e.getMessage());
174
        }
175
	}
176
177
	/**
178 5648 berkley
	 * 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 5621 berkley
	 * 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 5461 berkley
	 * 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 5402 berkley
	 * test to make sure that get and listObjects methods are publicly accessible
271
	 */
272
	public void testPublicAccess()
273
	{
274
	    try
275
	    {
276 5683 berkley
	        System.out.println("********************* testPublicAccess *********************");
277 5402 berkley
	        AuthToken token = new AuthToken("public");
278 5404 berkley
	        //AuthToken token = getToken();
279 5402 berkley
	        CrudService cs = CrudService.getInstance();
280
	        ObjectList ol = cs.listObjects(token, null, null, null);
281 5404 berkley
	        System.out.println("ol: " + ol.sizeObjectInfoList());
282
	        assertTrue(ol.sizeObjectInfoList() > 0);
283 5405 berkley
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 = ObjectFormat.convert("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 5427 berkley
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 = ObjectFormat.convert("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 5428 berkley
                data.read();
326
327 5427 berkley
                fail("should have thrown an exception");
328
            }
329
            catch(Exception e)
330
            {
331 5428 berkley
                /*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 5427 berkley
            }
337 5428 berkley
338
339
340 5427 berkley
            makeDocPublic(token, id, true);
341
            token = new AuthToken("public");
342
	        data = cs.get(token, id);
343 5402 berkley
	    }
344
	    catch(Exception e)
345
	    {
346
	        fail("Error in testPublicAccess: " + e.getMessage());
347
	    }
348
349
	}
350
351
	/**
352 5387 berkley
	 * 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 5630 berkley
	        Date d1 = new Date(new Date().getTime() - 5000);
360 5387 berkley
	        CrudService cs = CrudService.getInstance();
361
	        AuthToken token = getToken();
362
	        ObjectFormat of1 = ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0");
363
	        //create docs at different times
364
365
	        Identifier id = new Identifier();
366 5630 berkley
	        String docid = "test." + new Date().getTime();
367 5387 berkley
	        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 5630 berkley
	        makeDocPublic(token, id, true);
377 5387 berkley
	        assertTrue(idC.getValue().equals(id.getValue()));
378
	        SystemMetadata smC = getSystemMetadata(token, idC);
379
	        assertFalse(smC.getChecksum().getValue().startsWith("MD5"));
380
381 5630 berkley
	        Date d2 = new Date(new Date().getTime() + 5000);
382
383 5387 berkley
	        ObjectList ol = cs.listObjects(token, d1, d2, of1);
384 5460 berkley
	        assertTrue(ol.sizeObjectInfoList() > 0);
385 5387 berkley
	        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 5384 berkley
	 * 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 5390 berkley
	        Log lrs = cs.getLogRecords(token, fromDate, toDate, null);
410 5389 berkley
	        assertNotNull(lrs);
411 5746 berkley
	        System.out.println("log entry size: " + lrs.sizeLogEntryList());
412 5389 berkley
	        assertTrue(lrs.sizeLogEntryList() == 1);
413
	        LogEntry lrLogEvent = lrs.getLogEntry(0);
414
	        assertTrue(lrLogEvent.getEvent().name().equals("CREATE"));
415 5416 berkley
	        assertTrue(lrLogEvent.getIdentifier().getValue().equals(id.getValue()));
416 5384 berkley
	    }
417
	    catch(Exception e)
418
	    {
419
	        e.printStackTrace();
420
	        fail("testGetLogRecords threw an unexpected exception: " + e.getMessage());
421
	    }
422
	}
423
424
	/**
425 5377 berkley
	 * test the generation of system metadata for docs that don't already
426
	 * have it.  This will be used for migration of existing object stores
427
	 * to dataone.
428
	 */
429
	public void testGenerateMissingSystemMetadata()
430
	{
431
	    printTestHeader("testGenerateMissingSystemMetadata");
432
	    try
433
	    {
434
	        CrudService cs = CrudService.getInstance();
435 5798 berkley
	        AuthToken token = getToken("uid=dataone_cn_metacat,o=DATAONE,dc=ecoinformatics,dc=org", "umtmm4tcn");
436 5380 berkley
	        //create a document with no system metadata
437
	        String testDoc = getTestDoc();
438
	        Identifier id = new Identifier();
439
	        String docid = generateDocumentId();
440
	        id.setValue(docid);
441
442 5456 berkley
	        cs.insertOrUpdateDocument(testDoc, id, cs.getSessionData(token), "insert", false);
443 5380 berkley
	        //try to get its system metadata, should fail
444
	        try
445
	        {
446
	            getSystemMetadata(token, id);
447
	            fail("call to getSystemMetadata should have failed.");
448
	        }
449
	        catch(Exception e)
450
	        {}
451
452
	        //generate missing system metadata
453 5378 berkley
	        cs.generateMissingSystemMetadata(token);
454 5380 berkley
	        //try to get system metadata again, should succeed
455
	        getSystemMetadata(token, id);
456 5377 berkley
	    }
457
	    catch(Exception e)
458
	    {
459
	        fail("Unexpected error generating missing system metadata: " + e.getMessage());
460
	    }
461
	}
462
463
	/**
464 5375 berkley
	 * make sure that only valid sessions can update/delete
465
	 */
466
	public void testAccessControl()
467
	{
468 5377 berkley
	    printTestHeader("testAccessControl");
469 5375 berkley
        try
470
        {
471
            CrudService cs = CrudService.getInstance();
472
            AuthToken token = getToken();
473
            //create a doc
474
            Identifier id = createDoc(token, getTestDoc());
475
476
            //get the doc and sysmetadata
477
            String gotDoc = getDoc(token, id);
478
            SystemMetadata sm = getSystemMetadata(token, id);
479
480
            //break the session id
481
            String sessionid = "somefakesessionid";
482
            token = new AuthToken(sessionid);
483
484
            //update the doc
485
            gotDoc = gotDoc.replaceAll("XXX", "YYY");
486
            Identifier newid = new Identifier();
487
            newid.setValue(generateDocumentId());
488
            StringBufferInputStream sbis = new StringBufferInputStream(gotDoc);
489
            SystemMetadata newsm = createSystemMetadata(newid, gotDoc);
490
            Identifier updatedid = cs.update(token, newid, sbis, id, newsm);
491
            fail("exception should have been thrown.");
492
        }
493
        catch(Exception e)
494
        {
495
        }
496 5376 berkley
497
        try
498
        {
499
            CrudService cs = CrudService.getInstance();
500
            AuthToken token = new AuthToken("somefakesessionid");
501
            //create a doc
502
            Identifier id = createDoc(token, getTestDoc());
503
            fail("exception should have been thrown.");
504
        }
505
        catch(Exception e)
506
        {
507
        }
508 5375 berkley
	}
509
510
	/**
511 5359 berkley
	 * public ObjectList listObjects(AuthToken token, Date startTime, Date endTime,
512
     *     ObjectFormat objectFormat, boolean replicaStatus, int start, int count)
513
     *       throws NotAuthorized, InvalidRequest, NotImplemented, ServiceFailure, InvalidToken
514
	 */
515
	public void testListObjects()
516
	{
517
	    printTestHeader("testListObjects");
518
	    try
519
	    {
520
	        CrudService cs = CrudService.getInstance();
521
	        AuthToken token = getToken();
522
	        ObjectFormat of1 = ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0");
523 5362 berkley
	        ObjectFormat of2 = ObjectFormat.convert("eml://ecoinformatics.org/eml-2.0.0");
524 5359 berkley
	        //create docs at different times
525
	        Date d1 = new Date();
526
	        Identifier id1 = createDoc(token, getTestDoc(), of1);
527
            SystemMetadata sm1 = getSystemMetadata(token, id1);
528
529
            Date d2 = new Date();
530
            Identifier id2 = createDoc(token, getTestDoc(), of2);
531 5410 berkley
            makeDocPublic(token, id2, true);
532 5359 berkley
            SystemMetadata sm2 = getSystemMetadata(token, id2);
533
534
            Date d3 = new Date();
535
            Identifier id3 = createDoc(token, getTestDoc(), of1);
536 5410 berkley
            makeDocPublic(token, id3, true);
537 5359 berkley
            SystemMetadata sm3 = getSystemMetadata(token, id3);
538
539
            Date d4 = new Date();
540
            Identifier id4 = createDoc(token, getTestDoc(), of2);
541 5410 berkley
            makeDocPublic(token, id4, true);
542 5359 berkley
            SystemMetadata sm4 = getSystemMetadata(token, id4);
543
544
            Date d5 = new Date();
545
            Identifier id5 = createDoc(token, getTestDoc(), of1);
546 5410 berkley
            makeDocPublic(token, id5, true);
547 5359 berkley
            SystemMetadata sm5 = getSystemMetadata(token, id5);
548 5366 berkley
549
            Date d6 = new Date();
550
551 5359 berkley
            //now get the objects for specific time ranges and test that it returns
552
            //the correct objects
553 5370 berkley
554 5413 berkley
            //ObjectList list = cs.listObjects(token, null, null, null);
555 5374 berkley
            //System.out.println("list size: " + list.sizeObjectInfoList());
556 5387 berkley
557 5359 berkley
            //should return sm1 and sm2
558 5366 berkley
            ObjectList list1 = cs.listObjects(token, d1, d3, null);
559 5359 berkley
            assertTrue(list1.sizeObjectInfoList() == 2);
560 5366 berkley
            assertTrue(idInObjectList(id1, list1));
561
            assertTrue(idInObjectList(id2, list1));
562 5359 berkley
563 5387 berkley
            ObjectInfo info = list1.getObjectInfo(0);
564
565
566 5359 berkley
            //should only return sm1
567 5366 berkley
            ObjectList list2 = cs.listObjects(token, d1, d3, of1);
568 5359 berkley
            assertTrue(list2.sizeObjectInfoList() == 1);
569 5366 berkley
            assertTrue(idInObjectList(id1, list2));
570 5359 berkley
571
            //should return sm1-sm4
572 5366 berkley
            ObjectList list3 = cs.listObjects(token, d1, d5, null);
573 5359 berkley
            assertTrue(list3.sizeObjectInfoList() == 4);
574
            ObjectInfo oi4 = list3.getObjectInfo(0);
575 5366 berkley
            assertTrue(idInObjectList(id1, list3));
576
            assertTrue(idInObjectList(id2, list3));
577
            assertTrue(idInObjectList(id3, list3));
578
            assertTrue(idInObjectList(id4, list3));
579 5359 berkley
580
            //should only return sm2 and sm4
581 5366 berkley
            ObjectList list4 = cs.listObjects(token, d1, d5, of2);
582 5359 berkley
            assertTrue(list4.sizeObjectInfoList() == 2);
583 5366 berkley
            assertTrue(idInObjectList(id2, list4));
584
            assertTrue(idInObjectList(id4, list4));
585 5359 berkley
586
            //should return all
587 5366 berkley
            ObjectList list5 = cs.listObjects(token, d1, d6, null);
588 5359 berkley
            assertTrue(list5.sizeObjectInfoList() == 5);
589 5366 berkley
            assertTrue(idInObjectList(id1, list5));
590
            assertTrue(idInObjectList(id2, list5));
591
            assertTrue(idInObjectList(id3, list5));
592
            assertTrue(idInObjectList(id4, list5));
593
            assertTrue(idInObjectList(id5, list5));
594
595 5359 berkley
            //should return 1, 3, 5
596 5366 berkley
            ObjectList list6 = cs.listObjects(token, d1, d6, of1);
597
            assertTrue(list6.sizeObjectInfoList() == 3);
598
            assertTrue(idInObjectList(id1, list6));
599
            assertTrue(idInObjectList(id3, list6));
600
            assertTrue(idInObjectList(id5, list6));
601 5359 berkley
602 5411 berkley
            //should return 4 (id1 is not public)
603 5410 berkley
            token = new AuthToken("public");
604
            ObjectList list7 = cs.listObjects(token, d1, d6, null);
605 5413 berkley
            //System.out.println("list7 size: " + list7.sizeObjectInfoList());
606 5411 berkley
            assertTrue(list7.sizeObjectInfoList() == 4);
607 5410 berkley
608 5413 berkley
            //test paging
609
            ObjectList list8 = cs.listObjects(token, d1, d6, null, false, 2, 2);
610
            assertTrue(list8.getCount() == 2);
611
            assertTrue(list8.getStart() == 2);
612
            assertTrue(list8.getTotal() == 4);
613
614 5359 berkley
	    }
615
	    catch(Exception e)
616
	    {
617 5362 berkley
	        //e.printStackTrace();
618 5359 berkley
	        fail("Error in listObjects: " + e.getMessage());
619
	    }
620
	}
621
622 5366 berkley
	private boolean idInObjectList(Identifier id, ObjectList list)
623
	{
624
	    for(int i=0; i<list.sizeObjectInfoList(); i++)
625
	    {
626
	        ObjectInfo oi = list.getObjectInfo(i);
627
	        if(id.getValue().equals(oi.getIdentifier().getValue()))
628
	            return true;
629
	    }
630
	    return false;
631
	}
632
633 5359 berkley
	/**
634 5350 berkley
	 * public Identifier update(AuthToken token, Identifier guid,
635
     *       InputStream object, Identifier obsoletedGuid, SystemMetadata sysmeta)
636
     *         throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique,
637
     *           UnsupportedType, InsufficientResources, NotFound, InvalidSystemMetadata,
638
     *           NotImplemented
639
	 */
640
	public void testUpdate()
641
	{
642
	    printTestHeader("testUpdate");
643
	    try
644
	    {
645
	        CrudService cs = CrudService.getInstance();
646
	        AuthToken token = getToken();
647
            //create a doc
648
            Identifier id = createDoc(token, getTestDoc());
649 5351 berkley
650 5350 berkley
            //get the doc and sysmetadata
651
            String gotDoc = getDoc(token, id);
652
            SystemMetadata sm = getSystemMetadata(token, id);
653 5351 berkley
654 5350 berkley
            //update the doc
655
            gotDoc = gotDoc.replaceAll("XXX", "YYY");
656
            Identifier newid = new Identifier();
657
            newid.setValue(generateDocumentId());
658
            StringBufferInputStream sbis = new StringBufferInputStream(gotDoc);
659
            SystemMetadata newsm = createSystemMetadata(newid, gotDoc);
660
            Identifier updatedid = cs.update(token, newid, sbis, id, newsm);
661 5351 berkley
662 5350 berkley
            //get doc - check that it matches update
663
            String newdoc = getDoc(token, newid);
664
            assertTrue(gotDoc.equals(newdoc));
665 5351 berkley
666 5350 berkley
            //get sysmeta - check that ids and other fields are updated
667
            SystemMetadata newnewsm = getSystemMetadata(token, id);
668 5352 berkley
            assertTrue(newnewsm.getObsoletedBy(0).getValue().equals(newid.getValue()));
669
670
            //get the new sysmeta and make sure the obsoletes field is set
671
            SystemMetadata newnewnewsm = getSystemMetadata(token, newid);
672
            assertTrue(newnewnewsm.getObsolete(0).getValue().equals(id.getValue()));
673 5350 berkley
        }
674
        catch(Exception e)
675
        {
676
            e.printStackTrace();
677
            fail("Error in testUpdate: " + e.getMessage());
678
        }
679
	}
680
681
	/**
682 5341 berkley
	 * public SystemMetadata getSystemMetadata(AuthToken token, Identifier guid)
683
     *       throws InvalidToken, ServiceFailure, NotAuthorized, NotFound,
684
     *       InvalidRequest, NotImplemented
685
	 */
686
	public void testGetSystemMetadata()
687
	{
688 5344 berkley
	    printTestHeader("testGetSystemMetadata");
689
	    try
690
	    {
691
            CrudService cs = CrudService.getInstance();
692
            AuthToken token = getToken();
693
            //run create
694
            Identifier id = createDoc(token, getTestDoc());
695
            //get the systemMetadata and make sure it is the correct object for this testDoc
696
            SystemMetadata sm = getSystemMetadata(token, id);
697
            assertTrue(sm.getIdentifier().getValue().equals(id.getValue()));
698
            assertTrue(sm.getChecksum().getValue().equals(checksum(getTestDoc())));
699 5348 berkley
700
            try
701
            {
702
                Identifier fakeid = new Identifier();
703
                fakeid.setValue("somethingfake.234234");
704
                getSystemMetadata(token, fakeid);
705
                fail("getSystemMetadata should have thrown an exception.");
706
            }
707
            catch(Exception e)
708
            {
709
                assertTrue(true);
710
            }
711 5344 berkley
        }
712
        catch(Exception e)
713
        {
714
            e.printStackTrace();
715
            fail("Error testing system metadata: " + e.getMessage());
716
        }
717 5341 berkley
	}
718
719
	/**
720 5337 berkley
	 * create(AuthToken token, Identifier guid, InputStream object, SystemMetadata sysmeta)
721
     *   throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique, UnsupportedType,
722
     *       InsufficientResources, InvalidSystemMetadata, NotImplemented
723 5340 berkley
     *
724
     * public InputStream get(AuthToken token, Identifier guid)
725
     *       throws InvalidToken, ServiceFailure, NotAuthorized, NotFound,
726
     *       NotImplemented
727 5337 berkley
	 */
728 5340 berkley
	public void testCreateAndGet()
729 5337 berkley
	{
730 5344 berkley
	    printTestHeader("testCreateAndGet");
731 5337 berkley
	    try
732
	    {
733 5341 berkley
	        CrudService cs = CrudService.getInstance();
734
	        AuthToken token = getToken();
735
	        //run create
736 5343 berkley
	        Identifier id = createDoc(token, getTestDoc());
737 5362 berkley
	        //make these docs public for debugging purposes.
738 5410 berkley
	        makeDocPublic(token, id, true);
739 5352 berkley
            //compare the docs
740 5342 berkley
            String gotDoc = getDoc(token, id);
741 5343 berkley
            assertTrue(gotDoc.trim().equals(getTestDoc().trim()));
742 5348 berkley
743
            try
744
            {
745
                Identifier fakeid = new Identifier();
746
                fakeid.setValue("somethingfake.234234");
747
                getDoc(token, fakeid);
748
                fail("testCreateAndGet should have thrown an exception.");
749
            }
750
            catch(Exception e)
751
            {
752
                assertTrue(true);
753
            }
754 5337 berkley
        }
755
        catch(Exception e)
756
        {
757
            e.printStackTrace();
758
            fail("Error in testCreate: " + e.getMessage());
759
        }
760
	}
761 5335 berkley
762
	/**
763 5337 berkley
	 * getInstance()
764
	 */
765
	public void testSingletonAccessor()
766
	{
767 5344 berkley
	    printTestHeader("testSingletonAccessor");
768 5337 berkley
	    CrudService cs = CrudService.getInstance();
769
	    assertNotNull(cs);
770
	}
771
772
	/**
773 5335 berkley
	 * Run an initial test that always passes to check that the test harness is
774
	 * working.
775
	 */
776
	public void initialize()
777
	{
778 5344 berkley
	    printTestHeader("initialize");
779 5335 berkley
		assertTrue(1 == 1);
780
	}
781 5341 berkley
782 5342 berkley
	/**
783 5344 berkley
	 * return the systemMetadata object for id
784
	 */
785
	private SystemMetadata getSystemMetadata(AuthToken token, Identifier id)
786
	  throws Exception
787
	{
788
	    CrudService cs = CrudService.getInstance();
789
	    return cs.getSystemMetadata(token, id);
790
	}
791
792
	/**
793 5342 berkley
	 * get a doc from metacat using CrudService.get()
794
	 */
795
	private String getDoc(AuthToken token, Identifier id)
796
	  throws Exception
797
	{
798
	    CrudService cs = CrudService.getInstance();
799
        InputStream gotDocStream = cs.get(token, id);
800 5621 berkley
        return IOUtils.toString(gotDocStream);
801 5342 berkley
	}
802
803
	/**
804
	 * return a test document
805
	 */
806 5341 berkley
	private String getTestDoc()
807
	{
808 5350 berkley
	    return "<?xml version=\"1.0\"?><test><somecontent>This is some content XXX</somecontent></test>\n";
809 5341 berkley
	}
810
811
	/**
812
	 * authenticate and return a token
813 5798 berkley
	 * use the test.mcUser and test.mcPassword username/password combo
814 5341 berkley
	 */
815
	private AuthToken getToken()
816
	  throws Exception
817
	{
818 5798 berkley
        String username = PropertyService.getProperty("test.mcUser");
819
        String password = PropertyService.getProperty("test.mcPassword");
820
        return getToken(username, password);
821
	}
822
823
	/**
824
	 * authenticate and return a token using the given credentials
825
	 */
826
	private AuthToken getToken(String username, String password)
827
	  throws Exception
828
	{
829 5341 berkley
	    CrudService cs = CrudService.getInstance();
830
        //login and get a sessionid
831
        MetacatRestClient restClient = new MetacatRestClient(cs.getContextUrl());
832
        String response = restClient.login(username, password);
833
        String sessionid = restClient.getSessionId();
834
        SessionService sessionService = SessionService.getInstance();
835
        sessionService.registerSession(new SessionData(sessionid, username, new String[0], password, "CrudServiceLogin"));
836
        AuthToken token = new AuthToken(sessionid);
837
        return token;
838
	}
839
840
	/**
841 5342 berkley
	 * create a doc using CrudService.create() and return its id
842 5341 berkley
	 */
843 5343 berkley
	private Identifier createDoc(AuthToken token, String testDoc) throws Exception
844 5341 berkley
	{
845 5359 berkley
	    return createDoc(token, testDoc, ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0"));
846
	}
847
848
	/**
849
	 * create a doc using CrudService.create() and return its id
850
	 */
851
	private Identifier createDoc(AuthToken token, String testDoc, ObjectFormat format) throws Exception
852
	{
853 5341 berkley
	    Identifier id;
854
        CrudService cs = CrudService.getInstance();
855
856
        id = new Identifier();
857
        String docid = generateDocumentId();
858
        id.setValue(docid);
859 5344 berkley
860 5341 berkley
        //create the system metadata then run the create method
861
        StringBufferInputStream sbis = new StringBufferInputStream(testDoc);
862 5359 berkley
        SystemMetadata sm = createSystemMetadata(id, testDoc, format);
863 5350 berkley
        //create the doc
864
        cs.create(token, id, sbis, sm);
865 5611 berkley
        createCount++;
866 5350 berkley
        return id;
867
	}
868
869
	/**
870
	 * create a generic SystemMetadata object for testing
871
	 */
872
	private SystemMetadata createSystemMetadata(Identifier id, String testDoc)
873
	  throws Exception
874
	{
875 5359 berkley
	    return createSystemMetadata(id, testDoc,
876
	            ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0"));
877
	}
878
879
	/**
880
	 * create system metadata with a specified id, doc and format
881
	 */
882
	private SystemMetadata createSystemMetadata(Identifier id, String testDoc, ObjectFormat format)
883
	  throws Exception
884
	{
885 5350 berkley
	    SystemMetadata sm = new SystemMetadata();
886 5341 berkley
        //set the id
887
        sm.setIdentifier(id);
888 5359 berkley
        sm.setObjectFormat(format);
889 5341 berkley
        //create the checksum
890
        String checksumS = checksum(testDoc);
891
        ChecksumAlgorithm ca = ChecksumAlgorithm.convert("MD5");
892
        Checksum checksum = new Checksum();
893
        checksum.setValue(checksumS);
894
        checksum.setAlgorithm(ca);
895
        sm.setChecksum(checksum);
896
        //set the size
897 5760 leinfelder
        sm.setSize(testDoc.getBytes(MetaCatServlet.DEFAULT_ENCODING).length);
898 5341 berkley
        //submitter
899
        Principal p = new Principal();
900
        p.setValue("joe");
901
        sm.setSubmitter(p);
902
        sm.setRightsHolder(p);
903
        sm.setDateUploaded(new Date());
904
        sm.setDateSysMetadataModified(new Date());
905
        NodeReference nr = new NodeReference();
906
        nr.setValue("metacat");
907
        sm.setOriginMemberNode(nr);
908
        sm.setAuthoritativeMemberNode(nr);
909 5350 berkley
        return sm;
910 5341 berkley
	}
911 5344 berkley
912
	/**
913 5362 berkley
	 *  make a document public in metacat by inserting an access document
914
	 * @param id
915
	 */
916 5410 berkley
	private void makeDocPublic(AuthToken token, Identifier id, boolean systemMetadataToo)
917 5362 berkley
	  throws Exception
918
	{
919
	    CrudService cs = CrudService.getInstance();
920 5424 berkley
	    cs.setAccess(token, id, "public", "read", "allow", "allowFirst", systemMetadataToo);
921 5362 berkley
	}
922
923
	/**
924 5344 berkley
	 * print a header to start each test
925
	 */
926
	private void printTestHeader(String testName)
927
	{
928
	    System.out.println();
929 5389 berkley
	    System.out.println("*************** " + testName + " ***************");
930 5344 berkley
	}
931 5335 berkley
932 5337 berkley
	/**
933
	 * produce an md5 checksum for item
934
	 */
935
	private String checksum(String item)
936
	  throws Exception
937
	{
938
        StringBufferInputStream fis =  new StringBufferInputStream(item);
939
940
        byte[] buffer = new byte[1024];
941
        MessageDigest complete = MessageDigest.getInstance("MD5");
942
        int numRead;
943
944
        do
945
        {
946
          numRead = fis.read(buffer);
947
          if (numRead > 0)
948
          {
949
            complete.update(buffer, 0, numRead);
950
          }
951
        } while (numRead != -1);
952
953
954
        return getHex(complete.digest());
955
	}
956
957
	/**
958
	 * convert a byte array to a hex string
959
	 */
960
	private static String getHex( byte [] raw )
961
	{
962
	    final String HEXES = "0123456789ABCDEF";
963
        if ( raw == null ) {
964
          return null;
965
        }
966
        final StringBuilder hex = new StringBuilder( 2 * raw.length );
967
        for ( final byte b : raw ) {
968
          hex.append(HEXES.charAt((b & 0xF0) >> 4))
969
             .append(HEXES.charAt((b & 0x0F)));
970
        }
971
        return hex.toString();
972
    }
973 5335 berkley
}