@@ -36,17 +36,23 @@

import org.opennms.netmgt.config.api.EventConfDao;
import org.opennms.netmgt.events.api.EventProcessor;
import org.opennms.netmgt.model.events.EventUtils;
import org.opennms.netmgt.xml.event.AlarmData;
import org.opennms.netmgt.xml.event.Autoaction;
import org.opennms.netmgt.xml.event.Event;
import org.opennms.netmgt.xml.event.Header;
import org.opennms.netmgt.xml.event.Logmsg;
import org.opennms.netmgt.xml.event.Operaction;
import org.opennms.netmgt.xml.event.Parm;
import org.opennms.netmgt.xml.event.Tticket;
import org.opennms.netmgt.xml.event.UpdateField;
import org.opennms.netmgt.xml.event.Value;
import org.opennms.netmgt.xml.eventconf.Decode;
import org.opennms.netmgt.xml.eventconf.Maskelement;
import org.opennms.netmgt.xml.eventconf.Parameter;
import org.opennms.netmgt.xml.eventconf.Varbindsdecode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

@@ -96,6 +102,8 @@
*/
public final class EventExpander implements org.opennms.netmgt.dao.api.EventExpander, EventProcessor, InitializingBean {

private static final Logger LOG = LoggerFactory.getLogger(EventExpander.class);

private EventConfDao m_eventConfDao;

/**
@@ -723,6 +731,26 @@ public synchronized void expandEvent(Event e) {

e.setAlarmData(alarmData);
}

if (econf.getParameterCollection() != null && econf.getParameterCount() > 0) {
if (e.getParmCollection() == null) {
e.setParmCollection(new ArrayList<Parm>());
}
for (Parameter p : econf.getParameterCollection()) {
if (EventUtils.getParm(e, p.getName()) == null) {
Parm parm = new Parm();
parm.setParmName(p.getName());
Value v = new Value();
v.setContent(p.getValue());
v.setType("string");
v.setEncoding("text");
parm.setValue(v);
e.addParm(parm);
} else {
LOG.warn("expandEvent: the event {} already has a parameter named {}, the original content will be preserved. Check the event definition and rename the optional parameter.", e.getUei(),p.getName());
}
}
}
}

Map<String, Map<String, String>> decode = new HashMap<String, Map<String,String>>();
@@ -104,4 +104,33 @@ public void testExpandEventWithNoDaoMatches() {
//String matchText = "During a rescan";
//assertTrue("event description should contain '" + matchText + "'", event.getDescr().contains(matchText));
}

public void testOptionalParameters() {
String uei = "uei.opennms.org/testEventWithOptionalParameters";
EventBuilder builder = new EventBuilder(uei, "something");
Event event = builder.getEvent();

EventExpander expander = new EventExpander();
expander.setEventConfDao(m_eventConfDao);
expander.afterPropertiesSet();

org.opennms.netmgt.xml.eventconf.Event eventConfig = new org.opennms.netmgt.xml.eventconf.Event();
eventConfig.setUei(uei);
org.opennms.netmgt.xml.eventconf.Parameter p1 = new org.opennms.netmgt.xml.eventconf.Parameter();
p1.setName("username");
p1.setValue("agalue");
eventConfig.addParameter(p1);

EasyMock.expect(m_eventConfDao.findByEvent(event)).andReturn(eventConfig);
EasyMock.expect(m_eventConfDao.isSecureTag(EasyMock.anyObject())).andReturn(true).anyTimes();
m_mocks.replayAll();

expander.expandEvent(event);

assertEquals("event UEI", uei, event.getUei());
assertEquals("parameters count", 1, event.getParmCollection().size());
assertNotNull(event.getParm("username"));
assertEquals("parameter value", "agalue", event.getParm("username").getValue().getContent());
}

}
@@ -62,7 +62,8 @@
public class Event implements Serializable, Comparable<Event> {
private static final long serialVersionUID = 565808183599950549L;

private static final Varbindsdecode[] EMPTY_VARBINDSDECODE_ARRAY = new Varbindsdecode[0];
private static final Parameter[] EMPTY_PARAMETER_ARRAY = new Parameter[0];
private static final Varbindsdecode[] EMPTY_VARBINDSDECODE_ARRAY = new Varbindsdecode[0];
private static final Script[] EMPTY_SCRIPT_ARRAY = new Script[0];
private static final Operaction[] EMPTY_OPERACTION_ARRAY = new Operaction[0];
private static final String[] EMPTY_STRING_ARRAY = new String[0];
@@ -144,6 +145,13 @@ public class Event implements Serializable, Comparable<Event> {
@XmlElement(name="varbindsdecode", required=false)
private List<Varbindsdecode> m_varbindsdecodes = new ArrayList<Varbindsdecode>();

/**
* The varbind decoding tag used to decode value into a string
*/
// @Size(min=0)
@XmlElement(name="parameter", required=false)
private List<Parameter> m_parameters = new ArrayList<Parameter>();

/**
* The operator action to be taken when this event occurs
*/
@@ -266,6 +274,14 @@ public void addVarbindsdecode(final int index, final Varbindsdecode varbindsdeco
m_varbindsdecodes.add(index, varbindsdecode);
}

public void addParameter(final Parameter parameter) throws IndexOutOfBoundsException {
m_parameters.add(parameter);
}

public void addParameter(final int index, final Parameter parameter) throws IndexOutOfBoundsException {
m_parameters.add(index, parameter);
}

public Enumeration<Autoaction> enumerateAutoaction() {
return Collections.enumeration(m_autoactions);
}
@@ -290,6 +306,10 @@ public Enumeration<Varbindsdecode> enumerateVarbindsdecode() {
return Collections.enumeration(m_varbindsdecodes);
}

public Enumeration<Parameter> enumerateParameters() {
return Collections.enumeration(m_parameters);
}

public AlarmData getAlarmData() {
return m_alarmData;
}
@@ -452,6 +472,22 @@ public int getVarbindsdecodeCount() {
return m_varbindsdecodes.size();
}

public Parameter geParameter(final int index) throws IndexOutOfBoundsException {
return m_parameters.get(index);
}

public Parameter[] getParameter() {
return m_parameters.toArray(EMPTY_PARAMETER_ARRAY);
}

public List<Parameter> getParameterCollection() {
return m_parameters;
}

public int getParameterCount() {
return m_parameters.size();
}

/**
* @return true if this object is valid according to the schema
*/
@@ -488,6 +524,10 @@ public Iterator<Varbindsdecode> iterateVarbindsdecode() {
return m_varbindsdecodes.iterator();
}

public Iterator<Parameter> iterateParameter() {
return m_parameters.iterator();
}

public void marshal(final Writer out) throws MarshalException, ValidationException {
Marshaller.marshal(this, out);
}
@@ -568,6 +608,14 @@ public Varbindsdecode removeVarbindsdecodeAt(final int index) {
return m_varbindsdecodes.remove(index);
}

public boolean removeParameter(final Parameter parameter) {
return m_parameters.remove(parameter);
}

public Parameter removeParameterAt(final int index) {
return m_parameters.remove(index);
}

public void setAlarmData(final AlarmData alarmData) {
m_alarmData = alarmData;
}
@@ -750,6 +798,27 @@ public void setVarbindsdecodeCollection(final List<Varbindsdecode> decodes) {
setVarbindsdecode(decodes);
}

public void setParameter(final int index, final Parameter parameter) throws IndexOutOfBoundsException {
m_parameters.set(index, parameter);
}

public void setParameter(final Parameter[] parameters) {
m_parameters.clear();
for (final Parameter parameter : parameters) {
m_parameters.add(parameter);
}
}

public void setParameter(final List<Parameter> parameters) {
if (m_parameters == parameters) return;
m_parameters.clear();
m_parameters.addAll(parameters);
}

public void setParameterCollection(final List<Parameter> decodes) {
setParameterCollection(decodes);
}

public static Event unmarshal(final Reader reader) throws MarshalException, ValidationException {
return (Event) Unmarshaller.unmarshal(Event.class, reader);
}
@@ -783,6 +852,7 @@ public int hashCode() {
result = prime * result + ((m_tticket == null) ? 0 : m_tticket.hashCode());
result = prime * result + ((m_uei == null) ? 0 : m_uei.hashCode());
result = prime * result + ((m_varbindsdecodes == null) ? 0 : m_varbindsdecodes.hashCode());
result = prime * result + ((m_parameters == null) ? 0 : m_parameters.hashCode());
return result;
}

@@ -892,6 +962,11 @@ public boolean equals(final Object obj) {
} else if (!m_varbindsdecodes.equals(other.m_varbindsdecodes)) {
return false;
}
if (m_parameters == null) {
if (other.m_parameters != null) return false;
} else if (!m_parameters.equals(other.m_parameters)) {
return false;
}
return true;
}

