package org.epics.archiverappliance.mgmt; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.StringWriter; import java.net.URLEncoder; import java.util.Arrays; import java.util.List; import org.apache.commons.io.FileUtils; import org.apache.log4j.Logger; import org.epics.archiverappliance.SIOCSetup; import org.epics.archiverappliance.TomcatSetup; import org.epics.archiverappliance.config.ConfigService; import org.epics.archiverappliance.config.ConfigServiceForTests; import org.epics.archiverappliance.config.PVTypeInfo; import org.epics.archiverappliance.config.persistence.JDBM2Persistence; import org.epics.archiverappliance.utils.ui.GetUrlContent; import org.json.simple.JSONObject; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver; /** * Modify the metafields across the cluster. We archive and then send the modifyMetaFields to the other appliance. * @author mshankar * */ public class ModifyMetaFieldsTest { private static Logger logger = Logger.getLogger(ModifyMetaFieldsTest.class.getName()); File persistenceFolder = new File(ConfigServiceForTests.getDefaultPBTestFolder() + File.separator + "ModifyMetaFieldsTest"); TomcatSetup tomcatSetup = new TomcatSetup(); SIOCSetup siocSetup = new SIOCSetup(); WebDriver driver; @Before public void setUp() throws Exception { if(persistenceFolder.exists()) { FileUtils.deleteDirectory(persistenceFolder); } persistenceFolder.mkdirs(); siocSetup.startSIOCWithDefaultDB(); System.getProperties().put(ConfigService.ARCHAPPL_PERSISTENCE_LAYER, "org.epics.archiverappliance.config.persistence.JDBM2Persistence"); System.getProperties().put(JDBM2Persistence.ARCHAPPL_JDBM2_FILENAME, persistenceFolder.getPath() + File.separator + "testconfig.jdbm2"); tomcatSetup.setUpClusterWithWebApps(this.getClass().getSimpleName(), 2); driver = new FirefoxDriver(); } @After public void tearDown() throws Exception { driver.quit(); tomcatSetup.tearDown(); siocSetup.stopSIOC(); FileUtils.deleteDirectory(persistenceFolder); } @Test public void testChangeMetaFields() throws Exception { int port = ConfigServiceForTests.RETRIEVAL_TEST_PORT+1; driver.get("http://localhost:" + port + "/mgmt/ui/index.html"); WebElement pvstextarea = driver.findElement(By.id("archstatpVNames")); String pvName = "UnitTestNoNamingConvention:sine"; pvstextarea.sendKeys(pvName); WebElement archiveButton = driver.findElement(By.id("archstatArchive")); logger.debug("About to submit"); archiveButton.click(); // We have to wait for a few minutes here as it does take a while for the workflow to complete. Thread.sleep(5*60*1000); WebElement checkStatusButton = driver.findElement(By.id("archstatCheckStatus")); checkStatusButton.click(); Thread.sleep(2*1000); WebElement statusPVName = driver.findElement(By.cssSelector("#archstatsdiv_table tr:nth-child(1) td:nth-child(1)")); String pvNameObtainedFromTable = statusPVName.getText(); assertTrue("PV Name is not " + pvName + "; instead we get " + pvNameObtainedFromTable, pvName.equals(pvNameObtainedFromTable)); WebElement statusPVStatus = driver.findElement(By.cssSelector("#archstatsdiv_table tr:nth-child(1) td:nth-child(2)")); String pvArchiveStatusObtainedFromTable = statusPVStatus.getText(); String expectedPVStatus = "Being archived"; assertTrue("Expecting PV archive status to be " + expectedPVStatus + "; instead it is " + pvArchiveStatusObtainedFromTable, expectedPVStatus.equals(pvArchiveStatusObtainedFromTable)); String aapl0 = checkInPersistence(pvName, 0); String aapl1 = checkInPersistence(pvName, 1); assertTrue("Expecting the same appliance identity in both typeinfos, instead it is " + aapl0 + " in cluster member 0 and " + aapl1 + " in cluster member 1", aapl0.equals(aapl1)); // Let's pause the PV. String pausePVURL = "http://localhost:17665/mgmt/bpl/pauseArchivingPV?pv=" + URLEncoder.encode(pvName, "UTF-8"); JSONObject pauseStatus = GetUrlContent.getURLContentAsJSONObject(pausePVURL); assertTrue("Cannot pause PV", pauseStatus.containsKey("status") && pauseStatus.get("status").equals("ok")); Thread.sleep(5000); logger.info("Successfully paused the PV " + pvName); // Make the modifyMetaFields call to the other appliance. int clusterIndex = aapl0.equals("appliance0") ? 1 : 0; port = ConfigServiceForTests.RETRIEVAL_TEST_PORT + clusterIndex; String modifyMetaFieldsURL = "http://localhost:" + port + "/mgmt/bpl/modifyMetaFields?pv=" + URLEncoder.encode(pvName, "UTF-8") + "&command=clear" + "&command=add,HIHI,HIGH,LOLO,LOW" + "&command=add,DESC" + "&command=remove,HIHI,LOLO"; JSONObject status = GetUrlContent.getURLContentAsJSONObject(modifyMetaFieldsURL); logger.info(status.toJSONString()); Thread.sleep(5000); String[] expectedFields = new String[] {"HIGH", "LOW", "DESC"}; String[] fields0 = getFieldsFromPersistence(pvName, 0); String[] fields1 = getFieldsFromPersistence(pvName, 1); assertTrue("Expecting the fields to be " + fieldsToCSV(expectedFields) + " in cluster member 0 instead it is " + fieldsToCSV(fields0), arrayEquals(fields0, expectedFields)); assertTrue("Expecting the fields to be " + fieldsToCSV(expectedFields) + " in cluster member 1 instead it is " + fieldsToCSV(fields1), arrayEquals(fields1, expectedFields)); } /** * Do these two arrays contain the same set of fields * @param actualFields * @param expectedFields * @return */ private boolean arrayEquals(String[] actualFields, String[] expectedFields) { if(actualFields.length != expectedFields.length) return false; List<String> actualFieldsList = Arrays.asList(actualFields); List<String> expectedFieldsList = Arrays.asList(expectedFields); if(!expectedFieldsList.containsAll(actualFieldsList)) return false; if(!actualFieldsList.containsAll(expectedFieldsList)) return false; return true; } private String fieldsToCSV(String[] fields) { StringWriter buf = new StringWriter(); boolean isFirst = true; for(String field : fields) { if(isFirst) { isFirst = false; } else { buf.append(","); } buf.append(field); } return buf.toString(); } private String checkInPersistence(String pvName, int clusterIndex) throws Exception { logger.info("Checking for pvtype info in persistence for cluster member " + clusterIndex); String persistenceFile = persistenceFolder.getPath() + File.separator + "testconfig.jdbm2"; String persistenceFileForMember = persistenceFile.replace(".jdbm2", "_appliance" + clusterIndex + ".jdbm2"); System.getProperties().put(JDBM2Persistence.ARCHAPPL_JDBM2_FILENAME, persistenceFileForMember); JDBM2Persistence persistenceLayer = new JDBM2Persistence(); PVTypeInfo typeInfo = persistenceLayer.getTypeInfo(pvName); assertTrue("Expecting the pv typeinfo to be in persistence for cluster member " + clusterIndex, typeInfo != null); return typeInfo.getApplianceIdentity(); } private String[] getFieldsFromPersistence(String pvName, int clusterIndex) throws Exception { logger.info("Checking for pvtype info in persistence for cluster member " + clusterIndex); String persistenceFile = persistenceFolder.getPath() + File.separator + "testconfig.jdbm2"; String persistenceFileForMember = persistenceFile.replace(".jdbm2", "_appliance" + clusterIndex + ".jdbm2"); System.getProperties().put(JDBM2Persistence.ARCHAPPL_JDBM2_FILENAME, persistenceFileForMember); JDBM2Persistence persistenceLayer = new JDBM2Persistence(); PVTypeInfo typeInfo = persistenceLayer.getTypeInfo(pvName); assertTrue("Expecting the pv typeinfo to be in persistence for cluster member " + clusterIndex, typeInfo != null); return typeInfo.getArchiveFields(); } }