/*******************************************************************************
* This file is part of OpenNMS(R).
*
* Copyright (C) 2009-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.report.inventory;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;
import org.apache.log4j.Logger;
import org.exolab.castor.xml.MarshalException;
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.ValidationException;
import org.opennms.netmgt.config.RWSConfig;
import org.opennms.rancid.ConnectionProperties;
import org.opennms.rancid.InventoryElement2;
import org.opennms.rancid.InventoryMemory;
import org.opennms.rancid.InventoryNode;
import org.opennms.rancid.InventorySoftware;
import org.opennms.rancid.RWSClientApi;
import org.opennms.rancid.RancidApiException;
import org.opennms.rancid.RancidNode;
import org.opennms.rancid.Tuple;
import org.springframework.beans.factory.InitializingBean;
/**
* <p>InventoryReportCalculator class.</p>
*
* @author ranger
* @version $Id: $
*/
public class InventoryReportCalculator implements InitializingBean {
String m_baseDir;
// output file name
private String m_outputFileName;
ConnectionProperties m_cp;
/**
* <p>getOutputFileName</p>
*
* @return a {@link java.lang.String} object.
*/
public String getOutputFileName() {
return m_outputFileName;
}
/**
* <p>setOutputFileName</p>
*
* @param outputFileName a {@link java.lang.String} object.
*/
public void setOutputFileName(String outputFileName) {
m_outputFileName = outputFileName;
}
RWSConfig m_rwsConfig;
String theDate;
String user;
String theField;
Date reportRequestDate;
RwsNbinventoryreport rnbi;
/**
* <p>Getter for the field <code>theField</code>.</p>
*
* @return a {@link java.lang.String} object.
*/
public String getTheField() {
return theField;
}
/**
* <p>Setter for the field <code>theField</code>.</p>
*
* @param theField a {@link java.lang.String} object.
*/
public void setTheField(String theField) {
this.theField = theField;
}
/**
* <p>Getter for the field <code>theDate</code>.</p>
*
* @return a {@link java.lang.String} object.
*/
public String getTheDate() {
return theDate;
}
/**
* <p>Setter for the field <code>theDate</code>.</p>
*
* @param theDate a {@link java.lang.String} object.
*/
public void setTheDate(String theDate) {
this.theDate = theDate;
}
/**
* <p>Getter for the field <code>user</code>.</p>
*
* @return a {@link java.lang.String} object.
*/
public String getUser() {
return user;
}
/**
* <p>Setter for the field <code>user</code>.</p>
*
* @param user a {@link java.lang.String} object.
*/
public void setUser(String user) {
this.user = user;
}
/**
* <p>Getter for the field <code>reportRequestDate</code>.</p>
*
* @return a {@link java.util.Date} object.
*/
public Date getReportRequestDate() {
return reportRequestDate;
}
/**
* <p>Setter for the field <code>reportRequestDate</code>.</p>
*
* @param reportRequestDate a {@link java.util.Date} object.
*/
public void setReportRequestDate(Date reportRequestDate) {
this.reportRequestDate = reportRequestDate;
}
/**
* <p>getRwsConfig</p>
*
* @return a {@link org.opennms.netmgt.config.RWSConfig} object.
*/
public RWSConfig getRwsConfig() {
return m_rwsConfig;
}
/**
* <p>setRwsConfig</p>
*
* @param rwsConfig a {@link org.opennms.netmgt.config.RWSConfig} object.
*/
public void setRwsConfig(RWSConfig rwsConfig) {
m_rwsConfig = rwsConfig;
}
/**
* <p>getBaseDir</p>
*
* @return a {@link java.lang.String} object.
*/
public String getBaseDir() {
return m_baseDir;
}
/**
* <p>setBaseDir</p>
*
* @param baseDir a {@link java.lang.String} object.
*/
public void setBaseDir(String baseDir) {
m_baseDir = baseDir;
}
private static Logger log() {
return Logger.getLogger("Rancid");
}
/**
* <p>afterPropertiesSet</p>
*
* @throws java.lang.Exception if any.
*/
@Override
public void afterPropertiesSet() throws Exception {
RWSClientApi.init();
m_cp = m_rwsConfig.getBase();
}
private List<String> getGroups() {
try {
return RWSClientApi.getRWSResourceGroupsList(m_cp).getResource();
} catch (RancidApiException e) {
log().error("getGroups: has given exception "+ e.getMessage() + ". Skipped");
}
return new ArrayList<String>();
}
private List<String> getDeviceListOnGroup(String groupName) {
try {
return RWSClientApi.getRWSResourceDeviceList(m_cp, groupName).getResource();
} catch (RancidApiException e) {
log().error("getDeviceListOnGroup: group [" + groupName + "]. Skipped");
}
return new ArrayList<String>();
}
private List<String> getVersionListOnDevice(String deviceName, String groupName) {
try {
return RWSClientApi.getRWSResourceConfigList(m_cp, groupName, deviceName).getResource();
} catch (RancidApiException e) {
log().error("getVersionListOnDevice: device has no inventory ["+deviceName+ "]. " + e.getLocalizedMessage());
}
return new ArrayList<String>();
}
private RancidNode getFullNode(String groupName, String deviceName) {
try {
return RWSClientApi.getRWSRancidNodeInventory(m_cp ,groupName, deviceName);
} catch (RancidApiException e) {
log().error("getFullNode: device has no inventory ["+deviceName+ "]. " + e.getLocalizedMessage());
}
return null;
}
/**
* <p>calculate</p>
*/
public void calculate() {
rnbi = new RwsNbinventoryreport();
rnbi.setUser(user);
rnbi.setReportRequestDate(reportRequestDate.toString());
boolean withKey = false;
if (theField.compareTo("")!=0){
withKey = true;
rnbi.setTheField(theField);
}
SimpleDateFormat format = new SimpleDateFormat("yyyy/M/d");
Date tmp_date = new Date();
try {
tmp_date = format.parse(theDate);
}
catch (ParseException pe){
tmp_date = Calendar.getInstance().getTime();
}
log().debug("calculate:report date[" + tmp_date.toString() + "]");
rnbi.setReportDate(tmp_date.toString());
int totalGroups = 0;
int groupsMatching = 0;
int groupWithoutNodes = 0;
int groupsWithNodesWithoutinventoryAtAll = 0;
int groupsWithNodesWithoutinventoryAtReportDate = 0;
for(String groupName : getGroups()) {
log().debug("calculate:report group [" + groupName + "]");
totalGroups++;
GroupSet gs = new GroupSet();
gs.setGroupSetName(groupName);
int totalNodes = 0;
int nodeMatching = 0;
int nodesWithoutinventoryAtAll=0;
int nodesWithoutinventoryAtReportDate=0;
boolean groupHasDevices = false;
boolean groupHasNodesWithoutinventoryAtAll = false;
boolean groupHasNodesWithoutinventoryAtrequestDate = false;
for (String deviceName: getDeviceListOnGroup(groupName)) {
totalNodes++;
log().debug("calculate:report device [" + deviceName + "]");
RancidNode rancidNode = getFullNode(groupName, deviceName);
if ( rancidNode == null ) {
groupHasNodesWithoutinventoryAtAll = true;
nodesWithoutinventoryAtAll++;
continue;
}
InventoryNode invNode = new InventoryNode(rancidNode);
boolean found = false;
for (String versionMatch : getVersionListOnDevice(deviceName, groupName)) {
invNode = (InventoryNode)rancidNode.getNodeVersions().get(versionMatch);
log().debug("calculate:report parsing InventoryNode version[" + invNode.getVersionId() + "] date ["+invNode.getCreationDate()+"]");
if (tmp_date.compareTo(invNode.getCreationDate()) > 0 ) {
found = true;
log().debug("calculate:report Date found is ["+invNode.getCreationDate()+"] version is [" + versionMatch + "]");
break;
}
} //end for on version
if (found == false) {
log().debug("calculate: device has no configuration at this date["+deviceName+ "]");
groupHasNodesWithoutinventoryAtrequestDate = true;
nodesWithoutinventoryAtReportDate++;
continue;
}
//we have groupname devicename and version
NodeBaseInventory nodeBaseInv = getNodeBaseInventory(deviceName, groupName, invNode.getVersionId());
Nbisinglenode nbisn = new Nbisinglenode();
boolean includeNbisn = false;
nbisn.setConfigurationurl(nodeBaseInv.getConfigurationurl());
nbisn.setCreationdate(nodeBaseInv.getCreationdate());
nbisn.setDevicename(nodeBaseInv.getDevicename());
nbisn.setGroupname(nodeBaseInv.getGroupname());
nbisn.setStatus(nodeBaseInv.getStatus());
nbisn.setSwconfigurationurl(nodeBaseInv.getSwconfigurationurl());
nbisn.setVersion(nodeBaseInv.getVersion());
List<InventoryElement2RP> ie2rpList = new ArrayList<InventoryElement2RP>();
for (InventoryElement2 ie2 : nodeBaseInv.getIe()) {
InventoryElement2RP ie2rp = new InventoryElement2RP();
boolean addInventoryElement = false;
for (Tuple tuple: ie2.getTupleList()) {
if (withKey) {
if (Pattern.matches(theField,tuple.getDescription()) || Pattern.matches(theField,tuple.getName())) {
includeNbisn = true;
addInventoryElement=true;
}
} else {
includeNbisn = true;
addInventoryElement=true;
}
if (tuple.getName().equalsIgnoreCase("name")) {
ie2rp.setName(tuple.getDescription());
} else {
TupleRP trp = new TupleRP();
trp.setName(tuple.getName());
trp.setDescription(tuple.getDescription());
ie2rp.addTupleRP(trp);
}
}
for(InventoryMemory im: ie2.getMemoryList()) {
if (withKey) {
if (Pattern.matches(theField,"Memory") || Pattern.matches(theField,im.getType())) {
includeNbisn = true;
addInventoryElement=true;
}
} else {
includeNbisn = true;
addInventoryElement=true;
}
InventoryMemoryRP imrp = new InventoryMemoryRP();
imrp.setType(im.getType());
imrp.setSize(im.getSize());
ie2rp.addInventoryMemoryRP(imrp);
}
for(InventorySoftware is : ie2.getSoftwareList()) {
if (withKey) {
if (Pattern.matches(theField,"Software") || Pattern.matches(theField,is.getType()) ||
Pattern.matches(theField, is.getVersion())) {
includeNbisn = true;
addInventoryElement=true;
}
} else {
includeNbisn = true;
addInventoryElement=true;
}
InventorySoftwareRP isrp = new InventorySoftwareRP();
isrp.setType(is.getType());
isrp.setVersion(is.getVersion());
ie2rp.addInventorySoftwareRP(isrp);
}
if (addInventoryElement)
ie2rpList.add(ie2rp);
}
nbisn.setInventoryElement2RP(ie2rpList);
if(includeNbisn){
nodeMatching++;
groupHasDevices=true;
gs.addNbisinglenode(nbisn);
}
}
gs.setTotalNodes(totalNodes);
gs.setNodesMatching(nodeMatching);
gs.setNodesWithoutinventoryAtReportDate(nodesWithoutinventoryAtReportDate);
gs.setNodesWithoutinventoryAtAll(nodesWithoutinventoryAtAll);
rnbi.addGroupSet(gs);
if (groupHasDevices) groupsMatching++;
else groupWithoutNodes++;
if (groupHasDevices && groupHasNodesWithoutinventoryAtAll)
groupsWithNodesWithoutinventoryAtAll++;
if (groupHasDevices &&groupHasNodesWithoutinventoryAtrequestDate)
groupsWithNodesWithoutinventoryAtReportDate++;
} //end for groups
rnbi.setTotalGroups(totalGroups);
rnbi.setGroupsMatching(groupsMatching);
rnbi.setGroupsWithNodesWithoutinventoryAtAll(groupsWithNodesWithoutinventoryAtAll);
rnbi.setGroupsWithNodesWithoutinventoryAtReportDate(groupsWithNodesWithoutinventoryAtReportDate);
rnbi.setGroupWithoutNodes(groupWithoutNodes);
}
/**
* <p>getNodeBaseInventory</p>
*
* @param node a {@link java.lang.String} object.
* @param group a {@link java.lang.String} object.
* @param version a {@link java.lang.String} object.
* @return a {@link org.opennms.report.inventory.NodeBaseInventory} object.
*/
public NodeBaseInventory getNodeBaseInventory(String node, String group, String version) {
// get the latest version from the given date
log().debug("getNodeBaseInventory " + node +" "+group + " "+version);
NodeBaseInventory nbi = new NodeBaseInventory();
RancidNode rn;
try {
rn = RWSClientApi.getRWSRancidNodeInventory(m_cp, group, node);
} catch (RancidApiException e) {
log().debug("getNodeBaseInventory: inventory not found. Skipping");
return nbi;
}
InventoryNode in = (InventoryNode)rn.getNodeVersions().get(version);
nbi.setDevicename(node);
nbi.setGroupname(group);
nbi.setVersion(version);
nbi.setStatus(in.getParent().getState());
nbi.setCreationdate(in.getCreationDate());
nbi.setSwconfigurationurl(in.getSoftwareImageUrl());
nbi.setConfigurationurl(in.getConfigurationUrl());
try {
nbi.setIe( RWSClientApi.getRWSRancidNodeInventoryElement2(m_cp, rn, version));
} catch (RancidApiException e) {
log().debug("getNodeBaseInventory: inventory not found for version: " + version + ". Skipping");
}
return nbi;
}
/**
* <p>writeXML</p>
*
* @throws org.opennms.report.inventory.InventoryCalculationException if any.
*/
public void writeXML() throws InventoryCalculationException {
try {
log().debug("Writing the XML");
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmss");
String datestamp = fmt.format(reportRequestDate);
m_outputFileName = "/NODEINVENTORY" + datestamp + ".xml";
// Create a file name of type Category-monthFormat-startDate.xml
log().debug("Report Store XML file: " + m_outputFileName);
File reportFile = new File(m_baseDir, m_outputFileName);
// marshal the XML into the file.
marshal(reportFile);
} catch (InventoryCalculationException e) {
log().fatal("Unable to marshal report as XML");
throw new InventoryCalculationException(e);
}
}
/**
* <p>marshal</p>
*
* @param outputFile a {@link java.io.File} object.
* @throws org.opennms.report.inventory.InventoryCalculationException if any.
*/
public void marshal(File outputFile)
throws InventoryCalculationException {
try {
Writer fileWriter = new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8");
Marshaller marshaller = new Marshaller(fileWriter);
marshaller.setSuppressNamespaces(true);
marshaller.marshal(rnbi);
log().debug("The xml marshalled from the castor classes is saved in "
+ outputFile.getAbsoluteFile());
fileWriter.close();
} catch (MarshalException me) {
log().fatal("MarshalException ", me);
throw new InventoryCalculationException(me);
} catch (ValidationException ve) {
log().fatal("Validation Exception ", ve);
throw new InventoryCalculationException(ve);
} catch (IOException ioe) {
log().fatal("IO Exception ", ioe);
throw new InventoryCalculationException(ioe);
}
}
}