/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2006-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.model; import static org.opennms.core.utils.InetAddressUtils.toInteger; import java.io.Serializable; import java.math.BigInteger; import java.net.InetAddress; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.SequenceGenerator; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.persistence.Transient; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlIDREF; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import org.hibernate.annotations.Where; import org.springframework.core.style.ToStringCreator; @XmlRootElement(name = "service") @Entity @Table(name="ifServices") public class OnmsMonitoredService extends OnmsEntity implements Serializable, Comparable<OnmsMonitoredService> { /** * */ private static final long serialVersionUID = -7106081378757872886L; private Integer m_id; private Date m_lastGood; private Date m_lastFail; private String m_qualifier; private String m_status; private String m_source; private String m_notify; private OnmsServiceType m_serviceType; private OnmsIpInterface m_ipInterface; /* * This is a set only because we want it to be lazy * and we need a better query language (i.e. HQL) * to make this work. In this case, the Set size * will always be 1 or empty because there can only * be one outage at a time on a service. * * With distributed monitoring, there will probably * be a model change were one service can be represented * by more than one outage. */ private Set<OnmsOutage> m_currentOutages = new LinkedHashSet<OnmsOutage>(); private Set<OnmsApplication> m_applications = new LinkedHashSet<OnmsApplication>(); private static final Map<String, String> STATUS_MAP; static { STATUS_MAP = new HashMap<String, String>(); STATUS_MAP.put("A", "Managed"); STATUS_MAP.put("U", "Unmanaged"); STATUS_MAP.put("D", "Deleted"); STATUS_MAP.put("F", "Forced Unmanaged"); STATUS_MAP.put("N", "Not Monitored"); STATUS_MAP.put("R", "Rescan to Resume"); STATUS_MAP.put("S", "Rescan to Suspend"); STATUS_MAP.put("X", "Remotely Monitored"); } /** * <p>Constructor for OnmsMonitoredService.</p> */ public OnmsMonitoredService() { } /** * <p>Constructor for OnmsMonitoredService.</p> * * @param ipIf a {@link org.opennms.netmgt.model.OnmsIpInterface} object. * @param serviceType a {@link org.opennms.netmgt.model.OnmsServiceType} object. */ public OnmsMonitoredService(OnmsIpInterface ipIf, OnmsServiceType serviceType) { m_ipInterface = ipIf; m_ipInterface.getMonitoredServices().add(this); m_serviceType = serviceType; } /** * Unique identifier for ifService. * * @return a {@link java.lang.Integer} object. */ @Id @Column(nullable=false) @XmlAttribute(name="id") @SequenceGenerator(name="opennmsSequence", sequenceName="opennmsNxtId") @GeneratedValue(generator="opennmsSequence") public Integer getId() { return m_id; } /** * <p>setId</p> * * @param id a {@link java.lang.Integer} object. */ public void setId(Integer id) { m_id = id; } /** * <p>getIpAddress</p> * * @return a {@link java.lang.String} object. */ @XmlTransient @Transient public InetAddress getIpAddress() { return m_ipInterface.getIpAddress(); } /** * <p>getIpAddress</p> * * @return a {@link java.lang.String} object. * * @deprecated */ @XmlTransient @Transient public String getIpAddressAsString() { return m_ipInterface.getIpAddressAsString(); } /** * <p>getIfIndex</p> * * @return a {@link java.lang.Integer} object. */ @XmlTransient @Transient public Integer getIfIndex() { return m_ipInterface.getIfIndex(); } /** * <p>getLastGood</p> * * @return a {@link java.util.Date} object. */ @Temporal(TemporalType.TIMESTAMP) @Column(name="lastGood") public Date getLastGood() { return m_lastGood; } /** * <p>setLastGood</p> * * @param lastgood a {@link java.util.Date} object. */ public void setLastGood(Date lastgood) { m_lastGood = lastgood; } /** * <p>getLastFail</p> * * @return a {@link java.util.Date} object. */ @Temporal(TemporalType.TIMESTAMP) @Column(name="lastFail") public Date getLastFail() { return m_lastFail; } /** * <p>setLastFail</p> * * @param lastfail a {@link java.util.Date} object. */ public void setLastFail(Date lastfail) { m_lastFail = lastfail; } /** * <p>getQualifier</p> * * @return a {@link java.lang.String} object. */ @Column(name="qualifier", length=16) public String getQualifier() { return m_qualifier; } /** * <p>setQualifier</p> * * @param qualifier a {@link java.lang.String} object. */ public void setQualifier(String qualifier) { m_qualifier = qualifier; } /** * <p>getStatus</p> * * @return a {@link java.lang.String} object. */ @XmlAttribute @Column(name="status", length=1) public String getStatus() { return m_status; } /** * <p>setStatus</p> * * @param status a {@link java.lang.String} object. */ public void setStatus(String status) { m_status = status; } @Transient public String getStatusLong() { return STATUS_MAP.get(getStatus()); } /** * <p>getSource</p> * * @return a {@link java.lang.String} object. */ @XmlAttribute @Column(name="source", length=1) public String getSource() { return m_source; } /** * <p>setSource</p> * * @param source a {@link java.lang.String} object. */ public void setSource(String source) { m_source = source; } /** * <p>getNotify</p> * * @return a {@link java.lang.String} object. */ @Column(name="notify", length=1) public String getNotify() { return m_notify; } /** * <p>setNotify</p> * * @param notify a {@link java.lang.String} object. */ public void setNotify(String notify) { m_notify = notify; } /** * <p>getIpInterface</p> * * @return a {@link org.opennms.netmgt.model.OnmsIpInterface} object. */ @XmlIDREF @XmlElement(name="ipInterfaceId") @ManyToOne(optional=false, fetch=FetchType.LAZY) @JoinColumn(name="ipInterfaceId") public OnmsIpInterface getIpInterface() { return m_ipInterface; } /** * <p>setIpInterface</p> * * @param ipInterface a {@link org.opennms.netmgt.model.OnmsIpInterface} object. */ public void setIpInterface(OnmsIpInterface ipInterface) { m_ipInterface = ipInterface; } /** * <p>getNodeId</p> * * @return a {@link java.lang.Integer} object. */ @XmlTransient @Transient public Integer getNodeId() { return m_ipInterface.getNode().getId(); } /** * <p>getServiceType</p> * * @return a {@link org.opennms.netmgt.model.OnmsServiceType} object. */ @ManyToOne(optional=false) @JoinColumn(name="serviceId") public OnmsServiceType getServiceType() { return m_serviceType; } /** * <p>setServiceType</p> * * @param service a {@link org.opennms.netmgt.model.OnmsServiceType} object. */ public void setServiceType(OnmsServiceType service) { m_serviceType = service; } /** * <p>toString</p> * * @return a {@link java.lang.String} object. */ public String toString() { return new ToStringCreator(this) .append("id", m_id) .append("lastGood", m_lastGood) .append("lastFail", m_lastFail) .append("qualifier", m_qualifier) .append("status", m_status) .append("source", m_source) .append("notify", m_notify) .append("serviceType", m_serviceType) // cannot include these since the require db queries // .append("ipInterface", m_ipInterface) // .append("currentOutages", m_currentOutages) // .append("applications", m_applications) .toString(); } /** * <p>getServiceId</p> * * @return a {@link java.lang.Integer} object. */ @Transient public Integer getServiceId() { return getServiceType().getId(); } /** {@inheritDoc} */ public void visit(EntityVisitor visitor) { visitor.visitMonitoredService(this); visitor.visitMonitoredServiceComplete(this); } /** * <p>getServiceName</p> * * @return a {@link java.lang.String} object. */ @Transient public String getServiceName() { return getServiceType().getName(); } /** * <p>isDown</p> * * @return a boolean. */ @Transient public boolean isDown() { boolean down = true; if (!"A".equals(getStatus()) || m_currentOutages.isEmpty()) { return !down; } return down; } /** * <p>getCurrentOutages</p> * * @return a {@link java.util.Set} object. */ @XmlTransient @OneToMany(mappedBy="monitoredService", fetch=FetchType.LAZY) @Where(clause="ifRegainedService is null") public Set<OnmsOutage> getCurrentOutages() { return m_currentOutages; } /** * <p>setCurrentOutages</p> * * @param currentOutages a {@link java.util.Set} object. */ public void setCurrentOutages(Set<OnmsOutage> currentOutages) { m_currentOutages = currentOutages; } /** * <p>getApplications</p> * * @return a {@link java.util.Set} object. */ @ManyToMany( cascade={CascadeType.PERSIST, CascadeType.MERGE} ) @JoinTable( name="application_service_map", joinColumns={@JoinColumn(name="ifserviceid")}, inverseJoinColumns={@JoinColumn(name="appid")} ) public Set<OnmsApplication> getApplications() { return m_applications; } /** * <p>setApplications</p> * * @param applications a {@link java.util.Set} object. */ public void setApplications(Set<OnmsApplication> applications) { m_applications = applications; } /** * <p>addApplication</p> * * @param application a {@link org.opennms.netmgt.model.OnmsApplication} object. * @return a boolean. */ public boolean addApplication(OnmsApplication application) { return getApplications().add(application); } /** * <p>removeApplication</p> * * @param application a {@link org.opennms.netmgt.model.OnmsApplication} object. * @return a boolean. */ public boolean removeApplication(OnmsApplication application) { return getApplications().remove(application); } /** * <p>compareTo</p> * * @param o a {@link org.opennms.netmgt.model.OnmsMonitoredService} object. * @return a int. */ public int compareTo(OnmsMonitoredService o) { int diff; diff = getIpInterface().getNode().getLabel().compareToIgnoreCase(o.getIpInterface().getNode().getLabel()); if (diff != 0) { return diff; } BigInteger a = toInteger(getIpAddress()); BigInteger b = toInteger(o.getIpAddress()); diff = a.compareTo(b); if (diff != 0) { return diff; } return getServiceName().compareToIgnoreCase(o.getServiceName()); } /** * <p>mergeServiceAttributes</p> * * @param scanned a {@link org.opennms.netmgt.model.OnmsMonitoredService} object. */ public void mergeServiceAttributes(OnmsMonitoredService scanned) { if (hasNewValue(scanned.getQualifier(), getQualifier())) { setQualifier(scanned.getQualifier()); } if (hasNewStatusValue(scanned.getStatus(), getStatus())) { setStatus(scanned.getStatus()); } if (hasNewValue(scanned.getSource(), getSource())) { setSource(scanned.getSource()); } if (hasNewValue(scanned.getNotify(), getNotify())) { setNotify(scanned.getNotify()); } } private boolean hasNewStatusValue(String newStatus, String oldStatus) { /* * Don't overwrite the 'Not Monitored' in the database when provisioning the * node. The Poller will update it when scheduling it packages. */ return !"N".equals(oldStatus) && newStatus != null && !newStatus.equals(oldStatus); } }