package org.dataone.integration.it.testImplementations; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.util.Iterator; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.dataone.client.v1.itk.D1Object; import org.dataone.client.v1.types.D1TypeBuilder; import org.dataone.integration.ContextAwareTestCaseDataone; import org.dataone.integration.ExampleUtilities; import org.dataone.integration.adapters.CNCallAdapter; import org.dataone.integration.adapters.MNCallAdapter; import org.dataone.integration.it.ContextAwareAdapter; import org.dataone.integration.webTest.WebTestDescription; import org.dataone.integration.webTest.WebTestName; import org.dataone.service.exceptions.BaseException; import org.dataone.service.types.v1.AccessRule; import org.dataone.service.types.v1.Group; import org.dataone.service.types.v1.Identifier; import org.dataone.service.types.v1.Node; import org.dataone.service.types.v1.NodeReference; import org.dataone.service.types.v1.Permission; import org.dataone.service.types.v1.Person; import org.dataone.service.types.v1.Subject; import org.dataone.service.types.v1.SubjectInfo; import org.dataone.service.types.v2.SystemMetadata; import org.dataone.service.types.v2.TypeFactory; import org.dataone.service.util.TypeMarshaller; import org.w3c.dom.Document; import org.xml.sax.InputSource; public class CNDiagnosticFunctionalTestImplementations extends ContextAwareAdapter { /** wait time between creating/getting an object - since metacat indexing on separate thread */ private static final int METACAT_WAIT = 5000; public CNDiagnosticFunctionalTestImplementations(ContextAwareTestCaseDataone catc) { super(catc); } @WebTestName("echoCredentials - tests if the echoCredentials call succeeds for the testRightsHolder certificate") @WebTestDescription("this test calls echoCredentials() and verifies that " + "a SubjectInfo is returned, containing the expected values for the given testRightsHolder certificate, " + "and that no exception is thrown") public void testEchoCredentials_RightsHolder(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testEchoCredentials_RightsHolder(nodeIterator.next(), version); } private void testEchoCredentials_RightsHolder(Node node, String version) { CNCallAdapter callAdapter = new CNCallAdapter(getSession("testRightsHolder"), node, version); String currentUrl = node.getBaseURL(); printTestHeader("testEchoCredentials_RightsHolder(...) vs. node: " + currentUrl); try { // echo "testRightsHolder" credentials SubjectInfo subjInfo = callAdapter.echoCredentials(null); assertTrue("echoCredentials should echo a non-null SubjectInfo", subjInfo != null); boolean correctSubjectFound = false; for (Person person : subjInfo.getPersonList()) { String subjStr = person.getSubject().getValue(); if (subjStr.contains("DC=org") // order doesn't matter && subjStr.contains("DC=dataone") && subjStr.contains("CN=testRightsHolder")) { correctSubjectFound = true; break; } } assertTrue("echoCredentials() with the rights-holder certificate " + "should return SubjectInfo containing the correct subject", correctSubjectFound); } catch (BaseException e) { handleFail(callAdapter.getLatestRequestUrl(),e.getClass().getSimpleName() + ": " + e.getDetail_code() + ":: " + e.getDescription()); } catch(Exception e) { e.printStackTrace(); handleFail(currentUrl,e.getClass().getName() + ": " + e.getMessage()); } } @WebTestName("echoCredentials - tests if the echoCredentials call succeeds for the testPerson certificate") @WebTestDescription("this test calls echoCredentials() and verifies that " + "a SubjectInfo is returned, containing the expected values for the given testPerson certificate, " + "and that no exception is thrown") public void testEchoCredentials_TestPerson(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testEchoCredentials_TestPerson(nodeIterator.next(), version); } private void testEchoCredentials_TestPerson(Node node, String version) { CNCallAdapter callAdapter = new CNCallAdapter(getSession("testPerson"), node, version); String currentUrl = node.getBaseURL(); printTestHeader("testEchoCredentials_TestPerson(...) vs. node: " + currentUrl); try { // echo "testPerson" credentials SubjectInfo subjInfo = callAdapter.echoCredentials(null); assertTrue("echoCredentials should echo a non-null SubjectInfo", subjInfo != null); boolean personSubjectFound = false; boolean personSubject1Found = false; boolean personSubject2Found = false; boolean personSubject3Found = false; for (Person person : subjInfo.getPersonList()) { String subjStr = person.getSubject().getValue(); if (subjStr.contains("CN=testPerson") && subjStr.contains("DC=dataone") && subjStr.contains("DC=org")) personSubjectFound = true; if (subjStr.contains("CN=testEQPerson1") && subjStr.contains("DC=dataone") && subjStr.contains("DC=org")) personSubject1Found = true; if (subjStr.contains("CN=testEQPerson2") && subjStr.contains("DC=dataone") && subjStr.contains("DC=org")) personSubject2Found = true; if (subjStr.contains("CN=testEQPerson3") && subjStr.contains("DC=dataone") && subjStr.contains("DC=org")) personSubject3Found = true; } assertTrue("echoCredentials() with the testPerson certificate " + "should return SubjectInfo containing the correct subjects", personSubjectFound && personSubject1Found && personSubject2Found && personSubject3Found); boolean correctGroupFound = false; for (Group group : subjInfo.getGroupList()) { String groupStr = group.getSubject().getValue(); if (groupStr.contains("CN=testGroup") && groupStr.contains("DC=dataone") && groupStr.contains("DC=org")) { correctGroupFound = true; break; } } assertTrue("echoCredentials() with the testPerson certificate " + "should return SubjectInfo containing the correct group subject.", correctGroupFound); } catch (BaseException e) { handleFail(callAdapter.getLatestRequestUrl(),e.getClass().getSimpleName() + ": " + e.getDetail_code() + ":: " + e.getDescription()); } catch(Exception e) { e.printStackTrace(); handleFail(currentUrl,e.getClass().getName() + ": " + e.getMessage()); } } @WebTestName("echoSystemMetadata - tests if the echoSystemMetadata call succeeds") @WebTestDescription("this test calls echoSystemMetadata() and verifies that " + "an equivalent SystemMetadata object is sent back, " + "and that no exception is thrown") public void testEchoSystemMetadata(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testEchoSystemMetadata(nodeIterator.next(), version); } private void testEchoSystemMetadata(Node node, String version) { CNCallAdapter callAdapter = new CNCallAdapter(getSession(cnSubmitter), node, version); String currentUrl = node.getBaseURL(); printTestHeader("testEchoSystemMetadata(...) vs. node: " + currentUrl); try { AccessRule accessRule = new AccessRule(); getSession("testRightsHolder"); Subject subject = ContextAwareTestCaseDataone.getSubject("testRightsHolder"); accessRule.addSubject(subject); accessRule.addPermission(Permission.CHANGE_PERMISSION); Identifier pid = D1TypeBuilder.buildIdentifier("testEchoSystemMetadata_" + ExampleUtilities.generateIdentifier()); byte[] contentBytes = ExampleUtilities.getExampleObjectOfType(ExampleUtilities.FORMAT_EML_2_0_1); InputStream objectInputStream = new ByteArrayInputStream(contentBytes); NodeReference nodeReference = D1TypeBuilder.buildNodeReference("bogusAuthoritativeNode"); D1Object d1o = new D1Object(pid, contentBytes, D1TypeBuilder.buildFormatIdentifier(ExampleUtilities.FORMAT_EML_2_0_1), subject, nodeReference); SystemMetadata sysmeta = TypeFactory.convertTypeFromType(d1o.getSystemMetadata(), SystemMetadata.class); // Identifier pid = catc.createTestObject(callAdapter, "testEchoSystemMetadata", accessRule); // SystemMetadata sysmeta = callAdapter.getSystemMetadata(null, pid); SystemMetadata echoedSysmeta = callAdapter.echoSystemMetadata(null, sysmeta); assertTrue("echoSystemMetadata() should send back a valid SystemMetadata object", echoedSysmeta != null); assertTrue("echoSystemMetadata() - echoed system metadata identifier should match", sysmeta.getIdentifier().equals(echoedSysmeta.getIdentifier())); assertTrue("echoSystemMetadata() - echoed system metadata serialVersion should match", sysmeta.getSerialVersion().equals(echoedSysmeta.getSerialVersion())); assertTrue("echoSystemMetadata() - echoed system metadata checksum should match", sysmeta.getChecksum().getValue().equals(echoedSysmeta.getChecksum().getValue())); } catch (BaseException e) { handleFail(callAdapter.getLatestRequestUrl(),e.getClass().getSimpleName() + ": " + e.getDetail_code() + ":: " + e.getDescription()); } catch(Exception e) { e.printStackTrace(); handleFail(currentUrl,e.getClass().getName() + ": " + e.getMessage()); } } @WebTestName("echoIndexedObject - tests if the echoIndexedObject call succeeds") @WebTestDescription("this test calls echoIndexedObject() and verifies that a " + "valid stream is returned, that it contains the expected values which " + "would have been indexed, and that no exceptions are thrown") public void testEchoIndexedObject(Iterator nodeIterator, String version) { while (nodeIterator.hasNext()) testEchoIndexedObject(nodeIterator.next(), version); } private void testEchoIndexedObject(Node node, String version) { CNCallAdapter callAdapter = new CNCallAdapter(getSession(cnSubmitter), node, version); String currentUrl = node.getBaseURL(); printTestHeader("testEchoIndexedObject(...) vs. node: " + currentUrl); InputStream is = null; InputStream objectInputStream = null; try { AccessRule accessRule = new AccessRule(); getSession("testRightsHolder"); Subject subject = ContextAwareTestCaseDataone.getSubject("testRightsHolder"); accessRule.addSubject(subject); accessRule.addPermission(Permission.CHANGE_PERMISSION); Identifier pid = D1TypeBuilder.buildIdentifier("testEchoSystemMetadata_" + ExampleUtilities.generateIdentifier()); byte[] contentBytes = ExampleUtilities.getExampleObjectOfType(ExampleUtilities.FORMAT_EML_2_0_1); objectInputStream = new ByteArrayInputStream(contentBytes); NodeReference nodeReference = D1TypeBuilder.buildNodeReference("bogusAuthoritativeNode"); D1Object d1o = new D1Object(pid, contentBytes, D1TypeBuilder.buildFormatIdentifier(ExampleUtilities.FORMAT_EML_2_0_1), subject, nodeReference); SystemMetadata sysmeta = TypeFactory.convertTypeFromType(d1o.getSystemMetadata(), SystemMetadata.class); // Identifier pid = catc.createTestObject(callAdapter, "testEchoIndexedObject", accessRule); // assertTrue("Test object should be created succesfully.", pid != null); // Thread.sleep(METACAT_WAIT); // SystemMetadata sysmeta = callAdapter.getSystemMetadata(null, pid); // objStream = callAdapter.get(null, pid); is = callAdapter.echoIndexedObject(null, "solr", sysmeta, objectInputStream); assertTrue("testEchoIndexedObject() should return a non-null InputStream", is != null); Document doc = null; try { DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); doc = builder.parse(new InputSource(is)); // outputs to sysout // Transformer transformer = TransformerFactory.newInstance().newTransformer(); // DOMSource source = new DOMSource(doc); // StreamResult result = new StreamResult(new FileOutputStream(new File("C:\\Users\\Andrei\\stuff\\indexedObjResult.xml"))); // transformer.transform(source, result); } catch (Exception e) { handleFail(currentUrl, "echoIndexedObject() should return document representing the parsed object " + "as it would be prior to being added to a search index. " + e.getClass().getName() + ": " + e.getMessage()); } XPath xPath = XPathFactory.newInstance().newXPath(); String abstractExp = "/add/doc/field[@name='abstract']"; String abstractVal = xPath.compile(abstractExp).evaluate(doc); if(StringUtils.isBlank(abstractVal)) handleFail(callAdapter.getLatestRequestUrl(), "returned document has no abstract"); if(!abstractVal.startsWith("This metadata record describes moored seawater temperature data")) handleFail(callAdapter.getLatestRequestUrl(), "returned document should contain the same abstract as the metadata sent"); String authorGivenNameExp = "/add/doc/field[@name='author']"; String authorGivenNameVal = xPath.compile(authorGivenNameExp).evaluate(doc); if(StringUtils.isBlank(authorGivenNameVal)) handleFail(callAdapter.getLatestRequestUrl(), "returned document has no author given name"); if(!authorGivenNameVal.equals("Margaret McManus")) handleFail(callAdapter.getLatestRequestUrl(), "returned document should contain the same authorGivenName as the metadata sent"); String titleExp = "/add/doc/field[@name='title']"; String titleVal = xPath.compile(titleExp).evaluate(doc); if(StringUtils.isBlank(titleVal)) handleFail(callAdapter.getLatestRequestUrl(), "returned document has no title"); if(!titleVal.startsWith("PISCO: Physical Oceanography: moored temperature data")) handleFail(callAdapter.getLatestRequestUrl(), "returned document should contain the same title as the metadata sent"); String formatIdExpExp = "/add/doc/field[@name='formatId']"; String formatIdValVal = xPath.compile(formatIdExpExp).evaluate(doc); if(StringUtils.isBlank(formatIdValVal)) handleFail(callAdapter.getLatestRequestUrl(), "returned document has no format ID"); if(!formatIdValVal.equals("eml://ecoinformatics.org/eml-2.0.1")) handleFail(callAdapter.getLatestRequestUrl(), "returned document should contain the same formatId as the metadata sent"); String formatTypeExp = "/add/doc/field[@name='formatType']"; String formatTypeVal = xPath.compile(formatTypeExp).evaluate(doc); if(StringUtils.isBlank(formatTypeVal)) handleFail(callAdapter.getLatestRequestUrl(), "returned document has no format type"); if(!formatTypeVal.equals("METADATA")) handleFail(callAdapter.getLatestRequestUrl(), "returned document should contain the same formatType as the metadata sent"); } catch (BaseException e) { handleFail(callAdapter.getLatestRequestUrl(),e.getClass().getSimpleName() + ": " + e.getDetail_code() + ":: " + e.getDescription()); } catch(Exception e) { e.printStackTrace(); handleFail(currentUrl,e.getClass().getName() + ": " + e.getMessage()); } finally { IOUtils.closeQuietly(is); IOUtils.closeQuietly(objectInputStream); } } }