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
            //should return sm1 and sm2
140
            ObjectList list1 = cs.listObjects(token, d1, d3, null);
141
            assertTrue(list1.sizeObjectInfoList() == 2);
142
            assertTrue(idInObjectList(id1, list1));
143
            assertTrue(idInObjectList(id2, list1));
144
            
145
            //should only return sm1
146
            ObjectList list2 = cs.listObjects(token, d1, d3, of1);
147
            assertTrue(list2.sizeObjectInfoList() == 1);
148
            assertTrue(idInObjectList(id1, list2));
149
            
150
            //should return sm1-sm4
151
            ObjectList list3 = cs.listObjects(token, d1, d5, null);
152
            assertTrue(list3.sizeObjectInfoList() == 4);
153
            ObjectInfo oi4 = list3.getObjectInfo(0);
154
            assertTrue(idInObjectList(id1, list3));
155
            assertTrue(idInObjectList(id2, list3));
156
            assertTrue(idInObjectList(id3, list3));
157
            assertTrue(idInObjectList(id4, list3));
158
            
159
            //should only return sm2 and sm4
160
            ObjectList list4 = cs.listObjects(token, d1, d5, of2);
161
            assertTrue(list4.sizeObjectInfoList() == 2);
162
            assertTrue(idInObjectList(id2, list4));
163
            assertTrue(idInObjectList(id4, list4));
164
            
165
            //should return all
166
            ObjectList list5 = cs.listObjects(token, d1, d6, null);
167
            assertTrue(list5.sizeObjectInfoList() == 5);
168
            assertTrue(idInObjectList(id1, list5));
169
            assertTrue(idInObjectList(id2, list5));
170
            assertTrue(idInObjectList(id3, list5));
171
            assertTrue(idInObjectList(id4, list5));
172
            assertTrue(idInObjectList(id5, list5));
173
            
174
            //should return 1, 3, 5
175
            ObjectList list6 = cs.listObjects(token, d1, d6, of1);
176
            assertTrue(list6.sizeObjectInfoList() == 3);
177
            assertTrue(idInObjectList(id1, list6));
178
            assertTrue(idInObjectList(id3, list6));
179
            assertTrue(idInObjectList(id5, list6));
180
            
181
	    }
182
	    catch(Exception e)
183
	    {
184
	        //e.printStackTrace();
185
	        fail("Error in listObjects: " + e.getMessage());
186
	    }
187
	}
188
	
189
	private boolean idInObjectList(Identifier id, ObjectList list)
190
	{
191
	    for(int i=0; i<list.sizeObjectInfoList(); i++)
192
	    {
193
	        ObjectInfo oi = list.getObjectInfo(i);
194
	        if(id.getValue().equals(oi.getIdentifier().getValue()))
195
	            return true;
196
	    }
197
	    return false;
198
	}
199
	
200
	/**
201
	 * public Identifier update(AuthToken token, Identifier guid, 
202
     *       InputStream object, Identifier obsoletedGuid, SystemMetadata sysmeta) 
203
     *         throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique, 
204
     *           UnsupportedType, InsufficientResources, NotFound, InvalidSystemMetadata, 
205
     *           NotImplemented
206
	 */
207
	public void testUpdate()
