/src/server/xmlprovider/src/keymind/keywatch/bundles/provider/xmlrpc/FileHandler.java
http://keywatch.googlecode.com/ · Java · 427 lines · 274 code · 71 blank · 82 comment · 39 complexity · b88a72b61649ddbc3bb4ad6d3dea00e4 MD5 · raw file
- /**
- * -----------------------------------------------------------------------------------------------
- * File: FileHandler.java
- * Created 26.jun.2006
- *
- *
- * Copyright (c) 2007 by Keymind Computing as.
- * All rights reserved.
- *
- * This file is subject to the terms and conditions of the Apache Licence 2.0.
- * See the file LICENCE in the main directory of the Keywatch distribution for more details.
- *
- * Revision History (use svn log or TortoiseSVN):
- * $URL: http://keywatch.googlecode.com/svn/trunk/src/server/xmlprovider/src/keymind/keywatch/bundles/provider/xmlrpc/FileHandler.java $
- * $Date: 2009-12-14 18:16:33 +0100 (Mon, 14 Dec 2009) $
- * -----------------------------------------------------------------------------------------------
- */
- package keymind.keywatch.bundles.provider.xmlrpc;
-
- import keymind.keywatch.common.Log;
- import keymind.keywatch.domainmodel.eventDomain.Context;
- import keymind.keywatch.domainmodel.eventDomain.Event;
- import keymind.keywatch.domainmodel.eventDomain.Severity;
- import keymind.keywatch.domainmodel.eventDomain.Task;
- import keymind.keywatch.services.eventmanagement.IEventManagement;
- import org.w3c.dom.DOMException;
- import org.w3c.dom.Document;
- import org.w3c.dom.Node;
- import org.xml.sax.InputSource;
-
- import javax.xml.parsers.DocumentBuilder;
- import javax.xml.parsers.DocumentBuilderFactory;
- import javax.xml.parsers.ParserConfigurationException;
- import java.io.*;
- import java.util.Date;
- import java.util.zip.ZipEntry;
- import java.util.zip.ZipInputStream;
-
- /**
- * Internal class that handles incoming event files
- */
- public class FileHandler
- {
- static DocumentBuilderFactory factory =
- DocumentBuilderFactory.newInstance();
- private static Context ctx = null;
- private static Activator xmlProvider = null;
- private static IEventManagement eventManager = null;
-
- static final int SLEEP_ZIPPING = 50;
- static final int BUFSIZE_ZIP = 1024;
-
-
- /**
- * C'tor
- */
- public FileHandler()
- {
- // Initialize singletons
- if(xmlProvider == null)
- {
- ctx = KeyXmlRpcServer.getCtx();
- xmlProvider = KeyXmlRpcServer.getXmlProvider();
- eventManager = KeyXmlRpcServer.getEventManager();
- }
- }
-
-
- /**
- * Receives a file via XmlRpc form a connected client.
- *
- * @param inputFile Contents of the file
- * @param inputFileName The name of the file as it is on the client
- * @return true if filetransfer went OK, false otherwise
- * @throws Exception if a problem occurs.
- */
- public boolean ReceiveFile(byte[] inputFile, String inputFileName) throws Exception
- {
- boolean retVal;
-
- try
- {
- // We add a timestamp, since all incoming zip files have the same name (error.zip)
- long now = System.currentTimeMillis();
-
- // Create events directory if missing
- File f = new File(Constants.PROVIDER_DIR_EVENT);
- f.mkdir();
-
- String fullname = Constants.PROVIDER_DIR_EVENT + "/" +
- now + "_" + inputFileName;
-
- FileOutputStream outStream = new FileOutputStream(fullname);
-
- for (int i = 0; i < inputFile.length; i++)
- {
- outStream.write(inputFile[i]);
- }
-
- outStream.close();
-
- // If it's a zip file, extract files and remove it
- if (fullname.toLowerCase().endsWith(Constants.PROVIDER_EXT_ZIP))
- {
- boolean allOK = processZipFiles(fullname);
-
- // If the quarantine is active, move the zip file there, else delete it
- File originalZip = new File(fullname);
-
- // Save a copy if one or more xml's are malformed
- if (!allOK)
- {
- File errorDir = new File(Constants.PROVIDER_DIR_ERRORXML);
- errorDir.mkdir();
-
- File errorFile = new File(Constants.PROVIDER_DIR_ERRORXML +
- "/" + now + "_" + inputFileName);
-
- originalZip.renameTo(errorFile);
- }
- }
-
- retVal = true;
- }
- catch (Exception ex)
- {
- ex.printStackTrace();
- retVal = false;
- }
-
- return retVal;
-
- }// ReceiveFile
-
-
- /**
- * Helper that unpacks a zip file
- *
- * @param destinationPath Destination directory
- * @param filename Name of zip file (fully qualified)
- */
- void extractZipFiles(String destinationPath, String filename)
- {
- try
- {
- byte[] buf = new byte[BUFSIZE_ZIP];
-
- ZipInputStream zipinputstream = new ZipInputStream(new FileInputStream(filename));
- ZipEntry zipentry = zipinputstream.getNextEntry();
-
- while (zipentry != null)
- {
- String entryName = zipentry.getName();
- int n = 0;
-
- FileOutputStream fileoutputstream = null;
-
- File newFile = new File(entryName);
- String directory = newFile.getParent();
-
- if (directory == null)
- {
- if (newFile.isDirectory())
- {
- break;
- }
- }
-
- fileoutputstream = new FileOutputStream(destinationPath + entryName);
-
- while ((n = zipinputstream.read(buf, 0, BUFSIZE_ZIP)) > -1)
- {
- fileoutputstream.write(buf, 0, n);
- }
-
- fileoutputstream.close();
- zipinputstream.closeEntry();
- zipentry = zipinputstream.getNextEntry();
-
- }// foreach entry
-
- zipinputstream.close();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }// void extractZipFiles
-
-
- /**
- * Process xml files in-memory
- *
- * @param zipfile Name of zip-file
- * @return boolean value showing if the parsing happend correctly
- */
- boolean processZipFiles(String zipfile)
- {
- // Set to false if any of the files doesn't parse correctly
- boolean res = true;
-
- try
- {
- byte[] buf = new byte[BUFSIZE_ZIP];
-
- ZipInputStream zipinputstream = new ZipInputStream(new FileInputStream(zipfile));
- ZipEntry zipentry = zipinputstream.getNextEntry();
-
- while (zipentry != null)
- {
- String entryName = zipentry.getName();
- int n = 0;
-
- File newFile = new File(entryName);
- String directory = newFile.getParent();
-
- if (directory == null)
- {
- if (newFile.isDirectory())
- {
- break;
- }
- }
-
- ByteArrayOutputStream outstream = new ByteArrayOutputStream();
- while ((n = zipinputstream.read(buf, 0, BUFSIZE_ZIP)) > -1)
- {
- outstream.write(buf, 0, n);
- }
-
- String xml = outstream.toString();
- Event event = parse(xml);
-
- // Prepare next entry
- outstream.close();
- zipinputstream.closeEntry();
- zipentry = zipinputstream.getNextEntry();
-
- // Add event
- if (event != null)
- {
- try
- {
- eventManager.putEvent(new Context(), event);
- }
- catch (Exception ex)
- {
- // We trust putEvent to do the proper logging
- res = false;
- }
- }
- else
- {
- // The XML must've been malformed
- res = false;
- }
-
- // Be nice to the server; pause between each xml file.
- Thread.sleep(SLEEP_ZIPPING);
-
- }// foreach entry
-
- zipinputstream.close();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
-
- return res;
- }// void extractZipFiles
-
- /**
- * Get node text
- * @param node XML node
- * @return Text string
- * @throws DOMException Thrown on error
- */
- public static String getTextContent(Node node) throws DOMException
- {
- String textContent = "";
-
- if (node.getNodeType() == Node.ATTRIBUTE_NODE)
- {
- textContent = node.getNodeValue();
- }
- else
- {
- Node child = node.getFirstChild();
- if (child != null)
- {
- Node sibling = child.getNextSibling();
- if (sibling != null)
- {
- StringBuffer sb = new StringBuffer();
- getTextContent(node, sb);
- textContent = sb.toString();
- }
- else
- {
- if (child.getNodeType() == Node.TEXT_NODE || child.getNodeType() == Node.CDATA_SECTION_NODE)
- {
- textContent = child.getNodeValue();
- }
- else
- {
- textContent = getTextContent(child);
- }
- }
- }
- }
-
- return textContent;
- }
-
- /**
- * Get node text
- *
- * @param node XML node
- * @return Text string
- * @throws DOMException Thrown on error
- */
- private static void getTextContent(Node node, StringBuffer sb) throws DOMException
- {
- Node child = node.getFirstChild();
- while (child != null)
- {
- if (child.getNodeType() == Node.TEXT_NODE)
- {
- sb.append(child.getNodeValue());
- }
- else
- {
- getTextContent(child, sb);
- }
- child = child.getNextSibling();
- }
- }
-
-
- /**
- * Parse event XML
- *
- * @param xml XML string
- * @return Object representation of the event XML
- * @throws javax.xml.parsers.ParserConfigurationException Thrown on parse error
- */
- public Event parse(String xml) throws ParserConfigurationException
- {
- Event res;
-
- DocumentBuilder builder = factory.newDocumentBuilder();
-
- try
- {
- StringReader reader = new StringReader(xml);
- InputSource inputSource = new InputSource(reader);
- Document doc = builder.parse(inputSource);
-
- res = new Event();
-
- Severity severity = new Severity();
- String severityStr = getTextContent(doc.getElementsByTagName(
- Constants.PROVIDER_XMLTAG_SEVERITY).item(0));
- res.setSeverity(severity);
-
- severity.setEnumerator(Integer.parseInt(severityStr));
- res.setCreated(new Date(System.currentTimeMillis()));
-
- res.setShortDescription(getTextContent(
- doc.getElementsByTagName(Constants.PROVIDER_XMLTAG_MESSAGE).item(0)));
-
- res.setLongDescription(getTextContent(
- doc.getElementsByTagName(Constants.PROVIDER_XMLTAG_DESCRIPTION).item(0)));
-
- // For now we use the job signature as the event name
- res.setName(getTextContent(
- doc.getElementsByTagName(Constants.PROVIDER_XMLTAG_JOB).item(0)));
-
- // Attempt to set source task as precisely as possible. If the event comes from a job we
- // have not seen yet, we have no option but to use the root provider as source.
- Task rootTask = xmlProvider.getRootTask(ctx);
- Task source = null;
-
- try
- {
- String hostname = getTextContent(doc.getElementsByTagName(
- Constants.PROVIDER_XMLTAG_HOST).item(0));
- res.setHost(hostname);
-
- // Set source; if the event name is not set (not a job), use the agent as source
- String agentName = rootTask.getName() + "/" + hostname;
- if (res.getName() == null || res.getName().length() == 0)
- {
- source = KeyXmlRpcServer.findByName(rootTask, agentName);
- }
- else
- {
- source = KeyXmlRpcServer.findByName(
- KeyXmlRpcServer.findByName(rootTask, agentName), res.getName());
- }
- }
- catch (Exception ex)
- {
- // Suppressed; missing host is allowed
- }
-
- // Fall back to provider if source couldn't be deduced
- if (source == null)
- {
- source = xmlProvider.getRootTask(ctx);
- }
-
- res.setProvider(source);
- }
- catch (Exception ex)
- {
- res = null;
-
- // Couldn't parse
- Log.error(Constants.PROVIDER_XMLPARSER_ERROR_PREFIX + ex.toString());
- }
-
- return res;
- }
-
- }// class FileHandler