/*******************************************************************************
* This file is part of OpenNMS(R).
*
* Copyright (C) 2011 The OpenNMS Group, Inc.
* OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc.
*
* OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
*
* OpenNMS(R) is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* OpenNMS(R) is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenNMS(R). If not, see:
* http://www.gnu.org/licenses/
*
* For more information contact:
* OpenNMS(R) Licensing <license@opennms.org>
* http://www.opennms.org/
* http://www.opennms.com/
*******************************************************************************/
package org.opennms.netmgt.dao.jaxb;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.opennms.core.test.MockLogAppender;
import org.opennms.core.utils.LogUtils;
import org.opennms.core.xml.CastorUtils;
import org.opennms.core.xml.JaxbUtils;
import org.opennms.netmgt.model.events.EventBuilder;
import org.opennms.netmgt.xml.event.Event;
import org.opennms.netmgt.xml.event.Events;
import org.opennms.netmgt.xml.event.Log;
public class JaxbUtilsTest {
private static final String m_xmlWithNamespace = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><event uuid=\"1234\" xmlns=\"http://xmlns.opennms.org/xsd/event\"><dbid>37</dbid><dist-poller>localhost</dist-poller><creation-time>Friday, March 18, 2011 1:34:13 PM GMT</creation-time><master-station>chief</master-station><mask><maskelement><mename>generic</mename><mevalue>6</mevalue></maskelement></mask><uei>uei.opennms.org/test</uei><source>JaxbCastorEquivalenceTest</source><nodeid>1</nodeid><time>Friday, March 18, 2011 1:34:13 PM GMT</time><host>funkytown</host><interface>192.168.0.1</interface><snmphost>192.168.0.1</snmphost><service>ICMP</service><snmp><id>.1.3.6.15</id><idtext>I am a banana!</idtext><version>v2c</version><specific>0</specific><generic>6</generic><community>public</community><time-stamp>1300455253196</time-stamp></snmp><parms><parm><parmName>foo</parmName><value encoding=\"text\" type=\"string\">bar</value></parm></parms><descr>This is a test thingy.</descr><logmsg dest=\"logndisplay\" notify=\"true\">this is a log message</logmsg><severity>Indeterminate</severity><pathoutage>monkeys</pathoutage><correlation path=\"pathOutage\" state=\"on\"><cuei>uei.opennms.org/funky-stuff</cuei><cmin>1</cmin><cmax>17</cmax><ctime>yesterday</ctime></correlation><operinstruct>run away</operinstruct><autoaction state=\"off\">content</autoaction><operaction menutext=\"this is in the menu!\" state=\"on\">totally actiony</operaction><autoacknowledge state=\"off\">content</autoacknowledge><loggroup>foo</loggroup><loggroup>bar</loggroup><tticket state=\"on\">tticket stuff</tticket><forward mechanism=\"snmptcp\" state=\"on\">I like shoes.</forward><script language=\"zombo\">the unattainable is within reach, at zombo.com</script><ifIndex>53</ifIndex><ifAlias>giggetE</ifAlias><mouseovertext>click here to buy now!!!!1!1!</mouseovertext><alarm-data x733-probable-cause=\"27\" x733-alarm-type=\"TimeDomainViolation\" auto-clean=\"true\" clear-key=\"car\" alarm-type=\"19\" reduction-key=\"bus\"/></event>";
private static final String m_logXml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><log xmlns=\"http://xmlns.opennms.org/xsd/event\"><events><event><creation-time>Monday, March 21, 2011 8:34:21 PM GMT</creation-time><uei>uei.opennms.org/test</uei><source>JaxbUtilsTest</source><time>Monday, March 21, 2011 8:34:21 PM GMT</time><descr>test</descr></event><event><creation-time>Monday, March 21, 2011 8:34:21 PM GMT</creation-time><uei>uei.opennms.org/test</uei><source>JaxbUtilsTest</source><time>Monday, March 21, 2011 8:34:21 PM GMT</time><descr>test 2</descr></event></events></log>";
private static final String m_logXmlWithoutNamespace = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><log><events><event><creation-time>Monday, March 21, 2011 8:34:21 PM GMT</creation-time><uei>uei.opennms.org/test</uei><source>JaxbUtilsTest</source><time>Monday, March 21, 2011 8:34:21 PM GMT</time><descr>test</descr></event><event><creation-time>Monday, March 21, 2011 8:34:21 PM GMT</creation-time><uei>uei.opennms.org/test</uei><source>JaxbUtilsTest</source><time>Monday, March 21, 2011 8:34:21 PM GMT</time><descr>test 2</descr></event></events></log>";
@Before
public void setUp() {
MockLogAppender.setupLogging();
}
@After
public void tearDown() {
MockLogAppender.assertNoWarningsOrGreater();
}
@Test
public void testMarshalEvent() throws Exception {
final Event e = getEvent();
final String xml = JaxbUtils.marshal(e);
assertTrue(xml.contains("JaxbUtilsTest"));
LogUtils.debugf(this, "event = %s", e);
LogUtils.debugf(this, "xml = %s", xml);
final StringWriter sw = new StringWriter();
JaxbUtils.marshal(e, sw);
assertEquals(sw.toString(), xml);
final SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
final InputStream is = this.getClass().getResourceAsStream("/xsds/event.xsd");
// if this is null, it's because Eclipse can be confused by "classifier" test dependencies like opennms-model-*-xsds
// it only works if opennms-model is *not* pulled into eclipse (go figure)
Assume.assumeNotNull(is);
LogUtils.debugf(this, "Hooray! We have an XSD!");
final Schema schema = factory.newSchema(new StreamSource(is));
final Validator v = schema.newValidator();
v.validate(new StreamSource(new StringReader(xml)));
}
@Test
public void testUnmarshalEvent() throws Exception {
final Event event = JaxbUtils.unmarshal(Event.class, m_xmlWithNamespace);
LogUtils.debugf(this, "event = %s", event);
assertEquals("1234", event.getUuid());
assertEquals("192.168.0.1", event.getInterface());
}
@Test
public void testMarshalLog() throws Exception {
final Event e1 = getEvent();
final Event e2 = getEvent();
e2.setDescr("test 2");
final Events events = new Events();
events.addEvent(e1);
events.addEvent(e2);
final Log log = new Log();
log.setEvents(events);
final String xml = JaxbUtils.marshal(log);
LogUtils.debugf(this, "xml = %s", xml);
assertNotNull(xml);
assertTrue(xml.contains("JaxbUtilsTest"));
}
@Test
public void testUnmarshalLog() throws Exception {
final Log log = JaxbUtils.unmarshal(Log.class, m_logXml);
assertNotNull(log.getEvents());
assertEquals(2, log.getEvents().getEventCount());
assertEquals("JaxbUtilsTest", log.getEvents().getEvent(0).getSource());
final InputStream is = new ByteArrayInputStream(m_logXml.getBytes());
final Log log2 = CastorUtils.unmarshal(Log.class, is);
is.close();
assertNotNull(log2.getEvents());
assertEquals(2, log2.getEvents().getEventCount());
assertEquals("JaxbUtilsTest", log2.getEvents().getEvent(0).getSource());
assertNotNull(log2.getEvents().getEvent(0).getTime());
LogUtils.debugf(this, "castor log = %s", log2);
}
/**
* This test can be used to compare the performance of JAXB vs. Castor in XML unmarshalling speed.
* After running this test on my system when preparing for the OpenNMS 1.10 release, JAXB was
* roughly 30% faster than Castor.
*/
@Test
@Ignore
public void testUnmarshalLogCastorVersusJaxb() throws Exception {
long startTime = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
JaxbUtils.unmarshal(Log.class, m_logXml);
}
long jaxbTime = System.currentTimeMillis() - startTime;
final byte[] logBytes = m_logXml.getBytes();
startTime = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
CastorUtils.unmarshal(Log.class, new ByteArrayInputStream(logBytes));
}
long castorTime = System.currentTimeMillis() - startTime;
System.out.printf("JAXB unmarshal: %dms, Castor unmarshal: %dms\n", jaxbTime, castorTime);
}
/**
* This test can be used to compare the performance of JAXB vs. Castor in XML marshalling speed.
* After running this test on my system when preparing for the OpenNMS 1.10 release, JAXB was
* roughly 8 times faster than Castor.
*/
@Test
@Ignore
public void testMarshalLogCastorVersusJaxb() throws Exception {
Log log = JaxbUtils.unmarshal(Log.class, m_logXml);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
JaxbUtils.marshal(log);
// If you want to see the marshalled XML output...
//System.out.println(JaxbUtils.marshal(log));
}
long jaxbTime = System.currentTimeMillis() - startTime;
log = CastorUtils.unmarshal(Log.class, new ByteArrayInputStream(m_logXml.getBytes()));
startTime = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
CastorUtils.marshalWithTranslatedExceptions(log, new StringWriter());
// If you want to see the marshalled XML output...
//CastorUtils.marshalWithTranslatedExceptions(log, new OutputStreamWriter(System.out));
}
long castorTime = System.currentTimeMillis() - startTime;
System.out.printf("JAXB marshal: %dms, Castor marshal: %dms\n", jaxbTime, castorTime);
}
@Test
public void testUnmarshalLogNoNamespace() throws Exception {
final Log log = JaxbUtils.unmarshal(Log.class, m_logXmlWithoutNamespace);
assertNotNull(log.getEvents());
assertEquals(2, log.getEvents().getEventCount());
assertEquals("JaxbUtilsTest", log.getEvents().getEvent(0).getSource());
final InputStream is = new ByteArrayInputStream(m_logXmlWithoutNamespace.getBytes());
final Log log2 = CastorUtils.unmarshal(Log.class, is);
is.close();
assertNotNull(log2.getEvents());
assertEquals(2, log2.getEvents().getEventCount());
assertEquals("JaxbUtilsTest", log2.getEvents().getEvent(0).getSource());
assertNotNull(log2.getEvents().getEvent(0).getTime());
LogUtils.debugf(this, "castor log = %s", log2);
}
private Event getEvent() {
final EventBuilder eb = new EventBuilder("uei.opennms.org/test", "JaxbUtilsTest");
final Event e = eb
.setDescription("test")
.addParam("foo", "bar")
.getEvent();
return e;
}
@Test
public void testSendEventXml() throws Exception {
final String text = "<log>\n" +
" <events>\n" +
" <event >\n" +
" <uei>uei.opennms.org/internal/capsd/addNode</uei>\n" +
" <source>perl_send_event</source>\n" +
" <time>Tuesday, 12 April 2011 18:05:00 o'clock GMT</time>\n" +
" <host></host>\n" +
" <interface>10.0.0.1</interface>\n" +
" <parms>\n" +
" <parm>\n" +
" <parmName><![CDATA[txno]]></parmName>\n" +
" <value type=\"string\" encoding=\"text\"><![CDATA[1]]></value>\n" +
" </parm>\n" +
" <parm>\n" +
" <parmName><![CDATA[nodelabel]]></parmName>\n" +
" <value type=\"string\" encoding=\"text\"><![CDATA[test10]]></value>\n" +
" </parm>\n" +
" </parms>\n" +
" </event>\n" +
" </events>\n" +
"</log>\n";
final Log log = JaxbUtils.unmarshal(Log.class, text);
assertNotNull(log);
assertNotNull(log.getEvents());
assertEquals(1, log.getEvents().getEvent().length);
}
@Test
@Ignore
public void testValidationMemoryLeak() throws Exception {
final String text = "<log>\n" +
" <events>\n" +
" <event >\n" +
" <uei>uei.opennms.org/internal/capsd/addNode</uei>\n" +
" <source>perl_send_event</source>\n" +
" <time>Tuesday, 12 April 2011 18:05:00 o'clock GMT</time>\n" +
" <host></host>\n" +
" <interface>10.0.0.1</interface>\n" +
" <parms>\n" +
" <parm>\n" +
" <parmName><![CDATA[txno]]></parmName>\n" +
" <value type=\"string\" encoding=\"text\"><![CDATA[1]]></value>\n" +
" </parm>\n" +
" <parm>\n" +
" <parmName><![CDATA[nodelabel]]></parmName>\n" +
" <value type=\"string\" encoding=\"text\"><![CDATA[test10]]></value>\n" +
" </parm>\n" +
" </parms>\n" +
" </event>\n" +
" </events>\n" +
"</log>\n";
final int eventCount = 1000000;
final int logEvery = (eventCount / 1000);
MockLogAppender.setupLogging(true, "INFO");
LogUtils.infof(this, "starting");
Thread.sleep(30000);
for (int i = 0; i < eventCount; i++) {
if (i % logEvery == 0) {
LogUtils.infof(this, "- event #%d", i);
}
final Log log = JaxbUtils.unmarshal(Log.class, text);
assertNotNull(log);
assertNotNull(log.getEvents());
final String results = JaxbUtils.marshal(log);
assertNotNull(results);
assertTrue(results.contains("uei.opennms.org/internal/capsd/addNode"));
}
LogUtils.infof(this, "finished");
Thread.sleep(30000);
}
}