@@ -0,0 +1,124 @@
/*******************************************************************************
* This file is part of OpenNMS(R).
*
* Copyright (C) 2012-2014 The OpenNMS Group, Inc.
* OpenNMS(R) is Copyright (C) 1999-2014 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 Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero 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.xml.eventconf;

import java.io.Reader;
import java.io.Serializable;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

import org.exolab.castor.xml.MarshalException;
import org.exolab.castor.xml.Unmarshaller;
import org.exolab.castor.xml.ValidationException;
import org.exolab.castor.xml.Validator;
import org.opennms.core.xml.ValidateUsing;

/**
* Optional event parameter
*
* @author <a href="mailto:agaue@opennms.org>Alejandro Galue</a>
*/
@XmlRootElement(name="parameter")
@XmlAccessorType(XmlAccessType.FIELD)
@ValidateUsing("eventconf.xsd")
public class Parameter implements Serializable {

private static final long serialVersionUID = -2065585817005972567L;

@XmlAttribute(name="name", required=true)
private String m_name;

@XmlAttribute(name="value", required=true)
private String m_value;

public boolean hasName() {
return m_name != null ? true : false;
}

public String getName() {
return m_name;
}

public void setName(final String name) {
m_name = name;
}

public boolean hasValue() {
return m_value != null ? true : false;
}

public String getValue() {
return m_value;
}

public void setValue(final String value) {
m_value = value;
}

public static Parameter unmarshal(final Reader reader) throws MarshalException, ValidationException {
return (Parameter) Unmarshaller.unmarshal(Parameter.class, reader);
}

public void validate() throws ValidationException {
Validator validator = new Validator();
validator.validate(this);
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((m_name == null) ? 0 : m_name.hashCode());
result = prime * result + ((m_value == null) ? 0 : m_value.hashCode());
return result;
}

@Override
public boolean equals(final Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (!(obj instanceof Parameter)) return false;
final Parameter other = (Parameter) obj;
if (m_name == null) {
if (other.m_name != null) return false;
} else if (!m_name.equals(other.m_name)) {
return false;
}
if (m_value == null) {
if (other.m_value != null) return false;
} else if (!m_value.equals(other.m_value)) {
return false;
}
return true;
}

}
@@ -128,6 +128,14 @@
</annotation>
</element>

<element maxOccurs="unbounded" minOccurs="0" ref="this:parameter">
<annotation>
<documentation>An optional parameter (name-value pair) to be
assigned to the event. If this parameter duplciates an existing
parameter of the event, it will be ignored.</documentation>
</annotation>
</element>

<element maxOccurs="unbounded" minOccurs="0" ref="this:operaction">
<annotation>
<documentation>The operator action to be taken when this event
@@ -641,4 +649,11 @@
<attribute name="textual-convention" type="this:rfc1903-snmp-tc" use="optional" />
</complexType>
</element>

<element name="parameter">
<complexType>
<attribute name="name" type="string" use="required" />
<attribute name="value" type="string" use="required" />
</complexType>
</element>
</schema>