package com.rayo.server.storage; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.File; import java.net.URI; import java.util.ArrayList; import java.util.List; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import com.rayo.server.storage.model.Application; public class PropertiesBasedDatastoreTest extends BaseDatastoreTest { private File tempFile; @Before public void setup() throws Exception { store = new PropertiesBasedDatastore(getEmptyPropertiesResource()); } @After public void cleanup() throws Exception { clearCurrentTempFile(); } private void clearCurrentTempFile() { if (tempFile != null && tempFile.exists()) { tempFile.delete(); } tempFile = null; } @Test public void testLoadFromProperties() throws Exception { clearCurrentTempFile(); store = new PropertiesBasedDatastore(getRayoPropertiesResource()); assertEquals(((PropertiesBasedDatastore)store).getLoadFailures(), 0); } private Resource getEmptyPropertiesResource() throws Exception { tempFile = File.createTempFile("test", ".properties"); tempFile.deleteOnExit(); return new FileSystemResource(tempFile); } private Resource getRayoPropertiesResource() throws Exception { ClassPathResource resource = new ClassPathResource("rayo-routing.properties"); tempFile = File.createTempFile("test", ".properties"); tempFile.deleteOnExit(); File sourceFile = resource.getFile(); FileUtils.copyFile(sourceFile, tempFile); return new FileSystemResource(tempFile); } @Test public void testApplicationsCreatedWhenLoadedFromProperties() throws Exception { clearCurrentTempFile(); store = new PropertiesBasedDatastore(getRayoPropertiesResource()); assertEquals(((PropertiesBasedDatastore)store).getLoadFailures(), 0); List<Application> applications = store.getApplications(); assertEquals(applications.size(),3); List<String> jids = new ArrayList<String>(); for (Application app: applications) { jids.add(app.getBareJid()); } assertTrue(jids.contains("usera@localhost")); assertTrue(jids.contains("userb@localhost")); assertTrue(jids.contains("userc@localhost")); } @Test public void testAdddressesCreatedWhenLoadedFromProperties() throws Exception { clearCurrentTempFile(); store = new PropertiesBasedDatastore(getRayoPropertiesResource()); testDefaultAddresses(); } @Test public void testMappingsAddedWhenResourceChanges() throws Exception { clearCurrentTempFile(); store = new PropertiesBasedDatastore(getRayoPropertiesResource(), 1000); testDefaultAddresses(); assertFalse(store.getAddressesForApplication("userd@localhost").contains(".*userd.*")); // now add change the mappings. We add another resource String newMappings = ".*usera.*=usera@localhost\n" + ".*userb.*=userb@localhost\n" + ".*userc.*=userc@localhost\n" + ".*userd.*=userd@localhost\n" + ".*=usera@localhost\n"; FileUtils.writeStringToFile(tempFile, newMappings); // give some time to reload Thread.sleep(2000); testDefaultAddresses(); // check new address assertTrue(store.getAddressesForApplication("userd@localhost").contains(".*userd.*")); } @Test public void testMappingsRemovedWhenResourceChanges() throws Exception { clearCurrentTempFile(); store = new PropertiesBasedDatastore(getRayoPropertiesResource(), 1000); testDefaultAddresses(); assertFalse(store.getAddressesForApplication("userd@localhost").contains(".*userd.*")); // now add change the mappings. We add another resource String newMappings = ".*usera.*=usera@localhost\n" + ".*userb.*=userb@localhost\n" + ".*=usera@localhost\n" + " \n"; // erase existing stuff FileUtils.writeStringToFile(tempFile, newMappings); // give some time to reload Thread.sleep(2000); // one of the old addresses gone, but there others still there assertEquals(store.getAddressesForApplication("usera@localhost").size(),2); assertFalse(store.getAddressesForApplication("userc@localhost").contains(".*userc.*")); } @Test public void testPhoneNumberMappingsPreserved() throws Exception { clearCurrentTempFile(); store = new PropertiesBasedDatastore(getRayoPropertiesResource(), 1000); store.storeAddress("+14422225010", "userb@localhost"); assertTrue(store.getAddressesForApplication("userb@localhost").contains("+14422225010")); // let the file to be reloaded Thread.sleep(1500); // No nasty regexp changes on address for the data store. assertTrue(store.getAddressesForApplication("userb@localhost").contains("+14422225010")); } @Test public void testFileContentsChangeWhenMappingAdded() throws Exception { clearCurrentTempFile(); store = new PropertiesBasedDatastore(getRayoPropertiesResource()); testDefaultAddresses(); assertFalse(store.getAddressesForApplication("userd@localhost").contains(".*userd.*")); store.storeAddress(".*userd.*", "usera@localhost"); String filecontents = FileUtils.readFileToString(tempFile); assertTrue(filecontents.contains(".*userd.*=usera@localhost")); } @Test public void testFileContentsChangeWhenMappingRemoved() throws Exception { clearCurrentTempFile(); store = new PropertiesBasedDatastore(getRayoPropertiesResource()); testDefaultAddresses(); assertFalse(store.getAddressesForApplication("userd@localhost").contains(".*userd.*")); store.removeAddress(".*userb.*"); String filecontents = FileUtils.readFileToString(tempFile); assertFalse(filecontents.contains(".*userb.*")); } @Test public void testDuplicateAddressDoesNotCreateDuplicateMapping() throws Exception { clearCurrentTempFile(); store = new PropertiesBasedDatastore(getRayoPropertiesResource()); testDefaultAddresses(); assertFalse(store.getAddressesForApplication("userd@localhost").contains(".*userd.*")); store.storeAddress(".*userd.*", "usera@localhost"); String filecontents = FileUtils.readFileToString(tempFile); assertEquals(StringUtils.countMatches(filecontents, ".*userd.*"), 1); store.storeAddress(".*userd.*", "usera@localhost"); filecontents = FileUtils.readFileToString(tempFile); assertEquals(StringUtils.countMatches(filecontents, ".*userd.*"), 1); } @Test public void testDoNotLoadDuplicatesFromFile() throws Exception { clearCurrentTempFile(); tempFile = File.createTempFile("test", ".properties"); tempFile.deleteOnExit(); String newMappings = ".*usera.*=usera@localhost\n" + ".*usera.*=usera@localhost\n" + ".*usera.*=usera@localhost\n" + " \n"; // erase existing stuff FileUtils.writeStringToFile(tempFile, newMappings); store = new PropertiesBasedDatastore(new FileSystemResource(tempFile), 1000); assertEquals(store.getAddressesForApplication("usera@localhost").size(),1); } @Test public void testLookup() throws Exception { clearCurrentTempFile(); store = new PropertiesBasedDatastore(getRayoPropertiesResource()); assertNotNull(((PropertiesBasedDatastore)store).lookup(new URI("sip:usera@localhost"))); } @Test public void testMultipleMatchingRulesReturnFirstOne() throws Exception { clearCurrentTempFile(); tempFile = File.createTempFile("test", ".properties"); tempFile.deleteOnExit(); String newMappings = ".*usera.*=usera@localhost\n" + ".*sip.*=userb@localhost\n" + ".*=userc@localhost\n" + " \n"; // erase existing stuff FileUtils.writeStringToFile(tempFile, newMappings); store = new PropertiesBasedDatastore(new FileSystemResource(tempFile), 100000); assertEquals(((PropertiesBasedDatastore)store).lookup(new URI("sip:usera@localhost")),"usera@localhost"); assertEquals(((PropertiesBasedDatastore)store).lookup(new URI("sip:userb@localhost")),"userb@localhost"); assertEquals(((PropertiesBasedDatastore)store).lookup(new URI("userc@localhost")),"userc@localhost"); } @Test public void testMultipleMatchingRulesReturnFirstOne2() throws Exception { store.storeApplication(createApplication("usera@localhost")); store.storeApplication(createApplication("userb@localhost")); store.storeApplication(createApplication("userc@localhost")); store.storeAddress(".*usera.*", "usera@localhost"); store.storeAddress(".*sip.*", "userb@localhost"); store.storeAddress(".*", "userc@localhost"); assertEquals(((PropertiesBasedDatastore)store).lookup(new URI("sip:usera@localhost")),"usera@localhost"); assertEquals(((PropertiesBasedDatastore)store).lookup(new URI("sip:userb@localhost")),"userb@localhost"); assertEquals(((PropertiesBasedDatastore)store).lookup(new URI("userc@localhost")),"userc@localhost"); } @Test public void testMultipleMatchingRulesReturnFirstOne3() throws Exception { clearCurrentTempFile(); tempFile = File.createTempFile("test", ".properties"); tempFile.deleteOnExit(); String newMappings = " .*usera@localhost.*=usera@conference.jabber.org\n" + ".*@localhost.*=others@conference.jabber.org\n"; FileUtils.writeStringToFile(tempFile, newMappings); store = new PropertiesBasedDatastore(new FileSystemResource(tempFile), 1000); assertEquals(((PropertiesBasedDatastore)store).lookup(new URI("sip:usera@localhost")),"usera@conference.jabber.org"); } void testDefaultAddresses() throws Exception { assertEquals(store.getAddressesForApplication("usera@localhost").size(),2); assertTrue(store.getAddressesForApplication("usera@localhost").contains(".*usera.*")); assertTrue(store.getAddressesForApplication("usera@localhost").contains(".*")); assertTrue(store.getAddressesForApplication("userb@localhost").contains(".*userb.*")); assertTrue(store.getAddressesForApplication("userc@localhost").contains(".*userc.*")); // validate file contents if (tempFile != null) { String content = FileUtils.readFileToString(tempFile); assertTrue(content.contains(".*usera.*=usera@localhost")); assertTrue(content.contains(".*=usera@localhost")); assertTrue(content.contains(".*userb.*=userb@localhost")); assertTrue(content.contains(".*userc.*=userc@localhost")); } } Application createApplication(String jid) { Application app = buildApplication(jid); app.setJid(jid); return app; } }