/** * Configure CB4J record reader. * * @throws BatchConfigurationException thrown if record reader is not correctly configured */ private void configureRecordReader() throws BatchConfigurationException { String inputDataProperty = configurationProperties.getProperty(BatchConstants.INPUT_DATA_PATH); String encodingProperty = configurationProperties.getProperty(BatchConstants.INPUT_DATA_ENCODING); String skipHeaderProperty = configurationProperties.getProperty(BatchConstants.INPUT_DATA_SKIP_HEADER); // check if input data file is specified if (inputDataProperty == null) { String error = "Configuration failed : input data file is mandatory but was not specified"; logger.severe(error); throw new BatchConfigurationException(error); } try { boolean skipHeader; if (skipHeaderProperty != null) { skipHeader = Boolean.valueOf(skipHeaderProperty); } else { skipHeader = BatchConstants.DEFAULT_SKIP_HEADER; logger.info("Skip header property not specified, default to false"); } String encoding; if (encodingProperty == null || (encodingProperty.length() == 0)) { encoding = BatchConstants.DEFAULT_FILE_ENCODING; logger.info( "No encoding specified for input data, using system default encoding : " + encoding); } else { if (Charset.availableCharsets().get(Charset.forName(encodingProperty).name()) == null || !Charset.isSupported(encodingProperty)) { encoding = BatchConstants.DEFAULT_FILE_ENCODING; logger.warning( "Encoding '" + encodingProperty + "' not supported, using system default encoding : " + encoding); } else { encoding = encodingProperty; logger.info("Using '" + encoding + "' encoding for input file reading"); } } recordReader = new RecordReaderImpl(inputDataProperty, encoding, skipHeader); logger.info("Data input file : " + inputDataProperty); } catch (FileNotFoundException e) { String error = "Configuration failed : input data file '" + inputDataProperty + "' could not be opened"; logger.severe(error); throw new BatchConfigurationException(error); } }
/** * Configure the default record mapper. * * @return the default implementation of record mapper * @throws BatchConfigurationException if the target type class is not found */ private RecordMapper configureDefaultRecordMapper() throws BatchConfigurationException { RecordMapper recordMapper; String recordClassName = configurationProperties.getProperty(BatchConstants.INPUT_RECORD_CLASS); if (recordClassName == null || recordClassName.length() == 0) { try { Class recordProcessorClass = Class.forName(recordProcessor.getClass().getName()); Method[] declaredMethods = recordProcessorClass.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { if (declaredMethod.getName().equals("processRecord")) { recordClassName = declaredMethod.getParameterTypes()[0].getName(); break; } } } catch (ClassNotFoundException e) { String error = "Configuration failed : unable to get record class name from registered record processor implementation."; logger.severe(error); throw new BatchConfigurationException(error, e); } } String[] headers; String headersProperty = configurationProperties.getProperty(BatchConstants.INPUT_RECORD_HEADERS); if (headersProperty == null) { // if no headers specified, use field names declared in the header record String headerRecord = recordReader.getHeaderRecord(); Record record = recordParser.parseRecord( headerRecord, 0); // use the record parser to parse the header record using the right delimiter List<Field> fields = record.getFields(); headers = new String[fields.size()]; for (int i = 0; i < fields.size(); i++) { headers[i] = fields.get(i).getContent(); } } else { // headers specified, split the comma separated list headers = headersProperty.split(","); } try { recordMapper = new DefaultRecordMapperImpl(recordClassName, headers, typeConverters); } catch (ClassNotFoundException e) { String error = "Configuration failed : Class " + recordClassName + " not found."; logger.severe(error); throw new BatchConfigurationException(error, e); } return recordMapper; }
public boolean getJmxEnabled() { return Boolean.valueOf( configurationProperties.getProperty(BatchConstants.OUTPUT_DATA_JMX_ENABLED)); }
public boolean getSkipHeader() { return Boolean.valueOf( configurationProperties.getProperty(BatchConstants.INPUT_DATA_SKIP_HEADER)); }
public boolean getAbortOnFirstMappingException() { return Boolean.valueOf( configurationProperties.getProperty( BatchConstants.OUTPUT_DATA_ABORT_ON_FIRST_MAPPING_EXCEPTION)); }
public boolean getAbortOnFirstError() { return Boolean.valueOf( configurationProperties.getProperty(BatchConstants.OUTPUT_DATA_ABORT_ON_FIRST_ERROR)); }
public boolean getAbortOnFirstReject() { return Boolean.valueOf( configurationProperties.getProperty(BatchConstants.OUTPUT_DATA_ABORT_ON_FIRST_REJECT)); }
/** * Configure CB4J record parser. * * @throws BatchConfigurationException thrown if record parser is not correctly configured */ private void configureRecordParser() throws BatchConfigurationException { // read record type property and set default value if invalid input String recordTypeProperty = configurationProperties.getProperty(BatchConstants.INPUT_RECORD_TYPE); String recordType; if (recordTypeProperty == null || recordTypeProperty.length() == 0) { recordType = BatchConstants.DEFAULT_RECORD_TYPE; logger.info( "Record type property not specified, records will be considered as delimiter-separated values"); } else if (!RecordType.DSV.toString().equalsIgnoreCase(recordTypeProperty) && !RecordType.FLR.toString().equalsIgnoreCase(recordTypeProperty)) { recordType = BatchConstants.DEFAULT_RECORD_TYPE; logger.warning( "Record type property '" + recordTypeProperty + "' is invalid, records will be considered as delimiter-separated values"); } else { recordType = recordTypeProperty; } // fixed length record configuration if (RecordType.FLR.toString().equalsIgnoreCase(recordType)) { String fieldsLengthProperties = configurationProperties.getProperty(BatchConstants.INPUT_FIELD_LENGTHS); if (fieldsLengthProperties == null || fieldsLengthProperties.length() == 0) { String error = "Configuration failed : when using fixed length records, fields length values property '" + BatchConstants.INPUT_FIELD_LENGTHS + "' is mandatory but was not specified."; logger.severe(error); throw new BatchConfigurationException(error); } else { // parse fields length property and extract numeric values StringTokenizer stringTokenizer = new StringTokenizer(fieldsLengthProperties, ","); int[] fieldsLength = new int[stringTokenizer.countTokens()]; int index = 0; while (stringTokenizer.hasMoreTokens()) { String length = stringTokenizer.nextToken(); try { fieldsLength[index] = Integer.parseInt(length); index++; } catch (NumberFormatException e) { String error = "Configuration failed : field length '" + length + "' in property " + BatchConstants.INPUT_FIELD_LENGTHS + "=" + fieldsLengthProperties + " is not numeric."; logger.severe(error); throw new BatchConfigurationException(error); } } recordParser = new FlrRecordParserImpl(fieldsLength); } } else { // delimited values configuration String recordSizeProperty = configurationProperties.getProperty(BatchConstants.INPUT_RECORD_SIZE); try { String fieldsDelimiter = configurationProperties.getProperty(BatchConstants.INPUT_FIELD_DELIMITER); if (fieldsDelimiter == null || fieldsDelimiter.length() == 0) { fieldsDelimiter = BatchConstants.DEFAULT_FIELD_DELIMITER; logger.info("No field delimiter specified, using default : '" + fieldsDelimiter + "'"); } String trimWhitespacesProperty = configurationProperties.getProperty(BatchConstants.INPUT_FIELD_TRIM); boolean trimWhitespaces; if (trimWhitespacesProperty != null) { trimWhitespaces = Boolean.valueOf(trimWhitespacesProperty); } else { trimWhitespaces = BatchConstants.DEFAULT_FIELD_TRIM; logger.info("Trim whitespaces property not specified, default to " + trimWhitespaces); } String dataQualifierCharacterProperty = configurationProperties.getProperty(BatchConstants.INPUT_FIELD_QUALIFIER_CHAR); String dataQualifierCharacter = BatchConstants.DEFAULT_FIELD_QUALIFIER_CHAR; if (dataQualifierCharacterProperty != null && dataQualifierCharacterProperty.length() > 0) { dataQualifierCharacter = dataQualifierCharacterProperty; } else { logger.info( "Data qualifier character not specified, default to " + dataQualifierCharacter); } recordParser = new DsvRecordParserImpl(fieldsDelimiter, trimWhitespaces, dataQualifierCharacter); if (recordSizeProperty == null || recordSizeProperty.length() == 0) { logger.info( "Record size property not specified, it will be calculated from the header record"); String headerRecord = recordReader.getHeaderRecord(); Record record = recordParser.parseRecord( headerRecord, 0); // use the record parser to parse the header record using the right delimiter recordSizeProperty = String.valueOf(record.getFields().size()); } int recordSize = Integer.parseInt(recordSizeProperty); recordParser = new DsvRecordParserImpl( recordSize, fieldsDelimiter, trimWhitespaces, dataQualifierCharacter); logger.info("Record size : " + recordSize); logger.info("Fields delimiter : '" + fieldsDelimiter + "'"); logger.info("Data qualifier character : '" + dataQualifierCharacter + "'"); } catch (NumberFormatException e) { String error = "Record size property is not recognized as a number : " + recordSizeProperty; logger.severe(error); throw new BatchConfigurationException(error); } } }
/** * Configure loggers for ignored/rejected/errors records. * * @throws BatchConfigurationException thrown if loggers for ignored/rejected/errors records are * not correctly configured */ private void configureRecordsLoggers() throws BatchConfigurationException { String inputDataProperty = configurationProperties.getProperty(BatchConstants.INPUT_DATA_PATH); ReportFormatter reportFormatter = new ReportFormatter(); // ignored records logger String outputIgnored = configurationProperties.getProperty(BatchConstants.OUTPUT_DATA_IGNORED); if (outputIgnored == null || (outputIgnored.length() == 0)) { outputIgnored = BatchConfigurationUtil.removeExtension(inputDataProperty) + BatchConstants.DEFAULT_IGNORED_SUFFIX; logger.info("No log file specified for ignored records, using default : " + outputIgnored); } try { FileHandler ignoredRecordsHandler = new FileHandler(outputIgnored); ignoredRecordsHandler.setFormatter(reportFormatter); Logger ignoredRecordsReporter = Logger.getLogger(BatchConstants.LOGGER_CB4J_IGNORED); ignoredRecordsReporter.addHandler(ignoredRecordsHandler); } catch (IOException e) { String error = "Unable to use file for ignored records : " + outputIgnored; logger.severe(error); throw new BatchConfigurationException(error); } // rejected errors logger String outputRejected = configurationProperties.getProperty(BatchConstants.OUTPUT_DATA_REJECTED); if (outputRejected == null || (outputRejected.length() == 0)) { outputRejected = BatchConfigurationUtil.removeExtension(inputDataProperty) + BatchConstants.DEFAULT_REJECTED_SUFFIX; logger.info("No log file specified for rejected records, using default : " + outputRejected); } try { FileHandler rejectedRecordsHandler = new FileHandler(outputRejected); rejectedRecordsHandler.setFormatter(reportFormatter); Logger rejectedRecordsReporter = Logger.getLogger(BatchConstants.LOGGER_CB4J_REJECTED); rejectedRecordsReporter.addHandler(rejectedRecordsHandler); } catch (IOException e) { String error = "Unable to use file for rejected records : " + outputRejected; logger.severe(error); throw new BatchConfigurationException(error); } // errors record logger String outputErrors = configurationProperties.getProperty(BatchConstants.OUTPUT_DATA_ERRORS); if (outputErrors == null || (outputErrors.length() == 0)) { outputErrors = BatchConfigurationUtil.removeExtension(inputDataProperty) + BatchConstants.DEFAULT_ERRORS_SUFFIX; logger.info("No log file specified for error records, using default : " + outputErrors); } try { FileHandler errorRecordsHandler = new FileHandler(outputErrors); errorRecordsHandler.setFormatter(reportFormatter); Logger errorRecordsReporter = Logger.getLogger(BatchConstants.LOGGER_CB4J_ERRORS); errorRecordsReporter.addHandler(errorRecordsHandler); } catch (IOException e) { String error = "Unable to use file for error records : " + outputErrors; logger.severe(error); throw new BatchConfigurationException(error); } }
/** * Configure the batch engine. * * @throws BatchConfigurationException thrown if : * <ul> * <li>One of the mandatory parameters is not specified, please refer to the reference * documentation for all parameters details * <li>Log files for ignored and rejected records cannot be used * <li>One of the mandatory services is not specified, please refer to the reference * documentation for all mandatory services implementations * </ul> */ public void configure() throws BatchConfigurationException { /* * Configure CB4J logger */ configureCB4JLogger(); logger.info("Configuration started at : " + new Date()); /* * Check record processor */ if (recordProcessor == null) { String error = "Configuration failed : no record processor registered"; logger.severe(error); throw new BatchConfigurationException(error); } /* * Configure record reader */ configureRecordReader(); /* * Configure record parser */ configureRecordParser(); /* * Configure loggers for ignored/rejected/error records */ configureRecordsLoggers(); /* * Configure batch reporter : if no custom reporter registered, use default implementation */ if (batchReporter == null) { batchReporter = new DefaultBatchReporterImpl(); } batchReporter.init(); /* * Configure record validator with provided validators : if no custom validator registered, use default implementation */ if (recordValidator == null) { recordValidator = new DefaultRecordValidatorImpl(fieldValidators); } /* * Check record mapper : if no custom mapper registered, use default implementation */ if (recordMapper == null) { recordMapper = configureDefaultRecordMapper(); } /* * register JMX MBean */ if (Boolean.valueOf( configurationProperties.getProperty(BatchConstants.OUTPUT_DATA_JMX_ENABLED))) { configureJmxMBean(); } logger.info("Configuration successful"); logger.info("Configuration parameters details : " + configurationProperties); }