I currently have a file monitor, which reads an XML file and updates database tables base on the contents. When a file is read it is validated against a specific schema to ensure the contents are correct.
The result of the validation effects the destination of the file to move.
If the schema is successful, there are no issues when moving the file to the processed directory, however, when the schema fails I am unable to rename the file itself.
However, when I debug and explore the file paths to ensure the file is being moved to the right location, it often allows me to rename the file which makes me think this is a timing issue.
File Monitor Class :
// Get a directory listing; FilterFiles filterFiles = new FilterFiles(); String inbox = GlobalVars.getConfiguration().getInboundInbox(); String [] dir = new File(inbox).list(filterFiles); // Wait 500 ms before obtaining files (Avoid the ResourceBusy error); try { Thread.sleep(500); } catch (InterruptedException e) { // Log errors logger.info("Interrupted Exception " + e.getMessage()); new LogStackTrace(logger, e); e.printStackTrace(); } // Iterate through directory; for ( int a=0; a < dir.length; a++ ) { // Derive the full file path i.e. folder + path name; String fullFilePath = GetAbsoloutePath.getFullAbsoluteFilePath(inbox, dir[a]); logger.info("=========================================================="); logger.info(""); logger.info("Found File : " + fullFilePath); logger.info("=========================================================="); // Does the file exist & can we read the file at this time; File file = new File(fullFilePath); if (file.exists() && file.canRead()) { // Process the file; StringBuffer renamedFile = new StringBuffer(); // Rename the file to indicate InProgess; String fileName = file.getAbsolutePath(); String fileNameInProgress = fileName.trim() + ".InProgress"; // Delete the file if exists where we are moving the file to; File deleteFile = new File(fileNameInProgress); if (deleteFile.delete()) logger.info("Existing file deleted: " + fileNameInProgress); // Ensure file is renamed so we can see it is in progress if (!file.renameTo(new File(fileNameInProgress)) ) { // Logging logger.error("Failed to renamed file :" + fileName + " to " + fileNameInProgress); break; }else{ logger.info("Renamed file to : " + fileNameInProgress); // Pass back name of renamed file; renamedFile.append(fileNameInProgress); File renamedFileRef = new File(renamedFile.toString()); // Path to move - could be errors or processed String pathToMove = ""; // Parse XMobject ParseInboundXML par = new ParseInboundXML(); // check if parse was succesful if(par.parseXML(renamedFileRef, con)){ // Path to move XML file pathToMove = GlobalVars.getConfiguration().getInboundProcessed()+ "\\" + file.getName(); //Logging logger.info("File parsed and tables updated successfully"); logger.info("Moving file to : " + pathToMove); }else{ pathToMove = GlobalVars.getConfiguration().getInboundErrors()+ "\\" + file.getName(); //Logging logger.error("Errors when parsing file and updating tables"); logger.error("Moving file to : " + pathToMove); } // Help with garbage collection par = null; // New file File newPath = new File(pathToMove); // Need to check if this already exists in processed- if so we must override the existing file // Otherwise the move will not be processed and the same docuemnt will be continously processed if(newPath.exists()) newPath.delete();
After the above code has been executed, this block of code is executed and this is where the rename fails:
// Rename path so it is placed in processed folder if(renamedFileRef.renameTo(newPath)){ //Logging logger.info("File processed successfully"); }else{ // Logging logger.error("Unable process file"); }
Within the code you may notice the call to :
// Parse XMobject ParseInboundXML par = new ParseInboundXML(); // check if parse was succesful if(par.parseXML(renamedFileRef, con)){
This method is where the validation occurs and the parsing of the XML document and returns a true or false value depending on the outcome.
The area in which it fails is at the start of the method :
// Find schema path String schemaPath = GlobalVars.getConfiguration().getInboundSchemaLocation(); String schemaFileName = "WMS_" + file.getAbsoluteFile().toString().split("#")[2] + ".xsd"; // Schema location String schemaLocation = schemaPath + "\\" + schemaFileName; // Create schema factory SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); // Schema file Source schemaFile = new StreamSource(new File(schemaLocation)); // Apply schema and validate XML Schema schema = schemaFactory.newSchema(schemaFile); Validator validator = schema.newValidator(); Source xmlFile = new StreamSource(file); validator.validate(xmlFile);
I think the issue may lie around
Source xmlFile = new StreamSource(file);
as this is the file we try to rename, and i think if it fails validation, its possible that this may be keeping the file open and would explain why there are no issues when it passes validation.
No comments:
Post a Comment