package org.dataone.integration.it.testImplementations; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import org.dataone.client.exception.ClientSideException; import org.dataone.integration.ContextAwareTestCaseDataone; 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.Node; import org.dataone.service.types.v1.NodeReference; import org.dataone.service.types.v1.NodeReplicationPolicy; import org.dataone.service.types.v1.NodeState; import org.dataone.service.types.v1.NodeType; import org.dataone.service.types.v1.Ping; import org.dataone.service.types.v1.Schedule; import org.dataone.service.types.v1.Service; import org.dataone.service.types.v1.Services; import org.dataone.service.types.v1.Subject; import org.dataone.service.types.v1.SubjectInfo; import org.dataone.service.types.v1.Synchronization; import org.dataone.service.types.v2.NodeList; import org.dataone.service.types.v2.Property; import org.dataone.service.util.TypeMarshaller; public class NodeRegistryExtensibilityTestImplementations extends ContextAwareAdapter { public NodeRegistryExtensibilityTestImplementations(ContextAwareTestCaseDataone catc) { super(catc); } @WebTestName("register - Node with extra properties") @WebTestDescription("this test calls creates a new Node object, adds some properties, " + "(leaving the optional Property.type null) and calls register() with it. " + "It then fetches the Node info with getNodeCapabilities() and makes sure " + "the properties match what was added.") public void testRegister_NoPropType(Iterator nodeIterator, String version) { if (nodeIterator.hasNext()) // all CNs share LDAP data testRegister_NoPropType(nodeIterator.next(), version); else throw new AssertionError("No CN to test against!"); } private void testRegister_NoPropType(Node node, String version) { CNCallAdapter cn = new CNCallAdapter(getSession(cnSubmitter), node, "v2"); SubjectInfo verifiedSubjects = null; try { verifiedSubjects = cn.listSubjects(null, null, "verified", null, null); } catch (BaseException | ClientSideException e) { throw new AssertionError("Unable to fetch verified subjects on " + cn.getNodeBaseServiceUrl(), e); } if (verifiedSubjects.getPersonList() == null || verifiedSubjects.getPersonList().size() == 0) throw new AssertionError("No verified subjects on " + cn.getNodeBaseServiceUrl()); // create a new Node org.dataone.service.types.v2.Node newNode = new org.dataone.service.types.v2.Node(); newNode.setBaseURL("https://fake.node.org"); newNode.setContactSubjectList(new ArrayList()); newNode.setDescription("Node made for Register API testing"); NodeReference nodeRef = new NodeReference(); nodeRef.setValue("urn:node:TestNode"); newNode.setName("urn:node:TestNode"); newNode.setIdentifier(nodeRef); Ping ping = new Ping(); ping.setLastSuccess(new Date()); ping.setSuccess(true); newNode.setPing(ping); newNode.setReplicate(true); newNode.setState(NodeState.DOWN); List subjects = new ArrayList(); Subject subj = verifiedSubjects.getPerson(0).getSubject(); subjects.add(subj); newNode.setSubjectList(subjects); newNode.setContactSubjectList(subjects); Synchronization synchronization = new Synchronization(); Schedule schedule = new Schedule(); schedule.setHour("*"); schedule.setMday("*"); schedule.setMin("0/3"); schedule.setMon("*"); schedule.setSec("10"); schedule.setWday("?"); schedule.setYear("*"); synchronization.setSchedule(schedule); newNode.setSynchronization(synchronization); newNode.setSynchronize(false); newNode.setType(NodeType.MN); Services services = new Services(); Service service = new Service(); service.setName("MNCore"); service.setVersion("v2"); service.setAvailable(true); services.addService(service); newNode.setServices(services); // add to Node properties List propertyList = newNode.getPropertyList(); Property p1 = new Property(); p1.setKey("NodeLogo"); p1.setValue("(o_O)"); propertyList.add(p1); Property p2 = new Property(); p2.setKey("NodeTopping"); p2.setValue("Pepperoni"); propertyList.add(p2); try { log.info("Attempting to register new node: " + newNode.getName() + " (" + newNode.getBaseURL() + ") with CN " + cn.getNodeBaseServiceUrl()); cn.register(null, newNode); } catch (BaseException e) { throw new AssertionError(cn.getNodeBaseServiceUrl() + ": " + "testRegister() : " + "CN.register() call failed to register new node with exception: " + e.getClass().getSimpleName() + " : " + e.getDetail_code() + " : " + e.getDescription() + " : " + e.getMessage(), e); } catch (Exception e) { throw new AssertionError(cn.getNodeBaseServiceUrl() + ": " + "testRegister() : " + "CN.register() call failed to register new node with exception: " + e.getClass().getSimpleName() + " : " + e.getMessage(), e); } // get the node info org.dataone.service.types.v2.Node fetchedNode = null; try { fetchedNode = cn.getNodeCapabilities(nodeRef); } catch (BaseException e) { throw new AssertionError(cn.getNodeBaseServiceUrl() + ": " + "testRegister() : " + "CN.getNodeCapabilities() call failed with exception: " + e.getClass().getSimpleName() + " : " + e.getDetail_code() + " : " + e.getDescription() + " : " + e.getMessage(), e); } catch (Exception e) { throw new AssertionError(cn.getNodeBaseServiceUrl() + ": " + "testRegister() : " + "CN.getNodeCapabilities() call failed with exception: " + e.getClass().getSimpleName() + " : " + e.getMessage(), e); } finally { // ideally... unregister(newNode); } // check if node has properties we set List fetchedPropertyList = fetchedNode.getPropertyList(); assertTrue("testRegister(): fetched Node property list " + "should contain two properties. Number of properties: " + fetchedPropertyList.size(), fetchedPropertyList.size() == 2); Property fetchedP1 = fetchedPropertyList.get(0); assertTrue("testRegister(): fetched Node property 1 key " + "should match the property we gave it.", fetchedP1.getKey().equals(p1.getKey())); assertTrue("testRegister(): fetched Node property 1 type " + "should match the type we gave it (null).", fetchedP1.getType() == null); assertTrue("testRegister(): fetched Node property 1 value " + "should match the property we gave it.", fetchedP1.getValue().equals(p1.getValue())); Property fetchedP2 = fetchedPropertyList.get(1); assertTrue("testRegister(): fetched Node property 2 key " + "should match the property we gave it.", fetchedP2.getKey().equals(p2.getKey())); assertTrue("testRegister(): fetched Node property 2 type " + "should match the type we gave it (null).", fetchedP2.getType() == null); assertTrue("testRegister(): fetched Node property 2 value " + "should match the property we gave it.", fetchedP2.getValue().equals(p2.getValue())); } @WebTestName("register - Node with extra properties") @WebTestDescription("this test calls creates a new Node object, adds some properties, " + "and calls register() with it. It then fetches the Node info with " + "getNodeCapabilities() and makes sure the properties match what was added.") public void testRegister(Iterator nodeIterator, String version) { if (nodeIterator.hasNext()) // all CNs share LDAP data testRegister(nodeIterator.next(), version); else throw new AssertionError("No CN to test against!"); } private void testRegister(Node node, String version) { CNCallAdapter cn = new CNCallAdapter(getSession(cnSubmitter), node, "v2"); SubjectInfo verifiedSubjects = null; try { verifiedSubjects = cn.listSubjects(null, null, "verified", null, null); } catch (BaseException | ClientSideException e) { throw new AssertionError("Unable to fetch verified subjects on " + cn.getNodeBaseServiceUrl(), e); } if (verifiedSubjects.getPersonList() == null || verifiedSubjects.getPersonList().size() == 0) throw new AssertionError("No verified subjects on " + cn.getNodeBaseServiceUrl()); // create a new Node org.dataone.service.types.v2.Node newNode = new org.dataone.service.types.v2.Node(); newNode.setBaseURL("https://fake.node.org"); newNode.setContactSubjectList(new ArrayList()); newNode.setDescription("Node made for Register API testing"); NodeReference nodeRef = new NodeReference(); nodeRef.setValue("urn:node:TestNode"); newNode.setName("urn:node:TestNode"); newNode.setIdentifier(nodeRef); Ping ping = new Ping(); ping.setLastSuccess(new Date()); ping.setSuccess(true); newNode.setPing(ping); newNode.setReplicate(true); newNode.setState(NodeState.DOWN); List subjects = new ArrayList(); Subject subj = verifiedSubjects.getPerson(0).getSubject(); subjects.add(subj); newNode.setSubjectList(subjects); newNode.setContactSubjectList(subjects); Synchronization synchronization = new Synchronization(); Schedule schedule = new Schedule(); schedule.setHour("*"); schedule.setMday("*"); schedule.setMin("0/3"); schedule.setMon("*"); schedule.setSec("10"); schedule.setWday("?"); schedule.setYear("*"); synchronization.setSchedule(schedule); newNode.setSynchronization(synchronization); newNode.setSynchronize(false); newNode.setType(NodeType.MN); Services services = new Services(); Service service = new Service(); service.setName("MNCore"); service.setVersion("v2"); service.setAvailable(true); services.addService(service); newNode.setServices(services); // add to Node properties List propertyList = newNode.getPropertyList(); Property p1 = new Property(); p1.setKey("NodeLogo"); p1.setType("propType"); p1.setValue("(o_O)"); propertyList.add(p1); Property p2 = new Property(); p2.setKey("NodeTopping"); p2.setType("propType"); p2.setValue("Pepperoni"); propertyList.add(p2); try { log.info("Attempting to register new node: " + newNode.getName() + " (" + newNode.getBaseURL() + ") with CN " + cn.getNodeBaseServiceUrl()); cn.register(null, newNode); } catch (BaseException e) { throw new AssertionError(cn.getNodeBaseServiceUrl() + ": " + "testRegister() : " + "CN.register() call failed to register new node with exception: " + e.getClass().getSimpleName() + " : " + e.getDetail_code() + " : " + e.getDescription() + " : " + e.getMessage(), e); } catch (Exception e) { throw new AssertionError(cn.getNodeBaseServiceUrl() + ": " + "testRegister() : " + "CN.register() call failed to register new node with exception: " + e.getClass().getSimpleName() + " : " + e.getMessage(), e); } // get the node info org.dataone.service.types.v2.Node fetchedNode = null; try { fetchedNode = cn.getNodeCapabilities(nodeRef); } catch (BaseException e) { throw new AssertionError(cn.getNodeBaseServiceUrl() + ": " + "testRegister() : " + "CN.getNodeCapabilities() call failed with exception: " + e.getClass().getSimpleName() + " : " + e.getDetail_code() + " : " + e.getDescription() + " : " + e.getMessage(), e); } catch (Exception e) { throw new AssertionError(cn.getNodeBaseServiceUrl() + ": " + "testRegister() : " + "CN.getNodeCapabilities() call failed with exception: " + e.getClass().getSimpleName() + " : " + e.getMessage(), e); } finally { // ideally... unregister(newNode); } // check if node has properties we set List fetchedPropertyList = fetchedNode.getPropertyList(); assertTrue("testRegister(): fetched Node property list " + "should contain two properties. Number of properties: " + fetchedPropertyList.size(), fetchedPropertyList.size() == 2); Property fetchedP1 = fetchedPropertyList.get(0); assertTrue("testRegister(): fetched Node property 1 key " + "should match the property we gave it.", fetchedP1.getKey().equals(p1.getKey())); assertTrue("testRegister(): fetched Node property 1 type " + "should match the type we gave it.", fetchedP1.getType().equals(p1.getType())); assertTrue("testRegister(): fetched Node property 1 value " + "should match the property we gave it.", fetchedP1.getValue().equals(p1.getValue())); Property fetchedP2 = fetchedPropertyList.get(1); assertTrue("testRegister(): fetched Node property 2 key " + "should match the property we gave it.", fetchedP2.getKey().equals(p2.getKey())); assertTrue("testRegister(): fetched Node property 2 type " + "should match the type we gave it.", fetchedP2.getType().equals(p2.getType())); assertTrue("testRegister(): fetched Node property 2 value " + "should match the property we gave it.", fetchedP2.getValue().equals(p2.getValue())); } @WebTestName("updateNodeCapabilities - add extra properties to Node") @WebTestDescription("this test calls takes an existing Node, adds some properties, " + "and calls updateNodeCapabilities(). It then fetches the Node info with " + "getNodeCapabilities() and makes sure the properties match what was added.") public void testUpdateNodeCapabilities(Iterator nodeIterator, String version) { if (nodeIterator.hasNext()) // all CNs share LDAP data testUpdateNodeCapabilities(nodeIterator.next(), version); else throw new AssertionError("No CN to test against!"); } private void testUpdateNodeCapabilities(Node node, String version) { if (!catc.nodeListContainsV2Mn()) return; CNCallAdapter cn = new CNCallAdapter(getSession(cnSubmitter), node, "v2"); NodeList knownNodes = null; List oldPropertyListBackup = null; try { knownNodes = cn.listNodes(); } catch (Exception e) { e.printStackTrace(); throw new AssertionError(cn.getNodeBaseServiceUrl() + ": " + "testUpdateNodeCapabilities() : " + "unable to perform test setup, call to CN.listNodes() failed! : " + e.getMessage() + ", " + e.getCause() == null ? "" : e.getCause().getMessage()); } List v2MNs = new ArrayList(); for (Node n : knownNodes.getNodeList()) if (n.getType() == NodeType.MN && n.getState() == NodeState.UP) try { MNCallAdapter testMN = new MNCallAdapter(getSession(cnSubmitter), n, "v2"); Node capabilities = testMN.getCapabilities(); if (capabilities instanceof org.dataone.service.types.v2.Node == false) throw new AssertionError("v2 getCapabilities() should not be returning v1 Node types"); for (Service service : capabilities.getServices().getServiceList()) { if (service.getName().equalsIgnoreCase("MNCore") && service.getVersion().equalsIgnoreCase("v2")) { v2MNs.add((org.dataone.service.types.v2.Node) capabilities); break; } } } catch (Exception e) { continue; } assertTrue("testUpdateNodeCapabilities() requires CN.listNodes() to contain " + "at least one v2 MN since it tests the ability to save modifications to a Node's " + "property list (which is v2 Node only).", v2MNs.size() > 0); org.dataone.service.types.v2.Node v2MN = v2MNs.get(0); NodeReference mnRef = v2MN.getIdentifier(); log.warn("testing with node: " + mnRef.getValue()); // add to Node properties List propertyList = v2MN.getPropertyList(); if (propertyList == null) propertyList = new ArrayList(); Property p1 = new Property(); p1.setKey("NodeLogo"); p1.setType("propType"); p1.setValue("(o_O)"); propertyList.add(p1); Property p2 = new Property(); p2.setKey("NodeTopping"); p2.setType("propType"); p2.setValue("Pepperoni"); propertyList.add(p2); v2MN.setPropertyList(propertyList); // backup old node properties try { org.dataone.service.types.v2.Node oldNodeCapabilities = cn.getNodeCapabilities(mnRef); oldPropertyListBackup = oldNodeCapabilities.getPropertyList(); } catch (BaseException e) { throw new AssertionError(cn.getNodeBaseServiceUrl() + ": " + "testUpdateNodeCapabilities() : " + "CN.getPropertyList() call failed to get old properties with exception: " + e.getClass().getSimpleName() + " : " + e.getDetail_code() + " : " + e.getDescription() + " : " + e.getMessage(), e); } catch (Exception e) { throw new AssertionError(cn.getNodeBaseServiceUrl() + ": " + "testUpdateNodeCapabilities() : " + "CN.getPropertyList() call failed to get old properties with exception: " + e.getClass().getSimpleName() + " : " + e.getMessage(), e); } // update node properties on CN try { cn.updateNodeCapabilities(null, mnRef, v2MN); } catch (BaseException e) { throw new AssertionError(cn.getNodeBaseServiceUrl() + ": " + "testUpdateNodeCapabilities() : " + "CN.updateNodeCapabilities() call failed with exception: " + e.getClass().getSimpleName() + " : " + e.getDetail_code() + " : " + e.getDescription() + " : " + e.getMessage(), e); } catch (Exception e) { throw new AssertionError(cn.getNodeBaseServiceUrl() + ": " + "testUpdateNodeCapabilities() : " + "CN.updateNodeCapabilities() call failed with exception: " + e.getClass().getSimpleName() + " : " + e.getMessage(), e); } // get the node info org.dataone.service.types.v2.Node fetchedNode = null; try { fetchedNode = cn.getNodeCapabilities(mnRef); } catch (BaseException e) { throw new AssertionError(cn.getNodeBaseServiceUrl() + ": " + "testUpdateNodeCapabilities() : " + "CN.getNodeCapabilities() call failed to get updated info with exception: " + e.getClass().getSimpleName() + " : " + e.getDetail_code() + " : " + e.getDescription() + " : " + e.getMessage(), e); } catch (Exception e) { throw new AssertionError(cn.getNodeBaseServiceUrl() + ": " + "testUpdateNodeCapabilities() : " + "CN.getNodeCapabilities() call failed to get updated info with exception: " + e.getClass().getSimpleName() + " : " + e.getMessage(), e); } if (fetchedNode.getPropertyList() != null) { log.warn("fetchedNode has PropertyList size: " + fetchedNode.getPropertyList().size()); } else { log.warn("fetchedNode has null property list: " + fetchedNode.getPropertyList()); } // reset properties we changed on the node try { v2MN.setPropertyList(oldPropertyListBackup); cn.updateNodeCapabilities(null, mnRef, v2MN); } catch (BaseException e) { throw new AssertionError(cn.getNodeBaseServiceUrl() + ": " + "testUpdateNodeCapabilities() : " + "CN.updateNodeCapabilities() call failed to reset properties with exception: " + e.getClass().getSimpleName() + " : " + e.getDetail_code() + " : " + e.getDescription() + " : " + e.getMessage(), e); } catch (Exception e) { throw new AssertionError(cn.getNodeBaseServiceUrl() + ": " + "testUpdateNodeCapabilities() : " + "CN.updateNodeCapabilities() call failed to reset properties with exception: " + e.getClass().getSimpleName() + " : " + e.getMessage(), e); } // check if node is updated List fetchedPropertyList = fetchedNode.getPropertyList(); assertTrue("testUpdateNodeCapabilities(): fetched Node property list " + "should not be null", fetchedPropertyList != null); assertTrue("testUpdateNodeCapabilities(): fetched Node property list " + "should contain two properties. Number of properties: " + fetchedPropertyList.size(), fetchedPropertyList.size() == 2); Property fetchedP1 = fetchedPropertyList.get(0); assertTrue("testUpdateNodeCapabilities(): fetched Node property 1 key " + "should match the property we gave it.", fetchedP1.getKey().equals(p1.getKey())); assertTrue("testUpdateNodeCapabilities(): fetched Node property 1 value " + "should match the property we gave it.", fetchedP1.getValue().equals(p1.getValue())); Property fetchedP2 = fetchedPropertyList.get(1); assertTrue("testUpdateNodeCapabilities(): fetched Node property 2 key " + "should match the property we gave it.", fetchedP2.getKey().equals(p2.getKey())); assertTrue("testUpdateNodeCapabilities(): fetched Node property 2 value " + "should match the property we gave it.", fetchedP2.getValue().equals(p2.getValue())); } }