/*******************************************************************************
* 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.web.asset;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.NoSuchElementException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.opennms.core.resource.Vault;
import org.opennms.core.utils.WebSecurityUtils;
import org.opennms.web.api.Util;
import org.opennms.web.servlet.MissingParameterException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import au.com.bytecode.opencsv.CSVReader;
/**
* <p>ImportAssetsServlet class.</p>
*
* @author <A HREF="mailto:larry@opennms.org">Lawrence Karnowski</A>
* @author <A HREF="mailto:ranger@opennms.org">Benjamin Reed</A>
* @author <A HREF="http://www.opennms.org/">OpenNMS</A>
* @version $Id: $
* @since 1.8.1
*/
public class ImportAssetsServlet extends HttpServlet {
private Logger logger = LoggerFactory.getLogger(ImportAssetsServlet.class.getName());
private static final long serialVersionUID = 2L;
private List<String> errors = new ArrayList<String>();
private class AssetException extends Exception {
private static final long serialVersionUID = 2498335935646001342L;
public AssetException(String message) {
super(message);
}
public AssetException(String message, Throwable t) {
super(message, t);
}
}
/** The URL to redirect the client to in case of success. */
protected String redirectSuccess;
protected AssetModel model;
/**
* Looks up the <code>redirect.success</code> parameter in the servlet's
* configuration. If not present, this servlet will throw an exception so it will
* be marked unavailable.
*
* @throws javax.servlet.ServletException if any.
*/
public void init() throws ServletException {
ServletConfig config = this.getServletConfig();
this.redirectSuccess = config.getInitParameter("redirect.success");
if (this.redirectSuccess == null) {
throw new UnavailableException("Require a redirect.success init parameter.");
}
this.model = new AssetModel();
}
/**
* {@inheritDoc}
*
* Acknowledge the events specified in the POST and then redirect the client
* to an appropriate URL for display.
*/
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String assetsText = request.getParameter("assetsText");
if (assetsText == null) {
logger.error("assetsText was null");
throw new MissingParameterException("assetsText");
}
try {
List<Asset> assets = this.decodeAssetsText(assetsText);
List<Integer> nodesWithAssets = this.getCurrentAssetNodesList();
for (Asset asset : assets) {
// update with the current information
asset.setUserLastModified(request.getRemoteUser());
asset.setLastModifiedDate(new Date());
if (nodesWithAssets.contains(new Integer(asset.getNodeId()))) {
logger.debug("modifyAsset call for asset:'{}'", asset);
this.model.modifyAsset(asset);
} else {
logger.debug("createAsset:'{}'", asset);
this.model.createAsset(asset);
}
}
StringBuffer messageText = new StringBuffer();
messageText.append("Successfully imported ").append(assets.size()).append(" asset");
if (assets.size() > 1) {
messageText.append("s");
}
messageText.append(".");
if (errors.size() > 0) {
messageText.append(" ").append(errors.size()).append(" non-fatal errors occurred:");
for (String error : errors) {
messageText.append("<br />").append(error);
}
}
request.getSession().setAttribute("message", messageText.toString());
response.sendRedirect(response.encodeRedirectURL(this.redirectSuccess + "&showMessage=true"));
} catch (AssetException e) {
String message = "Error importing assets: " + e.getMessage();
redirectWithErrorMessage(request, response, e, message);
} catch (SQLException e) {
String message ="Database exception importing assets: " + e.getMessage();
redirectWithErrorMessage(request, response, e, message);
}
}
private void redirectWithErrorMessage(HttpServletRequest request, HttpServletResponse response,
Exception e, String message) throws IOException, UnsupportedEncodingException {
this.log(message, e);
request.getSession().setAttribute("message", message);
response.sendRedirect(response.encodeRedirectURL("import.jsp?showMessage=true"));
}
/**
* <p>decodeAssetsText</p>
*
* @param text a {@link java.lang.String} object.
* @return a {@link java.util.List} object.
* @throws org.opennms.web.asset.ImportAssetsServlet$AssetException if any.
*/
public List<Asset> decodeAssetsText(String text) throws AssetException {
CSVReader reader = new CSVReader(new StringReader(text));
String[] line;
List<Asset> list = new ArrayList<Asset>();
text = text.trim();
int count = 0;
try {
while ((line = reader.readNext()) != null) {
count++;
try {
logger.debug("asset line is:'{}'", line);
if (line.length != 59) {
logger.error("csv test row length was not 58 line length: '{}' line was:'{}', line length", line.length, line);
throw new NoSuchElementException();
}
// skip the first line if it's the headers
if (line[0].equals("Node Label")) {
logger.debug("line was header. line:'{}'", line);
continue;
}
Asset asset = new Asset();
asset.setNodeId(WebSecurityUtils.safeParseInt(line[1]));
asset.setCategory(Util.decode(line[2]));
asset.setManufacturer(Util.decode(line[3]));
asset.setVendor(Util.decode(line[4]));
asset.setModelNumber(Util.decode(line[5]));
asset.setSerialNumber(Util.decode(line[6]));
asset.setDescription(Util.decode(line[7]));
asset.setCircuitId(Util.decode(line[8]));
asset.setAssetNumber(Util.decode(line[9]));
asset.setOperatingSystem(Util.decode(line[10]));
asset.setRack(Util.decode(line[11]));
asset.setSlot(Util.decode(line[12]));
asset.setPort(Util.decode(line[13]));
asset.setRegion(Util.decode(line[14]));
asset.setDivision(Util.decode(line[15]));
asset.setDepartment(Util.decode(line[16]));
asset.setAddress1(Util.decode(line[17]));
asset.setAddress2(Util.decode(line[18]));
asset.setCity(Util.decode(line[19]));
asset.setState(Util.decode(line[20]));
asset.setZip(Util.decode(line[21]));
asset.setBuilding(Util.decode(line[22]));
asset.setFloor(Util.decode(line[23]));
asset.setRoom(Util.decode(line[24]));
asset.setVendorPhone(Util.decode(line[25]));
asset.setVendorFax(Util.decode(line[26]));
asset.setDateInstalled(Util.decode(line[27]));
asset.setLease(Util.decode(line[28]));
asset.setLeaseExpires(Util.decode(line[29]));
asset.setSupportPhone(Util.decode(line[30]));
asset.setMaintContract(Util.decode(line[31]));
asset.setVendorAssetNumber(Util.decode(line[32]));
asset.setMaintContractExpires(Util.decode(line[33]));
asset.setDisplayCategory(Util.decode(line[34]));
asset.setNotifyCategory(Util.decode(line[35]));
asset.setPollerCategory(Util.decode(line[36]));
asset.setThresholdCategory(Util.decode(line[37]));
asset.setUsername(Util.decode(line[38]));
asset.setPassword(Util.decode(line[39]));
asset.setEnable(Util.decode(line[40]));
asset.setConnection(Util.decode(line[41]));
asset.setAutoenable(Util.decode(line[42]));
asset.setComments(Util.decode(line[43]));
asset.setCpu(Util.decode(line[44]));
asset.setRam(Util.decode(line[45]));
asset.setStoragectrl(Util.decode(line[46]));
asset.setHdd1(Util.decode(line[47]));
asset.setHdd2(Util.decode(line[48]));
asset.setHdd3(Util.decode(line[49]));
asset.setHdd4(Util.decode(line[50]));
asset.setHdd5(Util.decode(line[51]));
asset.setHdd6(Util.decode(line[52]));
asset.setNumpowersupplies(Util.decode(line[53]));
asset.setInputpower(Util.decode(line[54]));
asset.setAdditionalhardware(Util.decode(line[55]));
asset.setAdmin(Util.decode(line[56]));
asset.setSnmpcommunity(Util.decode(line[57]));
asset.setRackunitheight(Util.decode(line[58]));
list.add(asset);
logger.debug("decoded asset:'{}'", asset);
} catch (NoSuchElementException e) {
errors.add("Ignoring malformed import for entry " + count + ", not enough values.");
} catch (NumberFormatException e) {
logger.error("NodeId parsing to int faild, ignoreing malformed import for entry number '{}' exception message:'{}'", count, e.getMessage());
errors.add("Ignoring malformed import for entry " + count + ", node id not a number.");
}
}
} catch (IOException e) {
logger.error("An error occurred reading the CSV input. Message:'{}'", e.getMessage());
throw new AssetException("An error occurred reading the CSV input.", e);
}
if (list.size() == 0) {
logger.error("No asset information was found, list size was 0");
throw new AssetException("No asset information was found.");
}
return list;
}
/**
* <p>getCurrentAssetNodesList</p>
*
* @return a {@link java.util.List} object.
* @throws java.sql.SQLException if any.
*/
public List<Integer> getCurrentAssetNodesList() throws SQLException {
Connection conn = Vault.getDbConnection();
List<Integer> list = new ArrayList<Integer>();
try {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT NODEID FROM ASSETS");
while (rs.next()) {
list.add(new Integer(rs.getInt("NODEID")));
}
rs.close();
stmt.close();
} finally {
Vault.releaseDbConnection(conn);
}
return list;
}
}