package qa.qcri.aidr; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Properties; import java.util.regex.Pattern; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.glassfish.jersey.jackson.JacksonFeature; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import qa.qcri.aidr.redis.JedisConnectionPool; import qa.qcri.aidr.utils.PersisterConfigurationProperty; import qa.qcri.aidr.utils.PersisterConfigurator; import qa.qcri.aidr.utils.Publisher; import redis.clients.jedis.Jedis; import com.google.gson.JsonObject; import com.google.gson.JsonParser; public class PersisterTesterTest { private static Logger logger = Logger.getLogger(PersisterTesterTest.class.getName()); private static PersisterConfigurator configProperties = PersisterConfigurator.getInstance(); private static String BASE_URI; public static String collectionCode; public static Long nItems; @BeforeClass public static void setUpBeforeClass() throws Exception { String config = System.getProperty("config"); Properties properties; if(StringUtils.isNotEmpty(config)){ try (InputStream input = new FileInputStream(config);){ properties = new Properties(); properties.load(input); for (Object property : properties.keySet()) { configProperties.setProperty(property.toString(), properties.get(property).toString()); } } catch (IOException e) { logger.error("Error in reading config properties file: " + config, e); fail("Error in reading config properties file: " + config); } } BASE_URI = configProperties.getProperty(PersisterConfigurationProperty.PERSISTER_REST_URI); nItems = Long.valueOf(System.getProperty("nItems")); SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); String timestamp = df.format(new Date()); collectionCode = timestamp+"-persister-test"; } @AfterClass public static void tearDownAfterClass() throws Exception { //Deleting the persister directory String filepath = configProperties.getProperty(PersisterConfigurationProperty.DEFAULT_PERSISTER_FILE_PATH); File folder = new File(filepath + collectionCode); if(folder.exists()){ FileUtils.deleteDirectory(folder); } } @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } @Test public void testOrder() throws UnsupportedEncodingException{ testCollectorPersister(); testTaggerPersister(); testCsvGenerator(); } public void testCollectorPersister() throws UnsupportedEncodingException { final String CHANNEL_NAME = configProperties.getProperty(PersisterConfigurationProperty.FETCHER_CHANNEL)+collectionCode; Client client = ClientBuilder.newBuilder().register(JacksonFeature.class).build(); WebTarget webResource; //collectorPersister/start logger.info("Starting persister for the collection : "+collectionCode); webResource = client.target(BASE_URI+"persister/start?collectionCode="+URLEncoder.encode(collectionCode, "UTF-8")); Response response = webResource.request(MediaType.APPLICATION_JSON).get(); String filepath = configProperties.getProperty(PersisterConfigurationProperty.DEFAULT_PERSISTER_FILE_PATH); String jsonResponse = response.readEntity(String.class); assertEquals(200, response.getStatus()); assertEquals( "Started persisting to " + filepath, jsonResponse); //Writing to redis n/2 items JedisConnectionPool connObject=null; connObject = new JedisConnectionPool(); Jedis publisherJedis = connObject.getJedisConnection(); new Publisher(publisherJedis, CHANNEL_NAME,nItems/2).start(); connObject.close(publisherJedis); //collectorPersister/status webResource = client.target(BASE_URI+"persister/start?collectionCode="+URLEncoder.encode(collectionCode, "UTF-8")); response = webResource.request(MediaType.APPLICATION_JSON).get(); jsonResponse = response.readEntity(String.class); assertEquals(200, response.getStatus()); assertEquals("A persister is already running for this collection code ["+collectionCode+"]", jsonResponse); //Writing to redis n/2 items connObject = new JedisConnectionPool(); publisherJedis = connObject.getJedisConnection(); new Publisher(publisherJedis, CHANNEL_NAME,(nItems-nItems/2)).start(); connObject.close(publisherJedis); //collectorPersister/stop logger.info("Stopping persister for the collection : "+collectionCode); webResource = client.target(BASE_URI+"persister/stop?collectionCode="+URLEncoder.encode(collectionCode, "UTF-8")); response = webResource.request(MediaType.APPLICATION_JSON).get(); jsonResponse = response.readEntity(String.class); assertEquals(200, response.getStatus()); assertEquals("Persistance of [" + collectionCode + "] has been stopped.", jsonResponse); //collectorPersister/status webResource = client.target(BASE_URI+"persister/stop?collectionCode="+URLEncoder.encode(collectionCode, "UTF-8")); response = webResource.request(MediaType.APPLICATION_JSON).get(); jsonResponse = response.readEntity(String.class); assertEquals(200, response.getStatus()); assertEquals("Unable to locate a running persister with the given collection code:[" + collectionCode + "]", jsonResponse); //Read the directory where the collector persister file should be located File folderLocation = new File(filepath + collectionCode); if(!folderLocation.exists()){ fail("Persister directory doesn't exist"); } File[] files = folderLocation.listFiles(); int count = 0; for (File file : files) { if(Pattern.matches(collectionCode+"_[0-9]{8}_vol-[0-9]+.json", file.getName())){ try(FileInputStream fstream = new FileInputStream(file);) { BufferedReader br = new BufferedReader(new InputStreamReader(fstream)); while (br.readLine() != null) { count++; } } catch (FileNotFoundException e) { logger.error("Persister file doesn't exist in testCollectorPersisterFileItems"); fail("Persister file doesn't exist in testCollectorPersisterFileItems"); } catch (IOException e) { logger.error("IOException in persister file in testCollectorPersisterFileItems"); fail("IOException in persister file in testCollectorPersisterFileItems"); } } } if(count!=nItems){ fail("No. of lines in JSON file ="+count+" doesn't match with total no. of lines in the redis."); } } public void testTaggerPersister() throws UnsupportedEncodingException { final String CHANNEL_NAME = configProperties.getProperty(PersisterConfigurationProperty.TAGGER_CHANNEL)+collectionCode; Client client = ClientBuilder.newBuilder().register(JacksonFeature.class).build(); WebTarget webResource; //taggerPersister/start logger.info("Starting tagger persister for the collection : "+collectionCode); webResource = client.target(BASE_URI+"taggerPersister/start?collectionCode="+URLEncoder.encode(collectionCode, "UTF-8")); Response response = webResource.request(MediaType.APPLICATION_JSON).get(); String jsonResponse = response.readEntity(String.class); assertEquals(200, response.getStatus()); String filepath = configProperties.getProperty(PersisterConfigurationProperty.DEFAULT_PERSISTER_FILE_PATH); assertEquals( "Started tagger persisting to " + filepath, jsonResponse); //Writing to redis n/2 items JedisConnectionPool connObject=null; connObject = new JedisConnectionPool(); Jedis publisherJedis = connObject.getJedisConnection(); new Publisher(publisherJedis, CHANNEL_NAME,nItems/2).start(); connObject.close(publisherJedis); //taggerPersister/status webResource = client.target(BASE_URI+"taggerPersister/start?collectionCode="+URLEncoder.encode(collectionCode, "UTF-8")); response = webResource.request(MediaType.APPLICATION_JSON).get(); jsonResponse = response.readEntity(String.class); assertEquals(200, response.getStatus()); assertEquals("A tagger persister is already running for this collection code [" + collectionCode + "]", jsonResponse); //Writing to redis n/2 items connObject = new JedisConnectionPool(); publisherJedis = connObject.getJedisConnection(); new Publisher(publisherJedis, CHANNEL_NAME,(nItems-nItems/2)).start(); connObject.close(publisherJedis); //taggerPersister/stop logger.info("Stopping tagger persister for the collection : "+collectionCode); webResource = client.target(BASE_URI+"taggerPersister/stop?collectionCode="+URLEncoder.encode(collectionCode, "UTF-8")); response = webResource.request(MediaType.APPLICATION_JSON).get(); jsonResponse = response.readEntity(String.class); assertEquals(200, response.getStatus()); assertEquals("Tagger Persistance of [" + collectionCode + "] has been stopped.", jsonResponse); //taggerPersister/status webResource = client.target(BASE_URI+"taggerPersister/stop?collectionCode="+URLEncoder.encode(collectionCode, "UTF-8")); response = webResource.request(MediaType.APPLICATION_JSON).get(); jsonResponse = response.readEntity(String.class); assertEquals(200, response.getStatus()); assertEquals("Unable to locate a running tagger persister with the given collection code:[" + collectionCode + "]", jsonResponse); //Read the directory where the collector persister file should be located File folderLocation = new File(filepath + collectionCode); if(!folderLocation.exists()){ fail("Persister directory doesn't exist"); } File[] files = folderLocation.listFiles(); int count = 0; for (File file : files) { if(Pattern.matches( "Classified_"+collectionCode+"_[0-9]{8}_vol-[0-9]+.json", file.getName())){ try(FileInputStream fstream = new FileInputStream(file);) { BufferedReader br = new BufferedReader(new InputStreamReader(fstream)); while (br.readLine()!= null) { count++; } } catch (FileNotFoundException e) { logger.error("Persister file doesn't exist in testCollectorPersisterFileItems"); fail("Persister file doesn't exist in testCollectorPersisterFileItems"); } catch (IOException e) { logger.error("IOException in persister file in testCollectorPersisterFileItems"); fail("IOException in persister file in testCollectorPersisterFileItems"); } } } if(count!=nItems){ fail("No. of lines in JSON file ="+count+" doesn't match with total no. of lines in the redis."); } } public void testCsvGenerator() throws UnsupportedEncodingException{ Client client = ClientBuilder.newBuilder().register(JacksonFeature.class).build(); WebTarget webResource; logger.info("Generating csv for the collection : "+collectionCode); webResource = client.target(BASE_URI+"taggerPersister/genCSV?collectionCode="+URLEncoder.encode(collectionCode, "UTF-8")); Response response = webResource.request(MediaType.APPLICATION_JSON).get(); String jsonResponse = response.readEntity(String.class); assertEquals(200, response.getStatus()); JsonParser parser = new JsonParser(); JsonObject jsonObj = (JsonObject) parser.parse(jsonResponse); Long count = 0L; if(jsonObj.get("url")!=null){ try { String fileDownloadLink = jsonObj.get("url").getAsString(); URL link = new URL(fileDownloadLink); try(InputStreamReader inputStreamReader = new InputStreamReader(link.openStream());){ BufferedReader br = new BufferedReader(inputStreamReader); while (br.readLine()!= null) { count++; } } catch (IOException e) { logger.error("IOException while reading the csv file"); fail("IOException while reading the csv file"); } } catch (MalformedURLException e) { logger.error("Error in the downloadable link for csv file"); fail("Error in the downloadable link for csv file"); } } else{ logger.error("Download link for csv file does not exist"); fail("Download link for csv file does not exist"); } count--; //Since first line in csv file contain column names Long exportLimit = Long.valueOf(configProperties.getProperty(PersisterConfigurationProperty.TWEETS_EXPORT_LIMIT)); if(count!=Math.min(nItems, exportLimit)){ fail("No. of lines in CSV file ="+count+" doesn't match with total no. of lines."); } } }