// // Copyright 2010 Cinch Logic Pty Ltd. // // http://www.chililog.com // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // package org.chililog.server.engine.parsers; import static org.junit.Assert.*; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; import org.chililog.server.common.ChiliLogException; import org.chililog.server.data.MongoConnection; import org.chililog.server.data.RepositoryEntryBO; import org.chililog.server.data.RepositoryEntryController; import org.chililog.server.data.RepositoryFieldConfigBO; import org.chililog.server.data.RepositoryConfigBO; import org.chililog.server.data.RepositoryParserConfigBO; import org.chililog.server.data.RepositoryEntryBO.Severity; import org.chililog.server.data.RepositoryParserConfigBO.AppliesTo; import org.chililog.server.data.RepositoryParserConfigBO.ParseFieldErrorHandling; import org.chililog.server.engine.parsers.DelimitedEntryParser; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBObject; /** * Test parsing and storing delimited repository entries * * @author vibul * */ public class DelimitedEntryParserTest { private static DB _db; @BeforeClass public static void classSetup() throws Exception { _db = MongoConnection.getInstance().getConnection(); assertNotNull(_db); } @AfterClass public static void classTeardown() throws Exception { // Clean up old test data if any exists DBCollection coll = _db.getCollection("repo_junit_test"); coll.drop(); } @Before public void testSetup() throws Exception { classTeardown(); } @Test public void testOK() throws ChiliLogException, ParseException { RepositoryConfigBO repoInfo = new RepositoryConfigBO(); repoInfo.setName("junit_test"); repoInfo.setDisplayName("JUnit Test 1"); RepositoryParserConfigBO repoParserInfo = new RepositoryParserConfigBO(); repoParserInfo.setName("parser1"); repoParserInfo.setAppliesTo(AppliesTo.All); repoParserInfo.setClassName(DelimitedEntryParser.class.getName()); repoParserInfo.setParseFieldErrorHandling(ParseFieldErrorHandling.SkipEntry); repoParserInfo.getProperties().put(DelimitedEntryParser.DELIMITER_PROPERTY_NAME, "|"); repoInfo.getParsers().add(repoParserInfo); RepositoryFieldConfigBO repoFieldInfo = new RepositoryFieldConfigBO(); repoFieldInfo.setName("field1"); repoFieldInfo.setDataType(RepositoryFieldConfigBO.DataType.String); repoFieldInfo.getProperties().put(DelimitedEntryParser.POSITION_FIELD_PROPERTY_NAME, "1"); repoParserInfo.getFields().add(repoFieldInfo); repoFieldInfo = new RepositoryFieldConfigBO(); repoFieldInfo.setName("field2"); repoFieldInfo.setDataType(RepositoryFieldConfigBO.DataType.Integer); repoFieldInfo.getProperties().put(DelimitedEntryParser.POSITION_FIELD_PROPERTY_NAME, "2"); repoParserInfo.getFields().add(repoFieldInfo); repoFieldInfo = new RepositoryFieldConfigBO(); repoFieldInfo.setName("field3"); repoFieldInfo.setDataType(RepositoryFieldConfigBO.DataType.Long); repoFieldInfo.getProperties().put(DelimitedEntryParser.POSITION_FIELD_PROPERTY_NAME, "3"); repoParserInfo.getFields().add(repoFieldInfo); repoFieldInfo = new RepositoryFieldConfigBO(); repoFieldInfo.setName("field4"); repoFieldInfo.setDataType(RepositoryFieldConfigBO.DataType.Double); repoFieldInfo.getProperties().put(DelimitedEntryParser.POSITION_FIELD_PROPERTY_NAME, "4"); repoParserInfo.getFields().add(repoFieldInfo); repoFieldInfo = new RepositoryFieldConfigBO(); repoFieldInfo.setName("field5"); repoFieldInfo.setDataType(RepositoryFieldConfigBO.DataType.Date); repoFieldInfo.getProperties().put(DelimitedEntryParser.POSITION_FIELD_PROPERTY_NAME, "5"); repoFieldInfo.getProperties().put(RepositoryFieldConfigBO.DATE_FORMAT_PROPERTY_NAME, "yyyy-MM-dd HH:mm:ss"); repoParserInfo.getFields().add(repoFieldInfo); repoFieldInfo = new RepositoryFieldConfigBO(); repoFieldInfo.setName("field6"); repoFieldInfo.setDataType(RepositoryFieldConfigBO.DataType.Boolean); repoFieldInfo.getProperties().put(DelimitedEntryParser.POSITION_FIELD_PROPERTY_NAME, "6"); repoParserInfo.getFields().add(repoFieldInfo); RepositoryEntryController c = RepositoryEntryController.getInstance(repoInfo); DelimitedEntryParser p = new DelimitedEntryParser(repoInfo, repoParserInfo); // Build preparsed fields StringBuilder preparsedFields = new StringBuilder(); preparsedFields.append("{"); preparsedFields.append("\"fld_p1\": 1,"); // Integer preparsedFields.append("\"fld_p2\": \"abc\","); // String preparsedFields.append("\"fld_p3\": true,"); // Boolean preparsedFields.append("\"fld_p4\": 8888888888,"); // Long. 10 - digit numbers converts to long preparsedFields.append("\"fld_p5\": \"NumberLong(888)\","); preparsedFields.append("\"fld_p6\": 5.5,"); // Double preparsedFields.append("\"fld_p7\": \"2010-11-29T19:41:46.000Z\","); preparsedFields.append("}"); // Save Line 1 OK RepositoryEntryBO entry = p.parse("2001-5-5T01:02:03.001Z", "log1", "127.0.0.1", Severity.Critical.toString(), preparsedFields.toString(), "line1|2|3|4.4|2001-5-5 5:5:5|True"); assertNotNull(entry); DBObject dbObject = entry.toDBObject(); c.save(_db, entry); // Get Line 1 DBCollection coll = _db.getCollection("repo_junit_test"); DBObject query = new BasicDBObject(); query.put("_id", entry.toDBObject().get("_id")); dbObject = coll.findOne(query); GregorianCalendar cal = new GregorianCalendar(); cal.setTimeZone(TimeZone.getTimeZone("GMT")); cal.set(2001, 4, 5, 1, 2, 3); cal.set(Calendar.MILLISECOND, 1); assertNotNull(dbObject); assertEquals(cal.getTimeInMillis(), ((Date) dbObject.get(RepositoryEntryBO.TIMESTAMP_FIELD_NAME)).getTime()); assertTrue(dbObject.containsField(RepositoryEntryBO.SAVED_TIMESTAMP_FIELD_NAME)); assertEquals("line1", dbObject.get("fld_field1")); assertEquals(2, dbObject.get("fld_field2")); assertEquals(3L, dbObject.get("fld_field3")); assertEquals(4.4d, dbObject.get("fld_field4")); assertEquals(new GregorianCalendar(2001, 4, 5, 5, 5, 5).getTime(), dbObject.get("fld_field5")); assertEquals(true, dbObject.get("fld_field6")); assertEquals("log1", dbObject.get(RepositoryEntryBO.SOURCE_FIELD_NAME)); assertEquals("127.0.0.1", dbObject.get(RepositoryEntryBO.HOST_FIELD_NAME)); assertEquals(Severity.Critical.toCode(), dbObject.get(RepositoryEntryBO.SEVERITY_FIELD_NAME)); assertEquals("line1|2|3|4.4|2001-5-5 5:5:5|True", dbObject.get(RepositoryEntryBO.MESSAGE_FIELD_NAME)); assertEquals(1, dbObject.get("fld_p1")); assertEquals("abc", dbObject.get("fld_p2")); assertEquals(true, dbObject.get("fld_p3")); assertEquals(8888888888L, dbObject.get("fld_p4")); assertEquals(888L, dbObject.get("fld_p5")); assertEquals(5.5d, dbObject.get("fld_p6")); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); assertEquals(sf.parse("2010-11-29T19:41:46GMT"), dbObject.get("fld_p7")); // Save Line 2 OK - no preparsed fields entry = p.parse("2021-5-5T05:05:05.002Z", "log1", "127.0.0.1", Severity.Debug.toString(), null, "line2|22|23|24.4|2021-5-5 5:5:5|xxx"); assertNotNull(entry); dbObject = entry.toDBObject(); c.save(_db, entry); // Get Line 2 query = new BasicDBObject(); query.put("_id", entry.toDBObject().get("_id")); dbObject = coll.findOne(query); cal = new GregorianCalendar(); cal.setTimeZone(TimeZone.getTimeZone("GMT")); cal.set(2021, 4, 5, 5, 5, 5); cal.set(Calendar.MILLISECOND, 2); assertNotNull(dbObject); assertEquals(cal.getTime(), dbObject.get(RepositoryEntryBO.TIMESTAMP_FIELD_NAME)); assertTrue(dbObject.containsField(RepositoryEntryBO.SAVED_TIMESTAMP_FIELD_NAME)); assertEquals("line2", dbObject.get("fld_field1")); assertEquals(22, dbObject.get("fld_field2")); assertEquals(23L, dbObject.get("fld_field3")); assertEquals(24.4d, dbObject.get("fld_field4")); assertEquals(new GregorianCalendar(2021, 4, 5, 5, 5, 5).getTime(), dbObject.get("fld_field5")); assertEquals(false, dbObject.get("fld_field6")); assertEquals("log1", dbObject.get(RepositoryEntryBO.SOURCE_FIELD_NAME)); assertEquals("127.0.0.1", dbObject.get(RepositoryEntryBO.HOST_FIELD_NAME)); assertEquals(Severity.Debug.toCode(), dbObject.get(RepositoryEntryBO.SEVERITY_FIELD_NAME)); assertEquals("line2|22|23|24.4|2021-5-5 5:5:5|xxx", dbObject.get(RepositoryEntryBO.MESSAGE_FIELD_NAME)); assertNull(dbObject.get("fld_p1")); assertNull(dbObject.get("fld_p2")); assertNull(dbObject.get("fld_p3")); assertNull(dbObject.get("fld_p4")); assertNull(dbObject.get("fld_p5")); assertNull(dbObject.get("fld_p6")); // Should only be 2 entries assertEquals(2, coll.find().count()); // Empty ts, source, host and message is ignored entry = p.parse("", "log1", "127.0.0.1", Severity.Warning.toString(), null, "aaa"); assertNull(entry); assertNotNull(p.getLastParseError()); entry = p.parse("2021-5-5T05:05:05.000Z", "", "127.0.0.1", Severity.Warning.toString(), null, "aaa"); assertNull(entry); assertNotNull(p.getLastParseError()); entry = p.parse("2021-5-5T05:05:05.000Z", "log1", null, Severity.Warning.toString(), null, "aaa"); assertNull(entry); assertNotNull(p.getLastParseError()); entry = p.parse("2021-5-5T5:5:5.0Z", "log1", "127.0.0.1", Severity.Warning.toString(), null, ""); assertNull(entry); assertNotNull(p.getLastParseError()); // Missing field entry = p.parse("2021-5-5T5:5:5Z", "log1", "127.0.0.1", Severity.Debug.toString(), null, "line3"); assertNull(entry); assertNotNull(p.getLastParseError()); } }