208
	{
209
	    printTestHeader("testUpdate");
210
	    try
211
	    {
212
	        CrudService cs = CrudService.getInstance();
213
	        AuthToken token = getToken();
214
            //create a doc
215
            Identifier id = createDoc(token, getTestDoc());
216
            
217
            //get the doc and sysmetadata
218
            String gotDoc = getDoc(token, id);
219
            SystemMetadata sm = getSystemMetadata(token, id);
220
            
221
            //update the doc
222
            gotDoc = gotDoc.replaceAll("XXX", "YYY");
223
            Identifier newid = new Identifier();
224
            newid.setValue(generateDocumentId());
225
            StringBufferInputStream sbis = new StringBufferInputStream(gotDoc);
226
            SystemMetadata newsm = createSystemMetadata(newid, gotDoc);
227
            Identifier updatedid = cs.update(token, newid, sbis, id, newsm);
228
            
229
            //get doc - check that it matches update
230
            String newdoc = getDoc(token, newid);
231
            assertTrue(gotDoc.equals(newdoc));
232
            
233
            //get sysmeta - check that ids and other fields are updated
234
            SystemMetadata newnewsm = getSystemMetadata(token, id);
235
            assertTrue(newnewsm.getObsoletedBy(0).getValue().equals(newid.getValue()));
236
            
237
            //get the new sysmeta and make sure the obsoletes field is set
238
            SystemMetadata newnewnewsm = getSystemMetadata(token, newid);
239
            assertTrue(newnewnewsm.getObsolete(0).getValue().equals(id.getValue()));
240
        }
241
        catch(Exception e)
242
        {
243
            e.printStackTrace();
244
            fail("Error in testUpdate: " + e.getMessage());
245
        }
246
	}
247
	
248
	/**
249
	 * public SystemMetadata getSystemMetadata(AuthToken token, Identifier guid)
250
     *       throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, 
251
     *       InvalidRequest, NotImplemented
252
	 */
253
	public void testGetSystemMetadata()
254
	{
255
	    printTestHeader("testGetSystemMetadata");
256
	    try
257
	    {
258
            CrudService cs = CrudService.getInstance();
259
            AuthToken token = getToken();
260
            //run create
261
            Identifier id = createDoc(token, getTestDoc());
262
            //get the systemMetadata and make sure it is the correct object for this testDoc
263
            SystemMetadata sm = getSystemMetadata(token, id);
264
            assertTrue(sm.getIdentifier().getValue().equals(id.getValue()));
265
            assertTrue(sm.getChecksum().getValue().equals(checksum(getTestDoc())));
266
            
267
            try
268
            {
269
                Identifier fakeid = new Identifier();
270
                fakeid.setValue("somethingfake.234234");
271
                getSystemMetadata(token, fakeid);
272
                fail("getSystemMetadata should have thrown an exception.");
273
            }
274
            catch(Exception e)
275
            {
276
                assertTrue(true);
277
            }
278
        }
279
        catch(Exception e)
280
        {
281
            e.printStackTrace();
282
            fail("Error testing system metadata: " + e.getMessage());
283
        }
284
	}
285
	
286
	/**
287
	 * create(AuthToken token, Identifier guid, InputStream object, SystemMetadata sysmeta) 
288
     *   throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique, UnsupportedType, 
289
     *       InsufficientResources, InvalidSystemMetadata, NotImplemented
290
     *
291
     * public InputStream get(AuthToken token, Identifier guid)
292
     *       throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, 
293
     *       NotImplemented
294
	 */
295
	public void testCreateAndGet()
296
	{
297
	    printTestHeader("testCreateAndGet");
298
	    try
299
	    {
300
	        CrudService cs = CrudService.getInstance();
301
	        AuthToken token = getToken();
302
	        //run create
303
	        Identifier id = createDoc(token, getTestDoc());
304
	        //make these docs public for debugging purposes.
305
	        makeDocPublic(id, true);
306
            //compare the docs
307
            String gotDoc = getDoc(token, id);
308
            assertTrue(gotDoc.trim().equals(getTestDoc().trim()));
309
            
310
            try
311
            {
312
                Identifier fakeid = new Identifier();
313
                fakeid.setValue("somethingfake.234234");
314
                getDoc(token, fakeid);
315
                fail("testCreateAndGet should have thrown an exception.");
316
            }
317
            catch(Exception e)
318
            {
319
                assertTrue(true);
320
            }
321
        }
322
        catch(Exception e)
323
        {
324
            e.printStackTrace();
325
            fail("Error in testCreate: " + e.getMessage());
326
        }
327
	}
328

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