Revision 8621
Added by Peter Slaughter almost 11 years ago
test/edu/ucsb/nceas/metacat/admin/upgrade/dataone/SyncAccessPolicyTest.java | ||
---|---|---|
27 | 27 |
|
28 | 28 |
import java.io.ByteArrayInputStream; |
29 | 29 |
import java.io.InputStream; |
30 |
import java.util.Hashtable; |
|
30 |
import java.util.ArrayList; |
|
31 |
import java.util.List; |
|
32 |
import java.util.Vector; |
|
31 | 33 |
|
32 | 34 |
import junit.framework.Test; |
33 | 35 |
import junit.framework.TestSuite; |
... | ... | |
45 | 47 |
import org.junit.Before; |
46 | 48 |
|
47 | 49 |
import edu.ucsb.nceas.metacat.IdentifierManager; |
48 |
import edu.ucsb.nceas.metacat.client.Metacat; |
|
49 |
import edu.ucsb.nceas.metacat.client.MetacatFactory; |
|
50 |
import edu.ucsb.nceas.metacat.client.MetacatAuthException; |
|
50 | 51 |
import edu.ucsb.nceas.metacat.client.MetacatInaccessibleException; |
52 |
import edu.ucsb.nceas.metacat.dataone.CNodeService; |
|
53 |
import edu.ucsb.nceas.metacat.dataone.MNodeService; |
|
51 | 54 |
import edu.ucsb.nceas.metacat.dataone.D1NodeServiceTest; |
52 |
import edu.ucsb.nceas.metacat.dataone.MNodeService; |
|
53 | 55 |
import edu.ucsb.nceas.metacat.dataone.SyncAccessPolicy; |
56 |
import edu.ucsb.nceas.metacat.util.DocumentUtil; |
|
54 | 57 |
import edu.ucsb.nceas.utilities.access.AccessControlInterface; |
55 | 58 |
|
56 | 59 |
/** |
... | ... | |
59 | 62 |
*/ |
60 | 63 |
public class SyncAccessPolicyTest extends D1NodeServiceTest { |
61 | 64 |
|
62 |
private Metacat m;
|
|
65 |
private CNode cn = null;
|
|
63 | 66 |
|
64 | 67 |
/** |
65 | 68 |
* Constructor to build the test |
... | ... | |
76 | 79 |
*/ |
77 | 80 |
@Before |
78 | 81 |
public void setUp() throws Exception { |
79 |
// super.setUp(); |
|
82 |
metacatConnectionNeeded = true; |
|
83 |
super.setUp(); |
|
80 | 84 |
|
85 |
/* |
|
86 |
* Determine the CN for the current host. This test must be run on a |
|
87 |
* registered MN. |
|
88 |
*/ |
|
81 | 89 |
try { |
82 |
debug("Test Metacat: " + metacatUrl); |
|
83 |
m = MetacatFactory.createMetacatConnection(metacatUrl); |
|
84 |
} catch (MetacatInaccessibleException mie) { |
|
85 |
System.err.println("Metacat is: " + metacatUrl); |
|
86 |
fail("Metacat connection failed." + mie.getMessage()); |
|
90 |
cn = D1Client.getCN(); |
|
91 |
} catch (ServiceFailure sf) { |
|
92 |
debug("Unable to get Coordinating node name for this MN"); |
|
93 |
fail(); |
|
87 | 94 |
} |
95 |
|
|
88 | 96 |
} |
89 | 97 |
|
90 | 98 |
/** |
... | ... | |
101 | 109 |
suite.addTest(new SyncAccessPolicyTest("initialize")); |
102 | 110 |
suite.addTest(new SyncAccessPolicyTest("testIsEqual")); |
103 | 111 |
suite.addTest(new SyncAccessPolicyTest("testSyncAccessPolicy")); |
112 |
suite.addTest(new SyncAccessPolicyTest( |
|
113 |
"testSyncEML201OnlineDataAccessPolicy")); |
|
104 | 114 |
|
105 | 115 |
return suite; |
106 | 116 |
} |
... | ... | |
115 | 125 |
|
116 | 126 |
/** |
117 | 127 |
* constructs a "fake" session with a test subject |
128 |
* |
|
118 | 129 |
* @return |
119 | 130 |
*/ |
120 | 131 |
@Override |
121 | 132 |
public Session getTestSession() throws Exception { |
122 | 133 |
Session session = new Session(); |
123 |
Subject subject = new Subject();
|
|
124 |
subject.setValue(anotheruser);
|
|
125 |
session.setSubject(subject);
|
|
126 |
return session;
|
|
134 |
Subject subject = new Subject();
|
|
135 |
subject.setValue(anotheruser);
|
|
136 |
session.setSubject(subject);
|
|
137 |
return session;
|
|
127 | 138 |
} |
139 |
|
|
128 | 140 |
/** |
129 | 141 |
* Test object creation |
130 | 142 |
*/ |
... | ... | |
150 | 162 |
return pid; |
151 | 163 |
} |
152 | 164 |
|
165 |
/** |
|
166 |
* This test checks that access policy of a pid is synced with the CN after |
|
167 |
* the docid is manually changed using the Metacat api (setaccess). |
|
168 |
*/ |
|
153 | 169 |
public void testSyncAccessPolicy() { |
154 | 170 |
|
155 | 171 |
AccessPolicy cnAccessPolicy = null; |
156 | 172 |
AccessPolicy mnAccessPolicy = null; |
157 | 173 |
SystemMetadata cnSysMeta = null; |
158 | 174 |
SystemMetadata mnSysMeta = null; |
159 |
String resultXML = null; |
|
160 | 175 |
|
161 | 176 |
String response = null; |
162 |
debug("Logging in with user: " + anotheruser + ", password: "
|
|
163 |
+ anotherpassword);
|
|
177 |
debug("\nStarting sync access policy test");
|
|
178 |
debug("Logging in with user: " + anotheruser + ", password: " + anotherpassword);
|
|
164 | 179 |
try { |
165 | 180 |
response = m.login(anotheruser, anotherpassword); |
166 |
debug("Login response: " + response); |
|
167 | 181 |
} catch (Exception e) { |
168 | 182 |
debug("Unable to login: " + response); |
169 | 183 |
fail(); |
170 | 184 |
} |
171 | 185 |
|
172 | 186 |
try { |
173 |
debug("\nStarting sync access policy test"); |
|
174 |
|
|
175 | 187 |
Identifier pid = null; |
176 |
// create the systemMetadata the normal way |
|
177 |
|
|
178 | 188 |
pid = createTestPid(); |
179 | 189 |
assertNotNull(pid); |
180 | 190 |
|
181 | 191 |
debug("Inserted new document: " + pid.getValue()); |
182 |
try { |
|
183 |
// Get sm, access policy for requested localId |
|
184 |
mnSysMeta = IdentifierManager.getInstance().getSystemMetadata( |
|
185 |
pid.getValue()); |
|
186 |
} catch (Exception e) { |
|
187 |
debug("Error getting system metadata for new pid: " |
|
188 |
+ pid.getValue() + ". Message: " + e.getMessage()); |
|
189 |
fail(); |
|
190 |
} |
|
191 |
|
|
192 |
CNode cn = null; |
|
193 |
|
|
194 |
try { |
|
195 |
cn = D1Client.getCN(); |
|
196 |
} catch (ServiceFailure sf) { |
|
197 |
debug("Unable to get Coordinating node name for this MN"); |
|
198 |
fail(); |
|
199 |
} |
|
200 |
|
|
201 | 192 |
boolean found = false; |
202 | 193 |
int attempts = 0; |
203 | 194 |
|
... | ... | |
208 | 199 |
// sync the access policies |
209 | 200 |
// (which is triggered by the Metacat setaccess call). |
210 | 201 |
|
211 |
debug("Checking for new docid on CN...");
|
|
202 |
debug("Checking for new pid on CN...");
|
|
212 | 203 |
found = false; |
213 | 204 |
for (int i = 0; i < 6; i++) { |
214 | 205 |
attempts = i; |
... | ... | |
216 | 207 |
// Get the test document from the CN |
217 | 208 |
// Get sm, access policy for requested pid from the CN |
218 | 209 |
try { |
219 |
cnSysMeta = cn.getSystemMetadata(pid); |
|
210 |
cnSysMeta = CNodeService.getInstance(request) |
|
211 |
.getSystemMetadata(pid); |
|
220 | 212 |
} catch (Exception e) { |
221 | 213 |
debug("Error getting system metadata for pid: " |
222 | 214 |
+ pid.getValue() + " from cn: " + e.getMessage()); |
... | ... | |
234 | 226 |
+ " after " + attempts + " attempts"); |
235 | 227 |
} |
236 | 228 |
|
237 |
Hashtable<String, String[]> fieldValuePairs = new Hashtable<String, String[]>(); |
|
238 |
fieldValuePairs = new Hashtable<String, String[]>(); |
|
239 |
|
|
240 | 229 |
String localId = null; |
241 | 230 |
try { |
242 | 231 |
localId = IdentifierManager.getInstance().getLocalId( |
... | ... | |
247 | 236 |
} |
248 | 237 |
|
249 | 238 |
debug("Updating permissions of localId: " + localId + ", guid: " |
250 |
+ pid.getValue() + ", username: " + username + " read, allow, allowFirst"); |
|
239 |
+ pid.getValue() + ", username: " + username |
|
240 |
+ " read, allow, allowFirst"); |
|
251 | 241 |
|
242 |
m.logout(); |
|
243 |
response = m.login(anotheruser, anotherpassword); |
|
244 |
|
|
245 |
/* Update the docid access policy with Metacat api */ |
|
252 | 246 |
try { |
253 |
response = m.setAccess(localId, username,
|
|
254 |
AccessControlInterface.READSTRING,
|
|
255 |
AccessControlInterface.ALLOW,
|
|
256 |
AccessControlInterface.ALLOWFIRST);
|
|
247 |
response = m.setAccess(localId, username, |
|
248 |
AccessControlInterface.READSTRING, |
|
249 |
AccessControlInterface.ALLOW,
|
|
250 |
AccessControlInterface.ALLOWFIRST);
|
|
257 | 251 |
} catch (Exception e) { |
258 | 252 |
debug("Response from setaccess: " + response); |
259 | 253 |
debug("Error setting access for localId: " + e.getMessage()); |
260 | 254 |
fail(); |
261 | 255 |
} |
262 |
|
|
256 |
|
|
263 | 257 |
debug("Response from setaccess: " + response); |
264 | 258 |
debug("Retrieving updated docid from CN to check if perms were updated..."); |
265 | 259 |
|
266 |
// Get the test document from the CN |
|
267 |
// Get sm, access policy for requested pid from the CN |
|
260 |
/* Reread SM from MN, CN */ |
|
268 | 261 |
try { |
269 |
cnSysMeta = cn.getSystemMetadata(pid); |
|
262 |
mnSysMeta = MNodeService.getInstance(request) |
|
263 |
.getSystemMetadata(pid); |
|
264 |
debug("Got SM from MN"); |
|
270 | 265 |
} catch (Exception e) { |
266 |
debug("Error getting system metadata for new pid: " |
|
267 |
+ pid.getValue() + ". Message: " + e.getMessage()); |
|
268 |
fail(); |
|
269 |
} |
|
270 |
|
|
271 |
// Get the test document from the CN |
|
272 |
try { |
|
273 |
cnSysMeta = CNodeService.getInstance(request) |
|
274 |
.getSystemMetadata(pid); |
|
275 |
debug("Got SM from CN"); |
|
276 |
} catch (Exception e) { |
|
271 | 277 |
debug("Error getting system metadata for pid: " |
272 | 278 |
+ pid.getValue() + " from cn: " + e.getMessage()); |
273 | 279 |
fail(); |
274 | 280 |
} |
275 | 281 |
|
282 |
/* Check if the access policy was updated on the MN */ |
|
283 |
mnAccessPolicy = mnSysMeta.getAccessPolicy(); |
|
284 |
found = false; |
|
285 |
List<Subject> subjectList = null; |
|
286 |
List<AccessRule> accessRules = mnAccessPolicy.getAllowList(); |
|
287 |
debug("Checking that access policy was added to MN"); |
|
288 |
// |
|
289 |
// for (AccessRule ar : accessRules) { |
|
290 |
// subjectList = ar.getSubjectList(); |
|
291 |
// for (Subject sj : subjectList) { |
|
292 |
// debug("Checking subject: " + sj.getValue()); |
|
293 |
// if (sj.getValue().contains(anotheruser)) { |
|
294 |
// debug("user " + anotheruser + " found"); |
|
295 |
// found = true; |
|
296 |
// } |
|
297 |
// debug("Foo"); |
|
298 |
// } |
|
299 |
// } |
|
300 |
// |
|
301 |
// assertTrue(found); |
|
276 | 302 |
debug("Checking privs retrieved from CN"); |
277 |
// Check if privs for the new user showed up on the CN |
|
278 |
mnAccessPolicy = mnSysMeta.getAccessPolicy(); |
|
279 | 303 |
debug("Getting access policy for pid: " + pid.getValue()); |
280 | 304 |
cnAccessPolicy = cnSysMeta.getAccessPolicy(); |
281 | 305 |
debug("Diffing access policies (MN,CN) for pid: " + pid.getValue()); |
282 | 306 |
SyncAccessPolicy syncAP = new SyncAccessPolicy(); |
283 | 307 |
debug("Comparing access policies..."); |
284 |
|
|
285 |
Boolean apEqual = new Boolean (syncAP.isEqual(mnAccessPolicy, cnAccessPolicy)); |
|
286 |
debug("Access policies are equal is " + apEqual.toString()); |
|
308 |
|
|
309 |
Boolean apEqual = new Boolean(syncAP.isEqual(mnAccessPolicy, |
|
310 |
cnAccessPolicy)); |
|
311 |
debug("Are access policies equal?: " + apEqual.toString()); |
|
287 | 312 |
assert (apEqual == true); |
288 | 313 |
|
314 |
deleteDocumentId(localId, SUCCESS, true); |
|
289 | 315 |
m.logout(); |
290 | 316 |
|
291 | 317 |
} catch (Exception e) { |
292 | 318 |
e.printStackTrace(); |
293 |
fail("Error running syncAP test: " + e.getMessage()); |
|
319 |
debug("Error running syncAP test: " + e.getMessage()); |
|
320 |
fail(); |
|
294 | 321 |
} |
295 | 322 |
|
296 | 323 |
debug("Done running testSyncAccessPolicy"); |
297 | 324 |
} |
298 |
|
|
325 |
|
|
326 |
/* |
|
327 |
* This test checks that the access policy of an online data object |
|
328 |
* (described in EML 2.0.1 <online> section) is properly synced with the CN |
|
329 |
* when the access policy is changed by modifying the access policy in the |
|
330 |
* <additionalMetadata> section of the parent document. |
|
331 |
*/ |
|
332 |
public void testSyncEML201OnlineDataAccessPolicy() { |
|
333 |
String newdocid = null; |
|
334 |
String onlineDocid; |
|
335 |
String onlinetestdatafile2 = "test/onlineDataFile2"; |
|
336 |
SystemMetadata mnSysMeta = null; |
|
337 |
SystemMetadata cnSysMeta = null; |
|
338 |
|
|
339 |
try { |
|
340 |
debug("\nRunning: testSyncEML201OnlineDataAccessPolicy"); |
|
341 |
String emlVersion = EML2_0_1; |
|
342 |
debug("logging in as: username=" + username + " password=" |
|
343 |
+ password); |
|
344 |
m.login(username, password); |
|
345 |
|
|
346 |
/* Create a data object */ |
|
347 |
onlineDocid = generateDocumentId(); |
|
348 |
uploadDocumentId(onlineDocid + ".1", onlinetestdatafile2, SUCCESS, |
|
349 |
false); |
|
350 |
debug("Inserted new data object with localid: " + onlineDocid |
|
351 |
+ ".1"); |
|
352 |
String accessRule1 = generateOneAccessRule("public", true, true, |
|
353 |
false, false, false); |
|
354 |
|
|
355 |
Vector<String> accessRules = new Vector<String>(); |
|
356 |
accessRules.add(accessRule1); |
|
357 |
String accessDoc = getAccessBlock(accessRules, ALLOWFIRST); |
|
358 |
testdocument = getTestEmlDoc("Testing insert", emlVersion, |
|
359 |
testEmlInlineBlock1, null, "ecogrid://knb/" + onlineDocid |
|
360 |
+ ".1", null, accessDoc, null, null, null, null); |
|
361 |
|
|
362 |
/* Insert the eml document that describes the data object */ |
|
363 |
newdocid = generateDocumentId(); |
|
364 |
insertDocumentId(newdocid + ".1", testdocument, SUCCESS, false); |
|
365 |
|
|
366 |
debug("Inserted document with localId: " + newdocid + ".1"); |
|
367 |
/* |
|
368 |
* Determine the D1 pid for the data object so that we can query the |
|
369 |
* CN for it. |
|
370 |
*/ |
|
371 |
String docidWithoutRev = DocumentUtil.getSmartDocId(onlineDocid |
|
372 |
+ ".1"); |
|
373 |
int rev = IdentifierManager.getInstance().getLatestRevForLocalId( |
|
374 |
onlineDocid + ".1"); |
|
375 |
String guid = IdentifierManager.getInstance().getGUID( |
|
376 |
docidWithoutRev, rev); |
|
377 |
|
|
378 |
Identifier pid = new Identifier(); |
|
379 |
pid.setValue(guid); |
|
380 |
|
|
381 |
/* |
|
382 |
* Wait for the cn to harvest metadata for the data object. We are |
|
383 |
* testing that an update of access rules in the parent eml document |
|
384 |
* for the enclosed online data object will trigger metacat (via |
|
385 |
* SyncAccessPolicy) to update the access policy on the CN, so the |
|
386 |
* data object has to be present on the CN before we continue. |
|
387 |
*/ |
|
388 |
debug("Checking for new data object pid " + pid.getValue() |
|
389 |
+ " on CN..."); |
|
390 |
boolean found = false; |
|
391 |
int attempts = 0; |
|
392 |
for (int i = 0; i < 6; i++) { |
|
393 |
attempts = i; |
|
394 |
Thread.sleep(1000 * 60); |
|
395 |
// Get sm for data object pid from the CN |
|
396 |
try { |
|
397 |
cnSysMeta = cn.getSystemMetadata(pid); |
|
398 |
} catch (Exception e) { |
|
399 |
debug("Error getting system metadata for pid: " |
|
400 |
+ pid.getValue() + " from cn: " + e.getMessage()); |
|
401 |
debug("Will request pid from CN again..."); |
|
402 |
continue; |
|
403 |
} |
|
404 |
|
|
405 |
found = true; |
|
406 |
debug("Data object pid " + pid.getValue() |
|
407 |
+ " has been read from CN."); |
|
408 |
break; |
|
409 |
} |
|
410 |
|
|
411 |
if (!found) { |
|
412 |
fail("Error, cannot read system metadata for pid: " + pid |
|
413 |
+ " after " + attempts + " attempts"); |
|
414 |
} |
|
415 |
|
|
416 |
// update the document access control for online data |
|
417 |
accessRule1 = generateOneAccessRule("public", true, true, false, |
|
418 |
false, false); |
|
419 |
String accessRule2 = generateOneAccessRule(anotheruser, true, true, |
|
420 |
false, false, false); |
|
421 |
|
|
422 |
accessRules = new Vector<String>(); |
|
423 |
accessRules.add(accessRule1); |
|
424 |
accessRules.add(accessRule2); |
|
425 |
String accessData = getAccessBlock(accessRules, ALLOWFIRST); |
|
426 |
testdocument = getTestEmlDoc("Testing insert", emlVersion, |
|
427 |
testEmlInlineBlock1, null, "ecogrid://knb/" + onlineDocid |
|
428 |
+ ".1", null, accessDoc, null, null, accessData, |
|
429 |
null); |
|
430 |
|
|
431 |
/* |
|
432 |
* Updating the parent document should trigger metacat to update the |
|
433 |
* access policy on the CN (via EML 201 parser and |
|
434 |
* SyncAccessPolicy). |
|
435 |
*/ |
|
436 |
updateDocumentId(newdocid + ".2", testdocument, SUCCESS, false); |
|
437 |
|
|
438 |
/* Get MN access policy for data object */ |
|
439 |
try { |
|
440 |
// Get sm, access policy for requested localId |
|
441 |
mnSysMeta = IdentifierManager.getInstance().getSystemMetadata( |
|
442 |
pid.getValue()); |
|
443 |
} catch (Exception e) { |
|
444 |
debug("Error getting system metadata for new pid: " |
|
445 |
+ pid.getValue() + ". Message: " + e.getMessage()); |
|
446 |
fail(); |
|
447 |
} |
|
448 |
/* Get CN access policy for data object */ |
|
449 |
try { |
|
450 |
cnSysMeta = cn.getSystemMetadata(pid); |
|
451 |
} catch (Exception e) { |
|
452 |
debug("Error getting system metadata for pid: " |
|
453 |
+ pid.getValue() + " from cn: " + e.getMessage()); |
|
454 |
fail(); |
|
455 |
} |
|
456 |
|
|
457 |
/* Compare MN and CN access policies */ |
|
458 |
debug("Getting CN,MN access policy for pid: " + pid.getValue()); |
|
459 |
AccessPolicy mnAccessPolicy = mnSysMeta.getAccessPolicy(); |
|
460 |
AccessPolicy cnAccessPolicy = cnSysMeta.getAccessPolicy(); |
|
461 |
debug("Diffing access policies (MN,CN) for pid: " + pid.getValue()); |
|
462 |
|
|
463 |
SyncAccessPolicy syncAP = new SyncAccessPolicy(); |
|
464 |
debug("Comparing access policies..."); |
|
465 |
|
|
466 |
Boolean apEqual = new Boolean(syncAP.isEqual(mnAccessPolicy, |
|
467 |
cnAccessPolicy)); |
|
468 |
|
|
469 |
debug("Are access policies equal?: " + apEqual.toString()); |
|
470 |
assert (apEqual == true); |
|
471 |
|
|
472 |
/* Delete the document */ |
|
473 |
deleteDocumentId(newdocid + ".2", SUCCESS, true); |
|
474 |
deleteDocumentId(onlineDocid + ".1", SUCCESS, true); |
|
475 |
|
|
476 |
// logout |
|
477 |
debug("logging out"); |
|
478 |
m.logout(); |
|
479 |
} catch (MetacatAuthException mae) { |
|
480 |
fail("Authorization failed:\n" + mae.getMessage()); |
|
481 |
} catch (MetacatInaccessibleException mie) { |
|
482 |
fail("Metacat Inaccessible:\n" + mie.getMessage()); |
|
483 |
} catch (Exception e) { |
|
484 |
fail("General exception:\n" + e.getMessage()); |
|
485 |
} |
|
486 |
debug("Done running testSyncEML201OnlineDataAccessPolicy"); |
|
487 |
} |
|
488 |
|
|
299 | 489 |
public void testIsEqual() { |
300 | 490 |
AccessPolicy ap1 = new AccessPolicy(); |
301 | 491 |
AccessRule ar1 = new AccessRule(); |
... | ... | |
304 | 494 |
subject1.setValue(username); |
305 | 495 |
ar1.addSubject(subject1); |
306 | 496 |
ap1.addAllow(ar1); |
307 |
|
|
497 |
|
|
308 | 498 |
AccessPolicy ap2 = new AccessPolicy(); |
309 | 499 |
AccessRule ar2 = new AccessRule(); |
310 | 500 |
ar2.addPermission(Permission.READ); |
... | ... | |
312 | 502 |
subject2.setValue(username); |
313 | 503 |
ar2.addSubject(subject2); |
314 | 504 |
ap2.addAllow(ar2); |
315 |
|
|
505 |
|
|
316 | 506 |
boolean isEqual = false; |
317 | 507 |
SyncAccessPolicy syncAP = new SyncAccessPolicy(); |
318 |
|
|
508 |
|
|
319 | 509 |
// try something that should be true |
320 | 510 |
isEqual = syncAP.isEqual(ap1, ap2); |
321 | 511 |
assertTrue(isEqual); |
322 |
|
|
512 |
|
|
323 | 513 |
// try something that makes them not equal |
324 | 514 |
Subject subject3 = new Subject(); |
325 | 515 |
subject3.setValue(anotheruser); |
326 | 516 |
ar2.addSubject(subject3); |
327 |
|
|
517 |
|
|
328 | 518 |
isEqual = syncAP.isEqual(ap1, ap2); |
329 | 519 |
assertFalse(isEqual); |
330 |
|
|
520 |
|
|
331 | 521 |
isEqual = syncAP.isEqual(ap1, null); |
332 | 522 |
assertFalse(isEqual); |
333 | 523 |
} |
Also available in: Unified diff
add test to check sync of access policies of data object referenced in EML 2.0.1 docs