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
 *
6
 *   '$Author: jones $'
7
 *     '$Date: 2010-02-03 17:58:12 -0900 (Wed, 03 Feb 2010) $'
8
 * '$Revision: 5211 $'
9
 *
10
 * This program is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
 */
24

    
25
package edu.ucsb.nceas.metacattest;
26

    
27
import java.io.ByteArrayInputStream;
28
import java.io.InputStream;
29
import java.sql.SQLException;
30
import java.util.*;
31

    
32
import org.dataone.client.v2.itk.D1Client;
33
import org.dataone.service.types.v1.Identifier;
34
import org.dataone.service.types.v1.NodeType;
35
import org.dataone.service.types.v1.Session;
36
import org.dataone.service.types.v1.Subject;
37
import org.dataone.service.types.v2.Node;
38
import org.dataone.service.types.v2.NodeList;
39
import org.dataone.service.types.v2.SystemMetadata;
40

    
41
import edu.ucsb.nceas.MCTestCase;
42
import edu.ucsb.nceas.metacat.AccessionNumber;
43
import edu.ucsb.nceas.metacat.AccessionNumberException;
44
import edu.ucsb.nceas.metacat.IdentifierManager;
45
import edu.ucsb.nceas.metacat.McdbDocNotFoundException;
46
import edu.ucsb.nceas.metacat.client.MetacatAuthException;
47
import edu.ucsb.nceas.metacat.client.MetacatInaccessibleException;
48
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
49
import edu.ucsb.nceas.metacat.dataone.CNodeService;
50
import edu.ucsb.nceas.metacat.dataone.D1NodeServiceTest;
51
import edu.ucsb.nceas.metacat.dataone.MNodeService;
52

    
53
import org.dataone.service.exceptions.InvalidSystemMetadata;
54
import org.dataone.service.exceptions.ServiceFailure;
55

    
56
public class IdentifierManagerTest extends D1NodeServiceTest {
57
    private String badGuid = "test:testIdThatDoesNotExist";
58
    
59
    public IdentifierManagerTest(String name) {
60
        super(name);
61
    }
62
    /**
63
     * Initialize the connection to metacat, and insert a document to be 
64
     * used for testing with a known docid.
65
     */
66
    public void setUp() {
67
        
68
        metacatConnectionNeeded = true;
69
        try {
70
            DBConnectionPool pool = DBConnectionPool.getInstance();
71
        } catch (SQLException e2) {
72
            fail(e2.getMessage());
73
        }
74
        
75
        try {
76
            super.setUp();
77
        } catch (Exception e1) {
78
            fail(e1.getMessage());
79
        }
80
    }
81
    
82
    /**
83
     * test getting a guid from the systemmetadata table
84
     */
85
    public void testGetGUID()
86
    {
87
        ph("testGetGUID");
88
        try
89
        {
90
            IdentifierManager im = IdentifierManager.getInstance();
91

    
92
            String docid = insertTestDocument();
93
            docid = docid.substring(0, docid.lastIndexOf("."));
94
            
95
            String gotGuid = im.getGUID(docid, 1);
96
            assertNotNull(gotGuid);
97
        }
98
        catch(Exception e)
99
        {
100
            fail("Unexpected exception in testGetGUID: " + e.getMessage());
101
        }
102
    }
103
    
104
    /**
105
     * test getting a list of all local ids
106
     */
107
    public void testGetAllLocalIds()
108
    {
109
        ph("testGetAllLocalIds");
110
        try
111
        {
112
            List l = IdentifierManager.getInstance().getAllLocalIds();
113
            for(int i=0; i<l.size(); i++)
114
            {
115
                System.out.println(l.get(i));
116
            }
117
            assertTrue(l.size() > 0);
118
        }
119
        catch(Exception e)
120
        {
121
            fail("Error in testGetAllLocalIds: " + e.getMessage());
122
        }
123
    }
124

    
125
    /** Test that IM instances can be created. */
126
    public void testGetInstance() {
127
        ph("testGetInstance");
128
        IdentifierManager im = IdentifierManager.getInstance();
129
        assertNotNull(im);
130
    }
131

    
132
    /** Test that known LocalId's can be looked up from GUIDs. */
133
    public void testGetLocalId() {
134
        ph("testGetLocalId");
135
        IdentifierManager im = IdentifierManager.getInstance();
136
        String docidWithRev = insertTestDocument();
137
        String docid = docidWithRev.substring(0, docidWithRev.lastIndexOf("."));
138
        String guid;
139
        String idReturned;
140
        try {
141
            guid = im.getGUID(docid, 1);
142
            idReturned = im.getLocalId(guid);
143
            assertEquals(docidWithRev, idReturned);
144
            
145
        } catch (McdbDocNotFoundException e) {
146
            fail(e.getMessage());
147
        } catch (SQLException e) {
148
            fail(e.getMessage());
149
        }
150
    }
151
    
152
    /** Test that unknown LocalId's return the proper exception. */
153
    public void testGetLocalIdNotFound() {
154
        ph("testGetLocalIdNotFound");
155
        IdentifierManager im = IdentifierManager.getInstance();
156
        String idReturned;
157
        try {
158
            idReturned = im.getLocalId(badGuid);
159
            fail("Failed: getLocalID() should have returned an document not " + 
160
                 "found exception but did not.");
161
        } catch (McdbDocNotFoundException e) {
162
            assertNotNull(e);
163
        } catch (SQLException e) {
164
            fail(e.getMessage());
165
        }
166
    }
167
    
168
    /** 
169
     * Test that an identifier is present in the system when it should
170
     *  be, and that it is not present when it shouldn't be. 
171
     */
172
    public void testIdentifierExists() {
173
        ph("testIdentifierExists");
174
        
175
        String goodGuid  = "";
176
        String accString = "";
177
        String docid     = "";
178
        int rev          = 0;
179
        
180
        try {
181
          IdentifierManager im = IdentifierManager.getInstance();
182
          accString = insertTestDocument();
183
          AccessionNumber accNumber = new AccessionNumber(accString, "NONE");
184
          docid = accNumber.getDocid();
185
          rev = new Integer(accNumber.getRev());
186
          goodGuid = im.getGUID(docid, rev);
187
          assertTrue(im.identifierExists(goodGuid));
188
          assertFalse(im.identifierExists(badGuid));
189
          
190
        } catch ( McdbDocNotFoundException dnfe ) {
191
          fail("The document " + docid + "couldn't be found. The error was: " +
192
               dnfe.getMessage());
193
          
194
        } catch ( AccessionNumberException ane ) {
195
          fail("The accession number could not be created for docid" +
196
               accString + ". The error was: " + ane.getMessage());
197
        
198
        } catch ( NumberFormatException nfe ) {
199
          fail("The revision number could not be created for docid" + 
200
               accString + ". The error was: " + nfe.getMessage());
201
          
202
           } catch ( SQLException sqle ) {
203
             fail("The accession number could not be created for docid" + 
204
                  accString + ". The error was: " + sqle.getMessage());
205

    
206
        }
207
    }
208
    
209
    /**
210
     * Test that we are able to create mappings from guids to localIds, and that
211
     * improperly formatted docids generate the proper exceptions.  This also tests
212
     * getLocalId() and getGUID()
213
     */
214
    public void testCreateMapping() {
215
       ph("testCreateMapping");
216
       try
217
       {
218
            IdentifierManager im = IdentifierManager.getInstance();
219
            String docid = "test." + new Date().getTime() + ".1";
220
            String guid = "guid:" + docid;
221
            im.createMapping(guid, docid);
222
            String guiddocid = docid.substring(0, docid.length() - 2);
223
            System.out.println("guiddocid: " + guiddocid);
224
            String guid2 = im.getGUID(guiddocid, 1);
225
            assertTrue(guid2.equals(guid));
226
            String docid2 = im.getLocalId(guid);
227
            assertTrue(docid.equals(docid2));
228
        } catch (McdbDocNotFoundException e) {
229
            e.printStackTrace();
230
            fail("createMapping failed to create proper localId from guid: " + e.getMessage());
231
        } catch (SQLException e) {
232
            fail(e.getMessage());
233
        }
234
    }
235
    
236
    
237
    /**
238
     * test the local id creation
239
     */
240
    public void testGenerateLocalId() {
241
      IdentifierManager im = IdentifierManager.getInstance();
242
      String localid = im.generateLocalId("mynewid." + new Date().getTime(), 1);
243
      System.out.println("localid: " + localid);
244
      assertTrue(localid != null);
245
    }
246
    
247
    /**
248
     * Test the method - getHeadPID for a speicified SID
249
     */
250
    public void testGetHeadPID() {
251
        
252
        try {
253
            //insert test documents with a series id
254
            Session session = getTestSession();
255
            Identifier guid = new Identifier();
256
            guid.setValue(generateDocumentId());
257
            InputStream object = new ByteArrayInputStream("test".getBytes("UTF-8"));
258
            SystemMetadata sysmeta = createSystemMetadata(guid, session.getSubject(), object);
259
            String sid1= "sid."+System.nanoTime();
260
            Identifier seriesId = new Identifier();
261
            seriesId.setValue(sid1);
262
            System.out.println("the first sid is "+seriesId.getValue());
263
            sysmeta.setSeriesId(seriesId);
264
            MNodeService.getInstance(request).create(session, guid, object, sysmeta);
265
            System.out.println("the first pid is "+guid.getValue());
266
            Identifier head = IdentifierManager.getInstance().getHeadPID(seriesId);
267
            System.out.println("the head 1 is "+head.getValue());
268
            assertTrue(head.getValue().equals(guid.getValue()));
269
            assertTrue(IdentifierManager.getInstance().systemMetadataSIDExists(seriesId.getValue()));
270
            assertTrue(!IdentifierManager.getInstance().systemMetadataPIDExists(seriesId.getValue()));
271
            assertTrue(IdentifierManager.getInstance().systemMetadataPIDExists(guid.getValue()));
272
            assertTrue(!IdentifierManager.getInstance().systemMetadataSIDExists(guid.getValue()));
273
            
274
            //do a update with the same series id
275
            Thread.sleep(1000);
276
            Identifier newPid = new Identifier();
277
            newPid.setValue(generateDocumentId()+"1");
278
            System.out.println("the second pid is "+newPid.getValue());
279
            SystemMetadata newSysMeta = createSystemMetadata(newPid, session.getSubject(), object);
280
            newSysMeta.setObsoletes(guid);
281
            newSysMeta.setSeriesId(seriesId);
282
            MNodeService.getInstance(request).update(session, guid, object, newPid, newSysMeta);
283
            // the pid should be the newPid when we try to get the sid1
284
            head = IdentifierManager.getInstance().getHeadPID(seriesId);
285
            System.out.println("the head 2 is "+head.getValue());
286
            assertTrue(head.getValue().equals(newPid.getValue()));
287
            
288
            //do another update with different series id
289
            Thread.sleep(1000);
290
            String sid2 = "sid."+System.nanoTime();
291
            Identifier seriesId2= new Identifier();
292
            seriesId2.setValue(sid2);
293
            System.out.println("the second sid is "+seriesId2.getValue());
294
            Identifier newPid2 = new Identifier();
295
            newPid2.setValue(generateDocumentId()+"2");
296
            System.out.println("the third pid is "+newPid2.getValue());
297
            SystemMetadata sysmeta3 = createSystemMetadata(newPid2, session.getSubject(), object);
298
            sysmeta3.setObsoletes(newPid);
299
            sysmeta3.setSeriesId(seriesId2);
300
            MNodeService.getInstance(request).update(session, newPid, object, newPid2, sysmeta3);
301
            
302
            // the pid should be the newPid when we try to get the sid1
303
            head =IdentifierManager.getInstance().getHeadPID(seriesId);
304
            System.out.println("the head 3 is "+head.getValue());
305
            assertTrue(head.getValue().equals(newPid.getValue()));
306
            
307
            // the pid should be the newPid2 when we try to get the sid2
308
            head = IdentifierManager.getInstance().getHeadPID(seriesId2);
309
            System.out.println("the head 4 is "+head.getValue());
310
            assertTrue(head.getValue().equals(newPid2.getValue()));
311
            
312
            // the pid should be null when we try to get a no-exist sid
313
            Identifier non_exist_sid = new Identifier();
314
            non_exist_sid.setValue("no-sid-exist-123qwe");
315
            assertTrue(IdentifierManager.getInstance().getHeadPID(non_exist_sid) == null);
316
            
317
            //case-2
318
            object = new ByteArrayInputStream("test".getBytes("UTF-8"));
319
            Identifier pid1_case2 = new Identifier();
320
            pid1_case2.setValue(generateDocumentId());
321
            String sid_case2_str= "sid."+System.nanoTime();
322
            Identifier sid_case2 = new Identifier();
323
            sid_case2.setValue(sid_case2_str);
324
            SystemMetadata sysmeta_case2 = createSystemMetadata(pid1_case2, session.getSubject(), object);
325
            sysmeta_case2.setSeriesId(sid_case2);
326
            CNodeService.getInstance(request).create(session, pid1_case2, object, sysmeta_case2);
327
            
328
            Thread.sleep(1000);
329
            Identifier pid2_case2 = new Identifier();
330
            pid2_case2.setValue(generateDocumentId());
331
            sysmeta = createSystemMetadata(pid2_case2, session.getSubject(), object);
332
            sysmeta.setSeriesId(sid_case2);
333
            try {
334
                CNodeService.getInstance(request).create(session, pid2_case2, object, sysmeta);
335
                fail("we shouldn't get here and an InvalidSystemMetacat exception should be thrown.");
336
            } catch (InvalidSystemMetadata e) {
337
                System.out.println("case 2======= Invalid system metadata");
338
            }
339
            
340
        } catch (Exception e) {
341
            fail(e.getMessage());
342
        }
343
        
344
    }
345

    
346
    /** 
347
     * Insert a test document, returning the docid that was used. 
348
     */
349
    private String insertTestDocument() {
350
        String accessBlock = getAccessBlock("public", true, true,
351
                false, false, false);
352
        String emldoc = getTestEmlDoc("Test identifier manager", EML2_1_0, null,
353
                null, "http://fake.example.com/somedata", null,
354
                accessBlock, null, null,
355
                null, null);
356
        System.out.println("inserting doc: " + emldoc);
357
        String docid = generateDocumentId() + ".1";
358
        try {
359
            m.login(username, password);
360
            String response = insertDocumentId(docid, emldoc, true, false);
361
        } catch (MetacatAuthException e) {
362
            fail(e.getMessage());
363
        } catch (MetacatInaccessibleException e) {
364
            fail(e.getMessage());
365
        }
366
        return docid;
367
    }
368
    
369
    private void ph(String s)
370
    {
371
        System.out.println("*********************** " + s + " ****************************");
372
    }
373
    
374
    /**
375
     * We want to act as the CN itself
376
     * @throws ServiceFailure 
377
     * @throws Exception 
378
     */
379
    @Override
380
    public Session getTestSession() throws Exception {
381
        Session session = super.getTestSession();
382
        
383
        // use the first CN we find in the nodelist
384
        NodeList nodeList = D1Client.getCN().listNodes();
385
        for (Node node : nodeList.getNodeList()) {
386
            if ( node.getType().equals(NodeType.CN) ) {
387
                
388
                List<Subject> subjects = node.getSubjectList();
389
                for (Subject subject : subjects) {
390
                   session.setSubject(subject);
391
                   // we are done here
392
                   return session;
393
                }
394
            }
395
        }
396
        // in case we didn't find it
397
        return session;
398
    }
399
    
400
}
(7-7/26)