Revision 5282
Added by Matt Jones over 14 years ago
test/edu/ucsb/nceas/metacattest/IdentifierManagerTest.java | ||
---|---|---|
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.sql.SQLException; |
|
28 |
|
|
29 |
import edu.ucsb.nceas.MCTestCase; |
|
30 |
import edu.ucsb.nceas.metacat.IdentifierManager; |
|
31 |
import edu.ucsb.nceas.metacat.McdbDocNotFoundException; |
|
32 |
import edu.ucsb.nceas.metacat.client.MetacatAuthException; |
|
33 |
import edu.ucsb.nceas.metacat.client.MetacatInaccessibleException; |
|
34 |
import edu.ucsb.nceas.metacat.database.DBConnectionPool; |
|
35 |
|
|
36 |
public class IdentifierManagerTest extends MCTestCase { |
|
37 |
private String badGuid = "test:testIdThatDoesNotExist"; |
|
38 |
|
|
39 |
/** |
|
40 |
* Initialize the connection to metacat, and insert a document to be |
|
41 |
* used for testing with a known docid. |
|
42 |
*/ |
|
43 |
public void setUp() { |
|
44 |
|
|
45 |
metacatConnectionNeeded = true; |
|
46 |
try { |
|
47 |
DBConnectionPool pool = DBConnectionPool.getInstance(); |
|
48 |
} catch (SQLException e2) { |
|
49 |
fail(e2.getMessage()); |
|
50 |
} |
|
51 |
|
|
52 |
try { |
|
53 |
super.setUp(); |
|
54 |
} catch (Exception e1) { |
|
55 |
fail(e1.getMessage()); |
|
56 |
} |
|
57 |
} |
|
58 |
|
|
59 |
/** Test that IM instances can be created. */ |
|
60 |
public void testGetInstance() { |
|
61 |
IdentifierManager im = IdentifierManager.getInstance(); |
|
62 |
assertNotNull(im); |
|
63 |
} |
|
64 |
|
|
65 |
/** Test that known LocalId's can be looked up from GUIDs. */ |
|
66 |
public void testGetLocalId() { |
|
67 |
IdentifierManager im = IdentifierManager.getInstance(); |
|
68 |
String docid = insertTestDocument(); |
|
69 |
String goodGuid = "test:" + docid; |
|
70 |
im.createMapping(goodGuid, docid); |
|
71 |
String idReturned; |
|
72 |
try { |
|
73 |
idReturned = im.getLocalId(goodGuid); |
|
74 |
assertEquals(docid, idReturned); |
|
75 |
} catch (McdbDocNotFoundException e) { |
|
76 |
fail(e.getMessage()); |
|
77 |
} |
|
78 |
} |
|
79 |
|
|
80 |
/** Test that unknown LocalId's return the proper exception. */ |
|
81 |
public void testGetLocalIdNotFound() { |
|
82 |
IdentifierManager im = IdentifierManager.getInstance(); |
|
83 |
String idReturned; |
|
84 |
try { |
|
85 |
idReturned = im.getLocalId(badGuid); |
|
86 |
fail("Failed: getLocalID() should have returned an document not " + |
|
87 |
"found exception but did not."); |
|
88 |
} catch (McdbDocNotFoundException e) { |
|
89 |
assertNotNull(e); |
|
90 |
} |
|
91 |
} |
|
92 |
|
|
93 |
/** |
|
94 |
* Test that an identifier is present in the system when it should |
|
95 |
* be, and that it is not present when it shouldn't be. |
|
96 |
*/ |
|
97 |
public void testIdentifierExists() { |
|
98 |
IdentifierManager im = IdentifierManager.getInstance(); |
|
99 |
String docid = insertTestDocument(); |
|
100 |
im.createMapping("test:"+docid, docid); |
|
101 |
String goodGuid = "test:" + docid; |
|
102 |
assertTrue(im.identifierExists(goodGuid)); |
|
103 |
assertFalse(im.identifierExists(badGuid)); |
|
104 |
} |
|
105 |
|
|
106 |
/** |
|
107 |
* Test that we are able to create mappings from guids to localIds, and that |
|
108 |
* improperly formatted docids generate the proper exceptions. |
|
109 |
*/ |
|
110 |
public void testCreateMapping() { |
|
111 |
IdentifierManager im = IdentifierManager.getInstance(); |
|
112 |
String docid = insertTestDocument(); |
|
113 |
im.createMapping("test:"+docid, docid); |
|
114 |
try { |
|
115 |
assertEquals(im.getLocalId("test:"+docid), docid); |
|
116 |
} catch (McdbDocNotFoundException e) { |
|
117 |
fail("createMapping failed to create proper localId from guid."); |
|
118 |
} |
|
119 |
} |
|
120 |
|
|
121 |
/** Insert a test document, returning the docid that was used. */ |
|
122 |
private String insertTestDocument() { |
|
123 |
String accessBlock = getAccessBlock("public", true, true, |
|
124 |
false, false, false); |
|
125 |
String emldoc = getTestEmlDoc("Test identifier manager", EML2_1_0, null, |
|
126 |
null, "http://fake.example.com/somedata", null, |
|
127 |
accessBlock, null, null, |
|
128 |
null, null); |
|
129 |
String docid = generateDocumentId() + ".1"; |
|
130 |
try { |
|
131 |
m.login(username, password); |
|
132 |
String response = insertDocumentId(docid, emldoc, true, false); |
|
133 |
} catch (MetacatAuthException e) { |
|
134 |
fail(e.getMessage()); |
|
135 |
} catch (MetacatInaccessibleException e) { |
|
136 |
fail(e.getMessage()); |
|
137 |
} |
|
138 |
return docid; |
|
139 |
} |
|
140 |
} |
|
0 | 141 |
test/edu/ucsb/nceas/metacattest/restservice/MetacatRestClientTest.java | ||
---|---|---|
78 | 78 |
private static final String DOCID = "docid"; |
79 | 79 |
private static final String DATAID = "dataid"; |
80 | 80 |
|
81 |
private static final String public_doc_id = "serhan.3.1";
|
|
81 |
private static final String public_doc_id = "doi:12345.5/playing/in/dirt/rev1";
|
|
82 | 82 |
private static final String authorized_doc_id = "serhan.4.2"; |
83 | 83 |
private static final String notexisting_doc_id = "serhan.1.1"; |
84 | 84 |
private static final String ecogridQueryFile= "test/restfiles/ecogrid_query.xml"; |
src/edu/ucsb/nceas/metacat/restservice/ResourceHandler.java | ||
---|---|---|
36 | 36 |
import org.apache.log4j.Logger; |
37 | 37 |
|
38 | 38 |
import edu.ucsb.nceas.metacat.DBUtil; |
39 |
import edu.ucsb.nceas.metacat.IdentifierManager; |
|
40 |
import edu.ucsb.nceas.metacat.McdbDocNotFoundException; |
|
39 | 41 |
import edu.ucsb.nceas.metacat.MetacatHandler; |
40 | 42 |
import edu.ucsb.nceas.metacat.util.RequestUtil; |
41 | 43 |
import edu.ucsb.nceas.metacat.util.SessionData; |
... | ... | |
414 | 416 |
/** |
415 | 417 |
* Earthgrid API > Query Service > Get Function : calls MetacatHandler > handleReadAction |
416 | 418 |
* |
417 |
* @param objectId ID of data object to be read
|
|
419 |
* @param guid ID of data object to be read
|
|
418 | 420 |
*/ |
419 |
private void getObject(String objectId) { |
|
420 |
params.put("docid", new String[] { objectId }); |
|
421 |
private void getObject(String guid) { |
|
422 |
// Look up the localId for this global identifier |
|
423 |
IdentifierManager im = IdentifierManager.getInstance(); |
|
424 |
String localId = ""; |
|
425 |
try { |
|
426 |
localId = im.getLocalId(guid); |
|
427 |
} catch (McdbDocNotFoundException e) { |
|
428 |
// Need to return the proper DataONE exception |
|
429 |
} |
|
430 |
|
|
431 |
// Now use that localId to read the object and return it |
|
432 |
params.put("docid", new String[] { localId }); |
|
421 | 433 |
handler.handleReadAction(params, request, response, username, password, |
422 | 434 |
groupNames); |
423 | 435 |
} |
... | ... | |
501 | 513 |
|
502 | 514 |
if (action.equals(FUNCTION_NAME_UPDATE) |
503 | 515 |
|| action.equals(FUNCTION_NAME_INSERT)) { |
516 |
// |
|
517 |
// WARNING: This should not be a Reader if we are inserting data |
|
518 |
// Nor should it be read into a String |
|
519 |
// so this seems like a latent bug to me (MBJ; 16Mar2010) |
|
504 | 520 |
BufferedReader reader = request.getReader(); |
505 | 521 |
StringBuffer buffer = new StringBuffer(); |
506 | 522 |
String line = null; |
src/edu/ucsb/nceas/metacat/client/rest/MetacatRest.java | ||
---|---|---|
54 | 54 |
*/ |
55 | 55 |
|
56 | 56 |
/** API OBJECTS Resource which handles with document operations*/ |
57 |
public static final String RESOURCE_OBJECTS = "objects";
|
|
57 |
public static final String RESOURCE_OBJECTS = "object"; |
|
58 | 58 |
/** API SESSION Resource which handles with user session operations*/ |
59 | 59 |
public static final String RESOURCE_SESSION = "session"; |
60 | 60 |
/** API IDENTIFIER Resource which controls object unique identifier operations*/ |
src/edu/ucsb/nceas/metacat/IdentifierManager.java | ||
---|---|---|
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.metacat; |
|
26 |
|
|
27 |
import java.sql.PreparedStatement; |
|
28 |
import java.sql.ResultSet; |
|
29 |
import java.sql.SQLException; |
|
30 |
|
|
31 |
import org.apache.log4j.Logger; |
|
32 |
|
|
33 |
import edu.ucsb.nceas.metacat.database.DBConnection; |
|
34 |
import edu.ucsb.nceas.metacat.database.DBConnectionPool; |
|
35 |
|
|
36 |
/** |
|
37 |
* Manage the relationship between Metacat local identifiers (LocalIDs) that are |
|
38 |
* codified as the (docid, rev) pair with globally uniqe string identifiers |
|
39 |
* (GUIDs) that are opaque strings. This class provides methods to manage these |
|
40 |
* identifiers, and to search for and look up LocalIDs based on their GUID and |
|
41 |
* vice versa. IdentifierManager is a singleton. |
|
42 |
* |
|
43 |
* @author Matthew Jones |
|
44 |
*/ |
|
45 |
public class IdentifierManager { |
|
46 |
|
|
47 |
/** |
|
48 |
* The single instance of the manager that is always returned. |
|
49 |
*/ |
|
50 |
private static IdentifierManager self = null; |
|
51 |
private Logger logMetacat = Logger.getLogger(EventLog.class); |
|
52 |
|
|
53 |
/** |
|
54 |
* A private constructor that initializes the class when getInstance() is |
|
55 |
* called. |
|
56 |
*/ |
|
57 |
private IdentifierManager() |
|
58 |
{ |
|
59 |
} |
|
60 |
|
|
61 |
/** |
|
62 |
* Return the single instance of the manager after initializing it if it |
|
63 |
* wasn't previously initialized. |
|
64 |
* |
|
65 |
* @return the single IdentifierManager instance |
|
66 |
*/ |
|
67 |
public static IdentifierManager getInstance() |
|
68 |
{ |
|
69 |
if (self == null) { |
|
70 |
self = new IdentifierManager(); |
|
71 |
} |
|
72 |
return self; |
|
73 |
} |
|
74 |
|
|
75 |
/** |
|
76 |
* Lookup a GUID from the database, and return the associated LocalID. If |
|
77 |
* the identifier is not found, throw an exception. |
|
78 |
* |
|
79 |
* @param guid the global identifier to look up |
|
80 |
* @return String containing the corresponding LocalId |
|
81 |
* @throws McdbDocNotFoundException if the identifier is not found |
|
82 |
*/ |
|
83 |
public String getLocalId(String guid) throws McdbDocNotFoundException |
|
84 |
{ |
|
85 |
String db_guid = ""; |
|
86 |
String docid = ""; |
|
87 |
int rev = 0; |
|
88 |
|
|
89 |
String query = "select guid, docid, rev from identifier where guid = ?"; |
|
90 |
|
|
91 |
DBConnection dbConn = null; |
|
92 |
int serialNumber = -1; |
|
93 |
try { |
|
94 |
// Get a database connection from the pool |
|
95 |
dbConn = DBConnectionPool.getDBConnection("Identifier.getLocalId"); |
|
96 |
serialNumber = dbConn.getCheckOutSerialNumber(); |
|
97 |
|
|
98 |
// Execute the insert statement |
|
99 |
PreparedStatement stmt = dbConn.prepareStatement(query); |
|
100 |
stmt.setString(1, guid); |
|
101 |
ResultSet rs = stmt.executeQuery(); |
|
102 |
if (rs.next()) { |
|
103 |
db_guid = rs.getString(1); |
|
104 |
docid = rs.getString(2); |
|
105 |
rev = rs.getInt(3); |
|
106 |
assert(db_guid.equals(guid)); |
|
107 |
} else { |
|
108 |
throw new McdbDocNotFoundException("Document not found:" + guid); |
|
109 |
} |
|
110 |
stmt.close(); |
|
111 |
} catch (SQLException e) { |
|
112 |
logMetacat.error("Error while looking up the local identifier: " |
|
113 |
+ e.getMessage()); |
|
114 |
} finally { |
|
115 |
// Return database connection to the pool |
|
116 |
DBConnectionPool.returnDBConnection(dbConn, serialNumber); |
|
117 |
} |
|
118 |
return docid + "." + rev; |
|
119 |
} |
|
120 |
|
|
121 |
/** |
|
122 |
* Determine if an identifier exists already, returning true if so. |
|
123 |
* |
|
124 |
* @param guid the global identifier to look up |
|
125 |
* @return boolean true if the identifier exists |
|
126 |
*/ |
|
127 |
public boolean identifierExists(String guid) |
|
128 |
{ |
|
129 |
boolean idExists = false; |
|
130 |
try { |
|
131 |
String id = getLocalId(guid); |
|
132 |
if (id != null) { |
|
133 |
idExists = true; |
|
134 |
} |
|
135 |
} catch (McdbDocNotFoundException e) { |
|
136 |
idExists = false; |
|
137 |
} |
|
138 |
return idExists; |
|
139 |
} |
|
140 |
|
|
141 |
/** |
|
142 |
* Create a mapping between two identifiers, one representing an |
|
143 |
* unconstrained, globally unique string (guid), and one a localId |
|
144 |
* in the Metacat docid format (scope.id.revision). |
|
145 |
* This mapping allows one to find the global id (guid) from the localId. |
|
146 |
* |
|
147 |
* @param guid the global string identifier to be mapped |
|
148 |
* @param localId the local identifier to be mapped |
|
149 |
*/ |
|
150 |
public void createMapping(String guid, String localId) |
|
151 |
{ |
|
152 |
int serialNumber = -1; |
|
153 |
DBConnection dbConn = null; |
|
154 |
try { |
|
155 |
|
|
156 |
// Parse the localId into scope and rev parts |
|
157 |
AccessionNumber acc = new AccessionNumber(localId, "NOACTION"); |
|
158 |
String docid = acc.getDocid(); |
|
159 |
int rev = (new Integer(acc.getRev()).intValue()); |
|
160 |
|
|
161 |
// Get a database connection from the pool |
|
162 |
dbConn = |
|
163 |
DBConnectionPool.getDBConnection("Identifier.createMapping"); |
|
164 |
serialNumber = dbConn.getCheckOutSerialNumber(); |
|
165 |
|
|
166 |
// Execute the insert statement |
|
167 |
String query = "insert into identifier (guid, docid, rev) values (?, ?, ?)"; |
|
168 |
PreparedStatement stmt = dbConn.prepareStatement(query); |
|
169 |
stmt.setString(1, guid); |
|
170 |
stmt.setString(2, docid); |
|
171 |
stmt.setInt(3, rev); |
|
172 |
int rows = stmt.executeUpdate(); |
|
173 |
|
|
174 |
stmt.close(); |
|
175 |
} catch (SQLException e) { |
|
176 |
logMetacat.error("SQL error while creating a mapping to the local identifier: " |
|
177 |
+ e.getMessage()); |
|
178 |
} catch (NumberFormatException e) { |
|
179 |
logMetacat.error("NumberFormat error while creating a mapping to the local identifier: " |
|
180 |
+ e.getMessage()); |
|
181 |
} catch (AccessionNumberException e) { |
|
182 |
logMetacat.error("AccessionNumber error while creating a mapping to the local identifier: " |
|
183 |
+ e.getMessage()); |
|
184 |
} finally { |
|
185 |
// Return database connection to the pool |
|
186 |
DBConnectionPool.returnDBConnection(dbConn, serialNumber); |
|
187 |
} |
|
188 |
} |
|
189 |
} |
|
0 | 190 |
src/edu/ucsb/nceas/metacat/McdbDocNotFoundException.java | ||
---|---|---|
37 | 37 |
// String sto stroe which docid couldn't find |
38 | 38 |
private String unfoundDocId = null; |
39 | 39 |
private String unfoundRevision = null; |
40 |
|
|
40 | 41 |
/** |
41 | 42 |
* Create a new McdbDocNotFoundException. |
42 | 43 |
*/ |
... | ... | |
59 | 60 |
} |
60 | 61 |
|
61 | 62 |
/** |
63 |
* Create a new exception but only set the message. |
|
64 |
* @param message a message giving information about why the document was not found |
|
65 |
*/ |
|
66 |
public McdbDocNotFoundException(String message) { |
|
67 |
super(message); |
|
68 |
} |
|
69 |
|
|
70 |
/** |
|
62 | 71 |
* Create a new McdbDocNotFoundException. |
63 | 72 |
* |
64 | 73 |
* @param e The exception to tunnel inside this exception |
Also available in: Unified diff
Added initial support for arbitrary string identifiers in metacat (referred to as a guid). The new identifier table is used to map arbitrary string identifiers to Metacat's current docid format (referred to as the localId). Added a new IdentifierManager class to manage this table, adding new mappings as objects are added to the system. Modified the MetacatTest service to utilize this mapping table to look up a localId from a guid. IdentiferManagerTest is working with these guids now, as is the MetacatTest service get() method, but other parts of the system are unaware of them (e.g., create, update, delete operations are unaware, and no mapping is created when new documents are created). As a consequence, the MetacatRestClientTest is not working (although it also had lots of hardcoded dependencies that need to be fixed as well).