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.dataone.service.exceptions.InvalidRequest;
43
import org.dataone.service.exceptions.InvalidToken;
44
import org.dataone.service.exceptions.NotAuthorized;
45
import org.dataone.service.exceptions.NotImplemented;
46
import org.dataone.service.exceptions.ServiceFailure;
47
import org.dataone.service.types.*;
48

    
49
import edu.ucsb.nceas.metacat.properties.PropertyService;
50
import edu.ucsb.nceas.metacat.client.rest.MetacatRestClient;
51

    
52
import edu.ucsb.nceas.metacat.service.SessionService;
53
import edu.ucsb.nceas.metacat.util.SessionData;
54

    
55
/**
56
 * A JUnit test for testing the dataone CrudService class
57
 */
58
public class CrudServiceTest extends MCTestCase 
59
{   
60
    /**
61
    * consstructor for the test
62
    */
63
    public CrudServiceTest(String name)
64
    {
65
        super(name);
66
    }
67
  
68
    /**
69
	 * Establish a testing framework by initializing appropriate objects
70
	 */
71
	public void setUp() throws Exception 
72
	{
73
		super.setUp();
74
	}
75

    
76
	/**
77
	 * Release any objects after tests are complete
78
	 */
79
	public void tearDown() 
80
	{
81
	}
82

    
83
	/**
84
	 * Create a suite of tests to be run together
85
	 */
86
	public static Test suite() 
87
	{
88
		TestSuite suite = new TestSuite();
89
		suite.addTest(new CrudServiceTest("initialize"));
90
		suite.addTest(new CrudServiceTest("testSingletonAccessor"));
91
		suite.addTest(new CrudServiceTest("testCreateAndGet"));
92
		suite.addTest(new CrudServiceTest("testGetSystemMetadata"));
93
		suite.addTest(new CrudServiceTest("testUpdate"));
94
		suite.addTest(new CrudServiceTest("testListObjects"));
95
		//suite.addTest(new CrudServiceTest(""));
96
		return suite;
97
	}
98
	
99
	/**
100
	 * public ObjectList listObjects(AuthToken token, Date startTime, Date endTime, 
101
     *     ObjectFormat objectFormat, boolean replicaStatus, int start, int count)
102
     *       throws NotAuthorized, InvalidRequest, NotImplemented, ServiceFailure, InvalidToken
103
	 */
104
	public void testListObjects()
105
	{
106
	    printTestHeader("testListObjects");
107
	    try
108
	    {
109
	        CrudService cs = CrudService.getInstance();
110
	        AuthToken token = getToken();
111
	        ObjectFormat of1 = ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0");
112
	        ObjectFormat of2 = ObjectFormat.convert("eml://ecoinformatics.org/eml-2.0.0");
113
	        //create docs at different times
114
	        Date d1 = new Date();
115
	        Identifier id1 = createDoc(token, getTestDoc(), of1);
116
            SystemMetadata sm1 = getSystemMetadata(token, id1);
117
            
118
            Date d2 = new Date();
119
            Identifier id2 = createDoc(token, getTestDoc(), of2);
120
            SystemMetadata sm2 = getSystemMetadata(token, id2);
121
            
122
            Date d3 = new Date();
123
            Identifier id3 = createDoc(token, getTestDoc(), of1);
124
            SystemMetadata sm3 = getSystemMetadata(token, id3);
125
              
126
            Date d4 = new Date();
127
            Identifier id4 = createDoc(token, getTestDoc(), of2);
128
            SystemMetadata sm4 = getSystemMetadata(token, id4);
129
            
130
            Date d5 = new Date();
131
            Identifier id5 = createDoc(token, getTestDoc(), of1);
132
            SystemMetadata sm5 = getSystemMetadata(token, id5);  
133
             
134
            Date d6 = new Date();
135
            
136
            //now get the objects for specific time ranges and test that it returns
137
            //the correct objects
138
            
139
            ObjectList list = cs.listObjects(token, null, null, null);
140
            System.out.println("list size: " + list.sizeObjectInfoList());
141
	        
142
            //should return sm1 and sm2
143
            ObjectList list1 = cs.listObjects(token, d1, d3, null);
144
            assertTrue(list1.sizeObjectInfoList() == 2);
145
            assertTrue(idInObjectList(id1, list1));
146
            assertTrue(idInObjectList(id2, list1));
147
            
148
            //should only return sm1
149
            ObjectList list2 = cs.listObjects(token, d1, d3, of1);
150
            assertTrue(list2.sizeObjectInfoList() == 1);
151
            assertTrue(idInObjectList(id1, list2));
152
            
153
            //should return sm1-sm4
154
            ObjectList list3 = cs.listObjects(token, d1, d5, null);
155
            assertTrue(list3.sizeObjectInfoList() == 4);
156
            ObjectInfo oi4 = list3.getObjectInfo(0);
157
            assertTrue(idInObjectList(id1, list3));
158
            assertTrue(idInObjectList(id2, list3));
159
            assertTrue(idInObjectList(id3, list3));
160
            assertTrue(idInObjectList(id4, list3));
161
            
162
            //should only return sm2 and sm4
163
            ObjectList list4 = cs.listObjects(token, d1, d5, of2);
164
            assertTrue(list4.sizeObjectInfoList() == 2);
165
            assertTrue(idInObjectList(id2, list4));
166
            assertTrue(idInObjectList(id4, list4));
167
            
168
            //should return all
169
            ObjectList list5 = cs.listObjects(token, d1, d6, null);
170
            assertTrue(list5.sizeObjectInfoList() == 5);
171
            assertTrue(idInObjectList(id1, list5));
172
            assertTrue(idInObjectList(id2, list5));
173
            assertTrue(idInObjectList(id3, list5));
174
            assertTrue(idInObjectList(id4, list5));
175
            assertTrue(idInObjectList(id5, list5));
176
            
177
            //should return 1, 3, 5
178
            ObjectList list6 = cs.listObjects(token, d1, d6, of1);
179
            assertTrue(list6.sizeObjectInfoList() == 3);
180
            assertTrue(idInObjectList(id1, list6));
181
            assertTrue(idInObjectList(id3, list6));
182
            assertTrue(idInObjectList(id5, list6));
183
            
184
	    }
185
	    catch(Exception e)
186
	    {
187
	        //e.printStackTrace();
188
	        fail("Error in listObjects: " + e.getMessage());
189
	    }
190
	}
191
	
192
	private boolean idInObjectList(Identifier id, ObjectList list)
193
	{
194
	    for(int i=0; i<list.sizeObjectInfoList(); i++)
195
	    {
196
	        ObjectInfo oi = list.getObjectInfo(i);
197
	        if(id.getValue().equals(oi.getIdentifier().getValue()))
198
	            return true;
199
	    }
200
	    return false;
201
	}
202
	
203
	/**
204
	 * public Identifier update(AuthToken token, Identifier guid, 
205
     *       InputStream object, Identifier obsoletedGuid, SystemMetadata sysmeta) 
206
     *         throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique, 
207
     *           UnsupportedType, InsufficientResources, NotFound, InvalidSystemMetadata, 
208
     *           NotImplemented
209
	 */
210
	public void testUpdate()
211
	{
212
	    printTestHeader("testUpdate");
213
	    try
214
	    {
215
	        CrudService cs = CrudService.getInstance();
216
	        AuthToken token = getToken();
217
            //create a doc
218
            Identifier id = createDoc(token, getTestDoc());
219
            
220
            //get the doc and sysmetadata
221
            String gotDoc = getDoc(token, id);
222
            SystemMetadata sm = getSystemMetadata(token, id);
223
            
224
            //update the doc
225
            gotDoc = gotDoc.replaceAll("XXX", "YYY");
226
            Identifier newid = new Identifier();
227
            newid.setValue(generateDocumentId());
228
            StringBufferInputStream sbis = new StringBufferInputStream(gotDoc);
229
            SystemMetadata newsm = createSystemMetadata(newid, gotDoc);
230
            Identifier updatedid = cs.update(token, newid, sbis, id, newsm);
231
            
232
            //get doc - check that it matches update
233
            String newdoc = getDoc(token, newid);
234
            assertTrue(gotDoc.equals(newdoc));
235
            
236
            //get sysmeta - check that ids and other fields are updated
237
            SystemMetadata newnewsm = getSystemMetadata(token, id);
238
            assertTrue(newnewsm.getObsoletedBy(0).getValue().equals(newid.getValue()));
239
            
240
            //get the new sysmeta and make sure the obsoletes field is set
241
            SystemMetadata newnewnewsm = getSystemMetadata(token, newid);
242
            assertTrue(newnewnewsm.getObsolete(0).getValue().equals(id.getValue()));
243
        }
244
        catch(Exception e)
245
        {
246
            e.printStackTrace();
247
            fail("Error in testUpdate: " + e.getMessage());
248
        }
249
	}
250
	
251
	/**
252
	 * public SystemMetadata getSystemMetadata(AuthToken token, Identifier guid)
253
     *       throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, 
254
     *       InvalidRequest, NotImplemented
255
	 */
256
	public void testGetSystemMetadata()
257
	{
258
	    printTestHeader("testGetSystemMetadata");
259
	    try
260
	    {
261
            CrudService cs = CrudService.getInstance();
262
            AuthToken token = getToken();
263
            //run create
264
            Identifier id = createDoc(token, getTestDoc());
265
            //get the systemMetadata and make sure it is the correct object for this testDoc
266
            SystemMetadata sm = getSystemMetadata(token, id);
267
            assertTrue(sm.getIdentifier().getValue().equals(id.getValue()));
268
            assertTrue(sm.getChecksum().getValue().equals(checksum(getTestDoc())));
269
            
270
            try
271
            {
272
                Identifier fakeid = new Identifier();
273
                fakeid.setValue("somethingfake.234234");
274
                getSystemMetadata(token, fakeid);
275
                fail("getSystemMetadata should have thrown an exception.");
276
            }
277
            catch(Exception e)
278
            {
279
                assertTrue(true);
280
            }
281
        }
282
        catch(Exception e)
283
        {
284
            e.printStackTrace();
285
            fail("Error testing system metadata: " + e.getMessage());
286
        }
287
	}
288
	
289
	/**
290
	 * create(AuthToken token, Identifier guid, InputStream object, SystemMetadata sysmeta) 
291
     *   throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique, UnsupportedType, 
292
     *       InsufficientResources, InvalidSystemMetadata, NotImplemented
293
     *
294
     * public InputStream get(AuthToken token, Identifier guid)
295
     *       throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, 
296
     *       NotImplemented
297
	 */
298
	public void testCreateAndGet()
299
	{
300
	    printTestHeader("testCreateAndGet");
301
	    try
302
	    {
303
	        CrudService cs = CrudService.getInstance();
304
	        AuthToken token = getToken();
305
	        //run create
306
	        Identifier id = createDoc(token, getTestDoc());
307
	        //make these docs public for debugging purposes.
308
	        makeDocPublic(id, true);
309
            //compare the docs
310
            String gotDoc = getDoc(token, id);
311
            assertTrue(gotDoc.trim().equals(getTestDoc().trim()));
312
            
313
            try
314
            {
315
                Identifier fakeid = new Identifier();
316
                fakeid.setValue("somethingfake.234234");
317
                getDoc(token, fakeid);
318
                fail("testCreateAndGet should have thrown an exception.");
319
            }
320
            catch(Exception e)
321
            {
322
                assertTrue(true);
323
            }
324
        }
325
        catch(Exception e)
326
        {
327
            e.printStackTrace();
328
            fail("Error in testCreate: " + e.getMessage());
329
        }
330
	}
331

    
332
	/**
333
	 * getInstance()
334
	 */
335
	public void testSingletonAccessor()
336
	{
337
	    printTestHeader("testSingletonAccessor");
338
	    CrudService cs = CrudService.getInstance();
339
	    assertNotNull(cs);
340
	}
341
	
342
	/**
343
	 * Run an initial test that always passes to check that the test harness is
344
	 * working.
345
	 */
346
	public void initialize() 
347
	{
348
	    printTestHeader("initialize");
349
		assertTrue(1 == 1);
350
	}
351
	
352
	/**
353
	 * return the systemMetadata object for id
354
	 */
355
	private SystemMetadata getSystemMetadata(AuthToken token, Identifier id)
356
	  throws Exception
357
	{
358
	    CrudService cs = CrudService.getInstance();
359
	    return cs.getSystemMetadata(token, id);
360
	}
361
	
362
	/**
363
	 * get a doc from metacat using CrudService.get()
364
	 */
365
	private String getDoc(AuthToken token, Identifier id)
366
	  throws Exception
367
	{
368
	    CrudService cs = CrudService.getInstance();
369
	    //try to get the same doc then compare them
370
        InputStream gotDocStream = cs.get(token, id);
371
        StringBuffer sb = new StringBuffer();
372
        byte[] b = new byte[1024];
373
        int numread = gotDocStream.read(b, 0, 1024);
374
        while(numread != -1)
375
        {
376
            sb.append(new String(b, 0, numread));
377
            numread = gotDocStream.read(b, 0, 1024);
378
        }
379
        return sb.toString();
380
	}
381
	
382
	/**
383
	 * return a test document
384
	 */
385
	private String getTestDoc()
386
	{
387
	    return "<?xml version=\"1.0\"?><test><somecontent>This is some content XXX</somecontent></test>\n";
388
	}
389
	
390
	/**
391
	 * authenticate and return a token
392
	 */
393
	private AuthToken getToken()
394
	  throws Exception
395
	{
396
	    CrudService cs = CrudService.getInstance();
397
        //login and get a sessionid
398
        MetacatRestClient restClient = new MetacatRestClient(cs.getContextUrl());
399
        String username = PropertyService.getProperty("test.mcUser");
400
        String password = PropertyService.getProperty("test.mcPassword");
401
        String response = restClient.login(username, password);
402
        String sessionid = restClient.getSessionId();
403
        SessionService sessionService = SessionService.getInstance();
404
        sessionService.registerSession(new SessionData(sessionid, username, new String[0], password, "CrudServiceLogin"));
405
        AuthToken token = new AuthToken(sessionid);
406
        return token;
407
	}
408
	
409
	/**
410
	 * create a doc using CrudService.create() and return its id
411
	 */
412
	private Identifier createDoc(AuthToken token, String testDoc) throws Exception
413
	{
414
	    return createDoc(token, testDoc, ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0"));
415
	}
416
	
417
	/**
418
	 * create a doc using CrudService.create() and return its id
419
	 */
420
	private Identifier createDoc(AuthToken token, String testDoc, ObjectFormat format) throws Exception
421
	{
422
	    Identifier id;
423
        CrudService cs = CrudService.getInstance();
424
        
425
        id = new Identifier();
426
        String docid = generateDocumentId();
427
        id.setValue(docid);
428
        
429
        //create the system metadata then run the create method
430
        StringBufferInputStream sbis = new StringBufferInputStream(testDoc);
431
        SystemMetadata sm = createSystemMetadata(id, testDoc, format);
432
        //create the doc
433
        cs.create(token, id, sbis, sm);
434
        return id;
435
	}
436
	
437
	/**
438
	 * create a generic SystemMetadata object for testing
439
	 */
440
	private SystemMetadata createSystemMetadata(Identifier id, String testDoc)
441
	  throws Exception
442
	{
443
	    return createSystemMetadata(id, testDoc, 
444
	            ObjectFormat.convert("eml://ecoinformatics.org/eml-2.1.0"));
445
	}
446
	
447
	/**
448
	 * create system metadata with a specified id, doc and format
449
	 */
450
	private SystemMetadata createSystemMetadata(Identifier id, String testDoc, ObjectFormat format)
451
	  throws Exception
452
	{
453
	    SystemMetadata sm = new SystemMetadata();
454
        //set the id
455
        sm.setIdentifier(id);
456
        sm.setObjectFormat(format);
457
        //create the checksum
458
        String checksumS = checksum(testDoc);
459
        ChecksumAlgorithm ca = ChecksumAlgorithm.convert("MD5");
460
        Checksum checksum = new Checksum();
461
        checksum.setValue(checksumS);
462
        checksum.setAlgorithm(ca);
463
        sm.setChecksum(checksum);
464
        //set the size
465
        sm.setSize(testDoc.getBytes().length);
466
        //submitter
467
        Principal p = new Principal();
468
        p.setValue("joe");
469
        sm.setSubmitter(p);
470
        sm.setRightsHolder(p);
471
        sm.setDateUploaded(new Date());
472
        sm.setDateSysMetadataModified(new Date());
473
        NodeReference nr = new NodeReference();
474
        nr.setValue("metacat");
475
        sm.setOriginMemberNode(nr);
476
        sm.setAuthoritativeMemberNode(nr);
477
        return sm;
478
	}
479
	
480
	/**
481
	 *  make a document public in metacat by inserting an access document
482
	 * @param id
483
	 */
484
	private void makeDocPublic(Identifier id, boolean systemMetadataToo)
485
	  throws Exception
486
	{
487
	    CrudService cs = CrudService.getInstance();
488
	    IdentifierManager im = IdentifierManager.getInstance();
489
	    cs.setAccess(getToken(), id, "public", "read", "allow", "allowFirst");
490
	    if(systemMetadataToo)
491
	    {
492
	        String smidS = im.getSystemMetadataId(id.getValue());
493
	        Identifier smid = new Identifier();
494
	        smid.setValue(smidS);
495
	        cs.setAccess(getToken(), smid, "public", "read", "allow", "allowFirst");
496
	    }
497
	}
498
	
499
	/**
500
	 * print a header to start each test
501
	 */
502
	private void printTestHeader(String testName)
503
	{
504
	    System.out.println();
505
	    System.out.println("********************************** " + testName + " **********************************");
506
	}
507
  
508
	/**
509
	 * produce an md5 checksum for item
510
	 */
511
	private String checksum(String item)
512
	  throws Exception
513
	{
514
        StringBufferInputStream fis =  new StringBufferInputStream(item);
515
        
516
        byte[] buffer = new byte[1024];
517
        MessageDigest complete = MessageDigest.getInstance("MD5");
518
        int numRead;
519
        
520
        do 
521
        {
522
          numRead = fis.read(buffer);
523
          if (numRead > 0) 
524
          {
525
            complete.update(buffer, 0, numRead);
526
          }
527
        } while (numRead != -1);
528
        
529
        
530
        return getHex(complete.digest());
531
	}
532
	
533
	/**
534
	 * convert a byte array to a hex string
535
	 */
536
	private static String getHex( byte [] raw ) 
537
	{
538
	    final String HEXES = "0123456789ABCDEF";
539
        if ( raw == null ) {
540
          return null;
541
        }
542
        final StringBuilder hex = new StringBuilder( 2 * raw.length );
543
        for ( final byte b : raw ) {
544
          hex.append(HEXES.charAt((b & 0xF0) >> 4))
545
             .append(HEXES.charAt((b & 0x0F)));
546
        }
547
        return hex.toString();
548
    }
549
}
    (1-1/1)